mirror of
https://github.com/ansible-collections/community.mysql.git
synced 2025-08-04 05:04:23 -07:00
Compare commits
63 commits
Author | SHA1 | Date | |
---|---|---|---|
|
a4d3246b22 |
||
|
21a5a8bd01 |
||
|
011bdbc2ef |
||
|
3ff1f48c41 |
||
|
3e975ca7a1 |
||
|
54efe0bbb8 |
||
|
62e2ed5d36 |
||
|
8687e575d7 |
||
|
cf25d85e49 |
||
|
cb323da665 |
||
|
963e042edd |
||
|
a026d60f84 |
||
|
43a8037232 |
||
|
43e688a37a |
||
|
878dc5794a |
||
|
85a63511b6 |
||
|
fadbd30572 |
||
|
2020870155 |
||
|
40da237de7 |
||
|
786470058c |
||
|
d363315ecb |
||
|
275d85067a |
||
|
c199000eee |
||
|
108c4ae729 |
||
|
4cfdbe64a3 |
||
|
836a1ce048 |
||
|
41e7ce5aaa |
||
|
99548e10cb |
||
|
6ebf59e234 |
||
|
97be51ef45 |
||
|
d8ab933d79 |
||
|
949cb0c1dd |
||
|
89eb2d2fea |
||
|
4d4a5f2a02 |
||
|
f7677aa05b |
||
|
0921d4eef5 |
||
|
f4736770e3 |
||
|
3bb7b00497 |
||
|
393023eb07 |
||
|
256817ca32 |
||
|
a2a4a1ff61 |
||
|
b730cd6675 |
||
|
2a57a4d659 |
||
|
278337d34f |
||
|
d5a1e3639a |
||
|
bfcf89073a |
||
|
15ee80b57c |
||
|
59d411ac82 |
||
|
b0de252ce2 |
||
|
96a255c00a |
||
|
f46b84e670 |
||
|
9386045797 |
||
|
ace830ef56 |
||
|
e5919428f1 |
||
|
dbcc7e7e60 |
||
|
f49206d3b3 |
||
|
64b06aa543 |
||
|
9c17158802 |
||
|
d200481305 |
||
|
b3a83aa0a3 |
||
|
fe8f3662eb |
||
|
59cbe5ffe3 | ||
|
d517d658a1 |
159 changed files with 5333 additions and 2199 deletions
5
.github/patchback.yml
vendored
Normal file
5
.github/patchback.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
backport_branch_prefix: patchback/backports/
|
||||||
|
backport_label_prefix: backport-
|
||||||
|
target_branch_prefix: stable-
|
||||||
|
...
|
405
.github/workflows/ansible-test-plugins.yml
vendored
405
.github/workflows/ansible-test-plugins.yml
vendored
|
@ -1,3 +1,4 @@
|
||||||
|
---
|
||||||
name: Plugins CI
|
name: Plugins CI
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
@ -14,98 +15,320 @@ on:
|
||||||
- cron: '0 6 * * *'
|
- cron: '0 6 * * *'
|
||||||
|
|
||||||
|
|
||||||
env:
|
|
||||||
mysql_version_file: "./ansible_collections/community/mysql/tests/integration/targets/setup_mysql/defaults/main.yml"
|
|
||||||
connector_version_file: "./ansible_collections/community/mysql/tests/integration/targets/setup_mysql/vars/main.yml"
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
sanity:
|
sanity:
|
||||||
name: "Sanity (Python: ${{ matrix.python }}, Ansible: ${{ matrix.ansible }})"
|
name: "Sanity (Ansible: ${{ matrix.ansible }})"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
ansible:
|
ansible:
|
||||||
- stable-2.9
|
- stable-2.12
|
||||||
- stable-2.10
|
- stable-2.13
|
||||||
- stable-2.11
|
- stable-2.14
|
||||||
- devel
|
- devel
|
||||||
steps:
|
steps:
|
||||||
|
- name: Perform sanity testing
|
||||||
- name: Check out code
|
uses: ansible-community/ansible-test-gh-action@release/v1
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
with:
|
||||||
path: ansible_collections/community/mysql
|
ansible-core-version: ${{ matrix.ansible }}
|
||||||
|
testing-type: sanity
|
||||||
- name: Set up Python
|
pull-request-change-detection: true
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: 3.8
|
|
||||||
|
|
||||||
- name: Install ansible-base (${{ matrix.ansible }})
|
|
||||||
run: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz --disable-pip-version-check
|
|
||||||
|
|
||||||
- name: Run sanity tests
|
|
||||||
run: ansible-test sanity --docker -v --color
|
|
||||||
working-directory: ./ansible_collections/community/mysql
|
|
||||||
|
|
||||||
integration:
|
integration:
|
||||||
name: "Integration (Python: ${{ matrix.python }}, Ansible: ${{ matrix.ansible }}, MySQL: ${{ matrix.mysql }}, Connector: ${{ matrix.connector }})"
|
name: "Integration (Python: ${{ matrix.python }}, Ansible: ${{ matrix.ansible }}, DB: ${{ matrix.db_engine_name }} ${{ matrix.db_engine_version }}, connector: ${{ matrix.connector_name }} ${{ matrix.connector_version }})"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
mysql:
|
|
||||||
- 5.7.31
|
|
||||||
- 8.0.22
|
|
||||||
ansible:
|
ansible:
|
||||||
- stable-2.9
|
- stable-2.12
|
||||||
- stable-2.10
|
- stable-2.13
|
||||||
- stable-2.11
|
- stable-2.14
|
||||||
- devel
|
- devel
|
||||||
|
db_engine_name:
|
||||||
|
- mysql
|
||||||
|
- mariadb
|
||||||
|
db_engine_version:
|
||||||
|
- 5.7.40
|
||||||
|
- 8.0.31
|
||||||
|
- 10.4.27
|
||||||
|
# - 10.5.18
|
||||||
|
# - 10.6.11
|
||||||
python:
|
python:
|
||||||
- 3.6
|
- '3.8'
|
||||||
connector:
|
- '3.9'
|
||||||
- pymysql==0.7.10
|
- '3.10'
|
||||||
- pymysql==0.9.3
|
connector_name:
|
||||||
- mysqlclient==2.0.1
|
- pymysql
|
||||||
|
- mysqlclient
|
||||||
|
connector_version:
|
||||||
|
- 0.7.11
|
||||||
|
- 0.9.3
|
||||||
|
# Before we can activate test with pymysql 1.0.2 we should debug the
|
||||||
|
# following plugins:
|
||||||
|
#
|
||||||
|
# mysql_query:
|
||||||
|
# test "Assert that create table IF NOT EXISTS is not changed with pymysql" failed
|
||||||
|
#
|
||||||
|
# mysql_replication:
|
||||||
|
# test "Assert that startreplica is not changed" failed
|
||||||
|
# - 1.0.2
|
||||||
|
- 2.0.1
|
||||||
|
- 2.0.3
|
||||||
|
- 2.1.1
|
||||||
exclude:
|
exclude:
|
||||||
- mysql: 8.0.22
|
- db_engine_name: mysql
|
||||||
connector: pymysql==0.7.10
|
db_engine_version: 10.4.27
|
||||||
|
|
||||||
|
- db_engine_name: mysql
|
||||||
|
db_engine_version: 10.5.18
|
||||||
|
|
||||||
|
- db_engine_name: mysql
|
||||||
|
db_engine_version: 10.6.11
|
||||||
|
|
||||||
|
- db_engine_name: mariadb
|
||||||
|
db_engine_version: 5.7.40
|
||||||
|
|
||||||
|
- db_engine_name: mariadb
|
||||||
|
db_engine_version: 8.0.31
|
||||||
|
|
||||||
|
- connector_name: pymysql
|
||||||
|
connector_version: 2.0.1
|
||||||
|
|
||||||
|
- connector_name: pymysql
|
||||||
|
connector_version: 2.0.3
|
||||||
|
|
||||||
|
- connector_name: pymysql
|
||||||
|
connector_version: 2.1.1
|
||||||
|
|
||||||
|
- connector_name: mysqlclient
|
||||||
|
connector_version: 0.7.11
|
||||||
|
|
||||||
|
- connector_name: mysqlclient
|
||||||
|
connector_version: 0.9.3
|
||||||
|
|
||||||
|
- connector_name: mysqlclient
|
||||||
|
connector_version: 1.0.2
|
||||||
|
|
||||||
|
- db_engine_name: mariadb
|
||||||
|
connector_version: 0.7.11
|
||||||
|
|
||||||
|
- db_engine_version: 5.7.40
|
||||||
|
python: '3.9'
|
||||||
|
|
||||||
|
- db_engine_version: 5.7.40
|
||||||
|
python: '3.10'
|
||||||
|
|
||||||
|
- db_engine_version: 5.7.40
|
||||||
|
ansible: stable-2.13
|
||||||
|
|
||||||
|
- db_engine_version: 5.7.40
|
||||||
|
ansible: stable-2.14
|
||||||
|
|
||||||
|
- db_engine_version: 5.7.40
|
||||||
|
ansible: devel
|
||||||
|
|
||||||
|
- db_engine_version: 8.0.31
|
||||||
|
python: '3.8'
|
||||||
|
|
||||||
|
- db_engine_version: 8.0.31
|
||||||
|
python: '3.8'
|
||||||
|
|
||||||
|
- db_engine_version: 10.4.27
|
||||||
|
python: '3.10'
|
||||||
|
|
||||||
|
- db_engine_version: 10.4.27
|
||||||
|
ansible: devel
|
||||||
|
|
||||||
|
- db_engine_version: 10.6.11
|
||||||
|
python: '3.8'
|
||||||
|
|
||||||
|
- db_engine_version: 10.6.11
|
||||||
|
python: '3.9'
|
||||||
|
|
||||||
|
- python: '3.8'
|
||||||
|
connector_version: 2.0.3
|
||||||
|
|
||||||
|
- python: '3.8'
|
||||||
|
connector_version: 2.1.1
|
||||||
|
|
||||||
|
- python: '3.9'
|
||||||
|
connector_version: 0.7.11
|
||||||
|
|
||||||
|
- python: '3.9'
|
||||||
|
connector_version: 2.0.1
|
||||||
|
|
||||||
|
- python: '3.9'
|
||||||
|
connector_version: 2.1.1
|
||||||
|
|
||||||
|
- python: '3.10'
|
||||||
|
connector_version: 0.7.11
|
||||||
|
|
||||||
|
- python: '3.10'
|
||||||
|
connector_version: 0.9.3
|
||||||
|
|
||||||
|
- python: '3.10'
|
||||||
|
connector_version: 2.0.1
|
||||||
|
|
||||||
|
- python: '3.10'
|
||||||
|
connector_version: 2.0.3
|
||||||
|
|
||||||
|
- python: '3.8'
|
||||||
|
ansible: stable-2.13
|
||||||
|
|
||||||
|
- python: '3.8'
|
||||||
|
ansible: stable-2.14
|
||||||
|
|
||||||
|
- python: '3.8'
|
||||||
|
ansible: devel
|
||||||
|
|
||||||
|
- python: '3.9'
|
||||||
|
ansible: stable-2.12
|
||||||
|
|
||||||
|
- python: '3.9'
|
||||||
|
ansible: devel
|
||||||
|
|
||||||
|
- python: '3.10'
|
||||||
|
ansible: stable-2.12
|
||||||
|
|
||||||
|
services:
|
||||||
|
db_primary:
|
||||||
|
image: docker.io/library/${{ matrix.db_engine_name }}:${{ matrix.db_engine_version }}
|
||||||
|
env:
|
||||||
|
MARIADB_ROOT_PASSWORD: msandbox
|
||||||
|
MYSQL_ROOT_PASSWORD: msandbox
|
||||||
|
ports:
|
||||||
|
- 3307:3306
|
||||||
|
# We write our own health-cmd because the mariadb container does not
|
||||||
|
# provide a healthcheck
|
||||||
|
options: >-
|
||||||
|
--health-cmd "mysqladmin ping -P 3306 -pmsandbox |grep alive || exit 1"
|
||||||
|
--health-start-period 10s
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 6
|
||||||
|
|
||||||
|
db_replica1:
|
||||||
|
image: docker.io/library/${{ matrix.db_engine_name }}:${{ matrix.db_engine_version }}
|
||||||
|
env:
|
||||||
|
MARIADB_ROOT_PASSWORD: msandbox
|
||||||
|
MYSQL_ROOT_PASSWORD: msandbox
|
||||||
|
ports:
|
||||||
|
- 3308:3306
|
||||||
|
options: >-
|
||||||
|
--health-cmd "mysqladmin ping -P 3306 -pmsandbox |grep alive || exit 1"
|
||||||
|
--health-start-period 10s
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 6
|
||||||
|
|
||||||
|
db_replica2:
|
||||||
|
image: docker.io/library/${{ matrix.db_engine_name }}:${{ matrix.db_engine_version }}
|
||||||
|
env:
|
||||||
|
MARIADB_ROOT_PASSWORD: msandbox
|
||||||
|
MYSQL_ROOT_PASSWORD: msandbox
|
||||||
|
ports:
|
||||||
|
- 3309:3306
|
||||||
|
options: >-
|
||||||
|
--health-cmd "mysqladmin ping -P 3306 -pmsandbox |grep alive || exit 1"
|
||||||
|
--health-start-period 10s
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 6
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Check out code
|
# No need to check for service health. GitHub Action took care of it.
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
- name: Restart MySQL server with settings for replication
|
||||||
|
run: |
|
||||||
|
docker exec ${{ job.services.db_primary.id }} bash -c 'echo -e [mysqld]\\nserver-id=1\\nlog-bin=/var/lib/mysql/primary-bin > /etc/mysql/conf.d/replication.cnf'
|
||||||
|
docker exec ${{ job.services.db_replica1.id }} bash -c 'echo -e [mysqld]\\nserver-id=2\\nlog-bin=/var/lib/mysql/replica1-bin > /etc/mysql/conf.d/replication.cnf'
|
||||||
|
docker exec ${{ job.services.db_replica2.id }} bash -c 'echo -e [mysqld]\\nserver-id=3\\nlog-bin=/var/lib/mysql/replica2-bin > /etc/mysql/conf.d/replication.cnf'
|
||||||
|
docker restart -t 30 ${{ job.services.db_primary.id }}
|
||||||
|
docker restart -t 30 ${{ job.services.db_replica1.id }}
|
||||||
|
docker restart -t 30 ${{ job.services.db_replica2.id }}
|
||||||
|
|
||||||
|
- name: Wait for the primary to be healthy
|
||||||
|
run: >
|
||||||
|
while ! /usr/bin/docker inspect
|
||||||
|
--format="{{if .Config.Healthcheck}}{{print .State.Health.Status}}{{end}}"
|
||||||
|
${{ job.services.db_primary.id }}
|
||||||
|
| grep healthy && [[ "$SECONDS" -lt 120 ]]; do sleep 1; done
|
||||||
|
|
||||||
|
- name: Compute docker_image - Set python_version_flat
|
||||||
|
run: >
|
||||||
|
echo "python_version_flat=$(echo ${{ matrix.python }}
|
||||||
|
| tr -d '.')" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Compute docker_image - Set connector_version_flat
|
||||||
|
run: >
|
||||||
|
echo "connector_version_flat=$(echo ${{ matrix.connector_version }}
|
||||||
|
|tr -d .)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Compute docker_image - Set db_engine_version_flat
|
||||||
|
run: >
|
||||||
|
echo "db_engine_version_flat=$(echo ${{ matrix.db_engine_version }}
|
||||||
|
| awk -F '.' '{print $1 $2}')" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Compute docker_image - Set db_client
|
||||||
|
run: >
|
||||||
|
if [[ ${{ env.db_engine_version_flat }} == 57 ]]; then
|
||||||
|
echo "db_client=my57" >> $GITHUB_ENV;
|
||||||
|
else
|
||||||
|
echo "db_client=$(echo ${{ matrix.db_engine_name }})" >> $GITHUB_ENV;
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Set docker_image
|
||||||
|
run: >
|
||||||
|
docker_image_multiline=("
|
||||||
|
ghcr.io/ansible-collections/community.mysql\
|
||||||
|
/test-container-${{ env.db_client }}\
|
||||||
|
-py${{ env.python_version_flat }}\
|
||||||
|
-${{ matrix.connector_name }}${{ env.connector_version_flat }}\
|
||||||
|
:latest")
|
||||||
|
|
||||||
|
echo "docker_image=$(printf '%s' $docker_image_multiline)"
|
||||||
|
>> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
Perform integration testing against
|
||||||
|
Ansible version ${{ matrix.ansible }}
|
||||||
|
under Python ${{ matrix.python }}
|
||||||
|
uses: ansible-community/ansible-test-gh-action@release/v1
|
||||||
with:
|
with:
|
||||||
path: ansible_collections/community/mysql
|
ansible-core-version: ${{ matrix.ansible }}
|
||||||
|
pre-test-cmd: >-
|
||||||
|
echo Setting db_engine_name to "${{ matrix.db_engine_name }}"...;
|
||||||
|
echo -n "${{ matrix.db_engine_name }}"
|
||||||
|
> tests/integration/db_engine_name;
|
||||||
|
|
||||||
- name: Set up Python
|
echo Setting db_engine_version to \
|
||||||
uses: actions/setup-python@v2
|
"${{ matrix.db_engine_version }}"...;
|
||||||
with:
|
echo -n "${{ matrix.db_engine_version }}"
|
||||||
python-version: 3.8
|
> tests/integration/db_engine_version;
|
||||||
|
|
||||||
- name: Install ansible-base (${{ matrix.ansible }})
|
echo Setting Connector name to "${{ matrix.connector_name }}"...;
|
||||||
run: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz --disable-pip-version-check
|
echo -n "${{ matrix.connector_name }}"
|
||||||
|
> tests/integration/connector_name;
|
||||||
|
|
||||||
- name: Set MySQL version (${{ matrix.mysql }})
|
echo Setting Connector name to "${{ matrix.connector_version }}"...;
|
||||||
run: "sed -i 's/^mysql_version:.*/mysql_version: \"${{ matrix.mysql }}\"/g' ${{ env.mysql_version_file }}"
|
echo -n "${{ matrix.connector_version }}"
|
||||||
|
> tests/integration/connector_version;
|
||||||
|
|
||||||
- name: Set Connector version (${{ matrix.connector }})
|
echo Setting Python version to "${{ matrix.python }}"...;
|
||||||
run: "sed -i 's/^python_packages:.*/python_packages: [${{ matrix.connector }}]/' ${{ env.connector_version_file }}"
|
echo -n "${{ matrix.python }}"
|
||||||
|
> tests/integration/python;
|
||||||
|
|
||||||
- name: Run integration tests
|
echo Setting Ansible version to "${{ matrix.ansible }}"...;
|
||||||
run: ansible-test integration --docker -v --color --retry-on-error --continue-on-error --python ${{ matrix.python }} --diff --coverage
|
echo -n "${{ matrix.ansible }}"
|
||||||
working-directory: ./ansible_collections/community/mysql
|
> tests/integration/ansible
|
||||||
|
docker-image: ${{ env.docker_image }}
|
||||||
- name: Generate coverage report.
|
target-python-version: ${{ matrix.python }}
|
||||||
run: ansible-test coverage xml -v --requirements --group-by command --group-by version
|
testing-type: integration
|
||||||
working-directory: ./ansible_collections/community/mysql
|
|
||||||
|
|
||||||
- uses: codecov/codecov-action@v1
|
|
||||||
with:
|
|
||||||
fail_ci_if_error: false
|
|
||||||
|
|
||||||
units:
|
units:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
name: Units (Ⓐ${{ matrix.ansible }})
|
name: Units (Ⓐ${{ matrix.ansible }})
|
||||||
strategy:
|
strategy:
|
||||||
# As soon as the first unit test fails,
|
# As soon as the first unit test fails,
|
||||||
|
@ -113,36 +336,30 @@ jobs:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
ansible:
|
ansible:
|
||||||
- stable-2.9
|
- stable-2.12
|
||||||
- stable-2.10
|
- stable-2.13
|
||||||
- stable-2.11
|
- stable-2.14
|
||||||
- devel
|
- devel
|
||||||
|
python:
|
||||||
|
- 3.8
|
||||||
|
- 3.9
|
||||||
|
exclude:
|
||||||
|
- python: '3.8'
|
||||||
|
ansible: stable-2.13
|
||||||
|
- python: '3.8'
|
||||||
|
ansible: stable-2.14
|
||||||
|
- python: '3.8'
|
||||||
|
ansible: devel
|
||||||
|
- python: '3.9'
|
||||||
|
ansible: stable-2.12
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: >-
|
||||||
uses: actions/checkout@v2
|
Perform unit testing against
|
||||||
|
Ansible version ${{ matrix.ansible }}
|
||||||
|
uses: ansible-community/ansible-test-gh-action@release/v1
|
||||||
with:
|
with:
|
||||||
path: ./ansible_collections/community/mysql
|
ansible-core-version: ${{ matrix.ansible }}
|
||||||
|
target-python-version: ${{ matrix.python }}
|
||||||
- name: Set up Python
|
testing-type: units
|
||||||
uses: actions/setup-python@v2
|
pull-request-change-detection: true
|
||||||
with:
|
|
||||||
python-version: 3.8
|
|
||||||
|
|
||||||
- name: Install ansible-base (${{matrix.ansible}})
|
|
||||||
run: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz --disable-pip-version-check
|
|
||||||
|
|
||||||
# Run the unit tests
|
|
||||||
- name: Run unit test
|
|
||||||
run: ansible-test units -v --color --docker --coverage
|
|
||||||
working-directory: ./ansible_collections/community/mysql
|
|
||||||
|
|
||||||
# ansible-test support producing code coverage date
|
|
||||||
- name: Generate coverage report
|
|
||||||
run: ansible-test coverage xml -v --requirements --group-by command --group-by version
|
|
||||||
working-directory: ./ansible_collections/community/mysql
|
|
||||||
|
|
||||||
# See the reports at https://codecov.io/gh/GITHUBORG/REPONAME
|
|
||||||
- uses: codecov/codecov-action@v1
|
|
||||||
with:
|
|
||||||
fail_ci_if_error: false
|
|
||||||
|
|
34
.github/workflows/ansible-test-roles.yml
vendored
34
.github/workflows/ansible-test-roles.yml
vendored
|
@ -1,3 +1,4 @@
|
||||||
|
---
|
||||||
name: Roles CI
|
name: Roles CI
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
@ -14,7 +15,7 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
molecule:
|
molecule:
|
||||||
name: "Molecule (Python: ${{ matrix.python }}, Ansible: ${{ matrix.ansible }}, MySQL: ${{ matrix.mysql }})"
|
name: "Molecule (Python: ${{ matrix.python }}, Ansible: ${{ matrix.ansible }}, MySQL: ${{ matrix.mysql }})"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
PY_COLORS: 1
|
PY_COLORS: 1
|
||||||
ANSIBLE_FORCE_COLOR: 1
|
ANSIBLE_FORCE_COLOR: 1
|
||||||
|
@ -23,14 +24,31 @@ jobs:
|
||||||
mysql:
|
mysql:
|
||||||
- 2.0.12
|
- 2.0.12
|
||||||
ansible:
|
ansible:
|
||||||
- stable-2.9
|
- stable-2.11
|
||||||
### it looks like there's errors for 2.10+ with ansible-lint (https://github.com/ansible/ansible-lint/pull/878)
|
- stable-2.12
|
||||||
### and molecule (_maybe_ relating to https://github.com/ansible-community/molecule/pull/2547)
|
- stable-2.13
|
||||||
# - stable-2.10
|
- devel
|
||||||
# - devel
|
|
||||||
python:
|
python:
|
||||||
- 2.7
|
- 3.6
|
||||||
- 3.8
|
- 3.8
|
||||||
|
- 3.9
|
||||||
|
exclude:
|
||||||
|
- python: 3.6
|
||||||
|
ansible: stable-2.12
|
||||||
|
- python: 3.6
|
||||||
|
ansible: stable-2.13
|
||||||
|
- python: 3.6
|
||||||
|
ansible: devel
|
||||||
|
- python: 3.8
|
||||||
|
ansible: stable-2.11
|
||||||
|
- python: 3.8
|
||||||
|
ansible: stable-2.13
|
||||||
|
- python: 3.8
|
||||||
|
ansible: devel
|
||||||
|
- python: 3.9
|
||||||
|
ansible: stable-2.11
|
||||||
|
- python: 3.9
|
||||||
|
ansible: stable-2.12
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
|
@ -44,7 +62,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python }}
|
python-version: ${{ matrix.python }}
|
||||||
|
|
||||||
- name: Install ansible-base (${{ matrix.ansible }})
|
- name: Install ansible-core (${{ matrix.ansible }})
|
||||||
run: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz --disable-pip-version-check
|
run: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz --disable-pip-version-check
|
||||||
|
|
||||||
- name: Install molecule and related dependencies
|
- name: Install molecule and related dependencies
|
||||||
|
|
67
.github/workflows/build-docker-image.yml
vendored
Normal file
67
.github/workflows/build-docker-image.yml
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
---
|
||||||
|
name: Build Docker Image for ansible-test
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
registry:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
image_name:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
context:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# Requirement to use 'context' in docker/build-push-action@v3
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# https://github.com/docker/login-action
|
||||||
|
- name: Log into registry ${{ inputs.registry }}
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ${{ inputs.registry }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
# https://github.com/docker/metadata-action
|
||||||
|
- name: Extract Docker metadata (tags, labels)
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v4
|
||||||
|
with:
|
||||||
|
images:
|
||||||
|
"${{ inputs.registry }}\
|
||||||
|
/${{ github.repository }}\
|
||||||
|
/${{ inputs.image_name }}"
|
||||||
|
tags: latest
|
||||||
|
|
||||||
|
# Setting up Docker Buildx with docker-container driver is required
|
||||||
|
# at the moment to be able to use a subdirectory with Git context
|
||||||
|
#
|
||||||
|
# https://github.com/docker/setup-buildx-action
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
|
# https://github.com/docker/build-push-action
|
||||||
|
- name: Build and push Docker image with Buildx
|
||||||
|
id: build-and-push
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: ${{ inputs.context }}
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
21
.github/workflows/docker-image-mariadb-py310-mysqlclient211.yml
vendored
Normal file
21
.github/workflows/docker-image-mariadb-py310-mysqlclient211.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mariadb-py310-mysqlclient211
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mariadb-py310-mysqlclient211/**'
|
||||||
|
- '.github/workflows/docker-image-mariadb-py310-mysqlclient211.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mariadb-py310-mysqlclient211
|
||||||
|
context: test-containers/mariadb-py310-mysqlclient211
|
21
.github/workflows/docker-image-mariadb-py310-pymysql102.yml
vendored
Normal file
21
.github/workflows/docker-image-mariadb-py310-pymysql102.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mariadb-py310-pymysql102
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mariadb-py310-pymysql102/**'
|
||||||
|
- '.github/workflows/docker-image-mariadb-py310-pymysql102.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mariadb-py310-pymysql102
|
||||||
|
context: test-containers/mariadb-py310-pymysql102
|
21
.github/workflows/docker-image-mariadb-py38-mysqlclient201.yml
vendored
Normal file
21
.github/workflows/docker-image-mariadb-py38-mysqlclient201.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mariadb-py38-mysqlclient201
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mariadb-py38-mysqlclient201/**'
|
||||||
|
- '.github/workflows/docker-image-mariadb-py38-mysqlclient201.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mariadb-py38-mysqlclient201
|
||||||
|
context: test-containers/mariadb-py38-mysqlclient201
|
21
.github/workflows/docker-image-mariadb-py38-pymysql093.yml
vendored
Normal file
21
.github/workflows/docker-image-mariadb-py38-pymysql093.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mariadb-py38-pymysql093
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mariadb-py38-pymysql093/**'
|
||||||
|
- '.github/workflows/docker-image-mariadb-py38-pymysql093.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mariadb-py38-pymysql093
|
||||||
|
context: test-containers/mariadb-py38-pymysql093
|
21
.github/workflows/docker-image-mariadb-py39-mysqlclient203.yml
vendored
Normal file
21
.github/workflows/docker-image-mariadb-py39-mysqlclient203.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mariadb-py39-mysqlclient203
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mariadb-py39-mysqlclient203/**'
|
||||||
|
- '.github/workflows/docker-image-mariadb-py39-mysqlclient203.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mariadb-py39-mysqlclient203
|
||||||
|
context: test-containers/mariadb-py39-mysqlclient203
|
21
.github/workflows/docker-image-mariadb-py39-pymysql093.yml
vendored
Normal file
21
.github/workflows/docker-image-mariadb-py39-pymysql093.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mariadb-py39-pymysql093
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mariadb-py39-pymysql093/**'
|
||||||
|
- '.github/workflows/docker-image-mariadb-py39-pymysql093.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mariadb-py39-pymysql093
|
||||||
|
context: test-containers/mariadb-py39-pymysql093
|
21
.github/workflows/docker-image-my57-py38-mysqlclient201.yml
vendored
Normal file
21
.github/workflows/docker-image-my57-py38-mysqlclient201.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI my57-py38-mysqlclient201
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/my57-py38-mysqlclient201/**'
|
||||||
|
- '.github/workflows/docker-image-my57-py38-mysqlclient201.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-my57-py38-mysqlclient201
|
||||||
|
context: test-containers/my57-py38-mysqlclient201
|
21
.github/workflows/docker-image-my57-py38-pymysql0711.yml
vendored
Normal file
21
.github/workflows/docker-image-my57-py38-pymysql0711.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI my57-py38-pymysql0711
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/my57-py38-pymysql0711/**'
|
||||||
|
- '.github/workflows/docker-image-my57-py38-pymysql0711.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-my57-py38-pymysql0711
|
||||||
|
context: test-containers/my57-py38-pymysql0711
|
21
.github/workflows/docker-image-my57-py38-pymysql093.yml
vendored
Normal file
21
.github/workflows/docker-image-my57-py38-pymysql093.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI my57-py38-pymysql093
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/my57-py38-pymysql093/**'
|
||||||
|
- '.github/workflows/docker-image-my57-py38-pymysql093.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-my57-py38-pymysql093
|
||||||
|
context: test-containers/my57-py38-pymysql093
|
21
.github/workflows/docker-image-mysql-py310-mysqlclient211.yml
vendored
Normal file
21
.github/workflows/docker-image-mysql-py310-mysqlclient211.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mysql-py310-mysqlclient211
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mysql-py310-mysqlclient211/**'
|
||||||
|
- '.github/workflows/docker-image-mysql-py310-mysqlclient211.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mysql-py310-mysqlclient211
|
||||||
|
context: test-containers/mysql-py310-mysqlclient211
|
21
.github/workflows/docker-image-mysql-py310-pymysql102.yml
vendored
Normal file
21
.github/workflows/docker-image-mysql-py310-pymysql102.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mysql-py310-pymysql102
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mysql-py310-pymysql102/**'
|
||||||
|
- '.github/workflows/docker-image-mysql-py310-pymysql102.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mysql-py310-pymysql102
|
||||||
|
context: test-containers/mysql-py310-pymysql102
|
21
.github/workflows/docker-image-mysql-py38-mysqlclient201.yml
vendored
Normal file
21
.github/workflows/docker-image-mysql-py38-mysqlclient201.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mysql-py38-mysqlclient201
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mysql-py38-mysqlclient201/**'
|
||||||
|
- '.github/workflows/docker-image-mysql-py38-mysqlclient201.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mysql-py38-mysqlclient201
|
||||||
|
context: test-containers/mysql-py38-mysqlclient201
|
21
.github/workflows/docker-image-mysql-py38-pymysql093.yml
vendored
Normal file
21
.github/workflows/docker-image-mysql-py38-pymysql093.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mysql-py38-pymysql093
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mysql-py38-pymysql093/**'
|
||||||
|
- '.github/workflows/docker-image-mysql-py38-pymysql093.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mysql-py38-pymysql093
|
||||||
|
context: test-containers/mysql-py38-pymysql093
|
21
.github/workflows/docker-image-mysql-py39-mysqlclient203.yml
vendored
Normal file
21
.github/workflows/docker-image-mysql-py39-mysqlclient203.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mysql-py39-mysqlclient203
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mysql-py39-mysqlclient203/**'
|
||||||
|
- '.github/workflows/docker-image-mysql-py39-mysqlclient203.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mysql-py39-mysqlclient203
|
||||||
|
context: test-containers/mysql-py39-mysqlclient203
|
21
.github/workflows/docker-image-mysql-py39-pymysql093.yml
vendored
Normal file
21
.github/workflows/docker-image-mysql-py39-pymysql093.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: Docker Image CI mysql-py39-pymysql093
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'test-containers/mysql-py39-pymysql093/*'
|
||||||
|
- '.github/workflows/docker-image-mysql-py39-pymysql093.yml'
|
||||||
|
- '.github/workflows/build-docker-image.yml'
|
||||||
|
branches-ignore:
|
||||||
|
- stable-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
call-workflow-passing-data:
|
||||||
|
uses: ./.github/workflows/build-docker-image.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
image_name: test-container-mysql-py39-pymysql093
|
||||||
|
context: test-containers/mysql-py39-pymysql093
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,5 +1,7 @@
|
||||||
/tests/output/
|
/tests/output/
|
||||||
|
/tests/integration/inventory
|
||||||
/changelogs/.plugin-cache.yaml
|
/changelogs/.plugin-cache.yaml
|
||||||
|
*.swp
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
@ -133,3 +135,6 @@ dmypy.json
|
||||||
|
|
||||||
# MacOS
|
# MacOS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
# IntelliJ IDEA or PyCharm
|
||||||
|
.idea/
|
||||||
|
|
|
@ -5,6 +5,191 @@ Community MySQL Collection Release Notes
|
||||||
.. contents:: Topics
|
.. contents:: Topics
|
||||||
|
|
||||||
|
|
||||||
|
v1.5.1
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Final maintenance release of ``community.mysql`` major version 1.
|
||||||
|
|
||||||
|
Major Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- The ``community.mysql`` 1.x.y release stream is now effectively End of Life. No more releases will be made. This follows the decision to support each major release for two years. This decision stems from this discussion (https://github.com/ansible-collections/community.mysql/discussions/537)
|
||||||
|
|
||||||
|
|
||||||
|
v1.5.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This is a minor release of the ``community.mysql`` collection.
|
||||||
|
This changelog contains all changes to the modules and plugins in this collection
|
||||||
|
that have been made after the previous release.
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- mysql_info - add ``connector_name`` and ``connector_version`` to returned values (https://github.com/ansible-collections/community.mysql/pull/497).
|
||||||
|
|
||||||
|
v1.4.8
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This is the patch release of the ``community.mysql`` collection.
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.7.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Include ``simplified_bsd.txt`` license file for various module utils.
|
||||||
|
|
||||||
|
v1.4.7
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This is the patch release of the ``community.mysql`` collection.
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.6.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- mysql_query - fix false change reports when ``IF EXISTS/IF NOT EXISTS`` clause is used (https://github.com/ansible-collections/community.mysql/issues/268).
|
||||||
|
- mysql_user - fix logic when ``update_password`` is set to ``on_create`` for users using ``plugin*`` arguments (https://github.com/ansible-collections/community.mysql/issues/334). The ``on_create`` sets ``password`` to None for old mysql_native_authentication but not for authentiation methods which uses the ``plugin*`` arguments. This PR changes this so ``on_create`` also exchange ``plugin``, ``plugin_hash_string``, ``plugin_auth_string`` to None in the list of arguments to change
|
||||||
|
|
||||||
|
v1.4.6
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This is the patch release of the ``community.mysql`` collection.
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.5.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Include ``PSF-license.txt`` file for ``plugins/module_utils/_version.py``.
|
||||||
|
|
||||||
|
v1.4.5
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This is the patch release of the ``community.mysql`` collection.
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.4.
|
||||||
|
|
||||||
|
Major Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- The community.mysql collection no longer supports ``Ansible 2.9`` and ``ansible-base 2.10``. While we take no active measures to prevent usage and there are no plans to introduce incompatible code to the modules, we will stop testing against ``Ansible 2.9`` and ``ansible-base 2.10``. Both will very soon be End of Life and if you are still using them, you should consider upgrading to the ``latest Ansible / ansible-core 2.11 or later`` as soon as possible (https://github.com/ansible-collections/community.mysql/pull/343).
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- mysql_user - fix missing dynamic privileges after revoke and grant privileges to user (https://github.com/ansible-collections/community.mysql/issues/120).
|
||||||
|
- mysql_user - fix parsing privs when a user has roles assigned (https://github.com/ansible-collections/community.mysql/issues/231).
|
||||||
|
- mysql_user - fix the possibility for a race condition that breaks certain (circular) replication configurations when ``DROP USER`` is executed on multiple nodes in the replica set. Adding ``IF EXISTS`` avoids the need to use ``sql_log_bin: no`` making the statement always replication safe (https://github.com/ansible-collections/community.mysql/pull/287).
|
||||||
|
|
||||||
|
v1.4.4
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This is the patch release of the ``community.mysql`` collection.
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.3.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Collection core functions - use vendored version of ``distutils.version`` instead of the deprecated Python standard library ``distutils`` (https://github.com/ansible-collections/community.mysql/pull/269).
|
||||||
|
|
||||||
|
v1.4.3
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This is the patch release of the ``community.mysql`` collection.
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.2.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- mysql_info - fix TypeError failure when there are databases that do not contain tables (https://github.com/ansible-collections/community.mysql/issues/204).
|
||||||
|
|
||||||
|
v1.4.2
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This is the patch release of the ``community.mysql`` collection.
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.1.
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- mysql_query - correctly reflect changed status in replace statements (https://github.com/ansible-collections/community.mysql/pull/193).
|
||||||
|
|
||||||
|
v1.4.1
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This is the patch release of the ``community.mysql`` collection.
|
||||||
|
This changelog contains all changes to the modules in this collection
|
||||||
|
that have been added after the release of ``community.mysql`` 1.4.0.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- mysql - revert changes of connector arguments made in pull request 116 causing the invalid keyword argument error (https://github.com/ansible-collections/community.mysql/pull/116).
|
||||||
|
|
||||||
|
v1.4.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This is the minor release of the ``community.mysql`` collection.
|
||||||
|
This changelog contains all changes to the modules in this collection
|
||||||
|
that have been added after the release of ``community.mysql`` 1.3.0.'
|
||||||
|
|
||||||
|
Major Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- mysql_user - the ``REQUIRESSL`` is an alias for the ``ssl`` key in the ``tls_requires`` option in ``community.mysql`` 2.0.0 and support will be dropped altogether in ``community.mysql`` 3.0.0 (https://github.com/ansible-collections/community.mysql/issues/121).
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- mysql module utils - change deprecated connection parameters ``passwd`` and ``db`` to ``password`` and ``database`` (https://github.com/ansible-collections/community.mysql/pull/116).
|
||||||
|
- mysql_collection - introduce codebabse split to handle divergences between MySQL and MariaDB (https://github.com/ansible-collections/community.mysql/pull/103).
|
||||||
|
- mysql_info - add `version.full` and `version.suffix` return values (https://github.com/ansible-collections/community.mysql/issues/114).
|
||||||
|
- mysql_user - deprecate the ``REQUIRESSL`` privilege (https://github.com/ansible-collections/community.mysql/issues/101).
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- mysql_user - add support for ``REPLICA MONITOR`` privilege (https://github.com/ansible-collections/community.mysql/issues/105).
|
||||||
|
|
||||||
v1.3.0
|
v1.3.0
|
||||||
======
|
======
|
||||||
|
|
199
CONTRIBUTING.md
199
CONTRIBUTING.md
|
@ -1,200 +1,5 @@
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
We follow [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) in all our contributions and interactions within this repository.
|
Refer to the [Ansible Contributing guidelines](https://docs.ansible.com/ansible/devel/community/index.html) to learn how to contribute to this collection.
|
||||||
|
|
||||||
If you are a committer, also refer to the [Ansible committer guidelines](https://docs.ansible.com/ansible/devel/community/committer_guidelines.html).
|
Refer to the [review checklist](https://docs.ansible.com/ansible/devel/community/collection_contributors/collection_reviewing.html) when triaging issues or reviewing PRs.
|
||||||
|
|
||||||
## Issue tracker
|
|
||||||
|
|
||||||
Whether you are looking for an opportunity to contribute or you found a bug and already know how to solve it, please go to the [issue tracker](https://github.com/ansible-collections/community.mysql/issues).
|
|
||||||
There you can find feature ideas to implement, reports about bugs to solve, or submit an issue to discuss your idea before implementing it which can help choose a right direction at the beginning of your work and potentially save a lot of time and effort.
|
|
||||||
Also somebody may already have started discussing or working on implementing the same or a similar idea,
|
|
||||||
so you can cooperate to create a better solution together.
|
|
||||||
|
|
||||||
## Open pull requests
|
|
||||||
|
|
||||||
Look through currently [open pull requests](https://github.com/ansible-collections/community.mysql/pulls).
|
|
||||||
You can help by reviewing them. Reviews help move pull requests to merge state. Some good pull requests cannot be merged only due to a lack of reviews. And it is always worth saying that good reviews are often more valuable than pull requests themselves. For more information how to provide a good review, refer to the [review checklist](REVIEW_CHECKLIST.md).
|
|
||||||
|
|
||||||
Also, consider taking up a valuable, reviewed, but abandoned pull request which you could politely ask the original authors to complete yourself.
|
|
||||||
|
|
||||||
## Discussions
|
|
||||||
|
|
||||||
For open questions, broad suggestions, and other comments that will not typically fit in the scope of an issue or pull request, [discussions](https://github.com/ansible-collections/community.mysql/discussions) are available. That section provides a place to have a more open and informal conversation about any and all things related to this collection, included but not limited to future development plans, functionality explanations and feature proposals that are not yet fleshed out enough for an issue of their own.
|
|
||||||
|
|
||||||
## Looking for an idea to implement
|
|
||||||
|
|
||||||
First, see the paragraphs above.
|
|
||||||
|
|
||||||
If you came up with a new feature, it is always worth creating an issue
|
|
||||||
before starting to write code to discuss the idea with the community first.
|
|
||||||
If you are going to implement the feature yourself, say it in the issue explicitly to avoid working in parallel with somebody else.
|
|
||||||
|
|
||||||
## Step-by-step guide how to get into development quickly
|
|
||||||
|
|
||||||
We assume that you use Linux as a work environment (you can use a virtual machine as well) and have `git` installed.
|
|
||||||
|
|
||||||
1. If possible, make sure that you have installed and started `docker`. While you can also run tests without docker, this makes it a lot easier since you do not have to install the precise requirements, and tests are running properly isolated and in the exact same environments as in CI. You often can also use `podman` with the `docker` executable shim, so if you have that you probably do not need to install `docker`.
|
|
||||||
|
|
||||||
2. Clone the [ansible-core](https://github.com/ansible/ansible) repository:
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/ansible/ansible.git
|
|
||||||
```
|
|
||||||
|
|
||||||
Instead of installing ansible-core from source, you can also work with an already existing installation of Ansible, ansible-base or ansible-core. Simply skip steps 2 and 3 in that case.
|
|
||||||
|
|
||||||
3. Go to the cloned repository and prepare the environment:
|
|
||||||
```bash
|
|
||||||
cd ansible && source hacking/env-setup
|
|
||||||
pip install -r requirements.txt
|
|
||||||
cd ~
|
|
||||||
```
|
|
||||||
4. Create the following directories in your home directory:
|
|
||||||
```bash
|
|
||||||
mkdir -p ~/ansible_collections/community/mysql
|
|
||||||
```
|
|
||||||
|
|
||||||
5. Fork the `community.mysql` repository through the GitHub web interface.
|
|
||||||
|
|
||||||
6. Clone the forked repository from your profile to the created path:
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/YOURACC/community.mysql.git ~/ansible_collections/community/mysql
|
|
||||||
```
|
|
||||||
|
|
||||||
If you prefer to use the SSH protocol:
|
|
||||||
```bash
|
|
||||||
git clone git@github.com:YOURACC/community.mysql.git ~/ansible_collections/community/mysql
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
7. Go to your new cloned repository.
|
|
||||||
```bash
|
|
||||||
cd ~/ansible_collections/community/mysql
|
|
||||||
```
|
|
||||||
|
|
||||||
8. Be sure you are in the main branch:
|
|
||||||
```bash
|
|
||||||
git status
|
|
||||||
```
|
|
||||||
|
|
||||||
9. Show remotes. There should be the `origin` repository only:
|
|
||||||
```bash
|
|
||||||
git remote -v
|
|
||||||
```
|
|
||||||
|
|
||||||
10. Add the `upstream` repository:
|
|
||||||
```bash
|
|
||||||
git remote add upstream https://github.com/ansible-collections/community.mysql.git
|
|
||||||
```
|
|
||||||
|
|
||||||
11. Update your local `main` branch:
|
|
||||||
```bash
|
|
||||||
git fetch upstream
|
|
||||||
git rebase upstream/main
|
|
||||||
```
|
|
||||||
|
|
||||||
12. Create a branch for your changes:
|
|
||||||
```bash
|
|
||||||
git checkout -b name_of_my_branch
|
|
||||||
```
|
|
||||||
|
|
||||||
13. We recommend you start with writing integration tests if applicable.
|
|
||||||
|
|
||||||
Note: If there are any difficulties with writing the tests or you are not sure if the case can be covered, feel free to skip this step.
|
|
||||||
If needed, other contributors can help you with it later.
|
|
||||||
|
|
||||||
All integration tests are stored in `tests/integration/targets` subdirectories.
|
|
||||||
Go to the subdirectory containing the name of module you are going to change.
|
|
||||||
For example, if you are fixing the `mysql_user` module, its tests are in `tests/integration/targets/test_mysql_user/tasks`.
|
|
||||||
|
|
||||||
The `main.yml` file holds test tasks and includes other test files.
|
|
||||||
Look for a suitable test file to integrate your tests or create and include a dedicated test file.
|
|
||||||
You can use one of the existing test files as a draft.
|
|
||||||
|
|
||||||
When fixing a bug, write a task which reproduces the bug from the issue.
|
|
||||||
|
|
||||||
Put the reported case in the tests, then run integration tests with the following command:
|
|
||||||
```bash
|
|
||||||
ansible-test integration test_mysql_user --docker -vvv
|
|
||||||
```
|
|
||||||
If the tests do not want to run, first, check you complete step 3 of this guide.
|
|
||||||
|
|
||||||
If the tests ran successfully, there are usually two possible outcomes:
|
|
||||||
a) If the bug has not appeared and the tests have passed successfully, ask the reporter to provide more details. The bug can be not a bug actually or can relate to a particular software version used or specifics of local environment configuration.
|
|
||||||
|
|
||||||
b) The bug has appeared and the tests has failed as expected showing the reported symptoms.
|
|
||||||
|
|
||||||
14. Fix the bug.
|
|
||||||
|
|
||||||
15. Run `flake8` against a changed file. If it is `plugins/modules/mysql_user.py`:
|
|
||||||
```bash
|
|
||||||
flake8 plugins/modules/mysql_user.py
|
|
||||||
```
|
|
||||||
It is worth installing and running `flake8` against the changed file(s) first.
|
|
||||||
It shows unused imports, which is not shown by sanity tests (see the next step), as well as other common issues.
|
|
||||||
Optionally, you can use the `--max-line-length=160` command-line argument.
|
|
||||||
|
|
||||||
16. Run sanity tests:
|
|
||||||
```bash
|
|
||||||
ansible-test sanity plugins/modules/mysql_user.py --docker
|
|
||||||
```
|
|
||||||
If they failed, look at the output carefully - it is usually very informative and helps to identify a problem line quickly.
|
|
||||||
Sanity failings usually relate to wrong code and documentation formatting.
|
|
||||||
|
|
||||||
17. Run integration tests:
|
|
||||||
```bash
|
|
||||||
ansible-test integration test_mysql_user --docker -vvv
|
|
||||||
```
|
|
||||||
|
|
||||||
There are two possible outcomes:
|
|
||||||
a) They have failed. Look at the output of the command.
|
|
||||||
Fix the problem place in the code and run again.
|
|
||||||
Repeat the cycle until the tests pass.
|
|
||||||
|
|
||||||
b) They have passed. Remember they failed originally? Our congratulations! You have fixed the bug.
|
|
||||||
|
|
||||||
18. Commit your changes with an informative but short commit message:
|
|
||||||
```bash
|
|
||||||
git add /path/to/changed/file
|
|
||||||
git commit -m "mysql_user: fix crash when ..."
|
|
||||||
```
|
|
||||||
|
|
||||||
19. Push the branch to the `origin` (your fork):
|
|
||||||
```bash
|
|
||||||
git push origin name_of_my_branch
|
|
||||||
```
|
|
||||||
|
|
||||||
20. Go to the `upstream` (http://github.com/ansible-collections/community.mysql).
|
|
||||||
|
|
||||||
21. Go to `Pull requests` tab and create a pull request.
|
|
||||||
|
|
||||||
GitHub is tracking your fork, so it should see the new branch in it and automatically offer
|
|
||||||
to create a pull request. Sometimes GitHub does not do it and you should click the `New pull request` button yourself.
|
|
||||||
Then choose `compare across forks` under the `Compare changes` title.
|
|
||||||
Choose your repository and the new branch you pushed in the right drop-down list.
|
|
||||||
Confirm. Fill out the pull request template with all information you want to mention.
|
|
||||||
Put "Fixes + link to the issue" in the pull request's description.
|
|
||||||
Put "[WIP] + short description" in the pull request's title. It's often a good idea to mention the name of the module/plugin you are modifying at the beginning of the description.
|
|
||||||
Click `Create pull request`.
|
|
||||||
|
|
||||||
22. Add a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#changelogs) to the `changelog/fragments` directory. It will be published in release notes, so users will know about the fix.
|
|
||||||
|
|
||||||
Commit and push it:
|
|
||||||
```bash
|
|
||||||
git add changelog/fragments/myfragment.yml
|
|
||||||
git commit -m "Add changelog fragment"
|
|
||||||
git push origin name_of_my_branch
|
|
||||||
```
|
|
||||||
|
|
||||||
23. The CI tests will run automatically on Red Hat infrastructure after every commit.
|
|
||||||
|
|
||||||
You will see the CI status in the bottom of your pull request.
|
|
||||||
If they are green, remove "[WIP]" from the title. Mention the issue reporter in a comment and let contributors know that the pull request is "Ready for review".
|
|
||||||
|
|
||||||
24. Wait for reviews. You can also ask for review on IRC in the #ansible-community channel.
|
|
||||||
|
|
||||||
25. If the pull request looks good to the community, committers will merge it.
|
|
||||||
|
|
||||||
For details, refer to the [Ansible developer guide](https://docs.ansible.com/ansible/latest/dev_guide/index.html).
|
|
||||||
|
|
||||||
If you find any inconsistencies or places in this document which can be improved, feel free to raise an issue or pull request to fix it.
|
|
||||||
|
|
274
CONTRIBUTORS
Normal file
274
CONTRIBUTORS
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
116davinder
|
||||||
|
20
|
||||||
|
28
|
||||||
|
29
|
||||||
|
4
|
||||||
|
4n70w4
|
||||||
|
abadger
|
||||||
|
abondis
|
||||||
|
acozine
|
||||||
|
adamchainz
|
||||||
|
adq
|
||||||
|
Akasurde
|
||||||
|
Alexander198961
|
||||||
|
alustenberg
|
||||||
|
aminvakil
|
||||||
|
amitk79
|
||||||
|
amree
|
||||||
|
Andersson007
|
||||||
|
andrewhowdencom
|
||||||
|
ansibot
|
||||||
|
anthonyxpalermo
|
||||||
|
antonioribeiro
|
||||||
|
apollo13
|
||||||
|
aquach
|
||||||
|
arcmop
|
||||||
|
asad-at-srt
|
||||||
|
AshDevilRed
|
||||||
|
aurimasl
|
||||||
|
axelll
|
||||||
|
axisK
|
||||||
|
azielke
|
||||||
|
baldpale
|
||||||
|
banyek
|
||||||
|
BarbzYHOOL
|
||||||
|
Berbe
|
||||||
|
bjne
|
||||||
|
bmalynovytch
|
||||||
|
bmildren
|
||||||
|
boreal321
|
||||||
|
brutus
|
||||||
|
burner1024
|
||||||
|
calfonso
|
||||||
|
candeira
|
||||||
|
caphrim007
|
||||||
|
cdalbergue
|
||||||
|
checkphi
|
||||||
|
chrismeyersfsu
|
||||||
|
ChristopherGAndrews
|
||||||
|
cmodijk
|
||||||
|
codeaken
|
||||||
|
codebymikey
|
||||||
|
coreylane
|
||||||
|
CormacBracken
|
||||||
|
cosmix
|
||||||
|
cptMikky
|
||||||
|
crashes
|
||||||
|
dagwieers
|
||||||
|
damianmoore
|
||||||
|
Davidffry
|
||||||
|
denisemauldin
|
||||||
|
diclophis
|
||||||
|
d-lee
|
||||||
|
dmp1ce
|
||||||
|
dnelson
|
||||||
|
dramaley
|
||||||
|
drybjed
|
||||||
|
drzraf
|
||||||
|
DSpeichert
|
||||||
|
dungdm93
|
||||||
|
dwagelaar
|
||||||
|
dylanjbarth
|
||||||
|
einarc
|
||||||
|
E-M
|
||||||
|
eowin
|
||||||
|
Ernest0x
|
||||||
|
esamattis
|
||||||
|
Everspace
|
||||||
|
F21
|
||||||
|
faitno
|
||||||
|
felixfontein
|
||||||
|
flatrocks
|
||||||
|
fourjay
|
||||||
|
fraff
|
||||||
|
g00fy-
|
||||||
|
geerlingguy
|
||||||
|
georgeOsdDev
|
||||||
|
ghjm
|
||||||
|
ghost
|
||||||
|
giacmir
|
||||||
|
giorgio-v
|
||||||
|
gkoller
|
||||||
|
gottwald
|
||||||
|
gstorme
|
||||||
|
gundalow
|
||||||
|
hansbaer
|
||||||
|
hchargois
|
||||||
|
hluaces
|
||||||
|
hwali
|
||||||
|
hyperfocus1338
|
||||||
|
igormukhingmailcom
|
||||||
|
imjoseangel
|
||||||
|
infigoKriti
|
||||||
|
ipergenitsa
|
||||||
|
iredmail
|
||||||
|
ivandigiusto
|
||||||
|
jadbaz
|
||||||
|
jaikdean
|
||||||
|
jamescassell
|
||||||
|
janosmiko
|
||||||
|
jarnold-timeout
|
||||||
|
JaSafieddine
|
||||||
|
jborean93
|
||||||
|
jctanner
|
||||||
|
jean-christophe-manciot
|
||||||
|
Jean-Daniel
|
||||||
|
jgornick
|
||||||
|
jhagg
|
||||||
|
jhoekx
|
||||||
|
jirib
|
||||||
|
jkleckner
|
||||||
|
jkordish
|
||||||
|
jlaska
|
||||||
|
Jmainguy
|
||||||
|
jochu
|
||||||
|
JoelFeiner
|
||||||
|
johnavp1989
|
||||||
|
jonatasbaldin
|
||||||
|
Jorge-Rodriguez
|
||||||
|
jpjaatin
|
||||||
|
jpmens
|
||||||
|
JSafieddine
|
||||||
|
jsmartin
|
||||||
|
juergenhoetzel
|
||||||
|
jw34
|
||||||
|
kalaisubbiah
|
||||||
|
kenichi-ogawa-1988
|
||||||
|
kkeane
|
||||||
|
klingac
|
||||||
|
kotso
|
||||||
|
kuntalFreshBooks
|
||||||
|
kurtdavis
|
||||||
|
larsks
|
||||||
|
ldesgrange
|
||||||
|
leeadh
|
||||||
|
LeonB
|
||||||
|
leucos
|
||||||
|
loomsen
|
||||||
|
lorin
|
||||||
|
lowwalker
|
||||||
|
lperezs
|
||||||
|
makmanalp
|
||||||
|
manuelmorena
|
||||||
|
MarcinOrlowski
|
||||||
|
markdorison
|
||||||
|
markotitel
|
||||||
|
marktheunissen
|
||||||
|
markuman
|
||||||
|
mattclay
|
||||||
|
matt-horwood-mayden
|
||||||
|
mavimo
|
||||||
|
maxamillion
|
||||||
|
maxbube
|
||||||
|
mcgoldrickm
|
||||||
|
meanstrong
|
||||||
|
meersjo
|
||||||
|
megamisan
|
||||||
|
michaeldg
|
||||||
|
michalmedvecky
|
||||||
|
MikeiLL
|
||||||
|
milky-milk
|
||||||
|
milosz
|
||||||
|
mistaka0s
|
||||||
|
mklassen
|
||||||
|
mkrizek
|
||||||
|
mmoya
|
||||||
|
mohag
|
||||||
|
mohsenSy
|
||||||
|
mpdehaan
|
||||||
|
MRwangyd
|
||||||
|
mverwijs
|
||||||
|
mvgrimes
|
||||||
|
mysqlbox
|
||||||
|
netmonk
|
||||||
|
nhojpatrick
|
||||||
|
nicolas-g
|
||||||
|
NielsH
|
||||||
|
nitinkansal1984
|
||||||
|
nitzmahone
|
||||||
|
Ompragash
|
||||||
|
on
|
||||||
|
order
|
||||||
|
organman91
|
||||||
|
p53
|
||||||
|
pakal
|
||||||
|
paulbadcock
|
||||||
|
pennycoders
|
||||||
|
petoju
|
||||||
|
petracvv
|
||||||
|
pgrenaud
|
||||||
|
philfry
|
||||||
|
pileofrogs
|
||||||
|
pkaramol
|
||||||
|
platypus-geek
|
||||||
|
plumbeo
|
||||||
|
pratikgadiya12
|
||||||
|
pshanbhag
|
||||||
|
r0bj
|
||||||
|
rajsshah86
|
||||||
|
reduzent
|
||||||
|
relrod
|
||||||
|
resmo
|
||||||
|
ricco24
|
||||||
|
richlv
|
||||||
|
riupie
|
||||||
|
rndmh3ro
|
||||||
|
robertdebock
|
||||||
|
robpblake
|
||||||
|
rokka-n
|
||||||
|
Roxyrob
|
||||||
|
roysmith
|
||||||
|
rthouvenin
|
||||||
|
ruudk
|
||||||
|
samccann
|
||||||
|
samdoran
|
||||||
|
sayap
|
||||||
|
scottbrown
|
||||||
|
seanorama
|
||||||
|
sedrubal
|
||||||
|
sergey-trukhin
|
||||||
|
Shaps
|
||||||
|
shrikeh
|
||||||
|
sivel
|
||||||
|
skalfyfan
|
||||||
|
skoriy88
|
||||||
|
sperantus
|
||||||
|
spoyd
|
||||||
|
steverweber
|
||||||
|
steveteahan
|
||||||
|
stijnopheide
|
||||||
|
stintel
|
||||||
|
stoned
|
||||||
|
strixBE
|
||||||
|
SWADESNA
|
||||||
|
tapologo
|
||||||
|
tejatsk14
|
||||||
|
tersmitten
|
||||||
|
the
|
||||||
|
the02
|
||||||
|
thomasliddledba
|
||||||
|
time-palominodb
|
||||||
|
timorunge
|
||||||
|
Tomasthanes
|
||||||
|
tomdymond
|
||||||
|
Tronde
|
||||||
|
tvlooy
|
||||||
|
tyll
|
||||||
|
UncertaintyP
|
||||||
|
unnecessary-username
|
||||||
|
vamshi8
|
||||||
|
vanne
|
||||||
|
vdboor
|
||||||
|
vmahadev
|
||||||
|
v-zhuravlev
|
||||||
|
webmat
|
||||||
|
wedi
|
||||||
|
whysthatso
|
||||||
|
willthames
|
||||||
|
windowsansiblernew
|
||||||
|
wrosario
|
||||||
|
xiata
|
||||||
|
Xyon
|
||||||
|
yangchao0512
|
||||||
|
ziegenberg
|
||||||
|
Zverik
|
5
MAINTAINERS
Normal file
5
MAINTAINERS
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
bmalynovytch
|
||||||
|
Jorge-Rodriguez
|
||||||
|
rsicart
|
||||||
|
laurent-indermuehle
|
||||||
|
Andersson007 (andersson007_ in #ansible-community IRC/Matrix)
|
3
MAINTAINING.md
Normal file
3
MAINTAINING.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Maintaining this collection
|
||||||
|
|
||||||
|
Refer to the [Maintainer guidelines](https://github.com/ansible/community-docs/blob/main/maintaining.rst).
|
112
Makefile
Normal file
112
Makefile
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
# To tell ansible-test and Make to not kill the containers on failure or
|
||||||
|
# end of tests. Disabled by default.
|
||||||
|
ifdef keep_containers_alive
|
||||||
|
_keep_containers_alive = --docker-terminate never
|
||||||
|
endif
|
||||||
|
|
||||||
|
# This match what GitHub Action will do. Disabled by default.
|
||||||
|
ifdef continue_on_errors
|
||||||
|
_continue_on_errors = --retry-on-error --continue-on-error
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
db_ver_tuple := $(subst ., , $(db_engine_version))
|
||||||
|
db_engine_version_flat := $(word 1, $(db_ver_tuple))$(word 2, $(db_ver_tuple))
|
||||||
|
|
||||||
|
con_ver_tuple := $(subst ., , $(connector_version))
|
||||||
|
connector_version_flat := $(word 1, $(con_ver_tuple))$(word 2, $(con_ver_tuple))$(word 3, $(con_ver_tuple))
|
||||||
|
|
||||||
|
py_ver_tuple := $(subst ., , $(python))
|
||||||
|
python_version_flat := $(word 1, $(py_ver_tuple))$(word 2, $(py_ver_tuple))
|
||||||
|
|
||||||
|
ifeq ($(db_engine_version_flat), 57)
|
||||||
|
db_client := my57
|
||||||
|
else
|
||||||
|
db_client := $(db_engine_name)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: test-integration
|
||||||
|
test-integration:
|
||||||
|
@echo -n $(db_engine_name) > tests/integration/db_engine_name
|
||||||
|
@echo -n $(db_engine_version) > tests/integration/db_engine_version
|
||||||
|
@echo -n $(connector_name) > tests/integration/connector_name
|
||||||
|
@echo -n $(connector_version) > tests/integration/connector_version
|
||||||
|
@echo -n $(python) > tests/integration/python
|
||||||
|
@echo -n $(ansible) > tests/integration/ansible
|
||||||
|
|
||||||
|
# Create podman network for systems missing it. Error can be ignored
|
||||||
|
podman network create podman || true
|
||||||
|
podman run \
|
||||||
|
--detach \
|
||||||
|
--replace \
|
||||||
|
--name primary \
|
||||||
|
--env MARIADB_ROOT_PASSWORD=msandbox \
|
||||||
|
--env MYSQL_ROOT_PASSWORD=msandbox \
|
||||||
|
--network podman \
|
||||||
|
--publish 3307:3306 \
|
||||||
|
--health-cmd 'mysqladmin ping -P 3306 -pmsandbox | grep alive || exit 1' \
|
||||||
|
docker.io/library/$(db_engine_name):$(db_engine_version) \
|
||||||
|
mysqld
|
||||||
|
podman run \
|
||||||
|
--detach \
|
||||||
|
--replace \
|
||||||
|
--name replica1 \
|
||||||
|
--env MARIADB_ROOT_PASSWORD=msandbox \
|
||||||
|
--env MYSQL_ROOT_PASSWORD=msandbox \
|
||||||
|
--network podman \
|
||||||
|
--publish 3308:3306 \
|
||||||
|
--health-cmd 'mysqladmin ping -P 3306 -pmsandbox | grep alive || exit 1' \
|
||||||
|
docker.io/library/$(db_engine_name):$(db_engine_version) \
|
||||||
|
mysqld
|
||||||
|
podman run \
|
||||||
|
--detach \
|
||||||
|
--replace \
|
||||||
|
--name replica2 \
|
||||||
|
--env MARIADB_ROOT_PASSWORD=msandbox \
|
||||||
|
--env MYSQL_ROOT_PASSWORD=msandbox \
|
||||||
|
--network podman \
|
||||||
|
--publish 3309:3306 \
|
||||||
|
--health-cmd 'mysqladmin ping -P 3306 -pmsandbox | grep alive || exit 1' \
|
||||||
|
docker.io/library/$(db_engine_name):$(db_engine_version) \
|
||||||
|
mysqld
|
||||||
|
# Setup replication and restart containers
|
||||||
|
podman exec primary bash -c 'echo -e [mysqld]\\nserver-id=1\\nlog-bin=/var/lib/mysql/primary-bin > /etc/mysql/conf.d/replication.cnf'
|
||||||
|
podman exec replica1 bash -c 'echo -e [mysqld]\\nserver-id=2\\nlog-bin=/var/lib/mysql/replica1-bin > /etc/mysql/conf.d/replication.cnf'
|
||||||
|
podman exec replica2 bash -c 'echo -e [mysqld]\\nserver-id=3\\nlog-bin=/var/lib/mysql/replica2-bin > /etc/mysql/conf.d/replication.cnf'
|
||||||
|
# Don't restart a container unless it is healthy
|
||||||
|
while ! podman healthcheck run primary && [[ "$$SECONDS" -lt 120 ]]; do sleep 1; done
|
||||||
|
podman restart -t 30 primary
|
||||||
|
while ! podman healthcheck run replica1 && [[ "$$SECONDS" -lt 120 ]]; do sleep 1; done
|
||||||
|
podman restart -t 30 replica1
|
||||||
|
while ! podman healthcheck run replica2 && [[ "$$SECONDS" -lt 120 ]]; do sleep 1; done
|
||||||
|
podman restart -t 30 replica2
|
||||||
|
while ! podman healthcheck run primary && [[ "$$SECONDS" -lt 120 ]]; do sleep 1; done
|
||||||
|
mkdir -p .venv/$(ansible)
|
||||||
|
python$(local_python_version) -m venv .venv/$(ansible)
|
||||||
|
|
||||||
|
# Start venv (use `; \` to keep the same shell)
|
||||||
|
source .venv/$(ansible)/bin/activate; \
|
||||||
|
python$(local_python_version) -m ensurepip; \
|
||||||
|
python$(local_python_version) -m pip install --disable-pip-version-check \
|
||||||
|
https://github.com/ansible/ansible/archive/$(ansible).tar.gz; \
|
||||||
|
set -x; \
|
||||||
|
ansible-test integration $(target) -v --color --coverage --diff \
|
||||||
|
--docker ghcr.io/ansible-collections/community.mysql/test-container\
|
||||||
|
-$(db_client)-py$(python_version_flat)-$(connector_name)$(connector_version_flat):latest \
|
||||||
|
--docker-network podman $(_continue_on_errors) $(_keep_containers_alive) --python $(python); \
|
||||||
|
set +x
|
||||||
|
# End of venv
|
||||||
|
|
||||||
|
rm tests/integration/db_engine_name
|
||||||
|
rm tests/integration/db_engine_version
|
||||||
|
rm tests/integration/connector_name
|
||||||
|
rm tests/integration/connector_version
|
||||||
|
rm tests/integration/python
|
||||||
|
rm tests/integration/ansible
|
||||||
|
ifndef keep_containers_alive
|
||||||
|
podman stop --time 0 --ignore primary replica1 replica2
|
||||||
|
podman rm --ignore --volumes primary replica1 replica2
|
||||||
|
endif
|
48
PSF-license.txt
Normal file
48
PSF-license.txt
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
||||||
|
("PSF"), and the Individual or Organization ("Licensee") accessing and
|
||||||
|
otherwise using this software ("Python") in source or binary form and
|
||||||
|
its associated documentation.
|
||||||
|
|
||||||
|
2. Subject to the terms and conditions of this License Agreement, PSF hereby
|
||||||
|
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
|
||||||
|
analyze, test, perform and/or display publicly, prepare derivative works,
|
||||||
|
distribute, and otherwise use Python alone or in any derivative version,
|
||||||
|
provided, however, that PSF's License Agreement and PSF's notice of copyright,
|
||||||
|
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
|
2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Python Software Foundation;
|
||||||
|
All Rights Reserved" are retained in Python alone or in any derivative version
|
||||||
|
prepared by Licensee.
|
||||||
|
|
||||||
|
3. In the event Licensee prepares a derivative work that is based on
|
||||||
|
or incorporates Python or any part thereof, and wants to make
|
||||||
|
the derivative work available to others as provided herein, then
|
||||||
|
Licensee hereby agrees to include in any such work a brief summary of
|
||||||
|
the changes made to Python.
|
||||||
|
|
||||||
|
4. PSF is making Python available to Licensee on an "AS IS"
|
||||||
|
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||||
|
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
||||||
|
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||||
|
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
|
||||||
|
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||||
|
|
||||||
|
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||||
|
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||||
|
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
|
||||||
|
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||||
|
|
||||||
|
6. This License Agreement will automatically terminate upon a material
|
||||||
|
breach of its terms and conditions.
|
||||||
|
|
||||||
|
7. Nothing in this License Agreement shall be deemed to create any
|
||||||
|
relationship of agency, partnership, or joint venture between PSF and
|
||||||
|
Licensee. This License Agreement does not grant permission to use PSF
|
||||||
|
trademarks or trade name in a trademark sense to endorse or promote
|
||||||
|
products or services of Licensee, or any third party.
|
||||||
|
|
||||||
|
8. By copying, installing or otherwise using Python, Licensee
|
||||||
|
agrees to be bound by the terms and conditions of this License
|
||||||
|
Agreement.
|
99
README.md
99
README.md
|
@ -1,5 +1,52 @@
|
||||||
# MySQL collection for Ansible
|
# MySQL collection for Ansible
|
||||||
[](https://github.com/ansible-collections/community.mysql/actions?query=workflow%3A"Plugins+CI") [](https://github.com/ansible-collections/community.mysql/actions?query=workflow%3A"Roles+CI") [](https://codecov.io/gh/ansible-collections/community.mysql)
|
[](https://github.com/ansible-collections/community.mysql/actions?query=workflow%3A"Plugins+CI") [](https://github.com/ansible-collections/community.mysql/actions?query=workflow%3A"Roles+CI") [](https://codecov.io/gh/ansible-collections/community.mysql) [](https://matrix.to/#/#mysql:ansible.com)
|
||||||
|
|
||||||
|
This collection is a part of the Ansible package.
|
||||||
|
|
||||||
|
## Code of Conduct
|
||||||
|
|
||||||
|
We follow the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) in all our interactions within this project.
|
||||||
|
|
||||||
|
If you encounter abusive behavior violating the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html), please refer to the [policy violations](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html#policy-violations) section of the Code of Conduct for information on how to raise a complaint.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
The content of this collection is made by [people](https://github.com/ansible-collections/community.mysql/blob/main/CONTRIBUTORS) just like you, a community of individuals collaborating on making the world better through developing automation software.
|
||||||
|
|
||||||
|
We are actively accepting new contributors.
|
||||||
|
|
||||||
|
Any kind of contribution is very welcome.
|
||||||
|
|
||||||
|
You don't know how to start? Refer to our [contribution guide](https://github.com/ansible-collections/community.mysql/blob/main/CONTRIBUTING.md)!
|
||||||
|
|
||||||
|
## Collection maintenance
|
||||||
|
|
||||||
|
The current maintainers (contributors with `write` or higher access) are listed in the [MAINTAINERS](https://github.com/ansible-collections/community.mysql/blob/main/MAINTAINERS) file. If you have questions or need help, feel free to mention them in the proposals.
|
||||||
|
|
||||||
|
To learn how to maintain / become a maintainer of this collection, refer to the [Maintainer guidelines](https://github.com/ansible-collections/community.mysql/blob/main/MAINTAINING.md).
|
||||||
|
|
||||||
|
It is necessary for maintainers of this collection to be subscribed to:
|
||||||
|
|
||||||
|
* The collection itself (the `Watch` button -> `All Activity` in the upper right corner of the repository's homepage).
|
||||||
|
* The "Changes Impacting Collection Contributors and Maintainers" [issue](https://github.com/ansible-collections/overview/issues/45).
|
||||||
|
|
||||||
|
They also should be subscribed to Ansible's [The Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn).
|
||||||
|
|
||||||
|
## Communication
|
||||||
|
|
||||||
|
We announce releases and important changes through Ansible's [The Bullhorn newsletter](https://eepurl.com/gZmiEP). Be sure you are subscribed.
|
||||||
|
|
||||||
|
Join us on Matrix in the `#mysql:ansible.com` [room](https://matrix.to/#/#mysql:ansible.com), the `#users:ansible.com` [room](https://matrix.to/#/#users:ansible.com) (general use questions and support), `#ansible-community:ansible.com` [room](https://matrix.to/#/#community:ansible.com) (community and collection development questions), and other Matrix rooms or corresponding bridged Libera.Chat channels. See the [Ansible Communication Guide](https://docs.ansible.com/ansible/devel/community/communication.html) for details.
|
||||||
|
|
||||||
|
We take part in the global quarterly [Ansible Contributor Summit](https://github.com/ansible/community/wiki/Contributor-Summit) virtually or in-person. Track [The Bullhorn newsletter](https://eepurl.com/gZmiEP) and join us.
|
||||||
|
|
||||||
|
For more information about communication, refer to the [Ansible Communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
|
||||||
|
|
||||||
|
## Governance
|
||||||
|
|
||||||
|
The process of decision making in this collection is based on discussing and finding consensus among participants.
|
||||||
|
|
||||||
|
Every voice is important and every idea is valuable. If you have something on your mind, create an issue or dedicated discussion and let's discuss it!
|
||||||
|
|
||||||
## Included content
|
## Included content
|
||||||
|
|
||||||
|
@ -11,12 +58,36 @@
|
||||||
- [mysql_user](https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_user_module.html)
|
- [mysql_user](https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_user_module.html)
|
||||||
- [mysql_variables](https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_variables_module.html)
|
- [mysql_variables](https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_variables_module.html)
|
||||||
|
|
||||||
## Tested with Ansible
|
## Tested with
|
||||||
|
|
||||||
- 2.9
|
### ansible-core
|
||||||
- 2.10
|
|
||||||
- 2.11
|
- 2.12
|
||||||
- devel
|
- 2.13
|
||||||
|
- 2.14
|
||||||
|
- current development version
|
||||||
|
|
||||||
|
### Databases
|
||||||
|
|
||||||
|
For MariaDB, only Long Term releases are tested.
|
||||||
|
|
||||||
|
- mysql 5.7.40
|
||||||
|
- mysql 8.0.31
|
||||||
|
- mariadb:10.3.34 (only collection version <= 3.5.1)
|
||||||
|
- mariadb:10.4.24 (only collection version >= 3.5.2)
|
||||||
|
- mariadb:10.5.18 (only collection version >= 3.5.2)
|
||||||
|
- mariadb:10.6.11 (only collection version >= 3.5.2)
|
||||||
|
- mariadb:10.11.?? (waiting for release)
|
||||||
|
|
||||||
|
|
||||||
|
### Database connectors
|
||||||
|
|
||||||
|
- pymysql 0.7.11 (Only tested with MySQL 5.7)
|
||||||
|
- pymysql 0.9.3
|
||||||
|
- pymysql 1.0.2 (only collection version >= ???) !!! Unsuported until future release !!!
|
||||||
|
- mysqlclient 2.0.1
|
||||||
|
- mysqlclient 2.0.3 (only collection version >= 3.5.2)
|
||||||
|
- mysqlclient 2.1.1 (only collection version >= 3.5.2)
|
||||||
|
|
||||||
## External requirements
|
## External requirements
|
||||||
|
|
||||||
|
@ -44,12 +115,20 @@ collections:
|
||||||
- name: community.mysql
|
- name: community.mysql
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note that if you install the collection from Ansible Galaxy, it will not be upgraded automatically if you upgrade the Ansible package. To upgrade the collection to the latest available version, run the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-galaxy collection install community.mysql --upgrade
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also install a specific version of the collection, for example, if you need to downgrade when something is broken in the latest version (please report an issue in this repository). Use the following syntax:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-galaxy collection install community.mysql:==2.0.0
|
||||||
|
```
|
||||||
|
|
||||||
See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details.
|
See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details.
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
See the [contribution guide](CONTRIBUTING.md).
|
|
||||||
|
|
||||||
## Licensing
|
## Licensing
|
||||||
|
|
||||||
<!-- Include the appropriate license information here and a pointer to the full licensing details. If the collection contains modules migrated from the ansible/ansible repo, you must use the same license that existed in the ansible/ansible repo. See the GNU license example below. -->
|
<!-- Include the appropriate license information here and a pointer to the full licensing details. If the collection contains modules migrated from the ansible/ansible repo, you must use the same license that existed in the ansible/ansible repo. See the GNU license example below. -->
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
# Review Checklist
|
|
||||||
|
|
||||||
When reviewing, keep in mind that we follow [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) in all our contributions and interactions within this repository.
|
|
||||||
|
|
||||||
If you are a committer, also refer to the [Ansible committer guidelines](https://docs.ansible.com/ansible/devel/community/committer_guidelines.html).
|
|
||||||
|
|
||||||
**General tips**
|
|
||||||
- Try to create a culture of collaboration when reviewing
|
|
||||||
- Welcome the author and thank them for the pull request
|
|
||||||
- When suggesting changes, try to use questions, not statements
|
|
||||||
- When suggesting mandatory changes, do it as politely as possible providing documentation references
|
|
||||||
- If your suggestion is optional or a matter of personal preferences, please say it explicitly
|
|
||||||
- When asking for adding tests or for complex code refactoring, say that the author is welcome to ask for clarifications and help if they need
|
|
||||||
- If somebody suggests a good idea, mention it or put a thumbs up
|
|
||||||
- After merging, thank the author and reviewers for their time and effort
|
|
||||||
|
|
||||||
**Standards and documentation**
|
|
||||||
- [ ] if the pull request is not a documentation fix, it must include a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#creating-a-changelog-fragment) - please check the format carefully
|
|
||||||
- [ ] if new files are added with the pull request, they follow the [licensing rules](https://github.com/ansible-collections/overview/blob/main/collection_requirements.rst#licensing)
|
|
||||||
- [ ] the changes follow the [Ansible documentation standards](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_documenting.html) and the [style guide](https://docs.ansible.com/ansible/devel/dev_guide/style_guide/index.html#style-guide)
|
|
||||||
- [ ] the changes follow the [development conventions](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_best_practices.html)
|
|
||||||
- [ ] if a new plugin is added, it is one of the [allowed plugin types](https://github.com/ansible-collections/overview/blob/main/collection_requirements.rst#modules-plugins)
|
|
||||||
- [ ] documentation, examples, and return sections use FQCNs for the `M(..)` [format macros](https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_documenting.html#linking-and-other-format-macros-within-module-documentation) when referring to modules
|
|
||||||
- [ ] modules and plugins from ansible-core use `ansible.builtin.` as a FQCN prefix when mentioned
|
|
||||||
- [ ] when a new option, module, plugin, or return value is added, the corresponding documentation or return sections use `version_added:` containing the *collection* version which they will be first released in
|
|
||||||
* this usually is the next minor release, sometimes the next major release (example: if 2.7.5 is the current release, the next minor release will be 2.8.0, and the next major release will be 3.0.0)
|
|
||||||
- [ ] FQCNs are used for `extends_documentation_fragment:`, unless the author is referring to doc_fragments from ansible-core
|
|
||||||
|
|
||||||
**Tests (if applicable and technically possible to implement)**
|
|
||||||
- [ ] the pull request has [integration tests](https://docs.ansible.com/ansible/devel/dev_guide/testing_integration.html)
|
|
||||||
- [ ] the pull request has [unit tests](https://docs.ansible.com/ansible/devel/dev_guide/testing_units.html)
|
|
||||||
- [ ] all changes are covered
|
|
||||||
- [ ] integration tests also cover `check_mode` (if it is supported)
|
|
||||||
- [ ] integration tests check an actual state of the system, not only what the module reports (for example, if the module changes a file, check that the file was actually changed by using the `ansible.builtin.stat` module)
|
|
||||||
|
|
||||||
**Other**
|
|
||||||
- [ ] the pull request does not contain merge commits (see GitHub warnings at the bottom of the pull request) - in this case, ask the author to rebase the pull request branch
|
|
||||||
- [ ] if the pull request contains breaking changes, ask the author and the collection maintainers if it is really needed and there is no way not to introduce them
|
|
166
TESTING.md
Normal file
166
TESTING.md
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
# Tests
|
||||||
|
|
||||||
|
This collection uses GitHub Actions to run ansible-test to validate its content. Three type of tests are used: Sanity, Integration and Units.
|
||||||
|
|
||||||
|
The tests covers plugins and roles (no role available yet, but tests are ready) and can be found here:
|
||||||
|
|
||||||
|
- Plugins: *.github/workflows/ansible-test-plugins.yml*
|
||||||
|
- Roles: *.github/workflows/ansible-test-roles.yml* (unused yet)
|
||||||
|
|
||||||
|
Everytime you push on your fork or you create a pull request, both workflows runs. You can see the output on the "Actions" tab.
|
||||||
|
|
||||||
|
|
||||||
|
## Integration tests
|
||||||
|
|
||||||
|
You can use GitHub to run ansible-test either on the community repo or your fork. But sometimes you want to quickly test a single version or a single target. To do that, you can use the Makefile present at the root of this repository.
|
||||||
|
|
||||||
|
For now, the makefile only supports Podman.
|
||||||
|
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
- python >= 3.8 and <= 3.10
|
||||||
|
- make
|
||||||
|
- podman
|
||||||
|
- Minimum 15GB of free space on the device storing containers images and volumes. You can use this command to check: `podman system info --format='{{.Store.GraphRoot}}'|xargs findmnt --noheadings --nofsroot --output SOURCE --target|xargs df -h --output=size,used,avail,pcent,target`
|
||||||
|
- Minimum 2GB of RAM
|
||||||
|
|
||||||
|
|
||||||
|
### Custom ansible-test containers
|
||||||
|
|
||||||
|
Our integrations tests use custom containers for ansible-test. Those images have their definition file stored in the directory [test-containers](test-containers/). We build and publish the images on ghcr.io under the ansible-collection namespace: E.G.:
|
||||||
|
`ghcr.io/ansible-collections/community.mysql/test-container-mariadb106-py310-mysqlclient211:latest`.
|
||||||
|
|
||||||
|
Availables images are listed [here](https://github.com/orgs/ansible-collections/packages).
|
||||||
|
|
||||||
|
|
||||||
|
### Makefile options
|
||||||
|
|
||||||
|
The Makefile accept the following options
|
||||||
|
|
||||||
|
- `local_python_version`
|
||||||
|
- Mandatory: false
|
||||||
|
- Choices:
|
||||||
|
- "3.8"
|
||||||
|
- "3.9"
|
||||||
|
- "3.10"
|
||||||
|
- Description: If `Python -V` shows an unsupported version, use this option and choose one of the version available on your system. Use `ls /usr/bin/python3*|grep -v config` to list them.
|
||||||
|
|
||||||
|
- `ansible`
|
||||||
|
- Mandatory: true
|
||||||
|
- Choices:
|
||||||
|
- "stable-2.12"
|
||||||
|
- "stable-2.13"
|
||||||
|
- "stable-2.14"
|
||||||
|
- "devel"
|
||||||
|
- Description: Version of ansible to install in a venv to run ansible-test
|
||||||
|
|
||||||
|
- `db_engine_name`
|
||||||
|
- Mandatory: true
|
||||||
|
- Choices:
|
||||||
|
- "mysql"
|
||||||
|
- "mariadb"
|
||||||
|
- Description: The name of the database engine to use for the service containers that will host a primary database and two replicas.
|
||||||
|
|
||||||
|
- `db_engine_version`
|
||||||
|
- Mandatory: true
|
||||||
|
- Choices:
|
||||||
|
- "5.7.40" <- mysql
|
||||||
|
- "8.0.31" <- mysql
|
||||||
|
- "10.4.24" <- mariadb
|
||||||
|
- "10.5.18" <- mariadb
|
||||||
|
- "10.6.11" <- mariadb
|
||||||
|
- Description: The tag of the container to use for the service containers that will host a primary database and two replicas. Do not use short version, like `mysql:8` (don't do that) because our tests expect a full version to filter tests precisely. For instance: `when: db_version is version ('8.0.22', '>')`. You can use any tag available on [hub.docker.com/_/mysql](https://hub.docker.com/_/mysql) and [hub.docker.com/_/mariadb](https://hub.docker.com/_/mariadb) but GitHub Action will only use the versions listed above.
|
||||||
|
|
||||||
|
- `connector_name`
|
||||||
|
- Mandatory: true
|
||||||
|
- Choices:
|
||||||
|
- "pymysql
|
||||||
|
- "mysqlclient"
|
||||||
|
- Description: The python package of the connector to use. In addition to selecting the test container, this value is also used for tests filtering: `when: connector_name == 'pymysql'`.
|
||||||
|
|
||||||
|
- `connector_version`
|
||||||
|
- Mandatory: true
|
||||||
|
- Choices:
|
||||||
|
- "0.7.11" <- pymysql (Only for MySQL 5.7)
|
||||||
|
- "0.9.3" <- pymysql
|
||||||
|
- "1.0.2" <- pymysql (Not working, need fix)
|
||||||
|
- "2.0.1" <- mysqlclient
|
||||||
|
- "2.0.3" <- mysqlclient
|
||||||
|
- "2.1.1" <- mysqlclient
|
||||||
|
- Description: The version of the python package of the connector to use. This value is used to filter tests meant for other connectors.
|
||||||
|
|
||||||
|
- `python`
|
||||||
|
- Mandatory: true
|
||||||
|
- Choices:
|
||||||
|
- "3.8"
|
||||||
|
- "3.9"
|
||||||
|
- "3.10"
|
||||||
|
- Description: The python version to use in the controller (ansible-test container).
|
||||||
|
|
||||||
|
- `target`
|
||||||
|
- Mandatory: false
|
||||||
|
- Choices:
|
||||||
|
- "test_mysql_db"
|
||||||
|
- "test_mysql_info"
|
||||||
|
- "test_mysql_query"
|
||||||
|
- "test_mysql_replication"
|
||||||
|
- "test_mysql_role"
|
||||||
|
- "test_mysql_user"
|
||||||
|
- "test_mysql_variables"
|
||||||
|
- Description: If omitted, all test targets will run. But you can limit the tests to a single target to speed up your tests.
|
||||||
|
|
||||||
|
- `keep_containers_alive`
|
||||||
|
- Mandatory: false
|
||||||
|
- Description: This option keeps all tree databases containers and the ansible-test container alive at the end of tests or in case of failure. This is useful to enter one of the containers with `podman exec -it <container-name> bash` for debugging. Rerunning the
|
||||||
|
tests will overwrite the 3 databases containers so no need to kill them in advance. But nothing will kill the ansible-test container. You must do that using `podman stop` and `podman rm`. Add any value to activate this option: `keep_containers_alive=1`
|
||||||
|
|
||||||
|
- `continue_on_errors`
|
||||||
|
- Mandatory: false
|
||||||
|
- Description: Tells ansible-test to retry on errors and also continue on errors. This is the way the GitHub Action's workflow runs the tests. This can be used to catch all errors in a single run, but you'll need to scroll up to find them. Add any value to activate this option: `continue_on_errors=1`
|
||||||
|
|
||||||
|
|
||||||
|
#### Makefile usage examples:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Run all targets
|
||||||
|
make ansible="stable-2.12" db_engine_name="mysql" db_engine_version="5.7.40" python="3.8" connector_name="pymysql" connector_version="0.7.11"
|
||||||
|
|
||||||
|
# A single target
|
||||||
|
make ansible="stable-2.14" db_engine_name="mysql" db_engine_version="5.7.40" python="3.8" connector_name="pymysql" connector_version="0.7.11" target="test_mysql_info"
|
||||||
|
|
||||||
|
# Keep databases and ansible tests containers alives
|
||||||
|
# A single target and continue on errors
|
||||||
|
make ansible="stable-2.14" db_engine_name="mysql" db_engine_version="8.0.31" python="3.9" connector_name="mysqlclient" connector_version="2.0.3" target="test_mysql_query" keep_containers_alive=1 continue_on_errors=1
|
||||||
|
|
||||||
|
# If your system has an usupported version of Python:
|
||||||
|
make local_python_version="3.8" ansible="stable-2.14" db_engine_name="mariadb" db_engine_version="10.6.11" python="3.9" connector_name="pymysql" connector_version="0.9.3"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Run all tests
|
||||||
|
|
||||||
|
GitHub Action offer a test matrix that run every combination of Python, MySQL, MariaDB and Connector against each other. To reproduce this, this repo provides a script called *run_all_tests.py*.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python run_all_tests.py
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Add a new Python, Connector or Database version
|
||||||
|
|
||||||
|
You can look into `[.github/workflows/ansible-test-plugins.yml](https://github.com/ansible-collections/community.mysql/tree/main/.github/workflows)` to see how those containers are built using [build-docker-image.yml](https://github.com/ansible-collections/community.mysql/blob/main/.github/workflows/build-docker-image.yml) and all [docker-image-xxx.yml](https://github.com/ansible-collections/community.mysql/blob/main/.github/workflows/docker-image-mariadb103-py38-mysqlclient201.yml) files.
|
||||||
|
|
||||||
|
1. Add a workflow in [.github/workflows/](.github/workflows)
|
||||||
|
1. Add a new folder in [test-containers](test-containers) containing a new Dockerfile. Your container must contains 3 things:
|
||||||
|
- Python
|
||||||
|
- A connector: The python package to connect to the database (pymysql, mysqlclient, ...)
|
||||||
|
- A mysql client to prepare databases before our tests starts. This client must provide both `mysql` and `mysqldump` commands.
|
||||||
|
1. Add your version in the matrix of *.github/workflows/ansible-test-plugins.yml*. You can use [run_all_tests.py](run_all_tests.py) to help you see what the matrix will be. Simply comment out the line `os.system(make_cmd)` before runing the script. You can also add `print(len(matrix))` to display how many tests there will be on GitHub Action.
|
||||||
|
1. Ask the lead maintainer to mark your new image(s) as `public` under [https://github.com/orgs/ansible-collections/packages](https://github.com/orgs/ansible-collections/packages)
|
||||||
|
|
||||||
|
After pushing your commit to the remote, the container will be built and published on ghcr.io. Have a look in the "Action" tab to see if it worked. In case of error `failed to copy: io: read/write on closed pipe` re-run the workflow, this append unfortunately a lot.
|
||||||
|
|
||||||
|
To see the docker image produced, go to the package page in the ansible-collection namespace [https://github.com/orgs/ansible-collections/packages](https://github.com/orgs/ansible-collections/packages). This page indicate a "Published x days ago" that is updated infrequently. To see the last time the container has been updated you must click on its title and look in the right hands side bellow the title "Last published".
|
|
@ -235,3 +235,191 @@ releases:
|
||||||
- 107-mysql_user_fix_grant_on_col_handling.yml
|
- 107-mysql_user_fix_grant_on_col_handling.yml
|
||||||
- 97-mysql_replication_deprecate_offending_terminology.yml
|
- 97-mysql_replication_deprecate_offending_terminology.yml
|
||||||
release_date: '2021-03-08'
|
release_date: '2021-03-08'
|
||||||
|
1.4.0:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- mysql_user - add support for ``REPLICA MONITOR`` privilege (https://github.com/ansible-collections/community.mysql/issues/105).
|
||||||
|
major_changes:
|
||||||
|
- mysql_user - the ``REQUIRESSL`` is an alias for the ``ssl`` key in the ``tls_requires``
|
||||||
|
option in ``community.mysql`` 2.0.0 and support will be dropped altogether
|
||||||
|
in ``community.mysql`` 3.0.0 (https://github.com/ansible-collections/community.mysql/issues/121).
|
||||||
|
minor_changes:
|
||||||
|
- mysql module utils - change deprecated connection parameters ``passwd`` and
|
||||||
|
``db`` to ``password`` and ``database`` (https://github.com/ansible-collections/community.mysql/pull/116).
|
||||||
|
- mysql_collection - introduce codebabse split to handle divergences between
|
||||||
|
MySQL and MariaDB (https://github.com/ansible-collections/community.mysql/pull/103).
|
||||||
|
- mysql_info - add `version.full` and `version.suffix` return values (https://github.com/ansible-collections/community.mysql/issues/114).
|
||||||
|
- mysql_user - deprecate the ``REQUIRESSL`` privilege (https://github.com/ansible-collections/community.mysql/issues/101).
|
||||||
|
release_summary: 'This is the minor release of the ``community.mysql`` collection.
|
||||||
|
|
||||||
|
This changelog contains all changes to the modules in this collection
|
||||||
|
|
||||||
|
that have been added after the release of ``community.mysql`` 1.3.0.'''
|
||||||
|
fragments:
|
||||||
|
- 1.4.0.yml
|
||||||
|
- 101-drop-requiressl-support.yml
|
||||||
|
- 103-mysql_and_mariadb_divergence.yml
|
||||||
|
- 108-mysql_priv_add_grant.yml
|
||||||
|
- 115-add_mysql_full_version_suffix_return_var.yml
|
||||||
|
- 116-change_deprecated_connection_ parameters.yml
|
||||||
|
release_date: '2021-04-16'
|
||||||
|
1.4.1:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- mysql - revert changes of connector arguments made in pull request 116 causing
|
||||||
|
the invalid keyword argument error (https://github.com/ansible-collections/community.mysql/pull/116).
|
||||||
|
release_summary: 'This is the patch release of the ``community.mysql`` collection.
|
||||||
|
|
||||||
|
This changelog contains all changes to the modules in this collection
|
||||||
|
|
||||||
|
that have been added after the release of ``community.mysql`` 1.4.0.'
|
||||||
|
fragments:
|
||||||
|
- 1.4.1.yml
|
||||||
|
- 153-mysql_revert_connector_changes.yml
|
||||||
|
release_date: '2021-04-23'
|
||||||
|
1.4.2:
|
||||||
|
changes:
|
||||||
|
minor_changes:
|
||||||
|
- mysql_query - correctly reflect changed status in replace statements (https://github.com/ansible-collections/community.mysql/pull/193).
|
||||||
|
release_summary: 'This is the patch release of the ``community.mysql`` collection.
|
||||||
|
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.1.'
|
||||||
|
fragments:
|
||||||
|
- 1.4.2.yml
|
||||||
|
- 193-reflect_changed_status_in_replace_statements.yml
|
||||||
|
release_date: '2021-08-11'
|
||||||
|
1.4.3:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- mysql_info - fix TypeError failure when there are databases that do not contain
|
||||||
|
tables (https://github.com/ansible-collections/community.mysql/issues/204).
|
||||||
|
release_summary: 'This is the patch release of the ``community.mysql`` collection.
|
||||||
|
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.2.'
|
||||||
|
fragments:
|
||||||
|
- 1.4.3.yml
|
||||||
|
- 205-mysql_info_fix_failure_when_no_tables_in_db.yml
|
||||||
|
release_date: '2021-09-23'
|
||||||
|
1.4.4:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- Collection core functions - use vendored version of ``distutils.version``
|
||||||
|
instead of the deprecated Python standard library ``distutils`` (https://github.com/ansible-collections/community.mysql/pull/269).
|
||||||
|
release_summary: 'This is the patch release of the ``community.mysql`` collection.
|
||||||
|
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.3.'
|
||||||
|
fragments:
|
||||||
|
- 1.4.4.yml
|
||||||
|
- 267-prepare_for_distutils_be_removed.yml
|
||||||
|
release_date: '2022-01-18'
|
||||||
|
1.4.5:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- mysql_user - fix missing dynamic privileges after revoke and grant privileges
|
||||||
|
to user (https://github.com/ansible-collections/community.mysql/issues/120).
|
||||||
|
- mysql_user - fix parsing privs when a user has roles assigned (https://github.com/ansible-collections/community.mysql/issues/231).
|
||||||
|
- 'mysql_user - fix the possibility for a race condition that breaks certain
|
||||||
|
(circular) replication configurations when ``DROP USER`` is executed on multiple
|
||||||
|
nodes in the replica set. Adding ``IF EXISTS`` avoids the need to use ``sql_log_bin:
|
||||||
|
no`` making the statement always replication safe (https://github.com/ansible-collections/community.mysql/pull/287).'
|
||||||
|
major_changes:
|
||||||
|
- The community.mysql collection no longer supports ``Ansible 2.9`` and ``ansible-base
|
||||||
|
2.10``. While we take no active measures to prevent usage and there are no
|
||||||
|
plans to introduce incompatible code to the modules, we will stop testing
|
||||||
|
against ``Ansible 2.9`` and ``ansible-base 2.10``. Both will very soon be
|
||||||
|
End of Life and if you are still using them, you should consider upgrading
|
||||||
|
to the ``latest Ansible / ansible-core 2.11 or later`` as soon as possible
|
||||||
|
(https://github.com/ansible-collections/community.mysql/pull/343).
|
||||||
|
release_summary: 'This is the patch release of the ``community.mysql`` collection.
|
||||||
|
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.4.'
|
||||||
|
fragments:
|
||||||
|
- 001-mysql_user_fix_pars_users_with_roles_assigned.yml
|
||||||
|
- 1.4.5.yml
|
||||||
|
- 307-mysql_user_add_if_exists_to_drop.yml
|
||||||
|
- 338-mysql_user_fix.yml
|
||||||
|
- drop_support_of_2.9-2.10.yml
|
||||||
|
release_date: '2022-05-13'
|
||||||
|
1.4.6:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- Include ``PSF-license.txt`` file for ``plugins/module_utils/_version.py``.
|
||||||
|
release_summary: 'This is the patch release of the ``community.mysql`` collection.
|
||||||
|
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.5.'
|
||||||
|
fragments:
|
||||||
|
- 1.4.6.yml
|
||||||
|
- psf-license.yml
|
||||||
|
release_date: '2022-05-17'
|
||||||
|
1.4.7:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- mysql_query - fix false change reports when ``IF EXISTS/IF NOT EXISTS`` clause
|
||||||
|
is used (https://github.com/ansible-collections/community.mysql/issues/268).
|
||||||
|
- mysql_user - fix logic when ``update_password`` is set to ``on_create`` for
|
||||||
|
users using ``plugin*`` arguments (https://github.com/ansible-collections/community.mysql/issues/334).
|
||||||
|
The ``on_create`` sets ``password`` to None for old mysql_native_authentication
|
||||||
|
but not for authentiation methods which uses the ``plugin*`` arguments. This
|
||||||
|
PR changes this so ``on_create`` also exchange ``plugin``, ``plugin_hash_string``,
|
||||||
|
``plugin_auth_string`` to None in the list of arguments to change
|
||||||
|
release_summary: 'This is the patch release of the ``community.mysql`` collection.
|
||||||
|
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.6.'
|
||||||
|
fragments:
|
||||||
|
- 1.4.7.yml
|
||||||
|
- 322-mysql_query_fix_false_change_report.yml
|
||||||
|
- 334-mysql_user_fix_logic_on_oncreate.yml
|
||||||
|
release_date: '2022-06-02'
|
||||||
|
1.4.8:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- Include ``simplified_bsd.txt`` license file for various module utils.
|
||||||
|
release_summary: 'This is the patch release of the ``community.mysql`` collection.
|
||||||
|
|
||||||
|
This changelog contains all changes to the modules in this collection that
|
||||||
|
|
||||||
|
have been added after the release of ``community.mysql`` 1.4.7.'
|
||||||
|
fragments:
|
||||||
|
- 1.4.8.yml
|
||||||
|
- simplified-bsd-license.yml
|
||||||
|
release_date: '2022-07-28'
|
||||||
|
1.5.0:
|
||||||
|
changes:
|
||||||
|
minor_changes:
|
||||||
|
- mysql_info - add ``connector_name`` and ``connector_version`` to returned
|
||||||
|
values (https://github.com/ansible-collections/community.mysql/pull/497).
|
||||||
|
release_summary: 'This is bugfix release of the ``community.mysql`` collection.
|
||||||
|
|
||||||
|
This changelog contains all changes to the modules and plugins in this collection
|
||||||
|
|
||||||
|
that have been made after the previous release.'
|
||||||
|
fragments:
|
||||||
|
- 1.5.0.yml
|
||||||
|
- 497_mysql_info_returns_connector_name_and_version.yml
|
||||||
|
- backport-stable-2-pr-452.yml
|
||||||
|
release_date: '2023-02-08'
|
||||||
|
1.5.1:
|
||||||
|
changes:
|
||||||
|
major_changes:
|
||||||
|
- The ``community.mysql`` 1.x.y release stream is now effectively End of Life.
|
||||||
|
No more releases will be made. This follows the decision to support each major
|
||||||
|
release for two years. This decision stems from this
|
||||||
|
discussion (https://github.com/ansible-collections/community.mysql/discussions/537)
|
||||||
|
release_summary: Final maintenance release of ``community.mysql`` major version
|
||||||
|
1.
|
||||||
|
fragments:
|
||||||
|
- 1.5.1.yml
|
||||||
|
- 490_refactor_integration_tests.yml
|
||||||
|
release_date: '2023-05-04'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
changelog_filename_template: CHANGELOG.rst
|
changelog_filename_template: ../CHANGELOG.rst
|
||||||
changelog_filename_version_depth: 0
|
changelog_filename_version_depth: 0
|
||||||
changes_file: changelog.yaml
|
changes_file: changelog.yaml
|
||||||
changes_format: combined
|
changes_format: combined
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
minor_changes:
|
|
||||||
- mysql_user - deprecate the ``REQUIRESSL`` privilege (https://github.com/ansible-collections/community.mysql/issues/101).
|
|
||||||
major_changes:
|
|
||||||
- mysql_user - the ``REQUIRESSL`` is an alias for the ``ssl`` key in the ``tls_requires`` option in ``community.mysql`` 2.0.0 and support will be dropped altogether in ``community.mysql`` 3.0.0 (https://github.com/ansible-collections/community.mysql/issues/121).
|
|
|
@ -1,2 +0,0 @@
|
||||||
minor_changes:
|
|
||||||
- mysql_collection - introduce codebabse split to handle divergences between MySQL and MariaDB (https://github.com/ansible-collections/community.mysql/pull/103).
|
|
|
@ -1,2 +0,0 @@
|
||||||
bugfixes:
|
|
||||||
- mysql_user - add support for ``REPLICA MONITOR`` privilege (https://github.com/ansible-collections/community.mysql/issues/105).
|
|
|
@ -1,2 +0,0 @@
|
||||||
minor_changes:
|
|
||||||
- mysql_info - add `version.full` and `version.suffix` return values (https://github.com/ansible-collections/community.mysql/issues/114).
|
|
|
@ -1,2 +0,0 @@
|
||||||
minor_changes:
|
|
||||||
- mysql module utils - change deprecated connection parameters ``passwd`` and ``db`` to ``password`` and ``database`` (https://github.com/ansible-collections/community.mysql/pull/116).
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
---
|
||||||
namespace: community
|
namespace: community
|
||||||
name: mysql
|
name: mysql
|
||||||
version: 1.3.0
|
version: 1.5.1
|
||||||
readme: README.md
|
readme: README.md
|
||||||
authors:
|
authors:
|
||||||
- Ansible community
|
- Ansible community
|
||||||
|
|
|
@ -35,6 +35,7 @@ options:
|
||||||
login_unix_socket:
|
login_unix_socket:
|
||||||
description:
|
description:
|
||||||
- The path to a Unix domain socket for local connections.
|
- The path to a Unix domain socket for local connections.
|
||||||
|
- Use this parameter to avoid the C(Please explicitly state intended protocol) error.
|
||||||
type: str
|
type: str
|
||||||
connect_timeout:
|
connect_timeout:
|
||||||
description:
|
description:
|
||||||
|
@ -44,6 +45,9 @@ options:
|
||||||
config_file:
|
config_file:
|
||||||
description:
|
description:
|
||||||
- Specify a config file from which user and password are to be read.
|
- Specify a config file from which user and password are to be read.
|
||||||
|
- The default config file, C(~/.my.cnf), if it exists, will be read, even if I(config_file) is not specified.
|
||||||
|
- The default config file, C(~/.my.cnf), if it exists, must contain a C([client]) section as a MySQL connector requirement.
|
||||||
|
- To prevent the default config file from being read, set I(config_file) to be an empty string.
|
||||||
type: path
|
type: path
|
||||||
default: '~/.my.cnf'
|
default: '~/.my.cnf'
|
||||||
ca_cert:
|
ca_cert:
|
||||||
|
@ -67,21 +71,25 @@ options:
|
||||||
- Whether to validate the server host name when an SSL connection is required. Corresponds to MySQL CLIs C(--ssl) switch.
|
- Whether to validate the server host name when an SSL connection is required. Corresponds to MySQL CLIs C(--ssl) switch.
|
||||||
- Setting this to C(false) disables hostname verification. Use with caution.
|
- Setting this to C(false) disables hostname verification. Use with caution.
|
||||||
- Requires pymysql >= 0.7.11.
|
- Requires pymysql >= 0.7.11.
|
||||||
- This optoin has no effect on MySQLdb.
|
- This option has no effect on MySQLdb.
|
||||||
type: bool
|
type: bool
|
||||||
version_added: '1.1.0'
|
version_added: '1.1.0'
|
||||||
requirements:
|
requirements:
|
||||||
- PyMySQL (Python 2.7 and Python 3.X), or
|
- mysqlclient (Python 3.5+) or
|
||||||
|
- PyMySQL (Python 2.7 and Python 3.x) or
|
||||||
- MySQLdb (Python 2.x)
|
- MySQLdb (Python 2.x)
|
||||||
notes:
|
notes:
|
||||||
- Requires the PyMySQL (Python 2.7 and Python 3.X) or MySQL-python (Python 2.X) package installed on the remote host.
|
- Requires the PyMySQL (Python 2.7 and Python 3.X) or MySQL-python (Python 2.X) package installed on the remote host.
|
||||||
The Python package may be installed with apt-get install python-pymysql (Ubuntu; see M(ansible.builtin.apt)) or
|
The Python package may be installed with apt-get install python-pymysql (Ubuntu; see M(ansible.builtin.apt)) or
|
||||||
yum install python2-PyMySQL (RHEL/CentOS/Fedora; see M(ansible.builtin.yum)). You can also use dnf install python2-PyMySQL
|
yum install python2-PyMySQL (RHEL/CentOS/Fedora; see M(ansible.builtin.yum)). You can also use dnf install python2-PyMySQL
|
||||||
for newer versions of Fedora; see M(ansible.builtin.dnf).
|
for newer versions of Fedora; see M(ansible.builtin.dnf).
|
||||||
- Be sure you have PyMySQL or MySQLdb library installed on the target machine
|
- Be sure you have mysqlclient, PyMySQL, or MySQLdb library installed on the target machine
|
||||||
for the Python interpreter Ansible uses, for example, if it is Python 3,
|
for the Python interpreter Ansible discovers. For example if ansible discovers and uses Python 3, you need to install
|
||||||
you must install the library for Python 3. You can also change the interpreter.
|
the Python 3 version of PyMySQL or mysqlclient. If ansible discovers and uses Python 2, you need to install the Python 2
|
||||||
For more information, see U(https://docs.ansible.com/ansible/latest/reference_appendices/interpreter_discovery.html).
|
version of either PyMySQL or MySQL-python.
|
||||||
|
- If you have trouble, it may help to force Ansible to use the Python interpreter you need by specifying
|
||||||
|
C(ansible_python_interpreter). For more information, see
|
||||||
|
U(https://docs.ansible.com/ansible/latest/reference_appendices/interpreter_discovery.html).
|
||||||
- Both C(login_password) and C(login_user) are required when you are
|
- Both C(login_password) and C(login_user) are required when you are
|
||||||
passing credentials. If none are present, the module will attempt to read
|
passing credentials. If none are present, the module will attempt to read
|
||||||
the credentials from C(~/.my.cnf), and finally fall back to using the MySQL
|
the credentials from C(~/.my.cnf), and finally fall back to using the MySQL
|
||||||
|
@ -94,4 +102,12 @@ notes:
|
||||||
- Alternatively, you can use the mysqlclient library instead of MySQL-python (MySQLdb)
|
- Alternatively, you can use the mysqlclient library instead of MySQL-python (MySQLdb)
|
||||||
which supports both Python 2.X and Python >=3.5.
|
which supports both Python 2.X and Python >=3.5.
|
||||||
See U(https://pypi.org/project/mysqlclient/) how to install it.
|
See U(https://pypi.org/project/mysqlclient/) how to install it.
|
||||||
|
- "If credentials from the config file (for example, C(/root/.my.cnf)) are not needed to connect to a database server, but
|
||||||
|
the file exists and does not contain a C([client]) section, before any other valid directives, it will be read and this
|
||||||
|
will cause the connection to fail, to prevent this set it to an empty string, (for example C(config_file: ''))."
|
||||||
|
- "To avoid the C(Please explicitly state intended protocol) error, use the I(login_unix_socket) argument,
|
||||||
|
for example, C(login_unix_socket: /run/mysqld/mysqld.sock)."
|
||||||
|
- Alternatively, to avoid using I(login_unix_socket) argument on each invocation you can specify the socket path
|
||||||
|
using the `socket` option in your MySQL config file (usually C(~/.my.cnf)) on the destination host, for
|
||||||
|
example C(socket=/var/lib/mysql/mysql.sock).
|
||||||
'''
|
'''
|
||||||
|
|
343
plugins/module_utils/_version.py
Normal file
343
plugins/module_utils/_version.py
Normal file
|
@ -0,0 +1,343 @@
|
||||||
|
# Vendored copy of distutils/version.py from CPython 3.9.5
|
||||||
|
#
|
||||||
|
# Implements multiple version numbering conventions for the
|
||||||
|
# Python Module Distribution Utilities.
|
||||||
|
#
|
||||||
|
# PSF License (see PSF-license.txt or https://opensource.org/licenses/Python-2.0)
|
||||||
|
#
|
||||||
|
|
||||||
|
"""Provides classes to represent module version numbers (one class for
|
||||||
|
each style of version numbering). There are currently two such classes
|
||||||
|
implemented: StrictVersion and LooseVersion.
|
||||||
|
|
||||||
|
Every version number class implements the following interface:
|
||||||
|
* the 'parse' method takes a string and parses it to some internal
|
||||||
|
representation; if the string is an invalid version number,
|
||||||
|
'parse' raises a ValueError exception
|
||||||
|
* the class constructor takes an optional string argument which,
|
||||||
|
if supplied, is passed to 'parse'
|
||||||
|
* __str__ reconstructs the string that was passed to 'parse' (or
|
||||||
|
an equivalent string -- ie. one that will generate an equivalent
|
||||||
|
version number instance)
|
||||||
|
* __repr__ generates Python code to recreate the version number instance
|
||||||
|
* _cmp compares the current instance with either another instance
|
||||||
|
of the same class or a string (which will be parsed to an instance
|
||||||
|
of the same class, thus must follow the same rules)
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
try:
|
||||||
|
RE_FLAGS = re.VERBOSE | re.ASCII
|
||||||
|
except AttributeError:
|
||||||
|
RE_FLAGS = re.VERBOSE
|
||||||
|
|
||||||
|
|
||||||
|
class Version:
|
||||||
|
"""Abstract base class for version numbering classes. Just provides
|
||||||
|
constructor (__init__) and reproducer (__repr__), because those
|
||||||
|
seem to be the same for all version numbering classes; and route
|
||||||
|
rich comparisons to _cmp.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, vstring=None):
|
||||||
|
if vstring:
|
||||||
|
self.parse(vstring)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "%s ('%s')" % (self.__class__.__name__, str(self))
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
c = self._cmp(other)
|
||||||
|
if c is NotImplemented:
|
||||||
|
return c
|
||||||
|
return c == 0
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
c = self._cmp(other)
|
||||||
|
if c is NotImplemented:
|
||||||
|
return c
|
||||||
|
return c < 0
|
||||||
|
|
||||||
|
def __le__(self, other):
|
||||||
|
c = self._cmp(other)
|
||||||
|
if c is NotImplemented:
|
||||||
|
return c
|
||||||
|
return c <= 0
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
c = self._cmp(other)
|
||||||
|
if c is NotImplemented:
|
||||||
|
return c
|
||||||
|
return c > 0
|
||||||
|
|
||||||
|
def __ge__(self, other):
|
||||||
|
c = self._cmp(other)
|
||||||
|
if c is NotImplemented:
|
||||||
|
return c
|
||||||
|
return c >= 0
|
||||||
|
|
||||||
|
|
||||||
|
# Interface for version-number classes -- must be implemented
|
||||||
|
# by the following classes (the concrete ones -- Version should
|
||||||
|
# be treated as an abstract class).
|
||||||
|
# __init__ (string) - create and take same action as 'parse'
|
||||||
|
# (string parameter is optional)
|
||||||
|
# parse (string) - convert a string representation to whatever
|
||||||
|
# internal representation is appropriate for
|
||||||
|
# this style of version numbering
|
||||||
|
# __str__ (self) - convert back to a string; should be very similar
|
||||||
|
# (if not identical to) the string supplied to parse
|
||||||
|
# __repr__ (self) - generate Python code to recreate
|
||||||
|
# the instance
|
||||||
|
# _cmp (self, other) - compare two version numbers ('other' may
|
||||||
|
# be an unparsed version string, or another
|
||||||
|
# instance of your version class)
|
||||||
|
|
||||||
|
|
||||||
|
class StrictVersion(Version):
|
||||||
|
"""Version numbering for anal retentives and software idealists.
|
||||||
|
Implements the standard interface for version number classes as
|
||||||
|
described above. A version number consists of two or three
|
||||||
|
dot-separated numeric components, with an optional "pre-release" tag
|
||||||
|
on the end. The pre-release tag consists of the letter 'a' or 'b'
|
||||||
|
followed by a number. If the numeric components of two version
|
||||||
|
numbers are equal, then one with a pre-release tag will always
|
||||||
|
be deemed earlier (lesser) than one without.
|
||||||
|
|
||||||
|
The following are valid version numbers (shown in the order that
|
||||||
|
would be obtained by sorting according to the supplied cmp function):
|
||||||
|
|
||||||
|
0.4 0.4.0 (these two are equivalent)
|
||||||
|
0.4.1
|
||||||
|
0.5a1
|
||||||
|
0.5b3
|
||||||
|
0.5
|
||||||
|
0.9.6
|
||||||
|
1.0
|
||||||
|
1.0.4a3
|
||||||
|
1.0.4b1
|
||||||
|
1.0.4
|
||||||
|
|
||||||
|
The following are examples of invalid version numbers:
|
||||||
|
|
||||||
|
1
|
||||||
|
2.7.2.2
|
||||||
|
1.3.a4
|
||||||
|
1.3pl1
|
||||||
|
1.3c4
|
||||||
|
|
||||||
|
The rationale for this version numbering system will be explained
|
||||||
|
in the distutils documentation.
|
||||||
|
"""
|
||||||
|
|
||||||
|
version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$',
|
||||||
|
RE_FLAGS)
|
||||||
|
|
||||||
|
def parse(self, vstring):
|
||||||
|
match = self.version_re.match(vstring)
|
||||||
|
if not match:
|
||||||
|
raise ValueError("invalid version number '%s'" % vstring)
|
||||||
|
|
||||||
|
(major, minor, patch, prerelease, prerelease_num) = \
|
||||||
|
match.group(1, 2, 4, 5, 6)
|
||||||
|
|
||||||
|
if patch:
|
||||||
|
self.version = tuple(map(int, [major, minor, patch]))
|
||||||
|
else:
|
||||||
|
self.version = tuple(map(int, [major, minor])) + (0,)
|
||||||
|
|
||||||
|
if prerelease:
|
||||||
|
self.prerelease = (prerelease[0], int(prerelease_num))
|
||||||
|
else:
|
||||||
|
self.prerelease = None
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.version[2] == 0:
|
||||||
|
vstring = '.'.join(map(str, self.version[0:2]))
|
||||||
|
else:
|
||||||
|
vstring = '.'.join(map(str, self.version))
|
||||||
|
|
||||||
|
if self.prerelease:
|
||||||
|
vstring = vstring + self.prerelease[0] + str(self.prerelease[1])
|
||||||
|
|
||||||
|
return vstring
|
||||||
|
|
||||||
|
def _cmp(self, other):
|
||||||
|
if isinstance(other, str):
|
||||||
|
other = StrictVersion(other)
|
||||||
|
elif not isinstance(other, StrictVersion):
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
if self.version != other.version:
|
||||||
|
# numeric versions don't match
|
||||||
|
# prerelease stuff doesn't matter
|
||||||
|
if self.version < other.version:
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# have to compare prerelease
|
||||||
|
# case 1: neither has prerelease; they're equal
|
||||||
|
# case 2: self has prerelease, other doesn't; other is greater
|
||||||
|
# case 3: self doesn't have prerelease, other does: self is greater
|
||||||
|
# case 4: both have prerelease: must compare them!
|
||||||
|
|
||||||
|
if (not self.prerelease and not other.prerelease):
|
||||||
|
return 0
|
||||||
|
elif (self.prerelease and not other.prerelease):
|
||||||
|
return -1
|
||||||
|
elif (not self.prerelease and other.prerelease):
|
||||||
|
return 1
|
||||||
|
elif (self.prerelease and other.prerelease):
|
||||||
|
if self.prerelease == other.prerelease:
|
||||||
|
return 0
|
||||||
|
elif self.prerelease < other.prerelease:
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
raise AssertionError("never get here")
|
||||||
|
|
||||||
|
# end class StrictVersion
|
||||||
|
|
||||||
|
# The rules according to Greg Stein:
|
||||||
|
# 1) a version number has 1 or more numbers separated by a period or by
|
||||||
|
# sequences of letters. If only periods, then these are compared
|
||||||
|
# left-to-right to determine an ordering.
|
||||||
|
# 2) sequences of letters are part of the tuple for comparison and are
|
||||||
|
# compared lexicographically
|
||||||
|
# 3) recognize the numeric components may have leading zeroes
|
||||||
|
#
|
||||||
|
# The LooseVersion class below implements these rules: a version number
|
||||||
|
# string is split up into a tuple of integer and string components, and
|
||||||
|
# comparison is a simple tuple comparison. This means that version
|
||||||
|
# numbers behave in a predictable and obvious way, but a way that might
|
||||||
|
# not necessarily be how people *want* version numbers to behave. There
|
||||||
|
# wouldn't be a problem if people could stick to purely numeric version
|
||||||
|
# numbers: just split on period and compare the numbers as tuples.
|
||||||
|
# However, people insist on putting letters into their version numbers;
|
||||||
|
# the most common purpose seems to be:
|
||||||
|
# - indicating a "pre-release" version
|
||||||
|
# ('alpha', 'beta', 'a', 'b', 'pre', 'p')
|
||||||
|
# - indicating a post-release patch ('p', 'pl', 'patch')
|
||||||
|
# but of course this can't cover all version number schemes, and there's
|
||||||
|
# no way to know what a programmer means without asking him.
|
||||||
|
#
|
||||||
|
# The problem is what to do with letters (and other non-numeric
|
||||||
|
# characters) in a version number. The current implementation does the
|
||||||
|
# obvious and predictable thing: keep them as strings and compare
|
||||||
|
# lexically within a tuple comparison. This has the desired effect if
|
||||||
|
# an appended letter sequence implies something "post-release":
|
||||||
|
# eg. "0.99" < "0.99pl14" < "1.0", and "5.001" < "5.001m" < "5.002".
|
||||||
|
#
|
||||||
|
# However, if letters in a version number imply a pre-release version,
|
||||||
|
# the "obvious" thing isn't correct. Eg. you would expect that
|
||||||
|
# "1.5.1" < "1.5.2a2" < "1.5.2", but under the tuple/lexical comparison
|
||||||
|
# implemented here, this just isn't so.
|
||||||
|
#
|
||||||
|
# Two possible solutions come to mind. The first is to tie the
|
||||||
|
# comparison algorithm to a particular set of semantic rules, as has
|
||||||
|
# been done in the StrictVersion class above. This works great as long
|
||||||
|
# as everyone can go along with bondage and discipline. Hopefully a
|
||||||
|
# (large) subset of Python module programmers will agree that the
|
||||||
|
# particular flavour of bondage and discipline provided by StrictVersion
|
||||||
|
# provides enough benefit to be worth using, and will submit their
|
||||||
|
# version numbering scheme to its domination. The free-thinking
|
||||||
|
# anarchists in the lot will never give in, though, and something needs
|
||||||
|
# to be done to accommodate them.
|
||||||
|
#
|
||||||
|
# Perhaps a "moderately strict" version class could be implemented that
|
||||||
|
# lets almost anything slide (syntactically), and makes some heuristic
|
||||||
|
# assumptions about non-digits in version number strings. This could
|
||||||
|
# sink into special-case-hell, though; if I was as talented and
|
||||||
|
# idiosyncratic as Larry Wall, I'd go ahead and implement a class that
|
||||||
|
# somehow knows that "1.2.1" < "1.2.2a2" < "1.2.2" < "1.2.2pl3", and is
|
||||||
|
# just as happy dealing with things like "2g6" and "1.13++". I don't
|
||||||
|
# think I'm smart enough to do it right though.
|
||||||
|
#
|
||||||
|
# In any case, I've coded the test suite for this module (see
|
||||||
|
# ../test/test_version.py) specifically to fail on things like comparing
|
||||||
|
# "1.2a2" and "1.2". That's not because the *code* is doing anything
|
||||||
|
# wrong, it's because the simple, obvious design doesn't match my
|
||||||
|
# complicated, hairy expectations for real-world version numbers. It
|
||||||
|
# would be a snap to fix the test suite to say, "Yep, LooseVersion does
|
||||||
|
# the Right Thing" (ie. the code matches the conception). But I'd rather
|
||||||
|
# have a conception that matches common notions about version numbers.
|
||||||
|
|
||||||
|
|
||||||
|
class LooseVersion(Version):
|
||||||
|
"""Version numbering for anarchists and software realists.
|
||||||
|
Implements the standard interface for version number classes as
|
||||||
|
described above. A version number consists of a series of numbers,
|
||||||
|
separated by either periods or strings of letters. When comparing
|
||||||
|
version numbers, the numeric components will be compared
|
||||||
|
numerically, and the alphabetic components lexically. The following
|
||||||
|
are all valid version numbers, in no particular order:
|
||||||
|
|
||||||
|
1.5.1
|
||||||
|
1.5.2b2
|
||||||
|
161
|
||||||
|
3.10a
|
||||||
|
8.02
|
||||||
|
3.4j
|
||||||
|
1996.07.12
|
||||||
|
3.2.pl0
|
||||||
|
3.1.1.6
|
||||||
|
2g6
|
||||||
|
11g
|
||||||
|
0.960923
|
||||||
|
2.2beta29
|
||||||
|
1.13++
|
||||||
|
5.5.kw
|
||||||
|
2.0b1pl0
|
||||||
|
|
||||||
|
In fact, there is no such thing as an invalid version number under
|
||||||
|
this scheme; the rules for comparison are simple and predictable,
|
||||||
|
but may not always give the results you want (for some definition
|
||||||
|
of "want").
|
||||||
|
"""
|
||||||
|
|
||||||
|
component_re = re.compile(r'(\d+ | [a-z]+ | \.)', re.VERBOSE)
|
||||||
|
|
||||||
|
def __init__(self, vstring=None):
|
||||||
|
if vstring:
|
||||||
|
self.parse(vstring)
|
||||||
|
|
||||||
|
def parse(self, vstring):
|
||||||
|
# I've given up on thinking I can reconstruct the version string
|
||||||
|
# from the parsed tuple -- so I just store the string here for
|
||||||
|
# use by __str__
|
||||||
|
self.vstring = vstring
|
||||||
|
components = [x for x in self.component_re.split(vstring) if x and x != '.']
|
||||||
|
for i, obj in enumerate(components):
|
||||||
|
try:
|
||||||
|
components[i] = int(obj)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.version = components
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.vstring
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "LooseVersion ('%s')" % str(self)
|
||||||
|
|
||||||
|
def _cmp(self, other):
|
||||||
|
if isinstance(other, str):
|
||||||
|
other = LooseVersion(other)
|
||||||
|
elif not isinstance(other, LooseVersion):
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
if self.version == other.version:
|
||||||
|
return 0
|
||||||
|
if self.version < other.version:
|
||||||
|
return -1
|
||||||
|
if self.version > other.version:
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# end class LooseVersion
|
|
@ -6,7 +6,7 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
|
# Copyright (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
|
||||||
#
|
#
|
||||||
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
# Simplified BSD License (see simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
||||||
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version
|
from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version
|
||||||
from distutils.version import LooseVersion
|
from ansible_collections.community.mysql.plugins.module_utils.version import LooseVersion
|
||||||
|
|
||||||
|
|
||||||
def uses_replica_terminology(cursor):
|
def uses_replica_terminology(cursor):
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from distutils.version import LooseVersion
|
from ansible_collections.community.mysql.plugins.module_utils.version import LooseVersion
|
||||||
from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version
|
from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version
|
from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version
|
||||||
from distutils.version import LooseVersion
|
from ansible_collections.community.mysql.plugins.module_utils.version import LooseVersion
|
||||||
|
|
||||||
|
|
||||||
def uses_replica_terminology(cursor):
|
def uses_replica_terminology(cursor):
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from distutils.version import LooseVersion
|
from ansible_collections.community.mysql.plugins.module_utils.version import LooseVersion
|
||||||
from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version
|
from ansible_collections.community.mysql.plugins.module_utils.mysql import get_server_version
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# Copyright (c), Jonathan Mainguy <jon@soh.re>, 2015
|
# Copyright (c), Jonathan Mainguy <jon@soh.re>, 2015
|
||||||
# Most of this was originally added by Sven Schliesing @muffl0n in the mysql_user.py module
|
# Most of this was originally added by Sven Schliesing @muffl0n in the mysql_user.py module
|
||||||
#
|
#
|
||||||
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
# Simplified BSD License (see simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
||||||
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
@ -23,13 +23,54 @@ try:
|
||||||
_mysql_cursor_param = 'cursor'
|
_mysql_cursor_param = 'cursor'
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
|
# mysqlclient is called MySQLdb
|
||||||
import MySQLdb as mysql_driver
|
import MySQLdb as mysql_driver
|
||||||
import MySQLdb.cursors
|
import MySQLdb.cursors
|
||||||
_mysql_cursor_param = 'cursorclass'
|
_mysql_cursor_param = 'cursorclass'
|
||||||
except ImportError:
|
except ImportError:
|
||||||
mysql_driver = None
|
mysql_driver = None
|
||||||
|
|
||||||
mysql_driver_fail_msg = 'The PyMySQL (Python 2.7 and Python 3.X) or MySQL-python (Python 2.X) module is required.'
|
mysql_driver_fail_msg = ('A MySQL module is required: for Python 2.7 either PyMySQL, or '
|
||||||
|
'MySQL-python, or for Python 3.X mysqlclient or PyMySQL. '
|
||||||
|
'Consider setting ansible_python_interpreter to use '
|
||||||
|
'the intended Python version.')
|
||||||
|
|
||||||
|
|
||||||
|
def get_connector_name(connector):
|
||||||
|
""" (class) -> str
|
||||||
|
Return the name of the connector (pymysql or mysqlclient (MySQLdb))
|
||||||
|
or 'Unknown' if not pymysql or MySQLdb. When adding a
|
||||||
|
connector here, also modify get_connector_version.
|
||||||
|
"""
|
||||||
|
if connector is None or not hasattr(connector, '__name__'):
|
||||||
|
return 'Unknown'
|
||||||
|
|
||||||
|
return connector.__name__
|
||||||
|
|
||||||
|
|
||||||
|
def get_connector_version(connector):
|
||||||
|
""" (class) -> str
|
||||||
|
Return the version of pymysql or mysqlclient (MySQLdb).
|
||||||
|
Return 'Unknown' if the connector name is unknown.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if connector is None:
|
||||||
|
return 'Unknown'
|
||||||
|
|
||||||
|
connector_name = get_connector_name(connector)
|
||||||
|
|
||||||
|
if connector_name == 'pymysql':
|
||||||
|
# pymysql has two methods:
|
||||||
|
# - __version__ that returns the string: 0.7.11.None
|
||||||
|
# - VERSION that returns the tuple (0, 7, 11, None)
|
||||||
|
v = connector.VERSION[:3]
|
||||||
|
return '.'.join(map(str, v))
|
||||||
|
elif connector_name == 'MySQLdb':
|
||||||
|
# version_info returns the tuple (2, 1, 1, 'final', 0)
|
||||||
|
v = connector.version_info[:3]
|
||||||
|
return '.'.join(map(str, v))
|
||||||
|
else:
|
||||||
|
return 'Unknown'
|
||||||
|
|
||||||
|
|
||||||
def parse_from_mysql_config_file(cnf):
|
def parse_from_mysql_config_file(cnf):
|
||||||
|
@ -79,7 +120,7 @@ def mysql_connect(module, login_user=None, login_password=None, config_file='',
|
||||||
if login_user is not None:
|
if login_user is not None:
|
||||||
config['user'] = login_user
|
config['user'] = login_user
|
||||||
if login_password is not None:
|
if login_password is not None:
|
||||||
config['password'] = login_password
|
config['passwd'] = login_password
|
||||||
if ssl_cert is not None:
|
if ssl_cert is not None:
|
||||||
config['ssl']['cert'] = ssl_cert
|
config['ssl']['cert'] = ssl_cert
|
||||||
if ssl_key is not None:
|
if ssl_key is not None:
|
||||||
|
@ -87,7 +128,7 @@ def mysql_connect(module, login_user=None, login_password=None, config_file='',
|
||||||
if ssl_ca is not None:
|
if ssl_ca is not None:
|
||||||
config['ssl']['ca'] = ssl_ca
|
config['ssl']['ca'] = ssl_ca
|
||||||
if db is not None:
|
if db is not None:
|
||||||
config['database'] = db
|
config['db'] = db
|
||||||
if connect_timeout is not None:
|
if connect_timeout is not None:
|
||||||
config['connect_timeout'] = connect_timeout
|
config['connect_timeout'] = connect_timeout
|
||||||
if check_hostname is not None:
|
if check_hostname is not None:
|
||||||
|
|
16
plugins/module_utils/version.py
Normal file
16
plugins/module_utils/version.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright: (c) 2021, Felix Fontein <felix@fontein.de>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
"""Provide version object to compare version numbers."""
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
# Once we drop support for ansible-core 2.11, we can
|
||||||
|
# remove the _version.py file, and replace the following import by
|
||||||
|
#
|
||||||
|
# from ansible.module_utils.compat.version import LooseVersion
|
||||||
|
|
||||||
|
from ._version import LooseVersion
|
|
@ -53,12 +53,12 @@ options:
|
||||||
description:
|
description:
|
||||||
- Execute the dump in a single transaction.
|
- Execute the dump in a single transaction.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
quick:
|
quick:
|
||||||
description:
|
description:
|
||||||
- Option used for dumping large tables.
|
- Option used for dumping large tables.
|
||||||
type: bool
|
type: bool
|
||||||
default: yes
|
default: true
|
||||||
ignore_tables:
|
ignore_tables:
|
||||||
description:
|
description:
|
||||||
- A list of table names that will be ignored in the dump
|
- A list of table names that will be ignored in the dump
|
||||||
|
@ -70,14 +70,14 @@ options:
|
||||||
description:
|
description:
|
||||||
- Dump binary columns using hexadecimal notation.
|
- Dump binary columns using hexadecimal notation.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
version_added: '0.1.0'
|
version_added: '0.1.0'
|
||||||
force:
|
force:
|
||||||
description:
|
description:
|
||||||
- Continue dump or import even if we get an SQL error.
|
- Continue dump or import even if we get an SQL error.
|
||||||
- Used only when I(state) is C(dump) or C(import).
|
- Used only when I(state) is C(dump) or C(import).
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
version_added: '0.1.0'
|
version_added: '0.1.0'
|
||||||
master_data:
|
master_data:
|
||||||
description:
|
description:
|
||||||
|
@ -96,7 +96,7 @@ options:
|
||||||
description:
|
description:
|
||||||
- Skip locking tables for read. Used when I(state=dump), ignored otherwise.
|
- Skip locking tables for read. Used when I(state=dump), ignored otherwise.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
version_added: '0.1.0'
|
version_added: '0.1.0'
|
||||||
dump_extra_args:
|
dump_extra_args:
|
||||||
description:
|
description:
|
||||||
|
@ -110,7 +110,7 @@ options:
|
||||||
- If C(yes), the module will internally execute commands via a shell.
|
- If C(yes), the module will internally execute commands via a shell.
|
||||||
- Used when I(state=import), ignored otherwise.
|
- Used when I(state=import), ignored otherwise.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
version_added: '0.1.0'
|
version_added: '0.1.0'
|
||||||
unsafe_login_password:
|
unsafe_login_password:
|
||||||
description:
|
description:
|
||||||
|
@ -121,7 +121,7 @@ options:
|
||||||
- Used only when I(state) is C(import) or C(dump) and
|
- Used only when I(state) is C(import) or C(dump) and
|
||||||
I(login_password) is passed, ignored otherwise.
|
I(login_password) is passed, ignored otherwise.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
version_added: '0.1.0'
|
version_added: '0.1.0'
|
||||||
restrict_config_file:
|
restrict_config_file:
|
||||||
description:
|
description:
|
||||||
|
@ -132,14 +132,14 @@ options:
|
||||||
under the hood that read named option file in addition to usual option files.
|
under the hood that read named option file in addition to usual option files.
|
||||||
- If this behavior is undesirable, use C(yes) to read only named option file.
|
- If this behavior is undesirable, use C(yes) to read only named option file.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
version_added: '0.1.0'
|
version_added: '0.1.0'
|
||||||
check_implicit_admin:
|
check_implicit_admin:
|
||||||
description:
|
description:
|
||||||
- Check if mysql allows login as root/nopassword before trying supplied credentials.
|
- Check if mysql allows login as root/nopassword before trying supplied credentials.
|
||||||
- If success, passed I(login_user)/I(login_password) will be ignored.
|
- If success, passed I(login_user)/I(login_password) will be ignored.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
version_added: '0.1.0'
|
version_added: '0.1.0'
|
||||||
config_overrides_defaults:
|
config_overrides_defaults:
|
||||||
description:
|
description:
|
||||||
|
@ -148,7 +148,7 @@ options:
|
||||||
- Used when I(stat) is C(present) or C(absent), ignored otherwise.
|
- Used when I(stat) is C(present) or C(absent), ignored otherwise.
|
||||||
- It needs Python 3.5+ as the default interpreter on a target host.
|
- It needs Python 3.5+ as the default interpreter on a target host.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
version_added: '0.1.0'
|
version_added: '0.1.0'
|
||||||
|
|
||||||
seealso:
|
seealso:
|
||||||
|
@ -183,10 +183,13 @@ extends_documentation_fragment:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
|
# If you encounter the "Please explicitly state intended protocol" error,
|
||||||
|
# use the login_unix_socket argument
|
||||||
- name: Create a new database with name 'bobdata'
|
- name: Create a new database with name 'bobdata'
|
||||||
community.mysql.mysql_db:
|
community.mysql.mysql_db:
|
||||||
name: bobdata
|
name: bobdata
|
||||||
state: present
|
state: present
|
||||||
|
login_unix_socket: /run/mysqld/mysqld.sock
|
||||||
|
|
||||||
- name: Create new databases with names 'foo' and 'bar'
|
- name: Create new databases with names 'foo' and 'bar'
|
||||||
community.mysql.mysql_db:
|
community.mysql.mysql_db:
|
||||||
|
@ -212,7 +215,7 @@ EXAMPLES = r'''
|
||||||
name: my_db
|
name: my_db
|
||||||
state: import
|
state: import
|
||||||
target: /tmp/dump.sql.bz2
|
target: /tmp/dump.sql.bz2
|
||||||
force: yes
|
force: true
|
||||||
|
|
||||||
- name: Dump multiple databases
|
- name: Dump multiple databases
|
||||||
community.mysql.mysql_db:
|
community.mysql.mysql_db:
|
||||||
|
@ -284,7 +287,7 @@ EXAMPLES = r'''
|
||||||
|
|
||||||
- name: Try to create database as root/nopassword first. If not allowed, pass the credentials
|
- name: Try to create database as root/nopassword first. If not allowed, pass the credentials
|
||||||
community.mysql.mysql_db:
|
community.mysql.mysql_db:
|
||||||
check_implicit_admin: yes
|
check_implicit_admin: true
|
||||||
login_user: bob
|
login_user: bob
|
||||||
login_password: 123456
|
login_password: 123456
|
||||||
name: bobdata
|
name: bobdata
|
||||||
|
@ -442,7 +445,7 @@ def db_import(module, host, user, password, db_name, target, all_databases, port
|
||||||
cmd.append("--defaults-extra-file=%s" % shlex_quote(config_file))
|
cmd.append("--defaults-extra-file=%s" % shlex_quote(config_file))
|
||||||
|
|
||||||
if check_implicit_admin:
|
if check_implicit_admin:
|
||||||
cmd += " --user=root --password=''"
|
cmd.append("--user=root --password=''")
|
||||||
else:
|
else:
|
||||||
if user:
|
if user:
|
||||||
cmd.append("--user=%s" % shlex_quote(user))
|
cmd.append("--user=%s" % shlex_quote(user))
|
||||||
|
|
|
@ -42,7 +42,7 @@ options:
|
||||||
description:
|
description:
|
||||||
- Includes names of empty databases to returned dictionary.
|
- Includes names of empty databases to returned dictionary.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
|
|
||||||
notes:
|
notes:
|
||||||
- Calculating the size of a database might be slow, depending on the number and size of tables in it.
|
- Calculating the size of a database might be slow, depending on the number and size of tables in it.
|
||||||
|
@ -58,6 +58,7 @@ seealso:
|
||||||
author:
|
author:
|
||||||
- Andrew Klychkov (@Andersson007)
|
- Andrew Klychkov (@Andersson007)
|
||||||
- Sebastian Gumprich (@rndmh3ro)
|
- Sebastian Gumprich (@rndmh3ro)
|
||||||
|
- Laurent Indermühle (@laurent-indermuehle)
|
||||||
|
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- community.mysql.mysql
|
- community.mysql.mysql
|
||||||
|
@ -76,9 +77,12 @@ EXAMPLES = r'''
|
||||||
# Display all info from databases group except settings:
|
# Display all info from databases group except settings:
|
||||||
# ansible databases -m mysql_info -a 'filter=!settings'
|
# ansible databases -m mysql_info -a 'filter=!settings'
|
||||||
|
|
||||||
|
# If you encounter the "Please explicitly state intended protocol" error,
|
||||||
|
# use the login_unix_socket argument
|
||||||
- name: Collect all possible information using passwordless root access
|
- name: Collect all possible information using passwordless root access
|
||||||
community.mysql.mysql_info:
|
community.mysql.mysql_info:
|
||||||
login_user: root
|
login_user: root
|
||||||
|
login_unix_socket: /run/mysqld/mysqld.sock
|
||||||
|
|
||||||
- name: Get MySQL version with non-default credentials
|
- name: Get MySQL version with non-default credentials
|
||||||
community.mysql.mysql_info:
|
community.mysql.mysql_info:
|
||||||
|
@ -93,14 +97,14 @@ EXAMPLES = r'''
|
||||||
filter: "!settings,!users"
|
filter: "!settings,!users"
|
||||||
|
|
||||||
- name: Collect info about databases and version using ~/.my.cnf as a credential file
|
- name: Collect info about databases and version using ~/.my.cnf as a credential file
|
||||||
become: yes
|
become: true
|
||||||
community.mysql.mysql_info:
|
community.mysql.mysql_info:
|
||||||
filter:
|
filter:
|
||||||
- databases
|
- databases
|
||||||
- version
|
- version
|
||||||
|
|
||||||
- name: Collect info about databases and version using ~alice/.my.cnf as a credential file
|
- name: Collect info about databases and version using ~alice/.my.cnf as a credential file
|
||||||
become: yes
|
become: true
|
||||||
community.mysql.mysql_info:
|
community.mysql.mysql_info:
|
||||||
config_file: /home/alice/.my.cnf
|
config_file: /home/alice/.my.cnf
|
||||||
filter:
|
filter:
|
||||||
|
@ -108,13 +112,13 @@ EXAMPLES = r'''
|
||||||
- version
|
- version
|
||||||
|
|
||||||
- name: Collect info about databases including empty and excluding their sizes
|
- name: Collect info about databases including empty and excluding their sizes
|
||||||
become: yes
|
become: true
|
||||||
community.mysql.mysql_info:
|
community.mysql.mysql_info:
|
||||||
config_file: /home/alice/.my.cnf
|
config_file: /home/alice/.my.cnf
|
||||||
filter:
|
filter:
|
||||||
- databases
|
- databases
|
||||||
exclude_fields: db_size
|
exclude_fields: db_size
|
||||||
return_empty_dbs: yes
|
return_empty_dbs: true
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
|
@ -203,6 +207,21 @@ slave_hosts:
|
||||||
type: dict
|
type: dict
|
||||||
sample:
|
sample:
|
||||||
- { "2": { "Host": "", "Master_id": 1, "Port": 3306 } }
|
- { "2": { "Host": "", "Master_id": 1, "Port": 3306 } }
|
||||||
|
connector_name:
|
||||||
|
description: Name of the python connector used by the module. When the connector is not identified, returns C(Unknown).
|
||||||
|
returned: always
|
||||||
|
type: str
|
||||||
|
sample:
|
||||||
|
- "pymysql"
|
||||||
|
- "MySQLdb"
|
||||||
|
version_added: '1.5.0'
|
||||||
|
connector_version:
|
||||||
|
description: Version of the python connector used by the module. When the connector is not identified, returns C(Unknown).
|
||||||
|
returned: always
|
||||||
|
type: str
|
||||||
|
sample:
|
||||||
|
- "1.0.2"
|
||||||
|
version_added: '1.5.0'
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
@ -213,6 +232,8 @@ from ansible_collections.community.mysql.plugins.module_utils.mysql import (
|
||||||
mysql_common_argument_spec,
|
mysql_common_argument_spec,
|
||||||
mysql_driver,
|
mysql_driver,
|
||||||
mysql_driver_fail_msg,
|
mysql_driver_fail_msg,
|
||||||
|
get_connector_name,
|
||||||
|
get_connector_version,
|
||||||
)
|
)
|
||||||
from ansible.module_utils.six import iteritems
|
from ansible.module_utils.six import iteritems
|
||||||
from ansible.module_utils._text import to_native
|
from ansible.module_utils._text import to_native
|
||||||
|
@ -474,6 +495,9 @@ class MySQL_Info(object):
|
||||||
self.info['databases'][db['name']] = {}
|
self.info['databases'][db['name']] = {}
|
||||||
|
|
||||||
if not exclude_fields or 'db_size' not in exclude_fields:
|
if not exclude_fields or 'db_size' not in exclude_fields:
|
||||||
|
if db['size'] is None:
|
||||||
|
db['size'] = 0
|
||||||
|
|
||||||
self.info['databases'][db['name']]['size'] = int(db['size'])
|
self.info['databases'][db['name']]['size'] = int(db['size'])
|
||||||
|
|
||||||
# If empty dbs are not needed in the returned dict, exit from the method
|
# If empty dbs are not needed in the returned dict, exit from the method
|
||||||
|
@ -552,21 +576,29 @@ def main():
|
||||||
if mysql_driver is None:
|
if mysql_driver is None:
|
||||||
module.fail_json(msg=mysql_driver_fail_msg)
|
module.fail_json(msg=mysql_driver_fail_msg)
|
||||||
|
|
||||||
|
connector_name = get_connector_name(mysql_driver)
|
||||||
|
connector_version = get_connector_version(mysql_driver)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cursor, db_conn = mysql_connect(module, login_user, login_password,
|
cursor, db_conn = mysql_connect(module, login_user, login_password,
|
||||||
config_file, ssl_cert, ssl_key, ssl_ca, db,
|
config_file, ssl_cert, ssl_key, ssl_ca, db,
|
||||||
check_hostname=check_hostname,
|
check_hostname=check_hostname,
|
||||||
connect_timeout=connect_timeout, cursor_class='DictCursor')
|
connect_timeout=connect_timeout, cursor_class='DictCursor')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
module.fail_json(msg="unable to connect to database, check login_user and login_password are correct or %s has the credentials. "
|
msg = ('unable to connect to database using %s %s, check login_user '
|
||||||
"Exception message: %s" % (config_file, to_native(e)))
|
'and login_password are correct or %s has the credentials. '
|
||||||
|
'Exception message: %s' % (connector_name, connector_version, config_file, to_native(e)))
|
||||||
|
module.fail_json(msg)
|
||||||
|
|
||||||
###############################
|
###############################
|
||||||
# Create object and do main job
|
# Create object and do main job
|
||||||
|
|
||||||
mysql = MySQL_Info(module, cursor)
|
mysql = MySQL_Info(module, cursor)
|
||||||
|
|
||||||
module.exit_json(changed=False, **mysql.get_info(filter_, exclude_fields, return_empty_dbs))
|
module.exit_json(changed=False,
|
||||||
|
connector_name=connector_name,
|
||||||
|
connector_version=connector_version,
|
||||||
|
**mysql.get_info(filter_, exclude_fields, return_empty_dbs))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -22,8 +22,15 @@ options:
|
||||||
description:
|
description:
|
||||||
- SQL query to run. Multiple queries can be passed using YAML list syntax.
|
- SQL query to run. Multiple queries can be passed using YAML list syntax.
|
||||||
- Must be a string or YAML list containing strings.
|
- Must be a string or YAML list containing strings.
|
||||||
|
- If you use I(named_args) or I(positional_args) any C(%) will be interpreted
|
||||||
|
as a formatting character. All literal C(%) characters in the query should be
|
||||||
|
escaped as C(%%).
|
||||||
|
- Note that if you use the C(IF EXISTS/IF NOT EXISTS) clauses in your query
|
||||||
|
and C(mysqlclient) connector, the module will report that
|
||||||
|
the state has been changed even if it has not. If it is important in your
|
||||||
|
workflow, use the C(PyMySQL) connector instead.
|
||||||
type: raw
|
type: raw
|
||||||
required: yes
|
required: true
|
||||||
positional_args:
|
positional_args:
|
||||||
description:
|
description:
|
||||||
- List of values to be passed as positional arguments to the query.
|
- List of values to be passed as positional arguments to the query.
|
||||||
|
@ -42,7 +49,7 @@ options:
|
||||||
description:
|
description:
|
||||||
- Where passed queries run in a single transaction (C(yes)) or commit them one-by-one (C(no)).
|
- Where passed queries run in a single transaction (C(yes)) or commit them one-by-one (C(no)).
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
seealso:
|
seealso:
|
||||||
- module: community.mysql.mysql_db
|
- module: community.mysql.mysql_db
|
||||||
author:
|
author:
|
||||||
|
@ -53,10 +60,13 @@ extends_documentation_fragment:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
|
# If you encounter the "Please explicitly state intended protocol" error,
|
||||||
|
# use the login_unix_socket argument
|
||||||
- name: Simple select query to acme db
|
- name: Simple select query to acme db
|
||||||
community.mysql.mysql_query:
|
community.mysql.mysql_query:
|
||||||
login_db: acme
|
login_db: acme
|
||||||
query: SELECT * FROM orders
|
query: SELECT * FROM orders
|
||||||
|
login_unix_socket: /run/mysqld/mysqld.sock
|
||||||
|
|
||||||
- name: Select query to db acme with positional arguments
|
- name: Select query to db acme with positional arguments
|
||||||
community.mysql.mysql_query:
|
community.mysql.mysql_query:
|
||||||
|
@ -80,7 +90,7 @@ EXAMPLES = r'''
|
||||||
query:
|
query:
|
||||||
- INSERT INTO articles (id, story) VALUES (2, 'my_long_story')
|
- INSERT INTO articles (id, story) VALUES (2, 'my_long_story')
|
||||||
- INSERT INTO prices (id, price) VALUES (123, '100.00')
|
- INSERT INTO prices (id, price) VALUES (123, '100.00')
|
||||||
single_transaction: yes
|
single_transaction: true
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
|
@ -103,6 +113,8 @@ rowcount:
|
||||||
sample: [5, 1]
|
sample: [5, 1]
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
import warnings
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible_collections.community.mysql.plugins.module_utils.mysql import (
|
from ansible_collections.community.mysql.plugins.module_utils.mysql import (
|
||||||
mysql_connect,
|
mysql_connect,
|
||||||
|
@ -112,7 +124,7 @@ from ansible_collections.community.mysql.plugins.module_utils.mysql import (
|
||||||
)
|
)
|
||||||
from ansible.module_utils._text import to_native
|
from ansible.module_utils._text import to_native
|
||||||
|
|
||||||
DML_QUERY_KEYWORDS = ('INSERT', 'UPDATE', 'DELETE')
|
DML_QUERY_KEYWORDS = ('INSERT', 'UPDATE', 'DELETE', 'REPLACE')
|
||||||
# TRUNCATE is not DDL query but it also returns 0 rows affected:
|
# TRUNCATE is not DDL query but it also returns 0 rows affected:
|
||||||
DDL_QUERY_KEYWORDS = ('CREATE', 'DROP', 'ALTER', 'RENAME', 'TRUNCATE')
|
DDL_QUERY_KEYWORDS = ('CREATE', 'DROP', 'ALTER', 'RENAME', 'TRUNCATE')
|
||||||
|
|
||||||
|
@ -196,9 +208,22 @@ def main():
|
||||||
executed_queries = []
|
executed_queries = []
|
||||||
rowcount = []
|
rowcount = []
|
||||||
|
|
||||||
|
already_exists = False
|
||||||
for q in query:
|
for q in query:
|
||||||
|
try:
|
||||||
|
with warnings.catch_warnings():
|
||||||
|
warnings.filterwarnings(action='error',
|
||||||
|
message='.*already exists*',
|
||||||
|
category=mysql_driver.Warning)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cursor.execute(q, arguments)
|
cursor.execute(q, arguments)
|
||||||
|
except mysql_driver.Warning:
|
||||||
|
# When something is run with IF NOT EXISTS
|
||||||
|
# and there's "already exists" MySQL warning,
|
||||||
|
# set the flag as True.
|
||||||
|
# PyMySQL throws the warning, mysqlclinet does NOT.
|
||||||
|
already_exists = True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if not autocommit:
|
if not autocommit:
|
||||||
|
@ -208,6 +233,7 @@ def main():
|
||||||
module.fail_json(msg="Cannot execute SQL '%s' args [%s]: %s" % (q, arguments, to_native(e)))
|
module.fail_json(msg="Cannot execute SQL '%s' args [%s]: %s" % (q, arguments, to_native(e)))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if not already_exists:
|
||||||
query_result.append([dict(row) for row in cursor.fetchall()])
|
query_result.append([dict(row) for row in cursor.fetchall()])
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -224,8 +250,12 @@ def main():
|
||||||
|
|
||||||
for keyword in DDL_QUERY_KEYWORDS:
|
for keyword in DDL_QUERY_KEYWORDS:
|
||||||
if keyword in q:
|
if keyword in q:
|
||||||
|
if already_exists:
|
||||||
|
# Indicates the entity already exists
|
||||||
|
changed = False
|
||||||
|
already_exists = False # Reset flag
|
||||||
|
else:
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
executed_queries.append(cursor._last_executed)
|
executed_queries.append(cursor._last_executed)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
|
|
@ -167,7 +167,7 @@ options:
|
||||||
description:
|
description:
|
||||||
- Fails on error when calling mysql.
|
- Fails on error when calling mysql.
|
||||||
type: bool
|
type: bool
|
||||||
default: False
|
default: false
|
||||||
version_added: '0.1.0'
|
version_added: '0.1.0'
|
||||||
|
|
||||||
notes:
|
notes:
|
||||||
|
@ -191,9 +191,12 @@ seealso:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
|
# If you encounter the "Please explicitly state intended protocol" error,
|
||||||
|
# use the login_unix_socket argument
|
||||||
- name: Stop mysql replica thread
|
- name: Stop mysql replica thread
|
||||||
community.mysql.mysql_replication:
|
community.mysql.mysql_replication:
|
||||||
mode: stopreplica
|
mode: stopreplica
|
||||||
|
login_unix_socket: /run/mysqld/mysqld.sock
|
||||||
|
|
||||||
- name: Get master binlog file name and binlog position
|
- name: Get master binlog file name and binlog position
|
||||||
community.mysql.mysql_replication:
|
community.mysql.mysql_replication:
|
||||||
|
@ -243,12 +246,12 @@ EXAMPLES = r'''
|
||||||
community.mysql.mysql_replication:
|
community.mysql.mysql_replication:
|
||||||
mode: startreplica
|
mode: startreplica
|
||||||
connection_name: master-1
|
connection_name: master-1
|
||||||
fail_on_error: yes
|
fail_on_error: true
|
||||||
|
|
||||||
- name: Change master and fail on error (like when replica thread is running)
|
- name: Change master and fail on error (like when replica thread is running)
|
||||||
community.mysql.mysql_replication:
|
community.mysql.mysql_replication:
|
||||||
mode: changemaster
|
mode: changemaster
|
||||||
fail_on_error: yes
|
fail_on_error: true
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -272,7 +275,6 @@ from ansible_collections.community.mysql.plugins.module_utils.mysql import (
|
||||||
mysql_common_argument_spec,
|
mysql_common_argument_spec,
|
||||||
)
|
)
|
||||||
from ansible.module_utils._text import to_native
|
from ansible.module_utils._text import to_native
|
||||||
from distutils.version import LooseVersion
|
|
||||||
|
|
||||||
executed_queries = []
|
executed_queries = []
|
||||||
|
|
||||||
|
|
|
@ -22,13 +22,14 @@ options:
|
||||||
required: true
|
required: true
|
||||||
password:
|
password:
|
||||||
description:
|
description:
|
||||||
- Set the user's password.
|
- Set the user's password. Only for C(mysql_native_password) authentication.
|
||||||
|
For other authentication plugins see the combination of I(plugin), I(plugin_hash_string), I(plugin_auth_string).
|
||||||
type: str
|
type: str
|
||||||
encrypted:
|
encrypted:
|
||||||
description:
|
description:
|
||||||
- Indicate that the 'password' field is a `mysql_native_password` hash.
|
- Indicate that the 'password' field is a `mysql_native_password` hash.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
host:
|
host:
|
||||||
description:
|
description:
|
||||||
- The 'host' part of the MySQL username.
|
- The 'host' part of the MySQL username.
|
||||||
|
@ -40,12 +41,12 @@ options:
|
||||||
to all hostnames for a given user.
|
to all hostnames for a given user.
|
||||||
- This option cannot be used when creating users.
|
- This option cannot be used when creating users.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
priv:
|
priv:
|
||||||
description:
|
description:
|
||||||
- "MySQL privileges string in the format: C(db.table:priv1,priv2)."
|
- "MySQL privileges string in the format: C(db.table:priv1,priv2)."
|
||||||
- "Multiple privileges can be specified by separating each one using
|
- "Multiple privileges can be specified by separating each one using
|
||||||
a forward slash: C(db.table:priv/db.table:priv)."
|
a forward slash: C(db.table1:priv/db.table2:priv)."
|
||||||
- The format is based on MySQL C(GRANT) statement.
|
- The format is based on MySQL C(GRANT) statement.
|
||||||
- Database and table names can be quoted, MySQL-style.
|
- Database and table names can be quoted, MySQL-style.
|
||||||
- If column privileges are used, the C(priv1,priv2) part must be
|
- If column privileges are used, the C(priv1,priv2) part must be
|
||||||
|
@ -53,13 +54,19 @@ options:
|
||||||
the module will always report changes. It includes grouping columns
|
the module will always report changes. It includes grouping columns
|
||||||
by permission (C(SELECT(col1,col2)) instead of C(SELECT(col1),SELECT(col2))).
|
by permission (C(SELECT(col1,col2)) instead of C(SELECT(col1),SELECT(col2))).
|
||||||
- Can be passed as a dictionary (see the examples).
|
- Can be passed as a dictionary (see the examples).
|
||||||
|
- Supports GRANTs for procedures and functions (see the examples).
|
||||||
|
- "Note: If you pass the same C(db.table) combination to this parameter
|
||||||
|
two or more times with different privileges,
|
||||||
|
for example, C('*.*:SELECT/*.*:SHOW VIEW'), only the last one will be applied,
|
||||||
|
in this example, it will be C(SHOW VIEW) respectively.
|
||||||
|
Use C('*.*:SELECT,SHOW VIEW') instead to apply both."
|
||||||
type: raw
|
type: raw
|
||||||
append_privs:
|
append_privs:
|
||||||
description:
|
description:
|
||||||
- Append the privileges defined by priv to the existing ones for this
|
- Append the privileges defined by priv to the existing ones for this
|
||||||
user instead of overwriting existing ones.
|
user instead of overwriting existing ones.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
tls_requires:
|
tls_requires:
|
||||||
description:
|
description:
|
||||||
- Set requirement for secure transport as a dictionary of requirements (see the examples).
|
- Set requirement for secure transport as a dictionary of requirements (see the examples).
|
||||||
|
@ -72,7 +79,7 @@ options:
|
||||||
description:
|
description:
|
||||||
- Whether binary logging should be enabled or disabled for the connection.
|
- Whether binary logging should be enabled or disabled for the connection.
|
||||||
type: bool
|
type: bool
|
||||||
default: yes
|
default: true
|
||||||
state:
|
state:
|
||||||
description:
|
description:
|
||||||
- Whether the user should exist.
|
- Whether the user should exist.
|
||||||
|
@ -85,11 +92,11 @@ options:
|
||||||
- Check if mysql allows login as root/nopassword before trying supplied credentials.
|
- Check if mysql allows login as root/nopassword before trying supplied credentials.
|
||||||
- If success, passed I(login_user)/I(login_password) will be ignored.
|
- If success, passed I(login_user)/I(login_password) will be ignored.
|
||||||
type: bool
|
type: bool
|
||||||
default: no
|
default: false
|
||||||
update_password:
|
update_password:
|
||||||
description:
|
description:
|
||||||
- C(always) will update passwords if they differ.
|
- C(always) will update passwords if they differ. This affects I(password) and the combination of I(plugin), I(plugin_hash_string), I(plugin_auth_string).
|
||||||
- C(on_create) will only set the password for newly created users.
|
- C(on_create) will only set the password or the combination of plugin, plugin_hash_string, plugin_auth_string for newly created users.
|
||||||
type: str
|
type: str
|
||||||
choices: [ always, on_create ]
|
choices: [ always, on_create ]
|
||||||
default: always
|
default: always
|
||||||
|
@ -145,16 +152,19 @@ extends_documentation_fragment:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
|
# If you encounter the "Please explicitly state intended protocol" error,
|
||||||
|
# use the login_unix_socket argument
|
||||||
- name: Removes anonymous user account for localhost
|
- name: Removes anonymous user account for localhost
|
||||||
community.mysql.mysql_user:
|
community.mysql.mysql_user:
|
||||||
name: ''
|
name: ''
|
||||||
host: localhost
|
host: localhost
|
||||||
state: absent
|
state: absent
|
||||||
|
login_unix_socket: /run/mysqld/mysqld.sock
|
||||||
|
|
||||||
- name: Removes all anonymous user accounts
|
- name: Removes all anonymous user accounts
|
||||||
community.mysql.mysql_user:
|
community.mysql.mysql_user:
|
||||||
name: ''
|
name: ''
|
||||||
host_all: yes
|
host_all: true
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Create database user with name 'bob' and password '12345' with all database privileges
|
- name: Create database user with name 'bob' and password '12345' with all database privileges
|
||||||
|
@ -168,7 +178,7 @@ EXAMPLES = r'''
|
||||||
community.mysql.mysql_user:
|
community.mysql.mysql_user:
|
||||||
name: bob
|
name: bob
|
||||||
password: '*EE0D72C1085C46C5278932678FBE2C6A782821B4'
|
password: '*EE0D72C1085C46C5278932678FBE2C6A782821B4'
|
||||||
encrypted: yes
|
encrypted: true
|
||||||
priv: '*.*:ALL'
|
priv: '*.*:ALL'
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
@ -188,6 +198,15 @@ EXAMPLES = r'''
|
||||||
'db1.*': 'ALL,GRANT'
|
'db1.*': 'ALL,GRANT'
|
||||||
'db2.*': 'ALL,GRANT'
|
'db2.*': 'ALL,GRANT'
|
||||||
|
|
||||||
|
# Use 'PROCEDURE' instead of 'FUNCTION' to apply GRANTs for a MySQL procedure instead.
|
||||||
|
- name: Grant a user the right to execute a function
|
||||||
|
community.mysql.mysql_user:
|
||||||
|
name: readonly
|
||||||
|
password: 12345
|
||||||
|
priv:
|
||||||
|
FUNCTION my_db.my_function: EXECUTE
|
||||||
|
state: present
|
||||||
|
|
||||||
# Note that REQUIRESSL is a special privilege that should only apply to *.* by itself.
|
# Note that REQUIRESSL is a special privilege that should only apply to *.* by itself.
|
||||||
# Setting this privilege in this manner is deprecated.
|
# Setting this privilege in this manner is deprecated.
|
||||||
# Use 'tls_requires' instead.
|
# Use 'tls_requires' instead.
|
||||||
|
@ -230,7 +249,7 @@ EXAMPLES = r'''
|
||||||
If mysql allows root/nopassword login, try it without the credentials first.
|
If mysql allows root/nopassword login, try it without the credentials first.
|
||||||
If it's not allowed, pass the credentials
|
If it's not allowed, pass the credentials
|
||||||
community.mysql.mysql_user:
|
community.mysql.mysql_user:
|
||||||
check_implicit_admin: yes
|
check_implicit_admin: true
|
||||||
login_user: root
|
login_user: root
|
||||||
login_password: 123456
|
login_password: 123456
|
||||||
name: sally
|
name: sally
|
||||||
|
@ -239,7 +258,7 @@ EXAMPLES = r'''
|
||||||
- name: Ensure no user named 'sally' exists at all
|
- name: Ensure no user named 'sally' exists at all
|
||||||
community.mysql.mysql_user:
|
community.mysql.mysql_user:
|
||||||
name: sally
|
name: sally
|
||||||
host_all: yes
|
host_all: true
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Specify grants composed of more than one word
|
- name: Specify grants composed of more than one word
|
||||||
|
@ -271,7 +290,7 @@ EXAMPLES = r'''
|
||||||
password: 12345
|
password: 12345
|
||||||
priv: "*.*:USAGE"
|
priv: "*.*:USAGE"
|
||||||
state: present
|
state: present
|
||||||
sql_log_bin: no
|
sql_log_bin: false
|
||||||
|
|
||||||
- name: Create user 'bob' authenticated with plugin 'AWSAuthenticationPlugin'
|
- name: Create user 'bob' authenticated with plugin 'AWSAuthenticationPlugin'
|
||||||
community.mysql.mysql_user:
|
community.mysql.mysql_user:
|
||||||
|
@ -379,7 +398,7 @@ def sanitize_requires(tls_requires):
|
||||||
if tls_requires:
|
if tls_requires:
|
||||||
for key in tls_requires.keys():
|
for key in tls_requires.keys():
|
||||||
sanitized_requires[key.upper()] = tls_requires[key]
|
sanitized_requires[key.upper()] = tls_requires[key]
|
||||||
if any([key in ["CIPHER", "ISSUER", "SUBJECT"] for key in sanitized_requires.keys()]):
|
if any(key in ["CIPHER", "ISSUER", "SUBJECT"] for key in sanitized_requires.keys()):
|
||||||
sanitized_requires.pop("SSL", None)
|
sanitized_requires.pop("SSL", None)
|
||||||
sanitized_requires.pop("X509", None)
|
sanitized_requires.pop("X509", None)
|
||||||
return sanitized_requires
|
return sanitized_requires
|
||||||
|
@ -694,6 +713,9 @@ def user_delete(cursor, user, host, host_all, check_mode):
|
||||||
hostnames = [host]
|
hostnames = [host]
|
||||||
|
|
||||||
for hostname in hostnames:
|
for hostname in hostnames:
|
||||||
|
try:
|
||||||
|
cursor.execute("DROP USER IF EXISTS %s@%s", (user, hostname))
|
||||||
|
except Exception:
|
||||||
cursor.execute("DROP USER %s@%s", (user, hostname))
|
cursor.execute("DROP USER %s@%s", (user, hostname))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -732,8 +754,19 @@ def privileges_get(cursor, user, host):
|
||||||
|
|
||||||
for grant in grants:
|
for grant in grants:
|
||||||
res = re.match("""GRANT (.+) ON (.+) TO (['`"]).*\\3@(['`"]).*\\4( IDENTIFIED BY PASSWORD (['`"]).+\\6)? ?(.*)""", grant[0])
|
res = re.match("""GRANT (.+) ON (.+) TO (['`"]).*\\3@(['`"]).*\\4( IDENTIFIED BY PASSWORD (['`"]).+\\6)? ?(.*)""", grant[0])
|
||||||
|
|
||||||
if res is None:
|
if res is None:
|
||||||
|
# If a user has roles assigned, we'll have one of priv tuples looking like
|
||||||
|
# GRANT `admin`@`%` TO `user1`@`localhost`
|
||||||
|
# which will result None as res value.
|
||||||
|
# As we use the mysql_role module (community.mysql 2.0.0+) to manipulate roles
|
||||||
|
# we just ignore such privs below:
|
||||||
|
res = re.match("""GRANT (.+) TO (['`"]).*""", grant[0])
|
||||||
|
if res:
|
||||||
|
continue
|
||||||
|
|
||||||
raise InvalidPrivsError('unable to parse the MySQL grant string: %s' % grant[0])
|
raise InvalidPrivsError('unable to parse the MySQL grant string: %s' % grant[0])
|
||||||
|
|
||||||
privileges = res.group(1).split(",")
|
privileges = res.group(1).split(",")
|
||||||
privileges = [pick(x.strip()) for x in privileges]
|
privileges = [pick(x.strip()) for x in privileges]
|
||||||
|
|
||||||
|
@ -934,6 +967,7 @@ def privileges_revoke(cursor, user, host, db_table, priv, grant_option):
|
||||||
query.append("FROM %s@%s")
|
query.append("FROM %s@%s")
|
||||||
query = ' '.join(query)
|
query = ' '.join(query)
|
||||||
cursor.execute(query, (user, host))
|
cursor.execute(query, (user, host))
|
||||||
|
cursor.execute("FLUSH PRIVILEGES")
|
||||||
|
|
||||||
|
|
||||||
def privileges_grant(cursor, user, host, db_table, priv, tls_requires):
|
def privileges_grant(cursor, user, host, db_table, priv, tls_requires):
|
||||||
|
@ -1233,7 +1267,7 @@ def main():
|
||||||
priv, append_privs, tls_requires, module)
|
priv, append_privs, tls_requires, module)
|
||||||
else:
|
else:
|
||||||
changed, msg = user_mod(cursor, user, host, host_all, None, encrypted,
|
changed, msg = user_mod(cursor, user, host, host_all, None, encrypted,
|
||||||
plugin, plugin_hash_string, plugin_auth_string,
|
None, None, None,
|
||||||
priv, append_privs, tls_requires, module)
|
priv, append_privs, tls_requires, module)
|
||||||
|
|
||||||
except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
|
except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
|
||||||
|
|
|
@ -22,7 +22,7 @@ options:
|
||||||
description:
|
description:
|
||||||
- Variable name to operate.
|
- Variable name to operate.
|
||||||
type: str
|
type: str
|
||||||
required: yes
|
required: true
|
||||||
value:
|
value:
|
||||||
description:
|
description:
|
||||||
- If set, then sets variable value to this.
|
- If set, then sets variable value to this.
|
||||||
|
@ -58,9 +58,12 @@ extends_documentation_fragment:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
|
# If you encounter the "Please explicitly state intended protocol" error,
|
||||||
|
# use the login_unix_socket argument
|
||||||
- name: Check for sync_binlog setting
|
- name: Check for sync_binlog setting
|
||||||
community.mysql.mysql_variables:
|
community.mysql.mysql_variables:
|
||||||
variable: sync_binlog
|
variable: sync_binlog
|
||||||
|
login_unix_socket: /run/mysqld/mysqld.sock
|
||||||
|
|
||||||
- name: Set read_only variable to 1 persistently
|
- name: Set read_only variable to 1 persistently
|
||||||
community.mysql.mysql_variables:
|
community.mysql.mysql_variables:
|
||||||
|
|
115
run_all_tests.py
Executable file
115
run_all_tests.py
Executable file
|
@ -0,0 +1,115 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
import os
|
||||||
|
|
||||||
|
github_workflow_file = '.github/workflows/ansible-test-plugins.yml'
|
||||||
|
|
||||||
|
|
||||||
|
def read_github_workflow_file():
|
||||||
|
with open(github_workflow_file, 'r') as gh_file:
|
||||||
|
try:
|
||||||
|
return yaml.safe_load(gh_file)
|
||||||
|
except yaml.YAMLError as exc:
|
||||||
|
print(exc)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_value(target, dict_yaml):
|
||||||
|
for key, value in dict_yaml.items():
|
||||||
|
if key == target:
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def extract_matrix(workflow_yaml):
|
||||||
|
jobs = extract_value('jobs', workflow_yaml)
|
||||||
|
integration = extract_value('integration', jobs)
|
||||||
|
strategy = extract_value('strategy', integration)
|
||||||
|
matrix = extract_value('matrix', strategy)
|
||||||
|
return matrix
|
||||||
|
|
||||||
|
|
||||||
|
def is_exclude(exclude_list, test_suite):
|
||||||
|
test_is_excluded = False
|
||||||
|
for excl in exclude_list:
|
||||||
|
match = 0
|
||||||
|
|
||||||
|
if 'ansible' in excl:
|
||||||
|
if excl.get('ansible') == test_suite.get('ansible'):
|
||||||
|
match += 1
|
||||||
|
|
||||||
|
if 'db_engine_name' in excl:
|
||||||
|
if excl.get('db_engine_name') == test_suite.get('db_engine_name'):
|
||||||
|
match += 1
|
||||||
|
|
||||||
|
if 'db_engine_version' in excl:
|
||||||
|
if excl.get('db_engine_version') == test_suite.get('db_engine_version'):
|
||||||
|
match += 1
|
||||||
|
|
||||||
|
if 'python' in excl:
|
||||||
|
if excl.get('python') == test_suite.get('python'):
|
||||||
|
match += 1
|
||||||
|
|
||||||
|
if 'connector_name' in excl:
|
||||||
|
if excl.get('connector_name') == test_suite.get('connector_name'):
|
||||||
|
match += 1
|
||||||
|
|
||||||
|
if 'connector_version' in excl:
|
||||||
|
if excl.get('connector_version') == test_suite.get('connector_version'):
|
||||||
|
match += 1
|
||||||
|
|
||||||
|
if match > 1:
|
||||||
|
test_is_excluded = True
|
||||||
|
return test_is_excluded
|
||||||
|
|
||||||
|
return test_is_excluded
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
workflow_yaml = read_github_workflow_file()
|
||||||
|
tests_matrix_yaml = extract_matrix(workflow_yaml)
|
||||||
|
|
||||||
|
matrix = []
|
||||||
|
exclude_list = tests_matrix_yaml.get('exclude')
|
||||||
|
for ansible in tests_matrix_yaml.get('ansible'):
|
||||||
|
for db_engine_name in tests_matrix_yaml.get('db_engine_name'):
|
||||||
|
for db_engine_version in tests_matrix_yaml.get('db_engine_version'):
|
||||||
|
for python in tests_matrix_yaml.get('python'):
|
||||||
|
for connector_name in tests_matrix_yaml.get('connector_name'):
|
||||||
|
for connector_version in tests_matrix_yaml.get('connector_version'):
|
||||||
|
test_suite = {
|
||||||
|
'ansible': ansible,
|
||||||
|
'db_engine_name': db_engine_name,
|
||||||
|
'db_engine_version': db_engine_version,
|
||||||
|
'python': python,
|
||||||
|
'connector_name': connector_name,
|
||||||
|
'connector_version': connector_version
|
||||||
|
}
|
||||||
|
if not is_exclude(exclude_list, test_suite):
|
||||||
|
matrix.append(test_suite)
|
||||||
|
|
||||||
|
for tests in matrix:
|
||||||
|
a = tests.get('ansible')
|
||||||
|
dn = tests.get('db_engine_name')
|
||||||
|
dv = tests.get('db_engine_version')
|
||||||
|
p = tests.get('python')
|
||||||
|
cn = tests.get('connector_name')
|
||||||
|
cv = tests.get('connector_version')
|
||||||
|
make_cmd = (
|
||||||
|
f'make '
|
||||||
|
f'ansible="{a}" '
|
||||||
|
f'db_engine_name="{dn}" '
|
||||||
|
f'db_engine_version="{dv}" '
|
||||||
|
f'python="{p}" '
|
||||||
|
f'connector_name="{cn}" '
|
||||||
|
f'connector_version="{cv}" '
|
||||||
|
f'test-integration'
|
||||||
|
)
|
||||||
|
print(f'Run tests for: Ansible: {a}, DB: {dn} {dv}, Python: {p}, Connector: {cn} {cv}')
|
||||||
|
os.system(make_cmd)
|
||||||
|
# TODO, allow for CTRL+C to break the loop more easily
|
||||||
|
# TODO, store the failures from this iteration
|
||||||
|
# TODO, display a summary of failures from every iterations
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
8
simplified_bsd.txt
Normal file
8
simplified_bsd.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
21
test-containers/mariadb-py310-mysqlclient211/Dockerfile
Normal file
21
test-containers/mariadb-py310-mysqlclient211/Dockerfile
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2204-test-container:main
|
||||||
|
# ubuntu2204 comes with mariadb-client-10.6
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
# python3.10-dev # Reqs for mysqlclient
|
||||||
|
# default-libmysqlclient-dev # Reqs for mysqlclient
|
||||||
|
# build-essential # Reqs for mysqlclient
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.10 \
|
||||||
|
python3.10-dev \
|
||||||
|
mariadb-client \
|
||||||
|
iproute2 \
|
||||||
|
default-libmysqlclient-dev \
|
||||||
|
build-essential
|
||||||
|
|
||||||
|
RUN python3.10 -m pip install --disable-pip-version-check --no-cache-dir mysqlclient==2.1.1
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
15
test-containers/mariadb-py310-pymysql102/Dockerfile
Normal file
15
test-containers/mariadb-py310-pymysql102/Dockerfile
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2204-test-container:main
|
||||||
|
# ubuntu2204 comes with mariadb-client-10.6
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.10 \
|
||||||
|
mariadb-client \
|
||||||
|
iproute2
|
||||||
|
|
||||||
|
RUN python3.10 -m pip install --disable-pip-version-check --no-cache-dir pymysql==1.0.2
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
21
test-containers/mariadb-py38-mysqlclient201/Dockerfile
Normal file
21
test-containers/mariadb-py38-mysqlclient201/Dockerfile
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2004-test-container:main
|
||||||
|
# ubuntu2004 comes with mariadb-client-10.3
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
# python3.8-dev # Reqs for mysqlclient
|
||||||
|
# default-libmysqlclient-dev # Reqs for mysqlclient
|
||||||
|
# build-essential # Reqs for mysqlclient
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.8 \
|
||||||
|
python3.8-dev \
|
||||||
|
mariadb-client \
|
||||||
|
iproute2 \
|
||||||
|
default-libmysqlclient-dev \
|
||||||
|
build-essential
|
||||||
|
|
||||||
|
RUN python3.8 -m pip install --disable-pip-version-check --no-cache-dir mysqlclient==2.0.1
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
15
test-containers/mariadb-py38-pymysql093/Dockerfile
Normal file
15
test-containers/mariadb-py38-pymysql093/Dockerfile
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2004-test-container:main
|
||||||
|
# ubuntu2004 comes with mariadb-client-10.3
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.8 \
|
||||||
|
mariadb-client \
|
||||||
|
iproute2
|
||||||
|
|
||||||
|
RUN python3.8 -m pip install --disable-pip-version-check --no-cache-dir pymysql==0.9.3
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
21
test-containers/mariadb-py39-mysqlclient203/Dockerfile
Normal file
21
test-containers/mariadb-py39-mysqlclient203/Dockerfile
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2004-test-container:main
|
||||||
|
# ubuntu2004 comes with mariadb-client-10.3
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
# python3.9-dev # Reqs for mysqlclient
|
||||||
|
# default-libmysqlclient-dev # Reqs for mysqlclient
|
||||||
|
# build-essential # Reqs for mysqlclient
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.9 \
|
||||||
|
python3.9-dev \
|
||||||
|
mariadb-client \
|
||||||
|
iproute2 \
|
||||||
|
default-libmysqlclient-dev \
|
||||||
|
build-essential
|
||||||
|
|
||||||
|
RUN python3.9 -m pip install --disable-pip-version-check --no-cache-dir mysqlclient==2.0.3
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
15
test-containers/mariadb-py39-pymysql093/Dockerfile
Normal file
15
test-containers/mariadb-py39-pymysql093/Dockerfile
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2004-test-container:main
|
||||||
|
# ubuntu2004 comes with mariadb-client-10.3
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.9 \
|
||||||
|
mariadb-client \
|
||||||
|
iproute2
|
||||||
|
|
||||||
|
RUN python3.9 -m pip install --disable-pip-version-check --no-cache-dir pymysql==0.9.3
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
21
test-containers/my57-py38-mysqlclient201/Dockerfile
Normal file
21
test-containers/my57-py38-mysqlclient201/Dockerfile
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FROM quay.io/ansible/ubuntu1804-test-container:main
|
||||||
|
# ubuntu1804 comes with mysql-client-5.7
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
# python3.8-dev # Reqs for mysqlclient
|
||||||
|
# default-libmysqlclient-dev # Reqs for mysqlclient
|
||||||
|
# build-essential # Reqs for mysqlclient
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.8 \
|
||||||
|
python3.8-dev \
|
||||||
|
mysql-client \
|
||||||
|
iproute2 \
|
||||||
|
default-libmysqlclient-dev \
|
||||||
|
build-essential
|
||||||
|
|
||||||
|
RUN python3.8 -m pip install --disable-pip-version-check --no-cache-dir mysqlclient==2.0.1
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
21
test-containers/my57-py38-pymysql0711/Dockerfile
Normal file
21
test-containers/my57-py38-pymysql0711/Dockerfile
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FROM quay.io/ansible/ubuntu1804-test-container:main
|
||||||
|
# ubuntu1804 comes with mysql-client-5.7
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
# python3.8-dev # Reqs for mysqlclient
|
||||||
|
# default-libmysqlclient-dev # Reqs for mysqlclient
|
||||||
|
# build-essential # Reqs for mysqlclient
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.8 \
|
||||||
|
python3.8-dev \
|
||||||
|
mysql-client \
|
||||||
|
iproute2 \
|
||||||
|
default-libmysqlclient-dev \
|
||||||
|
build-essential
|
||||||
|
|
||||||
|
RUN python3.8 -m pip install --disable-pip-version-check --no-cache-dir pymysql==0.7.11
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
15
test-containers/my57-py38-pymysql093/Dockerfile
Normal file
15
test-containers/my57-py38-pymysql093/Dockerfile
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
FROM quay.io/ansible/ubuntu1804-test-container:main
|
||||||
|
# ubuntu1804 comes with mysql-client-5.7
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.8 \
|
||||||
|
mysql-client \
|
||||||
|
iproute2
|
||||||
|
|
||||||
|
RUN python3.8 -m pip install --disable-pip-version-check --no-cache-dir pymysql==0.9.3
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
21
test-containers/mysql-py310-mysqlclient211/Dockerfile
Normal file
21
test-containers/mysql-py310-mysqlclient211/Dockerfile
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2204-test-container:main
|
||||||
|
# ubuntu2204 comes with mysql-client-8
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
# python3.10-dev # Reqs for mysqlclient
|
||||||
|
# default-libmysqlclient-dev # Reqs for mysqlclient
|
||||||
|
# build-essential # Reqs for mysqlclient
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.10 \
|
||||||
|
python3.10-dev \
|
||||||
|
mysql-client \
|
||||||
|
iproute2 \
|
||||||
|
default-libmysqlclient-dev \
|
||||||
|
build-essential
|
||||||
|
|
||||||
|
RUN python3.10 -m pip install --disable-pip-version-check --no-cache-dir mysqlclient==2.1.1
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
15
test-containers/mysql-py310-pymysql102/Dockerfile
Normal file
15
test-containers/mysql-py310-pymysql102/Dockerfile
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2204-test-container:main
|
||||||
|
# ubuntu2204 comes with mysql-client-8
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.10 \
|
||||||
|
mysql-client \
|
||||||
|
iproute2
|
||||||
|
|
||||||
|
RUN python3.10 -m pip install --disable-pip-version-check --no-cache-dir pymysql==1.0.2
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
21
test-containers/mysql-py38-mysqlclient201/Dockerfile
Normal file
21
test-containers/mysql-py38-mysqlclient201/Dockerfile
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2004-test-container:main
|
||||||
|
# ubuntu2004 comes with mysql-client-8
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
# python3.8-dev # Reqs for mysqlclient
|
||||||
|
# default-libmysqlclient-dev # Reqs for mysqlclient
|
||||||
|
# build-essential # Reqs for mysqlclient
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.8 \
|
||||||
|
python3.8-dev \
|
||||||
|
mysql-client \
|
||||||
|
iproute2 \
|
||||||
|
default-libmysqlclient-dev \
|
||||||
|
build-essential
|
||||||
|
|
||||||
|
RUN python3.8 -m pip install --disable-pip-version-check --no-cache-dir mysqlclient==2.0.1
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
15
test-containers/mysql-py38-pymysql093/Dockerfile
Normal file
15
test-containers/mysql-py38-pymysql093/Dockerfile
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2004-test-container:main
|
||||||
|
# ubuntu2004 comes with mysql-client-8
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.8 \
|
||||||
|
mysql-client \
|
||||||
|
iproute2
|
||||||
|
|
||||||
|
RUN python3.8 -m pip install --disable-pip-version-check --no-cache-dir pymysql==0.9.3
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
21
test-containers/mysql-py39-mysqlclient203/Dockerfile
Normal file
21
test-containers/mysql-py39-mysqlclient203/Dockerfile
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2004-test-container:main
|
||||||
|
# ubuntu2004 comes with mysql-client-8
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
# python3.9-dev # Reqs for mysqlclient
|
||||||
|
# default-libmysqlclient-dev # Reqs for mysqlclient
|
||||||
|
# build-essential # Reqs for mysqlclient
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.9 \
|
||||||
|
python3.9-dev \
|
||||||
|
mysql-client \
|
||||||
|
iproute2 \
|
||||||
|
default-libmysqlclient-dev \
|
||||||
|
build-essential
|
||||||
|
|
||||||
|
RUN python3.9 -m pip install --disable-pip-version-check --no-cache-dir mysqlclient==2.0.3
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
16
test-containers/mysql-py39-pymysql093/Dockerfile
Normal file
16
test-containers/mysql-py39-pymysql093/Dockerfile
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
FROM quay.io/ansible/ubuntu2004-test-container:main
|
||||||
|
# ubuntu2004 comes with mysql-client-8
|
||||||
|
|
||||||
|
# iproute2 # To grab docker network gateway address
|
||||||
|
RUN apt-get update -y && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --no-install-recommends && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
python3.9 \
|
||||||
|
mysql-client \
|
||||||
|
iproute2
|
||||||
|
|
||||||
|
# cffi # To connect to MySQL 8 with Python3.9 and PyMySQL
|
||||||
|
RUN python3.9 -m pip install --disable-pip-version-check --no-cache-dir cffi pymysql==0.9.3
|
||||||
|
|
||||||
|
ENV container=docker
|
||||||
|
CMD ["/sbin/init"]
|
|
@ -1,3 +1,5 @@
|
||||||
|
---
|
||||||
|
mysql_host: "{{ gateway_addr }}"
|
||||||
master_port: 3306
|
master_port: 3306
|
||||||
standby_port: 3307
|
standby_port: 3307
|
||||||
test_db: test_db
|
test_db: test_db
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
# Auxiliary step:
|
# Auxiliary step:
|
||||||
- name: Get master status
|
- name: Get master status
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ primary_db.port }}"
|
login_port: "{{ primary_db.port }}"
|
||||||
mode: getmaster
|
mode: getmaster
|
||||||
register: primary_status
|
register: primary_status
|
||||||
|
@ -19,10 +19,10 @@
|
||||||
# Set master_use_gtid disabled:
|
# Set master_use_gtid disabled:
|
||||||
- name: Run replication
|
- name: Run replication
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: changemaster
|
mode: changemaster
|
||||||
master_host: 127.0.0.1
|
master_host: '{{ mysql_host }}'
|
||||||
master_port: "{{ primary_db.port }}"
|
master_port: "{{ primary_db.port }}"
|
||||||
master_user: "{{ replication_user }}"
|
master_user: "{{ replication_user }}"
|
||||||
master_password: "{{ replication_pass }}"
|
master_password: "{{ replication_pass }}"
|
||||||
|
@ -38,13 +38,13 @@
|
||||||
# Start standby for further tests:
|
# Start standby for further tests:
|
||||||
- name: Start standby
|
- name: Start standby
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ primary_db.port }}"
|
login_port: "{{ primary_db.port }}"
|
||||||
mode: startslave
|
mode: startslave
|
||||||
|
|
||||||
- name: Get standby status
|
- name: Get standby status
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: getslave
|
mode: getslave
|
||||||
register: slave_status
|
register: slave_status
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
# Stop standby for further tests:
|
# Stop standby for further tests:
|
||||||
- name: Stop standby
|
- name: Stop standby
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: stopslave
|
mode: stopslave
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
# Auxiliary step:
|
# Auxiliary step:
|
||||||
- name: Get master status
|
- name: Get master status
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ primary_db.port }}"
|
login_port: "{{ primary_db.port }}"
|
||||||
mode: getmaster
|
mode: getmaster
|
||||||
register: primary_status
|
register: primary_status
|
||||||
|
@ -75,10 +75,10 @@
|
||||||
# Set master_use_gtid current_pos:
|
# Set master_use_gtid current_pos:
|
||||||
- name: Run replication
|
- name: Run replication
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: changemaster
|
mode: changemaster
|
||||||
master_host: 127.0.0.1
|
master_host: '{{ mysql_host }}'
|
||||||
master_port: "{{ primary_db.port }}"
|
master_port: "{{ primary_db.port }}"
|
||||||
master_user: "{{ replication_user }}"
|
master_user: "{{ replication_user }}"
|
||||||
master_password: "{{ replication_pass }}"
|
master_password: "{{ replication_pass }}"
|
||||||
|
@ -94,13 +94,13 @@
|
||||||
# Start standby for further tests:
|
# Start standby for further tests:
|
||||||
- name: Start standby
|
- name: Start standby
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ primary_db.port }}"
|
login_port: "{{ primary_db.port }}"
|
||||||
mode: startslave
|
mode: startslave
|
||||||
|
|
||||||
- name: Get standby status
|
- name: Get standby status
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: getslave
|
mode: getslave
|
||||||
register: slave_status
|
register: slave_status
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
# Stop standby for further tests:
|
# Stop standby for further tests:
|
||||||
- name: Stop standby
|
- name: Stop standby
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: stopslave
|
mode: stopslave
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@
|
||||||
# Auxiliary step:
|
# Auxiliary step:
|
||||||
- name: Get master status
|
- name: Get master status
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ primary_db.port }}"
|
login_port: "{{ primary_db.port }}"
|
||||||
mode: getmaster
|
mode: getmaster
|
||||||
register: primary_status
|
register: primary_status
|
||||||
|
@ -131,10 +131,10 @@
|
||||||
# Set master_use_gtid slave_pos:
|
# Set master_use_gtid slave_pos:
|
||||||
- name: Run replication
|
- name: Run replication
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: changemaster
|
mode: changemaster
|
||||||
master_host: 127.0.0.1
|
master_host: '{{ mysql_host }}'
|
||||||
master_port: "{{ primary_db.port }}"
|
master_port: "{{ primary_db.port }}"
|
||||||
master_user: "{{ replication_user }}"
|
master_user: "{{ replication_user }}"
|
||||||
master_password: "{{ replication_pass }}"
|
master_password: "{{ replication_pass }}"
|
||||||
|
@ -150,13 +150,13 @@
|
||||||
# Start standby for further tests:
|
# Start standby for further tests:
|
||||||
- name: Start standby
|
- name: Start standby
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ primary_db.port }}"
|
login_port: "{{ primary_db.port }}"
|
||||||
mode: startslave
|
mode: startslave
|
||||||
|
|
||||||
- name: Get standby status
|
- name: Get standby status
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: getslave
|
mode: getslave
|
||||||
register: slave_status
|
register: slave_status
|
||||||
|
@ -168,6 +168,6 @@
|
||||||
# Stop standby for further tests:
|
# Stop standby for further tests:
|
||||||
- name: Stop standby
|
- name: Stop standby
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: stopslave
|
mode: stopslave
|
||||||
|
|
|
@ -4,20 +4,20 @@
|
||||||
# Needs for further tests:
|
# Needs for further tests:
|
||||||
- name: Stop slave
|
- name: Stop slave
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: stopslave
|
mode: stopslave
|
||||||
|
|
||||||
- name: Reset slave all
|
- name: Reset slave all
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: resetslaveall
|
mode: resetslaveall
|
||||||
|
|
||||||
# Get master log pos:
|
# Get master log pos:
|
||||||
- name: Get master status
|
- name: Get master status
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ primary_db.port }}"
|
login_port: "{{ primary_db.port }}"
|
||||||
mode: getmaster
|
mode: getmaster
|
||||||
register: primary_status
|
register: primary_status
|
||||||
|
@ -25,10 +25,10 @@
|
||||||
# Test changemaster mode:
|
# Test changemaster mode:
|
||||||
- name: Run replication with connection_name
|
- name: Run replication with connection_name
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: changemaster
|
mode: changemaster
|
||||||
master_host: 127.0.0.1
|
master_host: '{{ mysql_host }}'
|
||||||
master_port: "{{ primary_db.port }}"
|
master_port: "{{ primary_db.port }}"
|
||||||
master_user: "{{ replication_user }}"
|
master_user: "{{ replication_user }}"
|
||||||
master_password: "{{ replication_pass }}"
|
master_password: "{{ replication_pass }}"
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
# Test startslave mode:
|
# Test startslave mode:
|
||||||
- name: Start slave with connection_name
|
- name: Start slave with connection_name
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: startslave
|
mode: startslave
|
||||||
connection_name: "{{ conn_name }}"
|
connection_name: "{{ conn_name }}"
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
# Test getslave mode:
|
# Test getslave mode:
|
||||||
- name: Get standby statu with connection_name
|
- name: Get standby statu with connection_name
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: getslave
|
mode: getslave
|
||||||
connection_name: "{{ conn_name }}"
|
connection_name: "{{ conn_name }}"
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- slave_status.Is_Slave == true
|
- slave_status.Is_Slave == true
|
||||||
- slave_status.Master_Host == '127.0.0.1'
|
- slave_status.Master_Host == ''{{ mysql_host }}''
|
||||||
- slave_status.Exec_Master_Log_Pos == primary_status.Position
|
- slave_status.Exec_Master_Log_Pos == primary_status.Position
|
||||||
- slave_status.Master_Port == {{ primary_db.port }}
|
- slave_status.Master_Port == {{ primary_db.port }}
|
||||||
- slave_status.Last_IO_Errno == 0
|
- slave_status.Last_IO_Errno == 0
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
# Test stopslave mode:
|
# Test stopslave mode:
|
||||||
- name: Stop slave with connection_name
|
- name: Stop slave with connection_name
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: stopslave
|
mode: stopslave
|
||||||
connection_name: "{{ conn_name }}"
|
connection_name: "{{ conn_name }}"
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
# Test reset
|
# Test reset
|
||||||
- name: Reset slave with connection_name
|
- name: Reset slave with connection_name
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: resetslave
|
mode: resetslave
|
||||||
connection_name: "{{ conn_name }}"
|
connection_name: "{{ conn_name }}"
|
||||||
|
@ -106,7 +106,7 @@
|
||||||
# Test reset all
|
# Test reset all
|
||||||
- name: Reset slave all with connection_name
|
- name: Reset slave all with connection_name
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: resetslaveall
|
mode: resetslaveall
|
||||||
connection_name: "{{ conn_name }}"
|
connection_name: "{{ conn_name }}"
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
# Preparation:
|
# Preparation:
|
||||||
- name: Create user for replication
|
- name: Create user for replication
|
||||||
shell: "echo \"GRANT REPLICATION SLAVE ON *.* TO '{{ replication_user }}'@'localhost' IDENTIFIED BY '{{ replication_pass }}'; FLUSH PRIVILEGES;\" | mysql -P {{ primary_db.port }} -h 127.0.0.1"
|
shell: "echo \"GRANT REPLICATION SLAVE ON *.* TO '{{ replication_user }}'@'localhost' IDENTIFIED BY '{{ replication_pass }}'; FLUSH PRIVILEGES;\" | mysql -P {{ primary_db.port }} -h '{{ mysql_host }}'"
|
||||||
|
|
||||||
- name: Create test database
|
- name: Create test database
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ primary_db.port }}'
|
login_port: '{{ primary_db.port }}'
|
||||||
state: present
|
state: present
|
||||||
name: '{{ test_db }}'
|
name: '{{ test_db }}'
|
||||||
|
@ -16,12 +16,12 @@
|
||||||
shell: 'mysqldump -P {{ primary_db.port }} -h 127.0.01 --all-databases --master-data=2 > {{ dump_path }}'
|
shell: 'mysqldump -P {{ primary_db.port }} -h 127.0.01 --all-databases --master-data=2 > {{ dump_path }}'
|
||||||
|
|
||||||
- name: Restore the dump to the replica
|
- name: Restore the dump to the replica
|
||||||
shell: 'mysql -P {{ replica_db.port }} -h 127.0.0.1 < {{ dump_path }}'
|
shell: "mysql -P {{ replica_db.port }} -h '{{ mysql_host }}' < {{ dump_path }}"
|
||||||
|
|
||||||
# Test getmaster mode:
|
# Test getmaster mode:
|
||||||
- name: Get master status
|
- name: Get master status
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ primary_db.port }}"
|
login_port: "{{ primary_db.port }}"
|
||||||
mode: getmaster
|
mode: getmaster
|
||||||
register: master_status
|
register: master_status
|
||||||
|
@ -35,10 +35,10 @@
|
||||||
# Test changemaster mode:
|
# Test changemaster mode:
|
||||||
- name: Run replication
|
- name: Run replication
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: changemaster
|
mode: changemaster
|
||||||
master_host: 127.0.0.1
|
master_host: '{{ mysql_host }}'
|
||||||
master_port: "{{ primary_db.port }}"
|
master_port: "{{ primary_db.port }}"
|
||||||
master_user: "{{ replication_user }}"
|
master_user: "{{ replication_user }}"
|
||||||
master_password: "{{ replication_pass }}"
|
master_password: "{{ replication_pass }}"
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
# Test startslave mode:
|
# Test startslave mode:
|
||||||
- name: Start slave
|
- name: Start slave
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: startslave
|
mode: startslave
|
||||||
register: result
|
register: result
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
# Test getslave mode:
|
# Test getslave mode:
|
||||||
- name: Get replica status
|
- name: Get replica status
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: getslave
|
mode: getslave
|
||||||
register: slave_status
|
register: slave_status
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- slave_status.Is_Slave == true
|
- slave_status.Is_Slave == true
|
||||||
- slave_status.Master_Host == '127.0.0.1'
|
- slave_status.Master_Host == ''{{ mysql_host }}''
|
||||||
- slave_status.Exec_Master_Log_Pos == master_status.Position
|
- slave_status.Exec_Master_Log_Pos == master_status.Position
|
||||||
- slave_status.Master_Port == {{ primary_db.port }}
|
- slave_status.Master_Port == {{ primary_db.port }}
|
||||||
- slave_status.Last_IO_Errno == 0
|
- slave_status.Last_IO_Errno == 0
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
# Test stopslave mode:
|
# Test stopslave mode:
|
||||||
- name: Stop slave
|
- name: Stop slave
|
||||||
mysql_replication:
|
mysql_replication:
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: "{{ replica_db.port }}"
|
login_port: "{{ replica_db.port }}"
|
||||||
mode: stopslave
|
mode: stopslave
|
||||||
register: result
|
register: result
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: "{{ role_name }} | Fake root | Ensure folder"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ playbook_dir }}/root"
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: "{{ role_name }} | Fake root | Ensure default file exists"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ playbook_dir }}/root/.my.cnf"
|
||||||
|
state: touch
|
18
tests/integration/targets/setup_controller/tasks/main.yml
Normal file
18
tests/integration/targets/setup_controller/tasks/main.yml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
####################################################################
|
||||||
|
# WARNING: These are designed specifically for Ansible tests #
|
||||||
|
# and should not be used as examples of how to write Ansible roles #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
- name: Prepare the fake root folder
|
||||||
|
ansible.builtin.import_tasks:
|
||||||
|
file: fake_root.yml
|
||||||
|
|
||||||
|
# setvars.yml requires the iproute2 package installed by install.yml
|
||||||
|
- name: Set variables
|
||||||
|
ansible.builtin.import_tasks:
|
||||||
|
file: setvars.yml
|
||||||
|
|
||||||
|
- name: Verify all components version under test
|
||||||
|
ansible.builtin.import_tasks:
|
||||||
|
file: verify.yml
|
79
tests/integration/targets/setup_controller/tasks/setvars.yml
Normal file
79
tests/integration/targets/setup_controller/tasks/setvars.yml
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: "{{ role_name }} | Setvars | Extract Podman/Docker Network Gateway"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: ip route|grep default|awk '{print $3}'
|
||||||
|
register: ip_route_output
|
||||||
|
|
||||||
|
- name: "{{ role_name }} | Setvars | Set Fact"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
gateway_addr: "{{ ip_route_output.stdout }}"
|
||||||
|
connector_name_lookup: >-
|
||||||
|
{{ lookup(
|
||||||
|
'file',
|
||||||
|
'/root/ansible_collections/community/mysql/tests/integration/connector_name'
|
||||||
|
) }}
|
||||||
|
connector_version_lookup: >-
|
||||||
|
{{ lookup(
|
||||||
|
'file',
|
||||||
|
'/root/ansible_collections/community/mysql/tests/integration/connector_version'
|
||||||
|
) }}
|
||||||
|
db_engine_name_lookup: >-
|
||||||
|
{{ lookup(
|
||||||
|
'file',
|
||||||
|
'/root/ansible_collections/community/mysql/tests/integration/db_engine_name'
|
||||||
|
) }}
|
||||||
|
db_engine_version_lookup: >-
|
||||||
|
{{ lookup(
|
||||||
|
'file',
|
||||||
|
'/root/ansible_collections/community/mysql/tests/integration/db_engine_version'
|
||||||
|
) }}
|
||||||
|
python_version_lookup: >-
|
||||||
|
{{ lookup(
|
||||||
|
'file',
|
||||||
|
'/root/ansible_collections/community/mysql/tests/integration/python'
|
||||||
|
) }}
|
||||||
|
ansible_version_lookup: >-
|
||||||
|
{{ lookup(
|
||||||
|
'file',
|
||||||
|
'/root/ansible_collections/community/mysql/tests/integration/ansible'
|
||||||
|
) }}
|
||||||
|
|
||||||
|
- name: "{{ role_name }} | Setvars | Set Fact using above facts"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
connector_name: "{{ connector_name_lookup.strip() }}"
|
||||||
|
connector_version: "{{ connector_version_lookup.strip() }}"
|
||||||
|
db_engine: "{{ db_engine_name_lookup.strip() }}"
|
||||||
|
db_version: "{{ db_engine_version_lookup.strip() }}"
|
||||||
|
python_version: "{{ python_version_lookup.strip() }}"
|
||||||
|
test_ansible_version: >-
|
||||||
|
{%- if ansible_version_lookup == 'devel' -%}
|
||||||
|
{{ ansible_version_lookup }}
|
||||||
|
{%- else -%}
|
||||||
|
{{ ansible_version_lookup.split('-')[1].strip() }}
|
||||||
|
{%- endif -%}
|
||||||
|
mysql_command: >-
|
||||||
|
mysql
|
||||||
|
-h{{ gateway_addr }}
|
||||||
|
-P{{ mysql_primary_port }}
|
||||||
|
-u{{ mysql_user }}
|
||||||
|
-p{{ mysql_password }}
|
||||||
|
--protocol=tcp
|
||||||
|
mysql_command_wo_port: >-
|
||||||
|
mysql
|
||||||
|
-h{{ gateway_addr }}
|
||||||
|
-u{{ mysql_user }}
|
||||||
|
-p{{ mysql_password }}
|
||||||
|
--protocol=tcp
|
||||||
|
|
||||||
|
- name: "{{ role_name }} | Setvars | Output test informations"
|
||||||
|
vars:
|
||||||
|
msg: |-
|
||||||
|
connector_name: {{ connector_name }}
|
||||||
|
connector_version: {{ connector_version }}
|
||||||
|
db_engine: {{ db_engine }}
|
||||||
|
db_version: {{ db_version }}
|
||||||
|
python_version: {{ python_version }}
|
||||||
|
test_ansible_version: {{ test_ansible_version }}
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "{{ msg.split('\n') }}"
|
59
tests/integration/targets/setup_controller/tasks/verify.yml
Normal file
59
tests/integration/targets/setup_controller/tasks/verify.yml
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- vars:
|
||||||
|
mysql_parameters: &mysql_params
|
||||||
|
login_user: root
|
||||||
|
login_password: msandbox
|
||||||
|
login_host: "{{ gateway_addr }}"
|
||||||
|
login_port: 3307
|
||||||
|
|
||||||
|
block:
|
||||||
|
|
||||||
|
- name: Query Primary container over TCP for MySQL/MariaDB version
|
||||||
|
mysql_info:
|
||||||
|
<<: *mysql_params
|
||||||
|
filter:
|
||||||
|
- version
|
||||||
|
register: primary_info
|
||||||
|
|
||||||
|
- name: Assert that test container runs the expected MySQL/MariaDB version
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'{{ primary_info.version.major }}.{{ primary_info.version.minor }}\
|
||||||
|
.{{ primary_info.version.release }}' == '{{ db_version }}'"
|
||||||
|
|
||||||
|
- name: Assert that mysql_info module used the expected version of pymysql
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- primary_info.connector_name == connector_name
|
||||||
|
- primary_info.connector_version == connector_version
|
||||||
|
when:
|
||||||
|
- connector_name == 'pymysql'
|
||||||
|
|
||||||
|
- name: Assert that mysql_info module used the expected version of mysqlclient
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- primary_info.connector_name == 'MySQLdb'
|
||||||
|
- primary_info.connector_version == connector_version
|
||||||
|
when:
|
||||||
|
- connector_name == 'mysqlclient'
|
||||||
|
|
||||||
|
- name: Display the python version in use
|
||||||
|
command:
|
||||||
|
cmd: python{{ python_version }} -V
|
||||||
|
changed_when: false
|
||||||
|
register: python_in_use
|
||||||
|
|
||||||
|
- name: Assert that expected Python is installed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- python_in_use.stdout is search(python_version)
|
||||||
|
|
||||||
|
- name: Assert that we run the expected ansible version
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- >
|
||||||
|
"{{ ansible_version.major }}.{{ ansible_version.minor }}"
|
||||||
|
is version(test_ansible_version, '==')
|
||||||
|
when:
|
||||||
|
- test_ansible_version != 'devel' # Devel will change overtime
|
|
@ -1,13 +0,0 @@
|
||||||
dbdeployer_version: 1.52.0
|
|
||||||
dbdeployer_home_dir: /opt/dbdeployer
|
|
||||||
|
|
||||||
home_dir: /root
|
|
||||||
|
|
||||||
percona_client_version: 5.7
|
|
||||||
|
|
||||||
mariadb_install: false
|
|
||||||
|
|
||||||
mysql_version: 8.0.22
|
|
||||||
mariadb_version: 10.5.4
|
|
||||||
|
|
||||||
mysql_base_port: 3306
|
|
|
@ -1,6 +0,0 @@
|
||||||
---
|
|
||||||
- name: "{{ role_name }} | handler | create dbdeployer installed file"
|
|
||||||
template:
|
|
||||||
src: installed_file.j2
|
|
||||||
dest: "{{ dbdeployer_installed_file }}"
|
|
||||||
listen: create zookeeper installed file
|
|
|
@ -1,15 +0,0 @@
|
||||||
---
|
|
||||||
- name: "{{ role_name }} | config | download mysql tarball"
|
|
||||||
get_url:
|
|
||||||
url: "{{ install_src }}"
|
|
||||||
dest: "{{ dbdeployer_sandbox_download_dir }}/{{ install_tarball }}"
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | config | run unpack tarball"
|
|
||||||
shell:
|
|
||||||
cmd: "dbdeployer unpack {{ dbdeployer_sandbox_download_dir }}/{{ install_tarball }}"
|
|
||||||
creates: "{{ dbdeployer_sandbox_binary_dir }}/{{ install_version }}"
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | config | setup replication topology"
|
|
||||||
shell:
|
|
||||||
cmd: "dbdeployer deploy multiple {{ install_version }} --base-port {{ mysql_base_port }} --my-cnf-options=\"master_info_repository='TABLE'\" --my-cnf-options=\"relay_log_info_repository='TABLE'\""
|
|
||||||
creates: "{{ dbdeployer_sandbox_home_dir }}/multi_msb_{{ install_version|replace('.','_') }}"
|
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
- name: "{{ role_name }} | dir | create dbdeployer directories"
|
|
||||||
file:
|
|
||||||
state: directory
|
|
||||||
path: "{{ item }}"
|
|
||||||
loop:
|
|
||||||
- "{{ dbdeployer_home_dir }}"
|
|
||||||
- "{{ dbdeployer_install_dir }}"
|
|
||||||
- "{{ dbdeployer_sandbox_download_dir }}"
|
|
||||||
- "{{ dbdeployer_sandbox_binary_dir }}"
|
|
||||||
- "{{ dbdeployer_sandbox_home_dir }}"
|
|
|
@ -1,59 +0,0 @@
|
||||||
---
|
|
||||||
- name: "{{ role_name }} | install | add apt signing key for percona"
|
|
||||||
apt_key:
|
|
||||||
keyserver: keyserver.ubuntu.com
|
|
||||||
id: 4D1BB29D63D98E422B2113B19334A25F8507EFA5
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | install | add percona repositories"
|
|
||||||
apt_repository:
|
|
||||||
repo: "{{ item }}"
|
|
||||||
state: present
|
|
||||||
loop: "{{ percona_mysql_repos }}"
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | install | install packages required by percona"
|
|
||||||
apt:
|
|
||||||
name: "{{ percona_mysql_packages }}"
|
|
||||||
state: present
|
|
||||||
environment:
|
|
||||||
DEBIAN_FRONTEND: noninteractive
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | install | install packages required by mysql connector"
|
|
||||||
apt:
|
|
||||||
name: "{{ install_python_prereqs }}"
|
|
||||||
state: present
|
|
||||||
environment:
|
|
||||||
DEBIAN_FRONTEND: noninteractive
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | install | install python packages"
|
|
||||||
pip:
|
|
||||||
name: "{{ python_packages }}"
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | install | install packages required by mysql"
|
|
||||||
apt:
|
|
||||||
name: "{{ install_prereqs }}"
|
|
||||||
state: present
|
|
||||||
environment:
|
|
||||||
DEBIAN_FRONTEND: noninteractive
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | install | download and unpack dbdeployer"
|
|
||||||
unarchive:
|
|
||||||
remote_src: true
|
|
||||||
src: "{{ dbdeployer_src }}"
|
|
||||||
dest: "{{ dbdeployer_install_dir }}"
|
|
||||||
creates: "{{ dbdeployer_installed_file }}"
|
|
||||||
register: dbdeployer_tarball_install
|
|
||||||
notify:
|
|
||||||
- create zookeeper installed file
|
|
||||||
until: dbdeployer_tarball_install is not failed
|
|
||||||
retries: 6
|
|
||||||
delay: 5
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | install | create symlink"
|
|
||||||
file:
|
|
||||||
src: "{{ dbdeployer_install_dir }}/dbdeployer-{{ dbdeployer_version }}.linux"
|
|
||||||
dest: /usr/local/bin/dbdeployer
|
|
||||||
follow: false
|
|
||||||
state: link
|
|
||||||
|
|
||||||
- meta: flush_handlers
|
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
####################################################################
|
|
||||||
# WARNING: These are designed specifically for Ansible tests #
|
|
||||||
# and should not be used as examples of how to write Ansible roles #
|
|
||||||
####################################################################
|
|
||||||
|
|
||||||
- import_tasks: setvars.yml
|
|
||||||
- import_tasks: dir.yml
|
|
||||||
- import_tasks: install.yml
|
|
||||||
- import_tasks: config.yml
|
|
||||||
- import_tasks: verify.yml
|
|
|
@ -1,28 +0,0 @@
|
||||||
---
|
|
||||||
- name: "{{ role_name }} | setvars | split mysql version in parts"
|
|
||||||
set_fact:
|
|
||||||
mysql_version_parts: "{{ mysql_version.split('.') }}"
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | setvars | get mysql major version"
|
|
||||||
set_fact:
|
|
||||||
mysql_major_version: "{{ mysql_version_parts[0] + '.' + mysql_version_parts[1] }}"
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | setvars | set the appropriate extension dependent on the mysql version"
|
|
||||||
set_fact:
|
|
||||||
mysql_compression_extension: "{{ mysql_version is version('8.0.0', '<') | ternary('gz', 'xz') }}"
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | setvars | set the install type"
|
|
||||||
set_fact:
|
|
||||||
install_type: "{{ mariadb_install | ternary('mariadb', 'mysql') }}"
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | setvars | set install_version"
|
|
||||||
set_fact:
|
|
||||||
install_version: "{{ lookup('vars', install_type + '_version') }}"
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | setvars | set install_tarball"
|
|
||||||
set_fact:
|
|
||||||
install_tarball: "{{ lookup('vars', install_type + '_tarball') }}"
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | setvars | set install_src"
|
|
||||||
set_fact:
|
|
||||||
install_src: "{{ lookup('vars', install_type + '_src') }}"
|
|
|
@ -1,27 +0,0 @@
|
||||||
---
|
|
||||||
- name: "{{ role_name }} | verify | confirm primary is running and get the port"
|
|
||||||
shell: "{{ dbdeployer_sandbox_home_dir }}/multi_msb_{{ install_version|replace('.','_') }}/n1 -BNe'select @@port'"
|
|
||||||
register: primary_port
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | verify | confirm replica1 is running and get the port"
|
|
||||||
shell: "{{ dbdeployer_sandbox_home_dir }}/multi_msb_{{ install_version|replace('.','_') }}/n2 -BNe'select @@port'"
|
|
||||||
register: replica1_port
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | verify | confirm replica2 is running and get the port"
|
|
||||||
shell: "{{ dbdeployer_sandbox_home_dir }}/multi_msb_{{ install_version|replace('.','_') }}/n3 -BNe'select @@port'"
|
|
||||||
register: replica2_port
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | verify | confirm primary is running on expected port"
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- primary_port.stdout|int == 3307
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | verify | confirm replica1 is running on expected port"
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- replica1_port.stdout|int == 3308
|
|
||||||
|
|
||||||
- name: "{{ role_name }} | verify | confirm replica2 is running on expected port"
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- replica2_port.stdout|int == 3309
|
|
|
@ -1 +0,0 @@
|
||||||
{{ dbdeployer_version }}
|
|
|
@ -1,31 +0,0 @@
|
||||||
---
|
|
||||||
dbdeployer_install_dir: "{{ dbdeployer_home_dir }}/dbdeployer_{{ dbdeployer_version }}"
|
|
||||||
dbdeployer_src: "https://github.com/datacharmer/dbdeployer/releases/download/v{{ dbdeployer_version }}/dbdeployer-{{ dbdeployer_version }}.linux.tar.gz"
|
|
||||||
dbdeployer_installed_file: "{{ dbdeployer_home_dir }}/dbdeployer_installed"
|
|
||||||
|
|
||||||
dbdeployer_sandbox_download_dir: "{{ home_dir }}/downloads"
|
|
||||||
dbdeployer_sandbox_binary_dir: "{{ home_dir }}/opt/mysql"
|
|
||||||
dbdeployer_sandbox_home_dir: "{{ home_dir }}/sandboxes"
|
|
||||||
|
|
||||||
percona_mysql_repos:
|
|
||||||
- deb http://repo.percona.com/apt {{ ansible_lsb.codename }} main
|
|
||||||
- deb-src http://repo.percona.com/apt {{ ansible_lsb.codename }} main
|
|
||||||
|
|
||||||
percona_mysql_packages:
|
|
||||||
- percona-server-client-{{ percona_client_version }}
|
|
||||||
|
|
||||||
python_packages: [pymysql == 0.9.3]
|
|
||||||
|
|
||||||
install_prereqs:
|
|
||||||
- libaio1
|
|
||||||
- libnuma1
|
|
||||||
|
|
||||||
install_python_prereqs:
|
|
||||||
- python3-dev
|
|
||||||
- default-libmysqlclient-dev
|
|
||||||
- build-essential
|
|
||||||
|
|
||||||
mysql_tarball: "mysql-{{ mysql_version }}-linux-glibc2.12-x86_64.tar.{{ mysql_compression_extension }}"
|
|
||||||
mysql_src: "https://dev.mysql.com/get/Downloads/MySQL-{{ mysql_major_version }}/{{ mysql_tarball }}"
|
|
||||||
mariadb_tarball: "mariadb-{{ mariadb_version }}-linux-x86_64.tar.gz"
|
|
||||||
mariadb_src: "https://downloads.mariadb.com/MariaDB/mariadb-{{ mariadb_version }}/bintar-linux-x86_64/{{ mariadb_tarball }}"
|
|
|
@ -2,9 +2,21 @@
|
||||||
# defaults file for test_mysql_db
|
# defaults file for test_mysql_db
|
||||||
mysql_user: root
|
mysql_user: root
|
||||||
mysql_password: msandbox
|
mysql_password: msandbox
|
||||||
|
mysql_host: '{{ gateway_addr }}'
|
||||||
mysql_primary_port: 3307
|
mysql_primary_port: 3307
|
||||||
|
|
||||||
db_name: 'data'
|
# Database names
|
||||||
|
db_names:
|
||||||
|
- "data"
|
||||||
|
# - "db%"
|
||||||
|
# Don't test % in stable-1. Support was added in v2
|
||||||
|
|
||||||
|
# Database formats
|
||||||
|
db_formats:
|
||||||
|
- { format_type: "sql", file: "dbdata.sql", format_msg_type: "ASCII", file2: "dump2.sql", file3: "dump3.sql", file4: "dump4.sql" }
|
||||||
|
- { format_type: "gz", file: "dbdata.gz", format_msg_type: "gzip", file2: "dump2.gz", file3: "dump3.gz", file4: "dump4.gz" }
|
||||||
|
- { format_type: "bz2", file: "dbdata.bz2", format_msg_type: "bzip2", file2: "dump2.bz2", file3: "dump3.bz2", file4: "dump4.bz2" }
|
||||||
|
|
||||||
db_name2: 'data2'
|
db_name2: 'data2'
|
||||||
db_user1: 'datauser1'
|
db_user1: 'datauser1'
|
||||||
db_user2: 'datauser2'
|
db_user2: 'datauser2'
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
- setup_mysql
|
- setup_controller
|
||||||
|
|
|
@ -1,43 +1,59 @@
|
||||||
- set_fact:
|
---
|
||||||
|
- name: Config overrides | Set facts
|
||||||
|
set_fact:
|
||||||
db_to_create: testdb1
|
db_to_create: testdb1
|
||||||
config_file: "/root/.my1.cnf"
|
config_file: "{{ playbook_dir }}/.my1.cnf"
|
||||||
fake_port: 9999
|
fake_port: 9999
|
||||||
fake_host: "blahblah.local"
|
fake_host: "blahblah.local"
|
||||||
include_dir: "/root/mycnf.d"
|
include_dir: "{{ playbook_dir }}/mycnf.d"
|
||||||
|
|
||||||
- name: Create custom config file
|
- name: Config overrides | Create custom config file
|
||||||
shell: 'echo "[client]" > {{ config_file }}'
|
shell: 'echo "[client]" > {{ config_file }}'
|
||||||
|
|
||||||
- name: Add fake port to config file
|
- name: Config overrides | Add fake port to config file
|
||||||
shell: 'echo "port = {{ fake_port }}" >> {{ config_file }}'
|
shell: 'echo "port = {{ fake_port }}" >> {{ config_file }}'
|
||||||
|
|
||||||
- name: Get pymysql version
|
- name: Config overrides | Add blank line
|
||||||
shell: pip show pymysql | awk '/Version/ {print $2}'
|
|
||||||
register: pymysql_version
|
|
||||||
|
|
||||||
- name: Add blank line
|
|
||||||
shell: 'echo "" >> {{ config_file }}'
|
shell: 'echo "" >> {{ config_file }}'
|
||||||
when: (pymysql_version.stdout | default('1000', true)) is version('0.9.3', '>=')
|
when:
|
||||||
|
- >
|
||||||
|
connector_name != 'pymysql'
|
||||||
|
or (
|
||||||
|
connector_name == 'pymysql'
|
||||||
|
and connector_version is version('0.9.3', '>=')
|
||||||
|
)
|
||||||
|
|
||||||
- name: Create include_dir
|
- name: Config overrides | Create include_dir
|
||||||
file:
|
file:
|
||||||
path: '{{ include_dir }}'
|
path: '{{ include_dir }}'
|
||||||
state: directory
|
state: directory
|
||||||
mode: '0777'
|
mode: '0777'
|
||||||
when: (pymysql_version.stdout | default('1000', true)) is version('0.9.3', '>=')
|
when:
|
||||||
|
- >
|
||||||
|
connector_name != 'pymysql'
|
||||||
|
or (
|
||||||
|
connector_name == 'pymysql'
|
||||||
|
and connector_version is version('0.9.3', '>=')
|
||||||
|
)
|
||||||
|
|
||||||
- name: Add include_dir
|
- name: Config overrides | Add include_dir
|
||||||
lineinfile:
|
lineinfile:
|
||||||
path: '{{ config_file }}'
|
path: '{{ config_file }}'
|
||||||
line: '!includedir {{ include_dir }}'
|
line: '!includedir {{ include_dir }}'
|
||||||
insertafter: EOF
|
insertafter: EOF
|
||||||
when: (pymysql_version.stdout | default('1000', true)) is version('0.9.3', '>=')
|
when:
|
||||||
|
- >
|
||||||
|
connector_name != 'pymysql'
|
||||||
|
or (
|
||||||
|
connector_name == 'pymysql'
|
||||||
|
and connector_version is version('0.9.3', '>=')
|
||||||
|
)
|
||||||
|
|
||||||
- name: Create database using fake port to connect to, must fail
|
- name: Config overrides | Create database using fake port to connect to, must fail
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_to_create }}'
|
name: '{{ db_to_create }}'
|
||||||
state: present
|
state: present
|
||||||
|
@ -47,17 +63,17 @@
|
||||||
ignore_errors: yes
|
ignore_errors: yes
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
- name: Must fail because login_port default has beed overriden by wrong value from config file
|
- name: Config overrides | Must fail because login_port default has beed overriden by wrong value from config file
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result is failed
|
- result is failed
|
||||||
- result.msg is search("unable to connect to database")
|
- result.msg is search("unable to connect to database")
|
||||||
|
|
||||||
- name: Create database using default port
|
- name: Config overrides | Create database using default port
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_to_create }}'
|
name: '{{ db_to_create }}'
|
||||||
state: present
|
state: present
|
||||||
|
@ -66,22 +82,22 @@
|
||||||
config_overrides_defaults: no
|
config_overrides_defaults: no
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
- name: Must not fail because of the default of login_port is correct
|
- name: Config overrides | Must not fail because of the default of login_port is correct
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result is changed
|
- result is changed
|
||||||
|
|
||||||
- name: Reinit custom config file
|
- name: Config overrides | Reinit custom config file
|
||||||
shell: 'echo "[client]" > {{ config_file }}'
|
shell: 'echo "[client]" > {{ config_file }}'
|
||||||
|
|
||||||
- name: Add fake host to config file
|
- name: Config overrides | Add fake host to config file
|
||||||
shell: 'echo "host = {{ fake_host }}" >> {{ config_file }}'
|
shell: 'echo "host = {{ fake_host }}" >> {{ config_file }}'
|
||||||
|
|
||||||
- name: Remove database using fake login_host
|
- name: Config overrides | Remove database using fake login_host
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_to_create }}'
|
name: '{{ db_to_create }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
@ -90,18 +106,17 @@
|
||||||
register: result
|
register: result
|
||||||
ignore_errors: yes
|
ignore_errors: yes
|
||||||
|
|
||||||
- name: Must fail because login_host default has beed overriden by wrong value from config file
|
- name: Config overrides | Must fail because login_host default has beed overriden by wrong value from config file
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result is failed
|
- result is failed
|
||||||
- result.msg is search("Can't connect to MySQL server on '{{ fake_host }}'") or result.msg is search("Unknown MySQL server host '{{ fake_host }}'")
|
- result.msg is search("Can't connect to MySQL server on '{{ fake_host }}'") or result.msg is search("Unknown MySQL server host '{{ fake_host }}'")
|
||||||
|
|
||||||
# Clean up
|
- name: Config overrides | Clean up test database
|
||||||
- name: Remove test db
|
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_to_create }}'
|
name: '{{ db_to_create }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
|
|
@ -1,57 +1,58 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
- set_fact:
|
- name: Encoding | Set fact
|
||||||
|
set_fact:
|
||||||
latin1_file1: "{{ tmp_dir }}/{{ file }}"
|
latin1_file1: "{{ tmp_dir }}/{{ file }}"
|
||||||
|
|
||||||
- name: Deleting Latin1 encoded Database
|
- name: Deleting Latin1 encoded Database
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_latin1_name }}'
|
name: '{{ db_latin1_name }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: create Latin1 encoded database
|
- name: Encoding | Create Latin1 encoded database
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_latin1_name }}'
|
name: '{{ db_latin1_name }}'
|
||||||
state: present
|
state: present
|
||||||
encoding: latin1
|
encoding: latin1
|
||||||
|
|
||||||
- name: create a table in Latin1 database
|
- name: Encoding | Create a table in Latin1 database
|
||||||
command: "{{ mysql_command }} {{ db_latin1_name }} -e \"create table testlatin1(id int, name varchar(100))\""
|
command: "{{ mysql_command }} {{ db_latin1_name }} -e \"create table testlatin1(id int, name varchar(100))\""
|
||||||
|
|
||||||
|
|
||||||
# Inserting a string in latin1 into table, , this string be tested later,
|
# Inserting a string in latin1 into table, , this string be tested later,
|
||||||
# so report any change of content in the test too
|
# so report any change of content in the test too
|
||||||
- name: inserting data into Latin1 database
|
- name: Encoding | Inserting data into Latin1 database
|
||||||
command: "{{ mysql_command }} {{ db_latin1_name }} -e \"insert into testlatin1 value(47,'Amédée Bôlüt')\""
|
command: "{{ mysql_command }} {{ db_latin1_name }} -e \"insert into testlatin1 value(47,'Amédée Bôlüt')\""
|
||||||
|
|
||||||
- name: selecting table
|
- name: Encoding | Selecting table
|
||||||
command: "{{ mysql_command }} {{ db_latin1_name }} -e \"select * from testlatin1\""
|
command: "{{ mysql_command }} {{ db_latin1_name }} -e \"select * from testlatin1\""
|
||||||
register: output
|
register: output
|
||||||
|
|
||||||
- name: Dumping a table in Latin1 database
|
- name: Encoding | Dumping a table in Latin1 database
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: "{{ db_latin1_name }}"
|
name: "{{ db_latin1_name }}"
|
||||||
encoding: latin1
|
encoding: latin1
|
||||||
target: "{{ latin1_file1 }}"
|
target: "{{ latin1_file1 }}"
|
||||||
state: dump
|
state: dump
|
||||||
register: dump_result
|
register: result
|
||||||
|
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- result is changed
|
- result is changed
|
||||||
|
|
||||||
- name: state dump - file name should exist
|
- name: Encoding | State dump - file name should exist (latin1_file1)
|
||||||
file:
|
file:
|
||||||
name: '{{ latin1_file1 }}'
|
name: '{{ latin1_file1 }}'
|
||||||
state: file
|
state: file
|
||||||
|
@ -59,40 +60,46 @@
|
||||||
- name: od the file and check of latin1 encoded string is present
|
- name: od the file and check of latin1 encoded string is present
|
||||||
shell: grep -a 47 {{ latin1_file1 }} | od -c |grep "A m 351 d 351 e B 364\|A m 303 251 d 303 251 e B 303"
|
shell: grep -a 47 {{ latin1_file1 }} | od -c |grep "A m 351 d 351 e B 364\|A m 303 251 d 303 251 e B 303"
|
||||||
|
|
||||||
- name: Dropping {{ db_latin1_name }} database
|
- name: Encoding | Dropping {{ db_latin1_name }} database
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_latin1_name }}'
|
name: '{{ db_latin1_name }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Importing the latin1 mysql script
|
- name: Encoding | Importing the latin1 mysql script
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
state: import
|
state: import
|
||||||
encoding: latin1
|
encoding: latin1
|
||||||
name: '{{ db_latin1_name }}'
|
name: '{{ db_latin1_name }}'
|
||||||
target: "{{ latin1_file1 }}"
|
target: "{{ latin1_file1 }}"
|
||||||
|
register: result
|
||||||
|
|
||||||
- assert:
|
- name: Encoding | Assert that importing latin1 is changed
|
||||||
|
assert:
|
||||||
that:
|
that:
|
||||||
- result is changed
|
- result is changed
|
||||||
|
|
||||||
- name: check encoding of table
|
- name: Encoding | Check encoding of table
|
||||||
shell: "{{ mysql_command }} {{ db_latin1_name }} -e \"SHOW FULL COLUMNS FROM testlatin1\""
|
ansible.builtin.command:
|
||||||
|
cmd: >
|
||||||
|
{{ mysql_command }}
|
||||||
|
{{ db_latin1_name }}
|
||||||
|
-e "SHOW FULL COLUMNS FROM {{ db_latin1_name }}.testlatin1"
|
||||||
register: output
|
register: output
|
||||||
failed_when: '"latin1_swedish_ci" not in output.stdout'
|
failed_when: '"latin1_swedish_ci" not in output.stdout'
|
||||||
|
|
||||||
- name: remove database
|
- name: Encoding | Clean up database
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_latin1_name }}'
|
name: '{{ db_latin1_name }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
---
|
---
|
||||||
|
- name: set fact tls_enabled
|
||||||
|
command: "{{ mysql_command }} \"-e SHOW VARIABLES LIKE 'have_ssl';\""
|
||||||
|
register: result
|
||||||
|
- set_fact:
|
||||||
|
tls_enabled: "{{ 'YES' in result.stdout | bool | default('false', true) }}"
|
||||||
|
|
||||||
- vars:
|
- vars:
|
||||||
mysql_parameters: &mysql_params
|
mysql_parameters: &mysql_params
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
when: tls_enabled
|
||||||
block:
|
block:
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
- shell: pip show pymysql | awk '/Version/ {print $2}'
|
|
||||||
register: pymysql_version
|
|
||||||
|
|
||||||
- name: get server certificate
|
- name: get server certificate
|
||||||
copy:
|
copy:
|
||||||
|
@ -22,6 +26,7 @@
|
||||||
mysql_user:
|
mysql_user:
|
||||||
<<: *mysql_params
|
<<: *mysql_params
|
||||||
name: '{{ user_name_1 }}'
|
name: '{{ user_name_1 }}'
|
||||||
|
host_all: true
|
||||||
state: absent
|
state: absent
|
||||||
ignore_errors: yes
|
ignore_errors: yes
|
||||||
|
|
||||||
|
@ -29,6 +34,7 @@
|
||||||
mysql_user:
|
mysql_user:
|
||||||
<<: *mysql_params
|
<<: *mysql_params
|
||||||
name: "{{ user_name_1 }}"
|
name: "{{ user_name_1 }}"
|
||||||
|
host: "%"
|
||||||
password: "{{ user_password_1 }}"
|
password: "{{ user_password_1 }}"
|
||||||
priv: '*.*:ALL,GRANT'
|
priv: '*.*:ALL,GRANT'
|
||||||
tls_requires:
|
tls_requires:
|
||||||
|
@ -40,7 +46,7 @@
|
||||||
state: absent
|
state: absent
|
||||||
login_user: '{{ user_name_1 }}'
|
login_user: '{{ user_name_1 }}'
|
||||||
login_password: '{{ user_password_1 }}'
|
login_password: '{{ user_password_1 }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
ca_cert: /tmp/cert.pem
|
ca_cert: /tmp/cert.pem
|
||||||
register: result
|
register: result
|
||||||
|
@ -49,12 +55,14 @@
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- result is failed
|
- result is failed
|
||||||
when: pymysql_version.stdout != ""
|
when:
|
||||||
|
- connector_name == 'pymysql'
|
||||||
|
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- result is succeeded
|
- result is succeeded
|
||||||
when: pymysql_version.stdout == ""
|
when:
|
||||||
|
- connector_name != 'pymysql'
|
||||||
|
|
||||||
- name: attempt connection with newly created user ignoring hostname
|
- name: attempt connection with newly created user ignoring hostname
|
||||||
mysql_db:
|
mysql_db:
|
||||||
|
@ -62,7 +70,7 @@
|
||||||
state: absent
|
state: absent
|
||||||
login_user: '{{ user_name_1 }}'
|
login_user: '{{ user_name_1 }}'
|
||||||
login_password: '{{ user_password_1 }}'
|
login_password: '{{ user_password_1 }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
ca_cert: /tmp/cert.pem
|
ca_cert: /tmp/cert.pem
|
||||||
check_hostname: no
|
check_hostname: no
|
||||||
|
@ -77,5 +85,5 @@
|
||||||
mysql_user:
|
mysql_user:
|
||||||
<<: *mysql_params
|
<<: *mysql_params
|
||||||
name: '{{ user_name_1 }}'
|
name: '{{ user_name_1 }}'
|
||||||
host: 127.0.0.1
|
host_all: true
|
||||||
state: absent
|
state: absent
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
---
|
||||||
####################################################################
|
####################################################################
|
||||||
# WARNING: These are designed specifically for Ansible tests #
|
# WARNING: These are designed specifically for Ansible tests #
|
||||||
# and should not be used as examples of how to write Ansible roles #
|
# and should not be used as examples of how to write Ansible roles #
|
||||||
|
@ -21,306 +22,41 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# ============================================================
|
- name: Check state present/absent
|
||||||
- name: alias mysql command to include default options
|
include_tasks: state_present_absent.yml
|
||||||
set_fact:
|
vars:
|
||||||
mysql_command: "mysql -u{{ mysql_user }} -p{{ mysql_password }} -P{{ mysql_primary_port }} --protocol=tcp"
|
db_name: "{{ item }}"
|
||||||
|
loop: "{{ db_names }}"
|
||||||
|
|
||||||
- name: remove database if it exists
|
- name: Check state dump/import
|
||||||
command: >
|
include_tasks: state_dump_import.yml
|
||||||
"{{ mysql_command }} -sse 'drop database {{ db_name }}'"
|
vars:
|
||||||
ignore_errors: True
|
db_name: "{{ item.0 }}"
|
||||||
|
file: "{{ item.1.file }}"
|
||||||
|
file2: "{{ item.1.file2 }}"
|
||||||
|
file3: "{{ item.1.file3 }}"
|
||||||
|
file4: "{{ item.1.file4 }}"
|
||||||
|
format_msg_type: "{{ item.1.format_msg_type }}"
|
||||||
|
format_type: "{{ item.1.format_type }}"
|
||||||
|
with_nested:
|
||||||
|
- "{{ db_names }}"
|
||||||
|
- "{{ db_formats }}"
|
||||||
|
|
||||||
- name: make sure the test database is not there
|
- name: Check state present/absent with multiple databases
|
||||||
command: "{{ mysql_command }} {{ db_name }}"
|
include_tasks: multi_db_create_delete.yml
|
||||||
register: mysql_db_check
|
|
||||||
failed_when: "'1049' not in mysql_db_check.stderr"
|
|
||||||
|
|
||||||
- name: test state=present for a database name (expect changed=true)
|
- name: Check state dump/import with encoding
|
||||||
mysql_db:
|
include_tasks: encoding_dump_import.yml
|
||||||
login_user: '{{ mysql_user }}'
|
vars:
|
||||||
login_password: '{{ mysql_password }}'
|
file: "latin1.sql"
|
||||||
login_host: 127.0.0.1
|
format_msg_type: "ASCII"
|
||||||
login_port: '{{ mysql_primary_port }}'
|
|
||||||
name: '{{ db_name }}'
|
|
||||||
state: present
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- name: assert output message that database exist
|
- name: Check MySQL config file
|
||||||
assert:
|
include_tasks: config_overrides_defaults.yml
|
||||||
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=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
|
|
||||||
|
|
||||||
- include: multi_db_create_delete.yml
|
|
||||||
|
|
||||||
- include: encoding_dump_import.yml file=latin1.sql format_msg_type=ASCII
|
|
||||||
|
|
||||||
- include: config_overrides_defaults.yml
|
|
||||||
when: ansible_python.version_info[0] >= 3
|
when: ansible_python.version_info[0] >= 3
|
||||||
|
|
||||||
- include: issue-28.yml
|
- name: Check issue 28
|
||||||
|
include_tasks: issue-28.yml
|
||||||
|
vars:
|
||||||
|
db_name: "{{ item }}"
|
||||||
|
loop: "{{ db_names }}"
|
||||||
|
|
|
@ -14,6 +14,18 @@
|
||||||
#
|
#
|
||||||
# ==========================================================================
|
# ==========================================================================
|
||||||
# Initial check - To confirm that database does not exist before executing check mode tasks
|
# Initial check - To confirm that database does not exist before executing check mode tasks
|
||||||
|
- name: Drop databases before test
|
||||||
|
mysql_db:
|
||||||
|
login_user: '{{ mysql_user }}'
|
||||||
|
login_password: '{{ mysql_password }}'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name:
|
||||||
|
- '{{ db1_name }}'
|
||||||
|
- '{{ db2_name }}'
|
||||||
|
- '{{ db3_name }}'
|
||||||
|
state: absent
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
register: mysql_result
|
register: mysql_result
|
||||||
|
@ -31,7 +43,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db1_name }}'
|
- '{{ db1_name }}'
|
||||||
|
@ -44,7 +56,7 @@
|
||||||
- name: assert successful completion of create database using check_mode since databases does not exist prior
|
- name: assert successful completion of create database using check_mode since databases does not exist prior
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- check_mode_result.changed == true
|
- check_mode_result is changed
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
@ -63,7 +75,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db1_name }}'
|
- '{{ db1_name }}'
|
||||||
|
@ -75,7 +87,7 @@
|
||||||
- name: assert successful completion of create database
|
- name: assert successful completion of create database
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result.changed == true
|
- result is changed
|
||||||
- result.db_list == ['{{ db1_name }}', '{{ db2_name }}', '{{ db3_name }}']
|
- result.db_list == ['{{ db1_name }}', '{{ db2_name }}', '{{ db3_name }}']
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
|
@ -95,7 +107,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db1_name }}'
|
- '{{ db1_name }}'
|
||||||
|
@ -108,7 +120,7 @@
|
||||||
- name: assert that recreation of existing databases does not make change (since recreated using check mode)
|
- name: assert that recreation of existing databases does not make change (since recreated using check mode)
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- check_mode_result.changed == false
|
- check_mode_result is not changed
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
@ -127,7 +139,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db1_name }}'
|
- '{{ db1_name }}'
|
||||||
|
@ -139,7 +151,7 @@
|
||||||
- name: assert that recreation of existing databases does not make change
|
- name: assert that recreation of existing databases does not make change
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result.changed == false
|
- result is not changed
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
@ -158,7 +170,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db2_name }}'
|
- '{{ db2_name }}'
|
||||||
|
@ -168,7 +180,7 @@
|
||||||
- name: assert successful completion of deleting database
|
- name: assert successful completion of deleting database
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result.changed == true
|
- result is changed
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
@ -187,7 +199,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db1_name }}'
|
- '{{ db1_name }}'
|
||||||
|
@ -200,7 +212,7 @@
|
||||||
- name: assert successful completion of recreation of partially existing database using check mode
|
- name: assert successful completion of recreation of partially existing database using check mode
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- check_mode_result.changed == true
|
- check_mode_result is changed
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
@ -219,7 +231,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db1_name }}'
|
- '{{ db1_name }}'
|
||||||
|
@ -231,7 +243,7 @@
|
||||||
- name: assert successful completion of create database
|
- name: assert successful completion of create database
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result.changed == true
|
- result is changed
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
@ -259,7 +271,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db1_name }}'
|
- '{{ db1_name }}'
|
||||||
|
@ -272,7 +284,7 @@
|
||||||
- name: assert successful completion of dump operation using check mode
|
- name: assert successful completion of dump operation using check mode
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- check_mode_dump_result.changed == true
|
- check_mode_dump_result is changed
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
@ -296,7 +308,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- "{{ db1_name }}"
|
- "{{ db1_name }}"
|
||||||
|
@ -336,7 +348,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- "{{ db4_name }}"
|
- "{{ db4_name }}"
|
||||||
|
@ -372,11 +384,12 @@
|
||||||
|
|
||||||
# ==========================================================================
|
# ==========================================================================
|
||||||
# Dump existing databases
|
# Dump existing databases
|
||||||
|
|
||||||
- name: Dump existing databases
|
- name: Dump existing databases
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db1_name }}'
|
- '{{ db1_name }}'
|
||||||
|
@ -386,13 +399,13 @@
|
||||||
target: '{{ dump1_file }}'
|
target: '{{ dump1_file }}'
|
||||||
register: dump_result
|
register: dump_result
|
||||||
|
|
||||||
- name: assert successful completion of dump operation
|
- name: Assert successful completion of dump operation (existing database)
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- dump_result.changed == true
|
- dump_result is changed
|
||||||
- dump_result.db_list == ['{{ db1_name }}', '{{ db2_name }}', '{{ db3_name }}']
|
- dump_result.db_list == ['{{ db1_name }}', '{{ db2_name }}', '{{ db3_name }}']
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: Run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
register: mysql_result
|
register: mysql_result
|
||||||
|
|
||||||
|
@ -403,7 +416,7 @@
|
||||||
- "'{{ db2_name }}' in mysql_result.stdout"
|
- "'{{ db2_name }}' in mysql_result.stdout"
|
||||||
- "'{{ db3_name }}' in mysql_result.stdout"
|
- "'{{ db3_name }}' in mysql_result.stdout"
|
||||||
|
|
||||||
- name: state dump - file name should exist
|
- name: State dump - file name should exist (dump1_file)
|
||||||
file:
|
file:
|
||||||
name: '{{ dump1_file }}'
|
name: '{{ dump1_file }}'
|
||||||
state: file
|
state: file
|
||||||
|
@ -429,7 +442,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: all
|
name: all
|
||||||
state: dump
|
state: dump
|
||||||
|
@ -439,7 +452,7 @@
|
||||||
- name: assert successful completion of dump operation
|
- name: assert successful completion of dump operation
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- dump_result.changed == true
|
- dump_result is changed
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
@ -454,7 +467,7 @@
|
||||||
- "'{{ db4_name }}' not in mysql_result.stdout"
|
- "'{{ db4_name }}' not in mysql_result.stdout"
|
||||||
- "'{{ db5_name }}' not in mysql_result.stdout"
|
- "'{{ db5_name }}' not in mysql_result.stdout"
|
||||||
|
|
||||||
- name: state dump - file name should exist
|
- name: state dump - file name should exist (dump2_file)
|
||||||
file:
|
file:
|
||||||
name: '{{ dump2_file }}'
|
name: '{{ dump2_file }}'
|
||||||
state: file
|
state: file
|
||||||
|
@ -467,7 +480,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db2_name }}'
|
- '{{ db2_name }}'
|
||||||
|
@ -479,7 +492,7 @@
|
||||||
- name: assert successful completion of delete databases which already exists using check mode
|
- name: assert successful completion of delete databases which already exists using check mode
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- check_mode_result.changed == true
|
- check_mode_result is changed
|
||||||
|
|
||||||
- name: run command to test state=absent for a database name
|
- name: run command to test state=absent for a database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
@ -497,7 +510,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db2_name }}'
|
- '{{ db2_name }}'
|
||||||
|
@ -508,7 +521,7 @@
|
||||||
- name: assert successful completion of deleting database
|
- name: assert successful completion of deleting database
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result.changed == true
|
- result is changed
|
||||||
- result.db_list == ['{{ db2_name }}', '{{ db3_name }}']
|
- result.db_list == ['{{ db2_name }}', '{{ db3_name }}']
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
|
@ -527,7 +540,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db2_name }}'
|
- '{{ db2_name }}'
|
||||||
|
@ -539,7 +552,7 @@
|
||||||
- name: assert that deletion of non existing databases does not make change (using check mode)
|
- name: assert that deletion of non existing databases does not make change (using check mode)
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- check_mode_result.changed == false
|
- check_mode_result is not changed
|
||||||
|
|
||||||
- name: run command to test state=absent for a database name
|
- name: run command to test state=absent for a database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
@ -557,7 +570,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db2_name }}'
|
- '{{ db2_name }}'
|
||||||
|
@ -568,7 +581,7 @@
|
||||||
- name: assert that deletion of non existing databases does not make change
|
- name: assert that deletion of non existing databases does not make change
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result.changed == false
|
- result is not changed
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
@ -586,7 +599,7 @@
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db1_name }}'
|
- '{{ db1_name }}'
|
||||||
|
@ -600,7 +613,7 @@
|
||||||
- name: assert successful completion of deleting database
|
- name: assert successful completion of deleting database
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result.changed == true
|
- result is changed
|
||||||
|
|
||||||
- name: run command to list databases like specified database name
|
- name: run command to list databases like specified database name
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'database%'\""
|
||||||
|
|
|
@ -17,81 +17,83 @@
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
- set_fact:
|
- name: Dump and Import | Set facts
|
||||||
|
set_fact:
|
||||||
db_file_name: "{{ tmp_dir }}/{{ file }}"
|
db_file_name: "{{ tmp_dir }}/{{ file }}"
|
||||||
wrong_sql_file: "{{ tmp_dir }}/wrong.sql"
|
wrong_sql_file: "{{ tmp_dir }}/wrong.sql"
|
||||||
dump_file1: "{{ tmp_dir }}/{{ file2 }}"
|
dump_file1: "{{ tmp_dir }}/{{ file2 }}"
|
||||||
dump_file2: "{{ tmp_dir }}/{{ file3 }}"
|
dump_file2: "{{ tmp_dir }}/{{ file3 }}"
|
||||||
db_user: "test"
|
db_user: "test"
|
||||||
db_user_unsafe_password: "pass!word"
|
db_user_unsafe_password: "pass!word"
|
||||||
config_file: "/root/.my.cnf"
|
config_file: "{{ playbook_dir }}/root/.my.cnf"
|
||||||
|
|
||||||
- name: create custom config file
|
- name: Dump and Import | Create custom config file
|
||||||
shell: 'echo "[client]" > {{ config_file }}'
|
shell: 'echo "[client]" > {{ config_file }}'
|
||||||
|
|
||||||
- name: create user for test unsafe_login_password parameter
|
- name: Dump and Import | Create user for test unsafe_login_password parameter
|
||||||
mysql_user:
|
mysql_user:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_user }}'
|
name: '{{ db_user }}'
|
||||||
|
host: '%'
|
||||||
password: '{{ db_user_unsafe_password }}'
|
password: '{{ db_user_unsafe_password }}'
|
||||||
priv: '*.*:ALL'
|
priv: '*.*:ALL'
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: state dump/import - create database
|
- name: Dump and Import | State dump/import - create database
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name }}'
|
name: '{{ db_name }}'
|
||||||
state: present
|
state: present
|
||||||
check_implicit_admin: yes
|
check_implicit_admin: yes
|
||||||
|
|
||||||
- name: create database
|
- name: Dump and Import | Create database
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name2 }}'
|
name: '{{ db_name2 }}'
|
||||||
state: present
|
state: present
|
||||||
check_implicit_admin: no
|
check_implicit_admin: no
|
||||||
|
|
||||||
- name: state dump/import - create table department
|
- name: Dump and Import | State dump/import - create table department
|
||||||
command: "{{ mysql_command }} {{ db_name }} \"-e create table department(id int, name varchar(100))\""
|
command: "{{ mysql_command }} {{ db_name }} \"-e create table department(id int, name varchar(100))\""
|
||||||
|
|
||||||
- name: state dump/import - create table employee
|
- name: Dump and Import | State dump/import - create table employee
|
||||||
command: "{{ mysql_command }} {{ db_name }} \"-e create table employee(id int, name varchar(100))\""
|
command: "{{ mysql_command }} {{ db_name }} \"-e create table employee(id int, name varchar(100))\""
|
||||||
|
|
||||||
- name: state dump/import - insert data into table employee
|
- name: Dump and Import | State dump/import - insert data into table employee
|
||||||
command: "{{ mysql_command }} {{ db_name }} \"-e insert into employee value(47,'Joe Smith')\""
|
command: "{{ mysql_command }} {{ db_name }} \"-e insert into employee value(47,'Joe Smith')\""
|
||||||
|
|
||||||
- name: state dump/import - insert data into table department
|
- name: Dump and Import | State dump/import - insert data into table department
|
||||||
command: "{{ mysql_command }} {{ db_name }} \"-e insert into department value(2,'Engineering')\""
|
command: "{{ mysql_command }} {{ db_name }} \"-e insert into department value(2,'Engineering')\""
|
||||||
|
|
||||||
- name: state dump/import - file name should not exist
|
- name: Dump and Import | State dump/import - file name should not exist
|
||||||
file:
|
file:
|
||||||
name: '{{ db_file_name }}'
|
name: '{{ db_file_name }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: database dump file1 should not exist
|
- name: Dump and Import | Database dump file1 should not exist
|
||||||
file:
|
file:
|
||||||
name: '{{ dump_file1 }}'
|
name: '{{ dump_file1 }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: database dump file2 should not exist
|
- name: Dump and Import | Database dump file2 should not exist
|
||||||
file:
|
file:
|
||||||
name: '{{ dump_file2 }}'
|
name: '{{ dump_file2 }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: state dump without department table.
|
- name: Dump and Import | State dump without department table.
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ db_user }}'
|
login_user: '{{ db_user }}'
|
||||||
login_password: '{{ db_user_unsafe_password }}'
|
login_password: '{{ db_user_unsafe_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
unsafe_login_password: yes
|
unsafe_login_password: yes
|
||||||
name: '{{ db_name }}'
|
name: '{{ db_name }}'
|
||||||
|
@ -102,28 +104,29 @@
|
||||||
force: yes
|
force: yes
|
||||||
master_data: 1
|
master_data: 1
|
||||||
skip_lock_tables: yes
|
skip_lock_tables: yes
|
||||||
dump_extra_args: --skip-triggers
|
dump_extra_args: >-
|
||||||
|
--skip-triggers
|
||||||
config_file: '{{ config_file }}'
|
config_file: '{{ config_file }}'
|
||||||
restrict_config_file: yes
|
restrict_config_file: yes
|
||||||
check_implicit_admin: no
|
check_implicit_admin: no
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
- name: assert successful completion of dump operation
|
- name: Dump and Import | Assert successful completion of dump operation
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result is changed
|
- result is changed
|
||||||
- result.executed_commands[0] is search("mysqldump --defaults-file={{ config_file }} --user={{ db_user }} --password=\*\*\*\*\*\*\*\* --force --host=127.0.0.1 --port={{ mysql_primary_port }} {{ db_name }} --skip-lock-tables --quick --ignore-table={{ db_name }}.department --master-data=1 --skip-triggers")
|
- result.executed_commands[0] is search(".department --master-data=1 --skip-triggers")
|
||||||
|
|
||||||
- name: state dump/import - file name should exist
|
- name: Dump and Import | State dump/import - file name should exist (db_file_name)
|
||||||
file:
|
file:
|
||||||
name: '{{ db_file_name }}'
|
name: '{{ db_file_name }}'
|
||||||
state: file
|
state: file
|
||||||
|
|
||||||
- name: state dump with multiple databases in comma separated form.
|
- name: Dump and Import | State dump with multiple databases in comma separated form for MySQL.
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: "{{ db_name }},{{ db_name2 }}"
|
name: "{{ db_name }},{{ db_name2 }}"
|
||||||
state: dump
|
state: dump
|
||||||
|
@ -131,22 +134,22 @@
|
||||||
check_implicit_admin: yes
|
check_implicit_admin: yes
|
||||||
register: dump_result1
|
register: dump_result1
|
||||||
|
|
||||||
- name: assert successful completion of dump operation (with multiple databases in comma separated form)
|
- name: Dump and Import | Assert successful completion of dump operation (with multiple databases in comma separated form)
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- dump_result1 is changed
|
- dump_result1 is changed
|
||||||
- dump_result1.executed_commands[0] is search(" --user=root --password=\*\*\*\*\*\*\*\*")
|
- dump_result1.executed_commands[0] is search(" --user=root --password=\*\*\*\*\*\*\*\*")
|
||||||
|
|
||||||
- name: state dump - dump file1 should exist
|
- name: Dump and Import | State dump - dump file1 should exist
|
||||||
file:
|
file:
|
||||||
name: '{{ dump_file1 }}'
|
name: '{{ dump_file1 }}'
|
||||||
state: file
|
state: file
|
||||||
|
|
||||||
- name: state dump with multiple databases in list form via check_mode
|
- name: Dump and Import | State dump with multiple databases in list form via check_mode
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db_name }}'
|
- '{{ db_name }}'
|
||||||
|
@ -156,26 +159,26 @@
|
||||||
register: dump_result
|
register: dump_result
|
||||||
check_mode: yes
|
check_mode: yes
|
||||||
|
|
||||||
- name: assert successful completion of dump operation (with multiple databases in list form) via check mode
|
- name: Dump and Import | Assert successful completion of dump operation (with multiple databases in list form) via check mode
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "dump_result.changed == true"
|
- dump_result is changed
|
||||||
|
|
||||||
- name: database dump file2 should not exist
|
- name: Dump and Import | Database dump file2 should not exist
|
||||||
stat:
|
stat:
|
||||||
path: '{{ dump_file2 }}'
|
path: '{{ dump_file2 }}'
|
||||||
register: stat_result
|
register: stat_result
|
||||||
|
|
||||||
- name: assert that check_mode does not create dump file for databases
|
- name: Dump and Import | Assert that check_mode does not create dump file for databases
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- stat_result.stat.exists is defined and not stat_result.stat.exists
|
- stat_result.stat.exists is defined and not stat_result.stat.exists
|
||||||
|
|
||||||
- name: state dump with multiple databases in list form.
|
- name: Dump and Import | State dump with multiple databases in list form.
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name:
|
name:
|
||||||
- '{{ db_name }}'
|
- '{{ db_name }}'
|
||||||
|
@ -184,39 +187,39 @@
|
||||||
target: '{{ dump_file2 }}'
|
target: '{{ dump_file2 }}'
|
||||||
register: dump_result2
|
register: dump_result2
|
||||||
|
|
||||||
- name: assert successful completion of dump operation (with multiple databases in list form)
|
- name: Dump and Import | Assert successful completion of dump operation (with multiple databases in list form)
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "dump_result2.changed == true"
|
- dump_result2 is changed
|
||||||
|
|
||||||
- name: state dump - dump file2 should exist
|
- name: Dump and Import | State dump - dump file2 should exist
|
||||||
file:
|
file:
|
||||||
name: '{{ dump_file2 }}'
|
name: '{{ dump_file2 }}'
|
||||||
state: file
|
state: file
|
||||||
|
|
||||||
- name: state dump/import - remove database
|
- name: Dump and Import | State dump/import - remove database
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name }}'
|
name: '{{ db_name }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: remove database
|
- name: Dump and Import | Remove database
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name2 }}'
|
name: '{{ db_name2 }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: test state=import to restore the database of type {{ format_type }} (expect changed=true)
|
- name: Dump and Import | Test state=import to restore the database of type {{ format_type }} (expect changed=true)
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ db_user }}'
|
login_user: '{{ db_user }}'
|
||||||
login_password: '{{ db_user_unsafe_password }}'
|
login_password: '{{ db_user_unsafe_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
unsafe_login_password: yes
|
unsafe_login_password: yes
|
||||||
name: '{{ db_name }}'
|
name: '{{ db_name }}'
|
||||||
|
@ -225,20 +228,20 @@
|
||||||
use_shell: yes
|
use_shell: yes
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
- name: show the tables
|
- name: Dump and Import | Show the tables
|
||||||
command: "{{ mysql_command }} {{ db_name }} \"-e show tables\""
|
command: "{{ mysql_command }} {{ db_name }} \"-e show tables\""
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
- name: assert that the department table is absent.
|
- name: Dump and Import | Assert that the department table is absent.
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "'department' not in result.stdout"
|
- "'department' not in result.stdout"
|
||||||
|
|
||||||
- name: test state=import to restore a database from multiple database dumped file1
|
- name: Dump and Import | Test state=import to restore a database from multiple database dumped file1
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name2 }}'
|
name: '{{ db_name2 }}'
|
||||||
state: import
|
state: import
|
||||||
|
@ -246,34 +249,34 @@
|
||||||
use_shell: no
|
use_shell: no
|
||||||
register: import_result
|
register: import_result
|
||||||
|
|
||||||
- name: assert output message restored a database from dump file1
|
- name: Dump and Import | Assert output message restored a database from dump file1
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "import_result.changed == true"
|
- import_result is changed
|
||||||
|
|
||||||
- name: remove database
|
- name: Dump and Import | Remove database
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name2 }}'
|
name: '{{ db_name2 }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: run command to list databases
|
- name: Dump and Import | Run command to list databases
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'data%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'data%'\""
|
||||||
register: mysql_result
|
register: mysql_result
|
||||||
|
|
||||||
- name: assert that db_name2 database does not exist
|
- name: Dump and Import | Assert that db_name2 database does not exist
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "'{{ db_name2 }}' not in mysql_result.stdout"
|
- "'{{ db_name2 }}' not in mysql_result.stdout"
|
||||||
|
|
||||||
- name: test state=import to restore a database from dumped file2 (check mode)
|
- name: Dump and Import | Test state=import to restore a database from dumped file2 (check mode)
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name2 }}'
|
name: '{{ db_name2 }}'
|
||||||
state: import
|
state: import
|
||||||
|
@ -281,96 +284,96 @@
|
||||||
register: check_import_result
|
register: check_import_result
|
||||||
check_mode: yes
|
check_mode: yes
|
||||||
|
|
||||||
- name: assert output message restored a database from dump file2 (check mode)
|
- name: Dump and Import | Assert output message restored a database from dump file2 (check mode)
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "check_import_result.changed == true"
|
- check_import_result is changed
|
||||||
|
|
||||||
- name: run command to list databases
|
- name: Dump and Import | Run command to list databases
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'data%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'data%'\""
|
||||||
register: mysql_result
|
register: mysql_result
|
||||||
|
|
||||||
- name: assert that db_name2 database does not exist (check mode)
|
- name: Dump and Import | Assert that db_name2 database does not exist (check mode)
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "'{{ db_name2 }}' not in mysql_result.stdout"
|
- "'{{ db_name2 }}' not in mysql_result.stdout"
|
||||||
|
|
||||||
- name: test state=import to restore a database from multiple database dumped file2
|
- name: Dump and Import | Test state=import to restore a database from multiple database dumped file2
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name2 }}'
|
name: '{{ db_name2 }}'
|
||||||
state: import
|
state: import
|
||||||
target: '{{ dump_file2 }}'
|
target: '{{ dump_file2 }}'
|
||||||
register: import_result2
|
register: import_result2
|
||||||
|
|
||||||
- name: assert output message restored a database from dump file2
|
- name: Dump and Import | Assert output message restored a database from dump file2
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- import_result2.changed == true
|
- import_result2 is changed
|
||||||
- import_result2.db_list == ['{{ db_name2 }}']
|
- import_result2.db_list == ['{{ db_name2 }}']
|
||||||
|
|
||||||
- name: run command to list databases
|
- name: Dump and Import | Run command to list databases
|
||||||
command: "{{ mysql_command }} \"-e show databases like 'data%'\""
|
command: "{{ mysql_command }} \"-e show databases like 'data%'\""
|
||||||
register: mysql_result
|
register: mysql_result
|
||||||
|
|
||||||
- name: assert that db_name2 database does exist after import
|
- name: Dump and Import | Assert that db_name2 database does exist after import
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "'{{ db_name2 }}' in mysql_result.stdout"
|
- "'{{ db_name2 }}' in mysql_result.stdout"
|
||||||
|
|
||||||
- name: test state=dump to backup the database of type {{ format_type }} (expect changed=true)
|
- name: Dump and Import | Test state=dump to backup the database of type {{ format_type }} (expect changed=true)
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name }}'
|
name: '{{ db_name }}'
|
||||||
state: dump
|
state: dump
|
||||||
target: '{{ db_file_name }}'
|
target: '{{ db_file_name }}'
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
- name: assert output message backup the database
|
- name: Dump and Import | Assert output message backup the database
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "result.changed == true"
|
- result is changed
|
||||||
- "result.db =='{{ db_name }}'"
|
- "result.db =='{{ db_name }}'"
|
||||||
|
|
||||||
# - name: assert database was backed up successfully
|
# - name: Dump and Import | Assert database was backed up successfully
|
||||||
# command: "file {{ db_file_name }}"
|
# command: "file {{ db_file_name }}"
|
||||||
# register: result
|
# register: result
|
||||||
#
|
#
|
||||||
# - name: assert file format type
|
# - name: Dump and Import | Assert file format type
|
||||||
# assert:
|
# assert:
|
||||||
# that:
|
# that:
|
||||||
# - "'{{ format_msg_type }}' in result.stdout"
|
# - "'{{ format_msg_type }}' in result.stdout"
|
||||||
|
|
||||||
- name: update database table employee
|
- name: Dump and Import | Update database table employee
|
||||||
command: "{{ mysql_command }} {{ db_name }} \"-e update employee set name='John Doe' where id=47\""
|
command: "{{ mysql_command }} {{ db_name }} \"-e update employee set name='John Doe' where id=47\""
|
||||||
|
|
||||||
- name: test state=import to restore the database of type {{ format_type }} (expect changed=true)
|
- name: Dump and Import | Test state=import to restore the database of type {{ format_type }} (expect changed=true)
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name }}'
|
name: '{{ db_name }}'
|
||||||
state: import
|
state: import
|
||||||
target: '{{ db_file_name }}'
|
target: '{{ db_file_name }}'
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
- name: assert output message restore the database
|
- name: Dump and Import | Assert output message restore the database
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "result.changed == true"
|
- result is changed
|
||||||
|
|
||||||
- name: select data from table employee
|
- name: Dump and Import | Select data from table employee
|
||||||
command: "{{ mysql_command }} {{ db_name }} \"-e select * from employee\""
|
command: "{{ mysql_command }} {{ db_name }} \"-e select * from employee\""
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
- name: assert data in database is from the restore database
|
- name: Dump and Import | Assert data in database is from the restore database
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "'47' in result.stdout"
|
- "'47' in result.stdout"
|
||||||
|
@ -380,14 +383,14 @@
|
||||||
# Test ``force`` parameter
|
# Test ``force`` parameter
|
||||||
##########################
|
##########################
|
||||||
|
|
||||||
- name: create wrong sql file
|
- name: Dump and Import | Create wrong sql file
|
||||||
shell: echo 'CREATE TABLE hello (id int); CREATE ELBAT ehlo (int id);' >> '{{ wrong_sql_file }}'
|
shell: echo 'CREATE TABLE hello (id int); CREATE ELBAT ehlo (int id);' >> '{{ wrong_sql_file }}'
|
||||||
|
|
||||||
- name: try to import without force parameter, must fail
|
- name: Dump and Import | Try to import without force parameter, must fail
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name }}'
|
name: '{{ db_name }}'
|
||||||
state: import
|
state: import
|
||||||
|
@ -398,13 +401,13 @@
|
||||||
|
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- result.failed == true
|
- result is failed
|
||||||
|
|
||||||
- name: try to import with force parameter
|
- name: Dump and Import | Try to import with force parameter
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name }}'
|
name: '{{ db_name }}'
|
||||||
state: import
|
state: import
|
||||||
|
@ -420,40 +423,24 @@
|
||||||
# Clean up
|
# Clean up
|
||||||
##########
|
##########
|
||||||
|
|
||||||
- name: remove database name
|
- name: Dump and Import | Clean up databases
|
||||||
mysql_db:
|
mysql_db:
|
||||||
login_user: '{{ mysql_user }}'
|
login_user: '{{ mysql_user }}'
|
||||||
login_password: '{{ mysql_password }}'
|
login_password: '{{ mysql_password }}'
|
||||||
login_host: 127.0.0.1
|
login_host: '{{ mysql_host }}'
|
||||||
login_port: '{{ mysql_primary_port }}'
|
login_port: '{{ mysql_primary_port }}'
|
||||||
name: '{{ db_name }}'
|
name: '{{ item }}'
|
||||||
state: absent
|
state: absent
|
||||||
|
loop:
|
||||||
|
- '{{ db_name }}'
|
||||||
|
- '{{ db_name2 }}'
|
||||||
|
|
||||||
- name: remove database
|
- name: Dump and Import | Clean up files
|
||||||
mysql_db:
|
|
||||||
login_user: '{{ mysql_user }}'
|
|
||||||
login_password: '{{ mysql_password }}'
|
|
||||||
login_host: 127.0.0.1
|
|
||||||
login_port: '{{ mysql_primary_port }}'
|
|
||||||
name: '{{ db_name2 }}'
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
- name: remove file name
|
|
||||||
file:
|
file:
|
||||||
name: '{{ db_file_name }}'
|
name: '{{ item }}'
|
||||||
state: absent
|
|
||||||
|
|
||||||
- name: remove file name
|
|
||||||
file:
|
|
||||||
name: '{{ wrong_sql_file }}'
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
- name: remove dump file1
|
|
||||||
file:
|
|
||||||
name: '{{ dump_file1 }}'
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
- name: remove dump file2
|
|
||||||
file:
|
|
||||||
name: '{{ dump_file2 }}'
|
|
||||||
state: absent
|
state: absent
|
||||||
|
loop:
|
||||||
|
- '{{ db_file_name }}'
|
||||||
|
- '{{ wrong_sql_file }}'
|
||||||
|
- '{{ dump_file1 }}'
|
||||||
|
- '{{ dump_file2 }}'
|
||||||
|
|
|
@ -0,0 +1,302 @@
|
||||||
|
---
|
||||||
|
# test code for mysql_db module with database name containing special chars
|
||||||
|
|
||||||
|
# This file is part of Ansible
|
||||||
|
#
|
||||||
|
# Ansible is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Ansible is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: State Present Absent | Remove database if it exists
|
||||||
|
command: >
|
||||||
|
"{{ mysql_command }} -sse 'DROP DATABASE IF EXISTS {{ db_name }}'"
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: State Present Absent | 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"
|
||||||
|
|
||||||
|
- name: State Present Absent | Test state=present for a database name (expect changed=true)
|
||||||
|
mysql_db:
|
||||||
|
login_user: '{{ mysql_user }}'
|
||||||
|
login_password: '{{ mysql_password }}'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: '{{ db_name }}'
|
||||||
|
state: present
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert output message that database exist
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.db == '{{ db_name }}'
|
||||||
|
- result.executed_commands == ["CREATE DATABASE `{{ db_name }}`"]
|
||||||
|
|
||||||
|
- name: State Present Absent | Run command to test state=present for a database name (expect db_name in stdout)
|
||||||
|
command: "{{ mysql_command }} -e \"show databases like '{{ db_name | regex_replace(\"([%_\\\\])\", \"\\\\\\1\") }}'\""
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert database exist
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'{{ db_name }}' in result.stdout"
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: State Present Absent | Test state=absent for a database name (expect changed=true)
|
||||||
|
mysql_db:
|
||||||
|
login_user: '{{ mysql_user }}'
|
||||||
|
login_password: '{{ mysql_password }}'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: '{{ db_name }}'
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | 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: State Present Absent | 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 | regex_replace(\"([%_\\\\])\", \"\\\\\\1\") }}'\""
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert database does not exist
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'{{ db_name }}' not in result.stdout"
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: State Present Absent | Test mysql_db encoding param not valid - issue 8075
|
||||||
|
mysql_db:
|
||||||
|
login_user: '{{ mysql_user }}'
|
||||||
|
login_password: '{{ mysql_password }}'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: datanotvalid
|
||||||
|
state: present
|
||||||
|
encoding: notvalid
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert test mysql_db encoding param not valid - issue 8075 (failed=true)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is failed
|
||||||
|
- "'Traceback' not in result.msg"
|
||||||
|
- "'Unknown character set' in result.msg"
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: State Present Absent | Test mysql_db using a valid encoding utf8 (expect changed=true)
|
||||||
|
mysql_db:
|
||||||
|
login_user: '{{ mysql_user }}'
|
||||||
|
login_password: '{{ mysql_password }}'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: 'en{{ db_name }}'
|
||||||
|
state: present
|
||||||
|
encoding: utf8
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert output message created a database
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.executed_commands == ["CREATE DATABASE `en{{ db_name }}` CHARACTER SET 'utf8'"]
|
||||||
|
|
||||||
|
- name: State Present Absent | Test database was created
|
||||||
|
command: "{{ mysql_command }} -e \"SHOW CREATE DATABASE `en{{ db_name }}`\""
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert created database is of encoding utf8
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'utf8' in result.stdout"
|
||||||
|
|
||||||
|
- name: State Present Absent | Remove database
|
||||||
|
mysql_db:
|
||||||
|
login_user: '{{ mysql_user }}'
|
||||||
|
login_password: '{{ mysql_password }}'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: 'en{{ db_name }}'
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: State Present Absent | Test mysql_db using valid encoding binary (expect changed=true)
|
||||||
|
mysql_db:
|
||||||
|
login_user: '{{ mysql_user }}'
|
||||||
|
login_password: '{{ mysql_password }}'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: 'en{{ db_name }}'
|
||||||
|
state: present
|
||||||
|
encoding: binary
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert output message that database was created
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.executed_commands == ["CREATE DATABASE `en{{ db_name }}` CHARACTER SET 'binary'"]
|
||||||
|
|
||||||
|
- name: State Present Absent | Run command to test database was created
|
||||||
|
command: "{{ mysql_command }} -e \"SHOW CREATE DATABASE `en{{ db_name }}`\""
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert created database is of encoding binary
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'binary' in result.stdout"
|
||||||
|
|
||||||
|
- name: State Present Absent | Remove database
|
||||||
|
mysql_db:
|
||||||
|
login_user: '{{ mysql_user }}'
|
||||||
|
login_password: '{{ mysql_password }}'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: 'en{{ db_name }}'
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: State Present Absent | Create user1 to access database dbuser1
|
||||||
|
mysql_user:
|
||||||
|
login_user: '{{ mysql_user }}'
|
||||||
|
login_password: '{{ mysql_password }}'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: user1
|
||||||
|
host: '%'
|
||||||
|
password: 'Hfd6fds^dfA8Ga'
|
||||||
|
priv: '*.*:ALL'
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: State Present Absent | Create database dbuser1 using user1
|
||||||
|
mysql_db:
|
||||||
|
login_user: user1
|
||||||
|
login_password: 'Hfd6fds^dfA8Ga'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: '{{ db_user1 }}'
|
||||||
|
state: present
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert output message that database was created
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: State Present Absent | Run command to test database was created using user1
|
||||||
|
command: "{{ mysql_command }} -e \"show databases like '{{ db_user1 | regex_replace(\"([%_\\\\])\", \"\\\\\\1\") }}'\""
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert database exist
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'{{ db_user1 }}' in result.stdout"
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: State Present Absent | Create user2 to access database with privilege select only
|
||||||
|
mysql_user:
|
||||||
|
login_user: '{{ mysql_user }}'
|
||||||
|
login_password: '{{ mysql_password }}'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: user2
|
||||||
|
password: 'kjsfd&F7safjad'
|
||||||
|
priv: '*.*:SELECT'
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: State Present Absent | Create database dbuser2 using user2 with no privilege to create (expect failed=true)
|
||||||
|
mysql_db:
|
||||||
|
login_user: user2
|
||||||
|
login_password: 'kjsfd&F7safjad'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: '{{ db_user2 }}'
|
||||||
|
state: present
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert output message that database was not created using dbuser2
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is failed
|
||||||
|
- "'Access denied' in result.msg"
|
||||||
|
|
||||||
|
- name: State Present Absent | Run command to test that database was not created
|
||||||
|
command: "{{ mysql_command }} -e \"show databases like '{{ db_user2 | regex_replace(\"([%_\\\\])\", \"\\\\\\1\") }}'\""
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert database does not exist
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'{{ db_user2 }}' not in result.stdout"
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: State Present Absent | Delete database using user2 with no privilege to delete (expect failed=true)
|
||||||
|
mysql_db:
|
||||||
|
login_user: user2
|
||||||
|
login_password: 'kjsfd&F7safjad'
|
||||||
|
login_host: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: '{{ db_user1 }}'
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert output message that database was not deleted using dbuser2
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is failed
|
||||||
|
- "'Access denied' in result.msg"
|
||||||
|
|
||||||
|
- name: State Present Absent | Run command to test database was not deleted
|
||||||
|
command: "{{ mysql_command }} -e \"show databases like '{{ db_user1 | regex_replace(\"([%_\\\\])\", \"\\\\\\1\") }}'\""
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert database still exist
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'{{ db_user1 }}' in result.stdout"
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
- name: State Present Absent | 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: '{{ mysql_host }}'
|
||||||
|
login_port: '{{ mysql_primary_port }}'
|
||||||
|
name: '{{ db_user1 }}'
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert output message that database was deleted using user1
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.executed_commands == ["DROP DATABASE `{{ db_user1 }}`"]
|
||||||
|
|
||||||
|
- name: State Present Absent | Run command to test database was deleted using user1
|
||||||
|
command: "{{ mysql_command }} -e \"show databases like '{{ db_name | regex_replace(\"([%_\\\\])\", \"\\\\\\1\") }}'\""
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: State Present Absent | Assert database does not exist
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'{{ db_user1 }}' not in result.stdout"
|
|
@ -2,7 +2,7 @@
|
||||||
# defaults file for test_mysql_info
|
# defaults file for test_mysql_info
|
||||||
mysql_user: root
|
mysql_user: root
|
||||||
mysql_password: msandbox
|
mysql_password: msandbox
|
||||||
mysql_host: 127.0.0.1
|
mysql_host: '{{ gateway_addr }}'
|
||||||
mysql_primary_port: 3307
|
mysql_primary_port: 3307
|
||||||
|
|
||||||
db_name: data
|
db_name: data
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
---
|
||||||
dependencies:
|
dependencies:
|
||||||
- setup_mysql
|
- setup_controller
|
||||||
- setup_remote_tmp_dir
|
- setup_remote_tmp_dir
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue