diff --git a/.github/workflows/ansible-test-plugins.yml b/.github/workflows/ansible-test-plugins.yml index 7e5c33d..da79c04 100644 --- a/.github/workflows/ansible-test-plugins.yml +++ b/.github/workflows/ansible-test-plugins.yml @@ -61,7 +61,7 @@ jobs: - stable-2.9 - stable-2.10 - stable-2.11 - - devel + #- devel python: - 3.6 connector: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 88207e9..edcfe55 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,200 +1,3 @@ # 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. - -If you are a committer, also refer to the [Ansible committer guidelines](https://docs.ansible.com/ansible/devel/community/committer_guidelines.html). - -## 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. +Refer to the [Ansible Contributing guidelines](https://github.com/ansible/community-docs/blob/main/contributing.rst) to learn how to contribute to this collection. diff --git a/CONTRIBUTORS b/CONTRIBUTORS new file mode 100644 index 0000000..718caa2 --- /dev/null +++ b/CONTRIBUTORS @@ -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 diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 0000000..c520538 --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1,3 @@ +bmalynovytch +Jorge-Rodriguez +Andersson007 (andersson007_ in #ansible-community IRC) diff --git a/MAINTAINING.md b/MAINTAINING.md new file mode 100644 index 0000000..9fad0d3 --- /dev/null +++ b/MAINTAINING.md @@ -0,0 +1,3 @@ +# Maintaining this collection + +Refer to the [Maintainer guidelines](https://github.com/ansible/community-docs/blob/main/maintaining.rst). diff --git a/README.md b/README.md index b1bd9d2..8d1349e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,46 @@ # MySQL collection for Ansible [![Plugins CI](https://github.com/ansible-collections/community.mysql/workflows/Plugins%20CI/badge.svg?event=push)](https://github.com/ansible-collections/community.mysql/actions?query=workflow%3A"Plugins+CI") [![Roles CI](https://github.com/ansible-collections/community.mysql/workflows/Roles%20CI/badge.svg?event=push)](https://github.com/ansible-collections/community.mysql/actions?query=workflow%3A"Roles+CI") [![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.mysql)](https://codecov.io/gh/ansible-collections/community.mysql) +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). + +## Communication + +We announce releases and important changes through Ansible's [The Bullhorn newsletter](https://eepurl.com/gZmiEP). Be sure you are subscribed. + +Join us in the `#ansible` (general use questions and support), `#ansible-community` (community and collection development questions), and other [IRC channels](https://docs.ansible.com/ansible/devel/community/communication.html#irc-channels) on [Libera.Chat](https://libera.chat). + +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 - **Modules**: @@ -20,7 +60,7 @@ ## External requirements -The MySQL modules rely on a MySQL connector. The list of supported drivers is below: +The MySQL modules rely on a MySQL connector. The list of supported drivers is below: - [PyMySQL](https://github.com/PyMySQL/PyMySQL) - [MySQLdb](https://github.com/PyMySQL/mysqlclient-python) @@ -44,12 +84,20 @@ collections: - 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. -## Contributing - -See the [contribution guide](CONTRIBUTING.md). - ## Licensing diff --git a/REVIEW_CHECKLIST.md b/REVIEW_CHECKLIST.md index 3ea3440..9dccf7e 100644 --- a/REVIEW_CHECKLIST.md +++ b/REVIEW_CHECKLIST.md @@ -1,38 +1,3 @@ # 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 +Refer to the [Collection review checklist](https://github.com/ansible/community-docs/blob/main/review_checklist.rst). diff --git a/changelogs/CHANGELOG.rst b/changelogs/CHANGELOG.rst index a80c771..e2ed3e6 100644 --- a/changelogs/CHANGELOG.rst +++ b/changelogs/CHANGELOG.rst @@ -5,6 +5,78 @@ Community MySQL Collection Release Notes .. contents:: Topics +v2.1.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`` 2.1.0. + +Minor Changes +------------- + +- mysql_query - correctly reflect changed status in replace statements (https://github.com/ansible-collections/community.mysql/pull/193). + +v2.1.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`` 2.0.0. + +Major Changes +------------- + +- mysql_replication - add deprecation warning that the ``Is_Slave`` and ``Is_Master`` return values will be replaced with ``Is_Primary`` and ``Is_Replica`` in ``community.mysql`` 3.0.0 (https://github.com/ansible-collections/community.mysql/pull/147). +- mysql_replication - the choices of the ``state`` option containing ``master`` will be finally replaced with the alternative ``primary`` choices in ``community.mysql`` 3.0.0, add deprecation warnings (https://github.com/ansible-collections/community.mysql/pull/150). + +Minor Changes +------------- + +- mysql_replication - add alternative (``primary``) choices to the ``state`` option choices containing ``master`` (https://github.com/ansible-collections/community.mysql/pull/150). +- mysql_replication - add the ``Is_Primary`` and ``Is_Replica`` alternatives to the ``Is_Slave`` and ``Is_Master`` return values as a preparation for replacement in ``community.mysql`` 3.0.0 (https://github.com/ansible-collections/community.mysql/pull/147). +- mysql_replication - change ``master_`` options to ``primary_`` options, add aliases to keep compatibility (https://github.com/ansible-collections/community.mysql/pull/150). + +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). + +v2.0.0 +====== + +Release Summary +--------------- + +This is release 2.0.0 of the ``community.mysql`` collection, released on 2021-04-15. + +Major Changes +------------- + +- mysql_replication - the return value ``Is_Slave`` and ``Is_Master`` will be replaced with ``Is_Replica`` and ``Is_Primary`` in ``community.mysql`` 3.0.0 (https://github.com/ansible-collections/community.mysql/issues/145). +- mysql_replication - the word ``master`` in messages returned by the module will be replaced with ``primary`` in ``community.mysql`` 3.0.0 (https://github.com/ansible-collections/community.mysql/issues/145). +- mysql_replication - the word ``slave`` in messages returned by the module replaced with ``replica`` (https://github.com/ansible-collections/community.mysql/issues/98). +- 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 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index c163341..497e740 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -235,3 +235,79 @@ releases: - 107-mysql_user_fix_grant_on_col_handling.yml - 97-mysql_replication_deprecate_offending_terminology.yml release_date: '2021-03-08' + 2.0.0: + changes: + bugfixes: + - mysql_user - add support for ``REPLICA MONITOR`` privilege (https://github.com/ansible-collections/community.mysql/issues/105). + major_changes: + - mysql_replication - the return value ``Is_Slave`` and ``Is_Master`` will be + replaced with ``Is_Replica`` and ``Is_Primary`` in ``community.mysql`` 3.0.0 + (https://github.com/ansible-collections/community.mysql/issues/145). + - mysql_replication - the word ``master`` in messages returned by the module + will be replaced with ``primary`` in ``community.mysql`` 3.0.0 (https://github.com/ansible-collections/community.mysql/issues/145). + - mysql_replication - the word ``slave`` in messages returned by the module + replaced with ``replica`` (https://github.com/ansible-collections/community.mysql/issues/98). + - 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 release 2.0.0 of the ``community.mysql`` collection, + released on 2021-04-15. + fragments: + - 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 + - 144-mysql_replication_remove_slave_from_messages.yml + - 2.0.0.yml + release_date: '2021-04-15' + 2.1.0: + 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). + major_changes: + - mysql_replication - add deprecation warning that the ``Is_Slave`` and ``Is_Master`` + return values will be replaced with ``Is_Primary`` and ``Is_Replica`` in ``community.mysql`` + 3.0.0 (https://github.com/ansible-collections/community.mysql/pull/147). + - mysql_replication - the choices of the ``state`` option containing ``master`` + will be finally replaced with the alternative ``primary`` choices in ``community.mysql`` + 3.0.0, add deprecation warnings (https://github.com/ansible-collections/community.mysql/pull/150). + minor_changes: + - mysql_replication - add alternative (``primary``) choices to the ``state`` + option choices containing ``master`` (https://github.com/ansible-collections/community.mysql/pull/150). + - mysql_replication - add the ``Is_Primary`` and ``Is_Replica`` alternatives + to the ``Is_Slave`` and ``Is_Master`` return values as a preparation for replacement + in ``community.mysql`` 3.0.0 (https://github.com/ansible-collections/community.mysql/pull/147). + - mysql_replication - change ``master_`` options to ``primary_`` options, add + aliases to keep compatibility (https://github.com/ansible-collections/community.mysql/pull/150). + 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`` 2.0.0.' + fragments: + - 147-mysql_replication_deprecate_ret_vals.yml + - 150-mysql_replication_master_related.yml + - 153-mysql_revert_connector_changes.yml + release_date: '2021-04-23' + 2.1.1: + 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`` 2.1.0.' + fragments: + - 193-reflect_changed_status_in_replace_statements.yml + - 2.1.1.yml + release_date: '2021-08-11' diff --git a/changelogs/fragments/101-drop-requiressl-support.yml b/changelogs/fragments/101-drop-requiressl-support.yml deleted file mode 100644 index fded3e3..0000000 --- a/changelogs/fragments/101-drop-requiressl-support.yml +++ /dev/null @@ -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). diff --git a/changelogs/fragments/103-mysql_and_mariadb_divergence.yml b/changelogs/fragments/103-mysql_and_mariadb_divergence.yml deleted file mode 100644 index 039c654..0000000 --- a/changelogs/fragments/103-mysql_and_mariadb_divergence.yml +++ /dev/null @@ -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). diff --git a/changelogs/fragments/108-mysql_priv_add_grant.yml b/changelogs/fragments/108-mysql_priv_add_grant.yml deleted file mode 100644 index 4cfd00e..0000000 --- a/changelogs/fragments/108-mysql_priv_add_grant.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- mysql_user - add support for ``REPLICA MONITOR`` privilege (https://github.com/ansible-collections/community.mysql/issues/105). diff --git a/changelogs/fragments/115-add_mysql_full_version_suffix_return_var.yml b/changelogs/fragments/115-add_mysql_full_version_suffix_return_var.yml deleted file mode 100644 index 3eadb46..0000000 --- a/changelogs/fragments/115-add_mysql_full_version_suffix_return_var.yml +++ /dev/null @@ -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). diff --git a/changelogs/fragments/116-change_deprecated_connection_ parameters.yml b/changelogs/fragments/116-change_deprecated_connection_ parameters.yml deleted file mode 100644 index d6b0d7e..0000000 --- a/changelogs/fragments/116-change_deprecated_connection_ parameters.yml +++ /dev/null @@ -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). \ No newline at end of file diff --git a/changelogs/fragments/144-mysql_replication_remove_slave_from_messages.yml b/changelogs/fragments/144-mysql_replication_remove_slave_from_messages.yml deleted file mode 100644 index e88691e..0000000 --- a/changelogs/fragments/144-mysql_replication_remove_slave_from_messages.yml +++ /dev/null @@ -1,4 +0,0 @@ -major_changes: -- mysql_replication - the word ``slave`` in messages returned by the module replaced with ``replica`` (https://github.com/ansible-collections/community.mysql/issues/98). -- mysql_replication - the return value ``Is_Slave`` and ``Is_Master`` will be replaced with ``Is_Replica`` and ``Is_Primary`` in ``community.mysql`` 3.0.0 (https://github.com/ansible-collections/community.mysql/issues/145). -- mysql_replication - the word ``master`` in messages returned by the module will be replaced with ``primary`` in ``community.mysql`` 3.0.0 (https://github.com/ansible-collections/community.mysql/issues/145). diff --git a/galaxy.yml b/galaxy.yml index dad76b9..3e6d8ff 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: community name: mysql -version: 1.3.0 +version: 2.1.1 readme: README.md authors: - Ansible community diff --git a/plugins/doc_fragments/mysql.py b/plugins/doc_fragments/mysql.py index 6d7a546..b7a9152 100644 --- a/plugins/doc_fragments/mysql.py +++ b/plugins/doc_fragments/mysql.py @@ -67,7 +67,7 @@ options: - 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. - Requires pymysql >= 0.7.11. - - This optoin has no effect on MySQLdb. + - This option has no effect on MySQLdb. type: bool version_added: '1.1.0' requirements: diff --git a/plugins/module_utils/mysql.py b/plugins/module_utils/mysql.py index 67e0033..5af9c20 100644 --- a/plugins/module_utils/mysql.py +++ b/plugins/module_utils/mysql.py @@ -79,7 +79,7 @@ def mysql_connect(module, login_user=None, login_password=None, config_file='', if login_user is not None: config['user'] = login_user if login_password is not None: - config['password'] = login_password + config['passwd'] = login_password if ssl_cert is not None: config['ssl']['cert'] = ssl_cert if ssl_key is not None: @@ -87,7 +87,7 @@ def mysql_connect(module, login_user=None, login_password=None, config_file='', if ssl_ca is not None: config['ssl']['ca'] = ssl_ca if db is not None: - config['database'] = db + config['db'] = db if connect_timeout is not None: config['connect_timeout'] = connect_timeout if check_hostname is not None: diff --git a/plugins/modules/mysql_query.py b/plugins/modules/mysql_query.py index ed3ace4..fc789c5 100644 --- a/plugins/modules/mysql_query.py +++ b/plugins/modules/mysql_query.py @@ -112,7 +112,7 @@ from ansible_collections.community.mysql.plugins.module_utils.mysql import ( ) 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: DDL_QUERY_KEYWORDS = ('CREATE', 'DROP', 'ALTER', 'RENAME', 'TRUNCATE') diff --git a/plugins/modules/mysql_replication.py b/plugins/modules/mysql_replication.py index e81ef17..12dffc4 100644 --- a/plugins/modules/mysql_replication.py +++ b/plugins/modules/mysql_replication.py @@ -15,7 +15,7 @@ DOCUMENTATION = r''' module: mysql_replication short_description: Manage MySQL replication description: -- Manages MySQL server replication, replica, master status, get and change master host. +- Manages MySQL server replication, replica, primary status, get and change primary host. author: - Balazs Pocze (@banyek) - Andrew Klychkov (@Andersson007) @@ -23,17 +23,19 @@ options: mode: description: - Module operating mode. Could be - C(changemaster) (CHANGE MASTER TO), - C(getmaster) (SHOW MASTER STATUS), + C(changeprimary | changemaster) (CHANGE PRIMARY | MASTER TO), + C(getprimary | getmaster) (SHOW PRIMARY | MASTER STATUS), C(getreplica | getslave) (SHOW REPLICA | SLAVE STATUS), C(startreplica | startslave) (START REPLICA | SLAVE), C(stopreplica | stopslave) (STOP REPLICA | SLAVE), - C(resetmaster) (RESET MASTER) - supported since community.mysql 0.1.0, + C(resetprimary | resetmaster) (RESET PRIMARY | MASTER) - supported since community.mysql 0.1.0, C(resetreplica, resetslave) (RESET REPLICA | SLAVE), C(resetreplicaall, resetslave) (RESET REPLICA | SLAVE ALL). type: str choices: + - changeprimary - changemaster + - getprimary - getmaster - getreplica - getslave @@ -41,40 +43,48 @@ options: - startslave - stopreplica - stopslave + - resetprimary - resetmaster - resetreplica - resetslave - resetreplicaall - resetslaveall default: getreplica - master_host: + primary_host: description: - - Same as mysql variable. + - Same as the C(MASTER_HOST) mysql variable. type: str - master_user: + aliases: [master_host] + primary_user: description: - - Same as mysql variable. + - Same as the C(MASTER_USER) mysql variable. type: str - master_password: + aliases: [master_user] + primary_password: description: - - Same as mysql variable. + - Same as the C(MASTER_PASSWORD) mysql variable. type: str - master_port: + aliases: [master_password] + primary_port: description: - - Same as mysql variable. + - Same as the C(MASTER_PORT) mysql variable. type: int - master_connect_retry: + aliases: [master_port] + primary_connect_retry: description: - - Same as mysql variable. + - Same as the C(MASTER_CONNECT_RETRY) mysql variable. type: int - master_log_file: + aliases: [master_connect_retry] + primary_log_file: description: - - Same as mysql variable. + - Same as the C(MASTER_LOG_FILE) mysql variable. type: str - master_log_pos: + aliases: [master_log_file] + primary_log_pos: description: - - Same as mysql variable. + - Same as the C(MASTER_LOG_POS) mysql variable. type: int + aliases: [master_log_pos] relay_log_file: description: - Same as mysql variable. @@ -83,7 +93,7 @@ options: description: - Same as mysql variable. type: int - master_ssl: + primary_ssl: description: - Same as the C(MASTER_SSL) mysql variable. - When setting it to C(yes), the connection attempt only succeeds @@ -92,43 +102,51 @@ options: L(MySQL encrypted replication documentation,https://dev.mysql.com/doc/refman/8.0/en/replication-solutions-encrypted-connections.html). type: bool default: false - master_ssl_ca: + aliases: [master_ssl] + primary_ssl_ca: description: - Same as the C(MASTER_SSL_CA) mysql variable. - For details, refer to L(MySQL encrypted replication documentation,https://dev.mysql.com/doc/refman/8.0/en/replication-solutions-encrypted-connections.html). type: str - master_ssl_capath: + aliases: [master_ssl_ca] + primary_ssl_capath: description: - Same as the C(MASTER_SSL_CAPATH) mysql variable. - For details, refer to L(MySQL encrypted replication documentation,https://dev.mysql.com/doc/refman/8.0/en/replication-solutions-encrypted-connections.html). type: str - master_ssl_cert: + aliases: [master_ssl_capath] + primary_ssl_cert: description: - Same as the C(MASTER_SSL_CERT) mysql variable. - For details, refer to L(MySQL encrypted replication documentation,https://dev.mysql.com/doc/refman/8.0/en/replication-solutions-encrypted-connections.html). type: str - master_ssl_key: + aliases: [master_ssl_cert] + primary_ssl_key: description: - Same as the C(MASTER_SSL_KEY) mysql variable. - For details, refer to L(MySQL encrypted replication documentation,https://dev.mysql.com/doc/refman/8.0/en/replication-solutions-encrypted-connections.html). type: str - master_ssl_cipher: + aliases: [master_ssl_key] + primary_ssl_cipher: description: - Same as the C(MASTER_SSL_CIPHER) mysql variable. - Specifies a colon-separated list of one or more ciphers permitted by the replica for the replication connection. - For details, refer to L(MySQL encrypted replication documentation,https://dev.mysql.com/doc/refman/8.0/en/replication-solutions-encrypted-connections.html). type: str - master_auto_position: + aliases: [master_ssl_cipher] + primary_auto_position: description: - Whether the host uses GTID based replication or not. + - Same as the C(MASTER_AUTO_POSITION) mysql variable. type: bool default: false - master_use_gtid: + aliases: [master_auto_position] + primary_use_gtid: description: - Configures the replica to use the MariaDB Global Transaction ID. - C(disabled) equals MASTER_USE_GTID=no command. @@ -140,16 +158,19 @@ options: choices: [current_pos, replica_pos, slave_pos, disabled] type: str version_added: '0.1.0' - master_delay: + aliases: [master_use_gtid] + primary_delay: description: - - Time lag behind the master's state (in seconds). + - Time lag behind the primary's state (in seconds). + - Same as the C(MASTER_DELAY) mysql variable. - Available from MySQL 5.6. - For more information see U(https://dev.mysql.com/doc/refman/8.0/en/replication-delayed.html). type: int version_added: '0.1.0' + aliases: [master_delay] connection_name: description: - - Name of the master connection. + - Name of the primary connection. - Supported from MariaDB 10.0.1. - Mutually exclusive with I(channel). - For more information see U(https://mariadb.com/kb/en/library/multi-source-replication/). @@ -195,16 +216,16 @@ EXAMPLES = r''' community.mysql.mysql_replication: mode: stopreplica -- name: Get master binlog file name and binlog position +- name: Get primary binlog file name and binlog position community.mysql.mysql_replication: - mode: getmaster + mode: getprimary -- name: Change master to master server 192.0.2.1 and use binary log 'mysql-bin.000009' with position 4578 +- name: Change primary to primary server 192.0.2.1 and use binary log 'mysql-bin.000009' with position 4578 community.mysql.mysql_replication: - mode: changemaster - master_host: 192.0.2.1 - master_log_file: mysql-bin.000009 - master_log_pos: 4578 + mode: changeprimary + primary_host: 192.0.2.1 + primary_log_file: mysql-bin.000009 + primary_log_pos: 4578 - name: Check replica status using port 3308 community.mysql.mysql_replication: @@ -212,42 +233,42 @@ EXAMPLES = r''' login_host: ansible.example.com login_port: 3308 -- name: On MariaDB change master to use GTID current_pos +- name: On MariaDB change primary to use GTID current_pos community.mysql.mysql_replication: - mode: changemaster - master_use_gtid: current_pos + mode: changeprimary + primary_use_gtid: current_pos -- name: Change master to use replication delay 3600 seconds +- name: Change primary to use replication delay 3600 seconds community.mysql.mysql_replication: - mode: changemaster - master_host: 192.0.2.1 - master_delay: 3600 + mode: changeprimary + primary_host: 192.0.2.1 + primary_delay: 3600 -- name: Start MariaDB replica with connection name master-1 +- name: Start MariaDB replica with connection name primary-1 community.mysql.mysql_replication: mode: startreplica - connection_name: master-1 + connection_name: primary-1 -- name: Stop replication in channel master-1 +- name: Stop replication in channel primary-1 community.mysql.mysql_replication: mode: stopreplica - channel: master-1 + channel: primary-1 - name: > Run RESET MASTER command which will delete all existing binary log files - and reset the binary log index file on the master + and reset the binary log index file on the primary community.mysql.mysql_replication: - mode: resetmaster + mode: resetprimary - name: Run start replica and fail the task on errors community.mysql.mysql_replication: mode: startreplica - connection_name: master-1 + connection_name: primary-1 fail_on_error: yes -- name: Change master and fail on error (like when replica thread is running) +- name: Change primary and fail on error (like when replica thread is running) community.mysql.mysql_replication: - mode: changemaster + mode: changeprimary fail_on_error: yes ''' @@ -257,7 +278,7 @@ queries: description: List of executed queries which modified DB's state. returned: always type: list - sample: ["CHANGE MASTER TO MASTER_HOST='master2.example.com',MASTER_PORT=3306"] + sample: ["CHANGE MASTER TO MASTER_HOST='primary2.example.com',MASTER_PORT=3306"] version_added: '0.1.0' ''' @@ -277,10 +298,13 @@ from distutils.version import LooseVersion executed_queries = [] -def get_master_status(cursor): +def get_primary_status(cursor): + # TODO: when it's available to change on MySQL's side, + # change MASTER to PRIMARY using the approach from + # get_replica_status() function. Same for other functions. cursor.execute("SHOW MASTER STATUS") - masterstatus = cursor.fetchone() - return masterstatus + primarystatus = cursor.fetchone() + return primarystatus def get_replica_status(cursor, connection_name='', channel='', term='REPLICA'): @@ -363,7 +387,7 @@ def reset_replica_all(module, cursor, connection_name='', channel='', fail_on_er return reset -def reset_master(module, cursor, fail_on_error=False): +def reset_primary(module, cursor, fail_on_error=False): query = 'RESET MASTER' try: executed_queries.append(query) @@ -400,7 +424,7 @@ def start_replica(module, cursor, connection_name='', channel='', fail_on_error= return started -def changemaster(cursor, chm, connection_name='', channel=''): +def changeprimary(cursor, chm, connection_name='', channel=''): if connection_name: query = "CHANGE MASTER '%s' TO %s" % (connection_name, ','.join(chm)) else: @@ -417,29 +441,33 @@ def main(): argument_spec = mysql_common_argument_spec() argument_spec.update( mode=dict(type='str', default='getreplica', choices=[ - 'getmaster', 'getreplica', 'getslave', 'changemaster', - 'stopreplica', 'stopslave', 'startreplica', 'startslave', - 'resetmaster', 'resetreplica', 'resetslave', + 'getprimary', 'getmaster', + 'getreplica', 'getslave', + 'changeprimary', 'changemaster', + 'stopreplica', 'stopslave', + 'startreplica', 'startslave', + 'resetprimary', 'resetmaster', + 'resetreplica', 'resetslave', 'resetreplicaall', 'resetslaveall']), - master_auto_position=dict(type='bool', default=False), - master_host=dict(type='str'), - master_user=dict(type='str'), - master_password=dict(type='str', no_log=True), - master_port=dict(type='int'), - master_connect_retry=dict(type='int'), - master_log_file=dict(type='str'), - master_log_pos=dict(type='int'), + primary_auto_position=dict(type='bool', default=False, aliases=['master_auto_position']), + primary_host=dict(type='str', aliases=['master_host']), + primary_user=dict(type='str', aliases=['master_user']), + primary_password=dict(type='str', no_log=True, aliases=['master_password']), + primary_port=dict(type='int', aliases=['master_port']), + primary_connect_retry=dict(type='int', aliases=['master_connect_retry']), + primary_log_file=dict(type='str', aliases=['master_log_file']), + primary_log_pos=dict(type='int', aliases=['master_log_pos']), relay_log_file=dict(type='str'), relay_log_pos=dict(type='int'), - master_ssl=dict(type='bool', default=False), - master_ssl_ca=dict(type='str'), - master_ssl_capath=dict(type='str'), - master_ssl_cert=dict(type='str'), - master_ssl_key=dict(type='str', no_log=False), - master_ssl_cipher=dict(type='str'), - master_use_gtid=dict(type='str', choices=[ - 'current_pos', 'replica_pos', 'slave_pos', 'disabled']), - master_delay=dict(type='int'), + primary_ssl=dict(type='bool', default=False, aliases=['master_ssl']), + primary_ssl_ca=dict(type='str', aliases=['master_ssl_ca']), + primary_ssl_capath=dict(type='str', aliases=['master_ssl_capath']), + primary_ssl_cert=dict(type='str', aliases=['master_ssl_cert']), + primary_ssl_key=dict(type='str', no_log=False, aliases=['master_ssl_key']), + primary_ssl_cipher=dict(type='str', aliases=['master_ssl_cipher']), + primary_use_gtid=dict(type='str', choices=[ + 'current_pos', 'replica_pos', 'slave_pos', 'disabled'], aliases=['master_use_gtid']), + primary_delay=dict(type='int', aliases=['master_delay']), connection_name=dict(type='str'), channel=dict(type='str'), fail_on_error=dict(type='bool', default=False), @@ -451,33 +479,33 @@ def main(): ], ) mode = module.params["mode"] - master_host = module.params["master_host"] - master_user = module.params["master_user"] - master_password = module.params["master_password"] - master_port = module.params["master_port"] - master_connect_retry = module.params["master_connect_retry"] - master_log_file = module.params["master_log_file"] - master_log_pos = module.params["master_log_pos"] + primary_host = module.params["primary_host"] + primary_user = module.params["primary_user"] + primary_password = module.params["primary_password"] + primary_port = module.params["primary_port"] + primary_connect_retry = module.params["primary_connect_retry"] + primary_log_file = module.params["primary_log_file"] + primary_log_pos = module.params["primary_log_pos"] relay_log_file = module.params["relay_log_file"] relay_log_pos = module.params["relay_log_pos"] - master_ssl = module.params["master_ssl"] - master_ssl_ca = module.params["master_ssl_ca"] - master_ssl_capath = module.params["master_ssl_capath"] - master_ssl_cert = module.params["master_ssl_cert"] - master_ssl_key = module.params["master_ssl_key"] - master_ssl_cipher = module.params["master_ssl_cipher"] - master_auto_position = module.params["master_auto_position"] + primary_ssl = module.params["primary_ssl"] + primary_ssl_ca = module.params["primary_ssl_ca"] + primary_ssl_capath = module.params["primary_ssl_capath"] + primary_ssl_cert = module.params["primary_ssl_cert"] + primary_ssl_key = module.params["primary_ssl_key"] + primary_ssl_cipher = module.params["primary_ssl_cipher"] + primary_auto_position = module.params["primary_auto_position"] ssl_cert = module.params["client_cert"] ssl_key = module.params["client_key"] ssl_ca = module.params["ca_cert"] check_hostname = module.params["check_hostname"] connect_timeout = module.params['connect_timeout'] config_file = module.params['config_file'] - master_delay = module.params['master_delay'] - if module.params.get("master_use_gtid") == 'disabled': - master_use_gtid = 'no' + primary_delay = module.params['primary_delay'] + if module.params.get("primary_use_gtid") == 'disabled': + primary_use_gtid = 'no' else: - master_use_gtid = module.params["master_use_gtid"] + primary_use_gtid = module.params["primary_use_gtid"] connection_name = module.params["connection_name"] channel = module.params['channel'] fail_on_error = module.params['fail_on_error'] @@ -512,21 +540,35 @@ def main(): # "REPLICA" must be used instead of "SLAVE" if impl.uses_replica_terminology(cursor): replica_term = 'REPLICA' - if master_use_gtid == 'slave_pos': - module.deprecate('master_use_gtid "slave_pos" value is deprecated, use "replica_pos" instead.', + if primary_use_gtid == 'slave_pos': + module.deprecate('primary_use_gtid | master_use_gtid "slave_pos" value is ' + 'deprecated, use "replica_pos" instead.', version='3.0.0', collection_name='community.mysql') - master_use_gtid = 'replica_pos' + primary_use_gtid = 'replica_pos' else: replica_term = 'SLAVE' - if master_use_gtid == 'replica_pos': - master_use_gtid = 'slave_pos' + if primary_use_gtid == 'replica_pos': + primary_use_gtid = 'slave_pos' - if mode in "getmaster": - status = get_master_status(cursor) + if mode in ('getprimary', 'getmaster'): + if mode == 'getmaster': + module.deprecate('"getmaster" option is deprecated, use "getprimary" instead.', + version='3.0.0', collection_name='community.mysql') + + status = get_primary_status(cursor) if not isinstance(status, dict): - status = dict(Is_Master=False, msg="Server is not configured as mysql master") + # TODO: change the word master to primary in 3.0.0 + status = dict(Is_Master=False, Is_Primary=False, + msg="Server is not configured as mysql master") else: status['Is_Master'] = True + status['Is_Primary'] = True + + module.deprecate('"Is_Master" and "Is_Slave" return values are deprecated ' + 'and will be replaced with "Is_Primary" and "Is_Replica" ' + 'in the next major release. Use "Is_Primary" and "Is_Replica" instead.', + version='3.0.0', collection_name='community.mysql') + module.exit_json(queries=executed_queries, **status) elif mode in ("getreplica", "getslave"): @@ -536,56 +578,62 @@ def main(): status = get_replica_status(cursor, connection_name, channel, replica_term) if not isinstance(status, dict): - # TODO: announce it and replace with Replica - # in the next major release. Maybe a warning? - status = dict(Is_Slave=False, msg="Server is not configured as mysql replica") + status = dict(Is_Slave=False, Is_Replica=False, msg="Server is not configured as mysql replica") else: - # TODO: announce it and replace with Replica - # in the next major release. Maybe a warning? status['Is_Slave'] = True + status['Is_Replica'] = True + + module.deprecate('"Is_Master" and "Is_Slave" return values are deprecated ' + 'and will be replaced with "Is_Primary" and "Is_Replica" ' + 'in the next major release. Use "Is_Primary" and "Is_Replica" instead.', + version='3.0.0', collection_name='community.mysql') + module.exit_json(queries=executed_queries, **status) - elif mode in "changemaster": + elif mode in ('changeprimary', 'changemaster'): + if mode == 'changemaster': + module.deprecate('"changemaster" option is deprecated, use "changeprimary" instead.', + version='3.0.0', collection_name='community.mysql') chm = [] result = {} - if master_host is not None: - chm.append("MASTER_HOST='%s'" % master_host) - if master_user is not None: - chm.append("MASTER_USER='%s'" % master_user) - if master_password is not None: - chm.append("MASTER_PASSWORD='%s'" % master_password) - if master_port is not None: - chm.append("MASTER_PORT=%s" % master_port) - if master_connect_retry is not None: - chm.append("MASTER_CONNECT_RETRY=%s" % master_connect_retry) - if master_log_file is not None: - chm.append("MASTER_LOG_FILE='%s'" % master_log_file) - if master_log_pos is not None: - chm.append("MASTER_LOG_POS=%s" % master_log_pos) - if master_delay is not None: - chm.append("MASTER_DELAY=%s" % master_delay) + if primary_host is not None: + chm.append("MASTER_HOST='%s'" % primary_host) + if primary_user is not None: + chm.append("MASTER_USER='%s'" % primary_user) + if primary_password is not None: + chm.append("MASTER_PASSWORD='%s'" % primary_password) + if primary_port is not None: + chm.append("MASTER_PORT=%s" % primary_port) + if primary_connect_retry is not None: + chm.append("MASTER_CONNECT_RETRY=%s" % primary_connect_retry) + if primary_log_file is not None: + chm.append("MASTER_LOG_FILE='%s'" % primary_log_file) + if primary_log_pos is not None: + chm.append("MASTER_LOG_POS=%s" % primary_log_pos) + if primary_delay is not None: + chm.append("MASTER_DELAY=%s" % primary_delay) if relay_log_file is not None: chm.append("RELAY_LOG_FILE='%s'" % relay_log_file) if relay_log_pos is not None: chm.append("RELAY_LOG_POS=%s" % relay_log_pos) - if master_ssl: + if primary_ssl: chm.append("MASTER_SSL=1") - if master_ssl_ca is not None: - chm.append("MASTER_SSL_CA='%s'" % master_ssl_ca) - if master_ssl_capath is not None: - chm.append("MASTER_SSL_CAPATH='%s'" % master_ssl_capath) - if master_ssl_cert is not None: - chm.append("MASTER_SSL_CERT='%s'" % master_ssl_cert) - if master_ssl_key is not None: - chm.append("MASTER_SSL_KEY='%s'" % master_ssl_key) - if master_ssl_cipher is not None: - chm.append("MASTER_SSL_CIPHER='%s'" % master_ssl_cipher) - if master_auto_position: + if primary_ssl_ca is not None: + chm.append("MASTER_SSL_CA='%s'" % primary_ssl_ca) + if primary_ssl_capath is not None: + chm.append("MASTER_SSL_CAPATH='%s'" % primary_ssl_capath) + if primary_ssl_cert is not None: + chm.append("MASTER_SSL_CERT='%s'" % primary_ssl_cert) + if primary_ssl_key is not None: + chm.append("MASTER_SSL_KEY='%s'" % primary_ssl_key) + if primary_ssl_cipher is not None: + chm.append("MASTER_SSL_CIPHER='%s'" % primary_ssl_cipher) + if primary_auto_position: chm.append("MASTER_AUTO_POSITION=1") - if master_use_gtid is not None: - chm.append("MASTER_USE_GTID=%s" % master_use_gtid) + if primary_use_gtid is not None: + chm.append("MASTER_USE_GTID=%s" % primary_use_gtid) try: - changemaster(cursor, chm, connection_name, channel) + changeprimary(cursor, chm, connection_name, channel) except mysql_driver.Warning as e: result['warning'] = to_native(e) except Exception as e: @@ -612,11 +660,17 @@ def main(): module.exit_json(msg="Replica stopped", changed=True, queries=executed_queries) else: module.exit_json(msg="Replica already stopped", changed=False, queries=executed_queries) - elif mode in "resetmaster": - reset = reset_master(module, cursor, fail_on_error) + elif mode in ('resetprimary', 'resetmaster'): + if mode == 'resetmaster': + module.deprecate('"resetmaster" option is deprecated, use "resetprimary" instead.', + version='3.0.0', collection_name='community.mysql') + + reset = reset_primary(module, cursor, fail_on_error) if reset is True: + # TODO: Change "Master" to "Primary" in release 3.0.0 module.exit_json(msg="Master reset", changed=True, queries=executed_queries) else: + # TODO: Change "Master" to "Primary" in release 3.0.0 module.exit_json(msg="Master already reset", changed=False, queries=executed_queries) elif mode in ("resetreplica", "resetslave"): if mode == "resetslave": diff --git a/plugins/modules/mysql_user.py b/plugins/modules/mysql_user.py index b39b11a..38c1a55 100644 --- a/plugins/modules/mysql_user.py +++ b/plugins/modules/mysql_user.py @@ -53,6 +53,7 @@ options: the module will always report changes. It includes grouping columns by permission (C(SELECT(col1,col2)) instead of C(SELECT(col1),SELECT(col2))). - Can be passed as a dictionary (see the examples). + - Supports GRANTs for procedures and functions (see the examples). type: raw append_privs: description: @@ -188,6 +189,15 @@ EXAMPLES = r''' 'db1.*': '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. # Setting this privilege in this manner is deprecated. # Use 'tls_requires' instead. diff --git a/tests/integration/targets/test_mysql_query/defaults/main.yml b/tests/integration/targets/test_mysql_query/defaults/main.yml index 51a3bd7..4ee25ff 100644 --- a/tests/integration/targets/test_mysql_query/defaults/main.yml +++ b/tests/integration/targets/test_mysql_query/defaults/main.yml @@ -7,6 +7,7 @@ test_db: testdb test_table1: test1 test_table2: test2 test_table3: test3 +test_table4: test4 test_script_path: /tmp/test.sql user_name_1: 'db_user1' diff --git a/tests/integration/targets/test_mysql_query/tasks/mysql_query_initial.yml b/tests/integration/targets/test_mysql_query/tasks/mysql_query_initial.yml index b01de55..30182fe 100644 --- a/tests/integration/targets/test_mysql_query/tasks/mysql_query_initial.yml +++ b/tests/integration/targets/test_mysql_query/tasks/mysql_query_initial.yml @@ -289,6 +289,38 @@ - result is failed - result.msg is search('the elements in query list must be strings') + - name: Create {{ test_table4 }} + mysql_query: + <<: *mysql_params + login_db: '{{ test_db }}' + query: 'CREATE TABLE {{ test_table4 }} (id int primary key, story text)' + + - name: Insert test data using replace statement + mysql_query: + <<: *mysql_params + login_db: '{{ test_db }}' + query: "REPLACE INTO {{ test_table4 }} VALUES (1, 'first')" + single_transaction: yes + register: result + + - assert: + that: + - result is changed + - result.rowcount == [1] + + - name: Replace test data + mysql_query: + <<: *mysql_params + login_db: '{{ test_db }}' + query: "REPLACE INTO {{ test_table4 }} VALUES (1, 'one')" + single_transaction: yes + register: result + + - assert: + that: + - result is changed + - result.rowcount == [2] + - name: Drop db {{ test_db }} mysql_query: <<: *mysql_params diff --git a/tests/integration/targets/test_mysql_replication/defaults/main.yml b/tests/integration/targets/test_mysql_replication/defaults/main.yml index fefcf29..d2d2080 100644 --- a/tests/integration/targets/test_mysql_replication/defaults/main.yml +++ b/tests/integration/targets/test_mysql_replication/defaults/main.yml @@ -7,7 +7,7 @@ mysql_replica2_port: 3309 test_db: test_db test_table: test_table -test_master_delay: 60 +test_primary_delay: 60 replication_user: replication_user replication_pass: replication_pass dump_path: /tmp/dump.sql diff --git a/tests/integration/targets/test_mysql_replication/tasks/issue-28.yml b/tests/integration/targets/test_mysql_replication/tasks/issue-28.yml index c666820..7943e35 100644 --- a/tests/integration/targets/test_mysql_replication/tasks/issue-28.yml +++ b/tests/integration/targets/test_mysql_replication/tasks/issue-28.yml @@ -36,7 +36,7 @@ - name: attempt connection with newly created user (expect failure) mysql_replication: - mode: getmaster + mode: getprimary login_user: '{{ user_name_1 }}' login_password: '{{ user_password_1 }}' login_host: 127.0.0.1 @@ -57,7 +57,7 @@ - name: attempt connection with newly created user ignoring hostname mysql_replication: - mode: getmaster + mode: getprimary login_user: '{{ user_name_1 }}' login_password: '{{ user_password_1 }}' login_host: 127.0.0.1 diff --git a/tests/integration/targets/test_mysql_replication/tasks/main.yml b/tests/integration/targets/test_mysql_replication/tasks/main.yml index 239598a..d4c7150 100644 --- a/tests/integration/targets/test_mysql_replication/tasks/main.yml +++ b/tests/integration/targets/test_mysql_replication/tasks/main.yml @@ -9,13 +9,13 @@ # Initial CI tests of mysql_replication module: - import_tasks: mysql_replication_initial.yml -# Tests of master_delay parameter: -- import_tasks: mysql_replication_master_delay.yml +# Tests of primary_delay parameter: +- import_tasks: mysql_replication_primary_delay.yml # Tests of channel parameter: - import_tasks: mysql_replication_channel.yml -# Tests of resetmaster mode: -- import_tasks: mysql_replication_resetmaster_mode.yml +# Tests of resetprimary mode: +- import_tasks: mysql_replication_resetprimary_mode.yml - include: issue-28.yml diff --git a/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_channel.yml b/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_channel.yml index 1bbc1bc..e314aae 100644 --- a/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_channel.yml +++ b/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_channel.yml @@ -8,26 +8,26 @@ login_host: 127.0.0.1 block: - # Get master log file and log pos: - - name: Get master status + # Get primary log file and log pos: + - name: Get primary status mysql_replication: <<: *mysql_params login_port: '{{ mysql_primary_port }}' - mode: getmaster + mode: getprimary register: mysql_primary_status - # Test changemaster mode: + # Test changeprimary mode: - name: Run replication with channel mysql_replication: <<: *mysql_params login_port: '{{ mysql_replica2_port }}' - mode: changemaster - master_host: '{{ mysql_host }}' - master_port: '{{ mysql_primary_port }}' - master_user: '{{ replication_user }}' - master_password: '{{ replication_pass }}' - master_log_file: '{{ mysql_primary_status.File }}' - master_log_pos: '{{ mysql_primary_status.Position }}' + mode: changeprimary + primary_host: '{{ mysql_host }}' + primary_port: '{{ mysql_primary_port }}' + primary_user: '{{ replication_user }}' + primary_password: '{{ replication_pass }}' + primary_log_file: '{{ mysql_primary_status.File }}' + primary_log_pos: '{{ mysql_primary_status.Position }}' channel: '{{ test_channel }}' register: result @@ -61,7 +61,7 @@ - assert: that: - - replica_status.Is_Slave == true + - replica_status.Is_Replica == true - replica_status.Master_Host == '{{ mysql_host }}' - replica_status.Exec_Master_Log_Pos == mysql_primary_status.Position - replica_status.Master_Port == {{ mysql_primary_port }} @@ -73,7 +73,7 @@ - assert: that: - - replica_status.Is_Slave == true + - replica_status.Is_Replica == true - replica_status.Source_Host == '{{ mysql_host }}' - replica_status.Exec_Source_Log_Pos == mysql_primary_status.Position - replica_status.Source_Port == {{ mysql_primary_port }} diff --git a/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_initial.yml b/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_initial.yml index 4e90707..c80bae4 100644 --- a/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_initial.yml +++ b/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_initial.yml @@ -49,22 +49,22 @@ - name: Restore the dump to replica2 shell: '{{ mysql_command }} -P{{ mysql_replica2_port }} < {{ dump_path }}' - # Test getmaster mode: - - name: Get master status + # Test getprimary mode: + - name: Get primary status mysql_replication: <<: *mysql_params login_port: '{{ mysql_primary_port }}' - mode: getmaster + mode: getprimary register: mysql_primary_status - assert: that: - - mysql_primary_status.Is_Master == true + - mysql_primary_status.Is_Primary == true - mysql_primary_status.Position != 0 - mysql_primary_status is not changed - # Test startreplica fails without changemaster first. This needs fail_on_error - - name: Start replica (using deprecated startslave choice) and fail because master is not specified; failing on error as requested + # Test startreplica fails without changeprimary first. This needs fail_on_error + - name: Start replica (using deprecated startslave choice) and fail because primary is not specified; failing on error as requested mysql_replication: <<: *mysql_params login_port: '{{ mysql_replica1_port }}' @@ -103,21 +103,21 @@ that: - result is not failed - # Test changemaster mode: - # master_ssl_ca will be set as '' to check the module's behaviour for #23976, + # Test changeprimary mode: + # primary_ssl_ca will be set as '' to check the module's behaviour for #23976, # must be converted to an empty string - name: Run replication mysql_replication: <<: *mysql_params login_port: '{{ mysql_replica1_port }}' - mode: changemaster - master_host: '{{ mysql_host }}' - master_port: '{{ mysql_primary_port }}' - master_user: '{{ replication_user }}' - master_password: '{{ replication_pass }}' - master_log_file: '{{ mysql_primary_status.File }}' - master_log_pos: '{{ mysql_primary_status.Position }}' - master_ssl_ca: '' + mode: changeprimary + primary_host: '{{ mysql_host }}' + primary_port: '{{ mysql_primary_port }}' + primary_user: '{{ replication_user }}' + primary_password: '{{ replication_pass }}' + primary_log_file: '{{ mysql_primary_status.File }}' + primary_log_pos: '{{ mysql_primary_status.Position }}' + primary_ssl_ca: '' register: result - assert: @@ -148,7 +148,7 @@ - assert: that: - - replica_status.Is_Slave == true + - replica_status.Is_Replica == true - replica_status.Master_Host == '{{ mysql_host }}' - replica_status.Exec_Master_Log_Pos == mysql_primary_status.Position - replica_status.Master_Port == {{ mysql_primary_port }} @@ -179,7 +179,7 @@ pause: seconds: 2 - # Test master log pos has been changed: + # Test primary log pos has been changed: - name: Get replica status mysql_replication: <<: *mysql_params diff --git a/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_master_delay.yml b/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_primary_delay.yml similarity index 84% rename from tests/integration/targets/test_mysql_replication/tasks/mysql_replication_master_delay.yml rename to tests/integration/targets/test_mysql_replication/tasks/mysql_replication_primary_delay.yml index 94a10b2..ecdcc81 100644 --- a/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_master_delay.yml +++ b/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_primary_delay.yml @@ -9,13 +9,13 @@ block: - # Test master_delay mode: + # Test primary_delay mode: - name: Run replication mysql_replication: <<: *mysql_params login_port: '{{ mysql_replica1_port }}' - mode: changemaster - master_delay: '{{ test_master_delay }}' + mode: changeprimary + primary_delay: '{{ test_primary_delay }}' register: result - assert: @@ -31,7 +31,7 @@ mode: startreplica register: result - # Check master_delay: + # Check primary_delay: - name: Get standby status mysql_replication: <<: *mysql_params @@ -41,5 +41,5 @@ - assert: that: - - replica_status.SQL_Delay == {{ test_master_delay }} + - replica_status.SQL_Delay == {{ test_primary_delay }} - replica_status is not changed diff --git a/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_resetmaster_mode.yml b/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_resetprimary_mode.yml similarity index 83% rename from tests/integration/targets/test_mysql_replication/tasks/mysql_replication_resetmaster_mode.yml rename to tests/integration/targets/test_mysql_replication/tasks/mysql_replication_resetprimary_mode.yml index 223e325..a4ed75e 100644 --- a/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_resetmaster_mode.yml +++ b/tests/integration/targets/test_mysql_replication/tasks/mysql_replication_resetprimary_mode.yml @@ -22,20 +22,20 @@ login_port: '{{ mysql_replica1_port }}' mode: resetreplicaall - # Get master initial status: - - name: Get master status + # Get primary initial status: + - name: Get primary status mysql_replication: <<: *mysql_params login_port: '{{ mysql_primary_port }}' - mode: getmaster + mode: getprimary register: mysql_primary_initial_status - # Test resetmaster mode: - - name: Reset master + # Test resetprimary mode: + - name: Reset primary mysql_replication: <<: *mysql_params login_port: '{{ mysql_primary_port }}' - mode: resetmaster + mode: resetprimary register: result - assert: @@ -43,12 +43,12 @@ - result is changed - result.queries == ["RESET MASTER"] - # Get master final status: - - name: Get master status + # Get primary final status: + - name: Get primary status mysql_replication: <<: *mysql_params login_port: '{{ mysql_primary_port }}' - mode: getmaster + mode: getprimary register: mysql_primary_final_status - assert: