diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:03:01 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:03:01 +0000 |
commit | a453ac31f3428614cceb99027f8efbdb9258a40b (patch) | |
tree | f61f87408f32a8511cbd91799f9cececb53e0374 /collections-debian-merged/ansible_collections/community/mongodb | |
parent | Initial commit. (diff) | |
download | ansible-upstream.tar.xz ansible-upstream.zip |
Adding upstream version 2.10.7+merged+base+2.10.8+dfsg.upstream/2.10.7+merged+base+2.10.8+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'collections-debian-merged/ansible_collections/community/mongodb')
192 files changed, 14203 insertions, 0 deletions
diff --git a/collections-debian-merged/ansible_collections/community/mongodb/.github/CODEOWNERS b/collections-debian-merged/ansible_collections/community/mongodb/.github/CODEOWNERS new file mode 100644 index 00000000..9a8248a8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/.github/CODEOWNERS @@ -0,0 +1,10 @@ +.github + +# Repo maintainers, and goverance team (like Anisble's @ansible-commit-external) +#* @rrey @seuf @gundalow-collections/community-goverance-team + +# or possibly, we may want to define teams at the org level. +# * @gundalow-collections/grafana-maintainers + +# Example of maintainer of just a single plugin +#grafana/plugins/modules/grafana_plugin.py @someone-else diff --git a/collections-debian-merged/ansible_collections/community/mongodb/.github/settings.yml b/collections-debian-merged/ansible_collections/community/mongodb/.github/settings.yml new file mode 100644 index 00000000..b026fe10 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/.github/settings.yml @@ -0,0 +1,89 @@ +### +# https://probot.github.io/apps/settings/ +# + +# DO NOT MODIFY +# this is a copy of https://github.com/gundalow-collection/.github/blob/master/.github/settings.yml +# Work around till https://github.com/probot/settings/pull/179 is merged + + + +repository: + # See https://developer.github.com/v3/repos/#edit for all available settings. + has_issues: true + has_wiki: false + has_pages: false + default_branch: master + allow_squash_merge: true + allow_merge_commit: false + allow_rebase_merge: true + +# Labels: define labels for Issues and Pull Requests +labels: + - name: bug + color: fbca04 + description: This issue/PR relates to a bug. + - name: feature + description: This issue/PR relates to a feature request. + color: 006b75 + - name: migrated_from_ansible_ansible + color: 5319e7 + description: This issue/PR was moved from gh/ansible/ansible + +branches: + - name: devel + # https://developer.github.com/v3/repos/branches/#update-branch-protection + # Branch Protection settings. Set to null to disable + protection: + # Required. Require at least one approving review on a pull request, before merging. Set to null to disable. + required_pull_request_reviews: + # The number of approvals required. (1-6) + required_approving_review_count: 1 + # Dismiss approved reviews automatically when a new commit is pushed. + dismiss_stale_reviews: true + # Blocks merge until code owners have reviewed. + require_code_owner_reviews: true + # Specify which users and teams can dismiss pull request reviews. Pass an empty dismissal_restrictions object to disable. User and team dismissal_restrictions are only available for organization-owned repositories. Omit this parameter for personal repositories. + dismissal_restrictions: + users: [] + teams: [] + # Required. Require status checks to pass before merging. Set to null to disable + required_status_checks: + # Required. Require branches to be up to date before merging. + strict: true + # Required. The list of status checks to require in order to merge into this branch + contexts: [] + # Required. Enforce all configured restrictions for administrators. Set to true to enforce required status checks for repository administrators. Set to null to disable. + enforce_admins: true + # Required. Restrict who can push to this branch. Team and user restrictions are only available for organization-owned repositories. Set to null to disable. + restrictions: + users: null + teams: null + - name: master + # https://developer.github.com/v3/repos/branches/#update-branch-protection + # Branch Protection settings. Set to null to disable + protection: + # Required. Require at least one approving review on a pull request, before merging. Set to null to disable. + required_pull_request_reviews: + # The number of approvals required. (1-6) + required_approving_review_count: 1 + # Dismiss approved reviews automatically when a new commit is pushed. + dismiss_stale_reviews: true + # Blocks merge until code owners have reviewed. + require_code_owner_reviews: true + # Specify which users and teams can dismiss pull request reviews. Pass an empty dismissal_restrictions object to disable. User and team dismissal_restrictions are only available for organization-owned repositories. Omit this parameter for personal repositories. + dismissal_restrictions: + users: [] + teams: [] + # Required. Require status checks to pass before merging. Set to null to disable + required_status_checks: + # Required. Require branches to be up to date before merging. + strict: true + # Required. The list of status checks to require in order to merge into this branch + contexts: [] + # Required. Enforce all configured restrictions for administrators. Set to true to enforce required status checks for repository administrators. Set to null to disable. + enforce_admins: true + # Required. Restrict who can push to this branch. Team and user restrictions are only available for organization-owned repositories. Set to null to disable. + restrictions: + users: null + teams: null diff --git a/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/ansible-test.yml b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/ansible-test.yml new file mode 100644 index 00000000..0cc49ce0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/ansible-test.yml @@ -0,0 +1,157 @@ +name: CI +on: + pull_request: + schedule: + - cron: "0 3 * * *" + +env: + mongodb_version_file: "./tests/integration/targets/setup_mongodb/defaults/main.yml" + +jobs: + sanity: + runs-on: ubuntu-20.04 + defaults: + run: + working-directory: ansible_collections/community/mongodb + steps: + + - name: Check out code + uses: actions/checkout@v2 + with: + path: ansible_collections/community/mongodb + + - name: Set up Python 3.6 + uses: actions/setup-python@v1 + with: + python-version: 3.6 + + - name: Install ansible-base (devel) + uses: nick-invision/retry@v2 + with: + timeout_minutes: 3 + max_attempts: 3 + command: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check + + - name: Run sanity tests + run: ansible-test sanity --docker -v --color --python 3.6 --exclude docs/* + + units: + runs-on: ubuntu-20.04 + defaults: + run: + working-directory: ansible_collections/community/mongodb + steps: + - name: Check out code + uses: actions/checkout@v2 + with: + path: ansible_collections/community/mongodb + + - name: Set up Python 3.6 + uses: actions/setup-python@v1 + with: + python-version: 3.6 + + - name: Install ansible-base (devel) + uses: nick-invision/retry@v2 + with: + timeout_minutes: 3 + max_attempts: 3 + command: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check + + - name: Run unit tests + run: ansible-test units --docker -v --color --python 3.6 --coverage + + - name: Generate coverage report. + run: ansible-test coverage xml -v --requirements --group-by command --group-by version + + - uses: codecov/codecov-action@v1 + with: + fail_ci_if_error: false + + integration_matrix: + runs-on: ubuntu-20.04 + defaults: + run: + working-directory: ansible_collections/community/mongodb + outputs: + matrix: ${{ steps.json-list.outputs.modules-to-test }} + + steps: + + - name: Check out code + uses: actions/checkout@v2 + with: + path: ansible_collections/community/mongodb + + - name: Generate module list + run: | + find tests/integration/targets -type d -maxdepth 1 -not -name 'setup*' | cut -d '/' -f4 | sort | awk NF | jq -sRc 'split("\n") | map(select(length > 0))' > int_test_modules.json + + - name: Set output variable + id: json-list + run: | + output=$(cat int_test_modules.json) + echo "::set-output name=modules-to-test::$output" + echo "$output" + + integration: + needs: integration_matrix + runs-on: ubuntu-20.04 + defaults: + run: + working-directory: ansible_collections/community/mongodb + strategy: + matrix: + python_version: + - "3.6" + mongodb_version: + - "4.2" + - "4.4" + mongodb_module: ${{ fromJson(needs.integration_matrix.outputs.matrix) }} + docker_image: + - ubuntu1804 + - centos8 + ansible_version: + - stable-2.10 + - devel + steps: + + - name: Check out code + uses: actions/checkout@v2 + with: + path: ansible_collections/community/mongodb + + - name: Set up Python ${{ matrix.python_version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python_version }} + + - name: Install ansible-base (${{ matrix.ansible_version }}) + uses: nick-invision/retry@v2 + with: + timeout_minutes: 3 + max_attempts: 3 + command: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check + + - name: Install community.general + uses: nick-invision/retry@v2 + with: + timeout_minutes: 3 + max_attempts: 3 + command: ansible-galaxy collection install community.general -p ansible_collections/ + + - name: Install community.crypto + uses: nick-invision/retry@v2 + with: + timeout_minutes: 3 + max_attempts: 3 + command: ansible-galaxy collection install community.crypto -p ansible_collections/ + + - name: Ensure MongoDB version is set to ${{ matrix.mongodb_version }} + run: "sed -i 's/^mongodb_version:.*/mongodb_version: \"${{ matrix.mongodb_version }}\"/g' ${{ env.mongodb_version_file }}" + + - name: Run integration tests on Python ${{ matrix.python_version }} | ${{ matrix.docker_image }} | ${{ matrix.ansible_version }} | ${{ matrix.mongodb_version }} + run: ansible-test integration --docker ${{ matrix.docker_image }} -v --color --retry-on-error --python ${{ matrix.python_version }} --continue-on-error --diff --coverage ${{ matrix.mongodb_module }} + + - name: Upload Coverage data + run: tests/coverage.sh diff --git a/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/documentation.yml b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/documentation.yml new file mode 100644 index 00000000..634eab20 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/documentation.yml @@ -0,0 +1,85 @@ +name: documentation + +on: + push: + branches: + - master + +jobs: + publish: + runs-on: ubuntu-20.04 + defaults: + run: + working-directory: ansible_collections/community/mongodb + steps: + + - name: Checkout + uses: actions/checkout@v2 + with: + path: ansible_collections/community/mongodb + + - name: Set up Python 3.6 + uses: actions/setup-python@v1 + with: + python-version: 3.6 + + - name: Install ansible-base (devel) + run: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check + + - name: Build collection + run: ansible-galaxy collection build . + + - name: Install collection + run: ansible-galaxy collection install community-mongodb-*.tar.gz + + - name: Install ansible-doc-extractor + run: pip install wheel setuptools ansible-doc-extractor --upgrade + + - name: Install rstdoc + run: pip install -v rstdoc + + - name: Create docs dir + run: mkdir -p docs/{lookup,cache} + + - name: Create rst files from modules + run: ansible-doc-extractor ./docs plugins/modules/mongodb_*.py + + - name: Create rst files from lookup + run: ansible-doc-extractor ./docs/lookup plugins/lookup/mongodb*.py + + - name: Create rst files from cache + run: ansible-doc-extractor ./docs/cache plugins/cache/mongodb*.py + + - name: Create collection index document + run: | + echo "# MongoDB Ansible Collection Documentation" > docs/index.md + echo "## Modules" >> docs/index.md + find plugins/modules -type f -name 'mongodb_*.py' -exec bash -c 'echo "- [$(basename "{}" ".py")]($(basename {} .py).html)"' \; >> docs/index.md + echo "## Lookup" >> docs/index.md + find plugins/lookup -type f -name 'mongodb*.py' -exec bash -c 'echo "- [$(basename "{}" ".py")](lookup/$(basename {} .py).html)"' \; >> docs/index.md + echo "## Cache" >> docs/index.md + find plugins/cache -type f -name 'mongodb*.py' -exec bash -c 'echo "- [$(basename "{}" ".py")](cache/$(basename {} .py).html)"' \; >> docs/index.md + + - name: Create module html documents from rst files + run: | + find ./docs -type f -name 'mongodb_*.rst' -maxdepth 1 -exec bash -c 'rstdoc {} "docs/$(basename "{}" ".rst").html" rst_html' \; + + - name: Create lookup html documents from rst files + run: | + find ./docs/lookup -type f -name 'mongodb*.rst' -maxdepth 1 -exec bash -c 'rstdoc {} "docs/lookup/$(basename "{}" ".rst").html" rst_html' \; + + - name: Create cache html documents from rst files + run: | + find ./docs/cache -type f -name 'mongodb*.rst' -maxdepth 1 -exec bash -c 'rstdoc {} "docs/cache/$(basename "{}" ".rst").html" rst_html' \; + + - name: Remove intermediary rst docs + run: find docs/ -name '*.rst' -delete + + - name: Deploy + if: success() + uses: crazy-max/ghaction-github-pages@v1 + with: + target_branch: gh-pages + build_dir: ansible_collections/community/mongodb/docs + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/mongodb-cache.yml b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/mongodb-cache.yml new file mode 100644 index 00000000..5432260d --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/mongodb-cache.yml @@ -0,0 +1,304 @@ +name: CI +on: + pull_request: + schedule: + - cron: "0 3 * * *" + +jobs: + mongodb-cache: + runs-on: ubuntu-20.04 + defaults: + run: + working-directory: ansible_collections/community/mongodb + env: + ANSIBLE_CACHE_PLUGIN: "community.mongodb.mongodb" + ANSIBLE_CACHE_PLUGIN_CONNECTION: "mongodb://mongoadmin:secret@localhost:27017/cache?authSource=admin" + ANSIBLE_CACHE_PLUGIN_TIMEOUT: 0 + strategy: + matrix: + python_version: + - "3.5" + - "3.8" + ansible_version: + - stable-2.10 + - devel + steps: + + - name: Check out code + uses: actions/checkout@v2 + with: + path: ansible_collections/community/mongodb + + - name: Set up Python 3.6 + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python_version }} + + - name: Install ansible-base (${{ matrix.ansible_version }}) + uses: nick-invision/retry@v2 + with: + timeout_minutes: 3 + max_attempts: 3 + command: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check + + - name: Build the collection + run: ansible-galaxy collection build + + - name: Rename the build artifact + run: mv community-mongodb-*.tar.gz community-mongodb-latest.tar.gz + + - name: Install collection + run: ansible-galaxy collection install community-mongodb-*.tar.gz + + - name: Create docker volume + run: docker volume create mongocache + + - name: Run the mongodb cache inside a docker container + run: + docker run -d --name mongocache -e MONGO_INITDB_ROOT_USERNAME=mongoadmin + -e MONGO_INITDB_ROOT_PASSWORD=secret -p 27017:27017 + -v mongocache:/data/db mongo:latest + + - name: Install mongodb-org-shell + uses: nick-invision/retry@v2 + with: + timeout_minutes: 3 + max_attempts: 3 + command: sudo apt-get install mongodb-org-shell + + # https://github.community/t/set-output-truncates-multiline-strings/16852/5 + - name: Run ansible without pymongo installed to generate the warning + id: no-pymongo + run: | + output=$(ansible localhost -m setup 2>&1) + echo "$output" + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=nopymongo::$output" + + - name: Test cache handling of missing pymongo + uses: nick-invision/assert-action@v1 + with: + expected: "The 'pymongo' python module is required for the mongodb fact cache" + actual: ${{ steps.no-pymongo.outputs.nopymongo }} + comparison: contains + + - name: Install pymongo + uses: nick-invision/retry@v2 + with: + timeout_minutes: 3 + max_attempts: 3 + command: pip install pymongo + + - name: Run ansible to generate the mongodb cache + run: ansible localhost -m setup + + - name: Query mongo to see what we have in the cache + id: mongo1 + run: | + output=$(mongo cache --authenticationDatabase admin -u mongoadmin -p secret --eval "db.cache.find()") + echo "$output" + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=mongo::$output" + + - name: Test that we have something that looks like a cache record + uses: nick-invision/assert-action@v1 + with: + expected: ansible_processor_count + actual: ${{ steps.mongo1.outputs.mongo }} + comparison: contains + + - name: Collection should not have a ttl index + id: mongo2 + run: | + output=$(mongo cache --authenticationDatabase admin -u mongoadmin -p secret --eval "db.cache.getIndexes()") + echo "$output" + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=mongo::$output" + + - name: Test that we don't have an index called ttl + uses: nick-invision/assert-action@v1 + with: + expected: ttl + actual: ${{ steps.mongo2.outputs.mongo }} + comparison: notContains + + - name: Test that we have good output from getindexes + uses: nick-invision/assert-action@v1 + with: + expected: "_id_" + actual: ${{ steps.mongo2.outputs.mongo }} + comparison: contains + + - name: Repeat the action to hit the cache again + run: ansible localhost -m setup + + - name: Query mongo to see what we have in the cach3 + id: mongo3 + run: | + output=$(mongo cache --authenticationDatabase admin -u mongoadmin -p secret --eval "db.cache.find()") + echo "$output" + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=mongo::$output" + + - name: Test that we have something that looks like a cache record + uses: nick-invision/assert-action@v1 + with: + expected: ansible_processor_count + actual: ${{ steps.mongo3.outputs.mongo }} + comparison: contains + + - name: Collection should not have a ttl index + id: mongo4 + run: | + output=$(mongo cache --authenticationDatabase admin -u mongoadmin -p secret --eval "db.cache.getIndexes()") + echo "$output" + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=mongo::$output" + + - name: Test that we don't have an index called ttl + uses: nick-invision/assert-action@v1 + with: + expected: ttl + actual: ${{ steps.mongo4.outputs.mongo }} + comparison: notContains + + - name: Test that we have good output from getindexes + uses: nick-invision/assert-action@v1 + with: + expected: "_id_" + actual: ${{ steps.mongo4.outputs.mongo }} + comparison: contains + + - name: Run the action again with a modified timeout + env: + ANSIBLE_CACHE_PLUGIN_TIMEOUT: 3600 + run: ansible localhost -m setup + + - name: Query mongo to see what we have in the cache + id: mongo5 + run: | + output=$(mongo cache --authenticationDatabase admin -u mongoadmin -p secret --eval "db.cache.find()") + echo "$output" + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=mongo::$output" + + - name: Test that we have something that looks like a cache record + uses: nick-invision/assert-action@v1 + with: + expected: ansible_processor_count + actual: ${{ steps.mongo5.outputs.mongo }} + comparison: contains + + - name: Collection should have a ttl index + id: mongo6 + run: | + output=$(mongo cache --authenticationDatabase admin -u mongoadmin -p secret --eval "db.cache.getIndexes()") + echo "$output" + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=mongo::$output" + + - name: Test that we do have an index called ttl + uses: nick-invision/assert-action@v1 + with: + expected: ttl + actual: ${{ steps.mongo6.outputs.mongo }} + comparison: contains + + - name: Repeat the action + env: + ANSIBLE_CACHE_PLUGIN_TIMEOUT: 3600 + run: ansible localhost -m setup + + - name: Query mongo to see what we have in the cache + id: mongo7 + run: | + output=$(mongo cache --authenticationDatabase admin -u mongoadmin -p secret --eval "db.cache.find()") + echo "$output" + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=mongo::$output" + + - name: Test that we have something that looks like a cache record + uses: nick-invision/assert-action@v1 + with: + expected: ansible_processor_count + actual: ${{ steps.mongo7.outputs.mongo }} + comparison: contains + + - name: Collection should have a ttl index + id: mongo8 + run: | + output=$(mongo cache --authenticationDatabase admin -u mongoadmin -p secret --eval "db.cache.getIndexes()") + echo "$output" + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=mongo::$output" + + - name: Test that we do have an index called ttl + uses: nick-invision/assert-action@v1 + with: + expected: ttl + actual: ${{ steps.mongo8.outputs.mongo }} + comparison: contains + + - name: Set timeout back to zero + env: + ANSIBLE_CACHE_PLUGIN_TIMEOUT: 0 + run: ansible localhost -m setup + + - name: Query mongo to see what we have in the cache + id: mongo9 + run: | + output=$(mongo cache --authenticationDatabase admin -u mongoadmin -p secret --eval "db.cache.find()") + echo "$output" + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=mongo::$output" + + - name: Test that we have something that looks like a cache record + uses: nick-invision/assert-action@v1 + with: + expected: ansible_processor_count + actual: ${{ steps.mongo9.outputs.mongo }} + comparison: contains + + - name: Collection should not have a ttl index + id: mongo10 + run: | + output=$(mongo cache --authenticationDatabase admin -u mongoadmin -p secret --eval "db.cache.getIndexes()") + echo "$output" + output="${output//'%'/'%25'}" + output="${output//$'\n'/'%0A'}" + output="${output//$'\r'/'%0D'}" + echo "::set-output name=mongo::$output" + + - name: Test that we don't have an index called ttl + uses: nick-invision/assert-action@v1 + with: + expected: ttl + actual: ${{ steps.mongo10.outputs.mongo }} + comparison: notContains + + - name: Test that we have good output from getindexes + uses: nick-invision/assert-action@v1 + with: + expected: "_id_" + actual: ${{ steps.mongo10.outputs.mongo }} + comparison: contains diff --git a/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/publish_collection.yml b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/publish_collection.yml new file mode 100644 index 00000000..5f7a4433 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/publish_collection.yml @@ -0,0 +1,58 @@ +name: Build & Publish Collection +on: + push: + branches: + - master + +jobs: + build_publish: + + runs-on: ubuntu-20.04 + defaults: + run: + working-directory: ansible_collections/community/mongodb + steps: + + - name: Check out code + uses: actions/checkout@v2 + with: + path: ansible_collections/community/mongodb + + - name: Set up Python 3.6 + uses: actions/setup-python@v1 + with: + python-version: 3.6 + + - name: Install ansible-base (devel) + run: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check + + - name: Build the collection + run: ansible-galaxy collection build + + - name: Rename the build artifact + run: mv community-mongodb-*.tar.gz community-mongodb-latest.tar.gz + + - name: Upload community-mongodb-latest.tar.gz as an artifact + uses: actions/upload-artifact@v1 + with: + name: community-mongodb-latest + path: ansible_collections/community/mongodb/community-mongodb-latest.tar.gz + + # Moving the tag leaves an orphan artifact. Just changing the artifact doesn't move the tag. + - name: Delete latest tag and release + uses: dev-drprasad/delete-tag-and-release@v0.1.2 + with: + delete_release: true + tag_name: latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload files to release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: ansible_collections/community/mongodb/community-mongodb-latest.tar.gz + asset_name: community-mongodb-latest.tar.gz + body: "Development release" + tag: latest + overwrite: true diff --git a/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/test-roles.yml b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/test-roles.yml new file mode 100644 index 00000000..e131f49e --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/test-roles.yml @@ -0,0 +1,83 @@ +name: CI_roles +on: + pull_request: + schedule: + - cron: "0 6 * * *" + +jobs: + + roles_matrix: + runs-on: ubuntu-20.04 + defaults: + run: + working-directory: ansible_collections/community/mongodb + outputs: + matrix: ${{ steps.json-list.outputs.roles-to-test }} + + steps: + + - name: Check out code + uses: actions/checkout@v2 + with: + path: ansible_collections/community/mongodb + + - name: Generate module list + run: | + find roles -type d -maxdepth 1 -mindepth 1 | cut -d '/' -f2 | awk NF | jq -sRc 'split("\n") | map(select(length > 0))' > int_test_roles.json + + - name: Set output variable + id: json-list + run: | + output=$(cat int_test_roles.json) + echo "::set-output name=roles-to-test::$output" + echo "$output" + + roles: + runs-on: ubuntu-20.04 + needs: roles_matrix + defaults: + run: + working-directory: ansible_collections/community/mongodb + + strategy: + matrix: + python_version: + - "3.6" + mongodb_role: ${{ fromJson(needs.roles_matrix.outputs.matrix) }} + + steps: + - name: Check out code + uses: actions/checkout@v2 + with: + path: ansible_collections/community/mongodb + + - name: Set up Python ${{ matrix.test_scenario.python_version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.test_scenario.python_version }} + + - name: Uninstall existing ansible + run: sudo apt remove ansible + + - name: Ensure wheel is installed + run: pip install wheel + + - name: Install requirements + run: | + export pyv=$(python -c 'from platform import python_version; print(python_version()[:3])') + pip install --requirement requirements-${pyv}.txt + - name: Add molecule location to path + run: echo "${HOME}/.local/bin" >> $GITHUB_PATH + + - name: Build the collection + run: ansible-galaxy collection build + + - name: Rename the build artifact + run: mv community-mongodb-*.tar.gz community-mongodb-latest.tar.gz + + - name: Install collection + run: ansible-galaxy collection install community-mongodb-*.tar.gz + + - name: Run molecule test for ${{ matrix.mongodb_role }} + run: molecule test + working-directory: ansible_collections/community/mongodb/roles/${{ matrix.mongodb_role }} diff --git a/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/x509.yml b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/x509.yml new file mode 100644 index 00000000..1f7a7ba7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/.github/workflows/x509.yml @@ -0,0 +1,166 @@ +name: CI +on: + pull_request: + schedule: + - cron: "0 3 * * *" + +jobs: + x509_membership_auth: + runs-on: ubuntu-20.04 + defaults: + run: + working-directory: ansible_collections/community/mongodb/tests/ansible-operator + steps: + + - name: Check out code + uses: actions/checkout@v2 + with: + path: ansible_collections/community/mongodb + + - name: Setup Minikube + uses: manusa/actions-setup-minikube@v2.3.0 + with: + minikube version: 'v1.13.1' + kubernetes version: 'v1.19.2' + github token: ${{ secrets.GITHUB_TOKEN }} + + - name: Install cert-manager + run: | + kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.1/cert-manager.yaml + + - name: Generate certs + run: | + openssl genrsa -out ca.key 8192 + openssl req -x509 -new -nodes -key ca.key -sha256 -subj "/CN=mongodb-cluster-ca.local" -days 36500 -reqexts v3_req -extensions v3_ca -out ca.crt + + - name: Wait for a bit + run: sleep 60 + + - name: Register the certs with k8 + run: | + kubectl create secret tls mongodb-cluster-ca-key-pair --key=ca.key --cert=ca.crt + kubectl apply -f ca-issuer.yaml + + - name: make install + run: make install + + - name: Create k8 namesapce + run: kubectl create ns ansible-operator-system + + - name: use minikubes docker + run: eval $(minikube docker-env --shell sh) + + - name: make docker-build + run: make docker-build IMG=test-mongodb-operator:latest + + - name: make deploy + run: make deploy IMG=test-mongodb-operator:latest + + - name: Wait for controller to be ready + run: kubectl wait --for=condition=available deployment/ansible-operator-controller-manager -n ansible-operator-system --timeout=60s + + #- name: Debug step + # run: kubectl api-resources | grep mongo -i + + # - name: Debug step + # run: kubectl get pods --all-namespaces + + # - name: Debug step + # run: kubectl describe pod -n ansible-operator-system ansible-operator-controller-manager + + - name: Setup the k8 mongodb env + run: | + kubectl apply -f config/samples/mongodb_v1alpha1_mongodb.yaml + sleep 10 + kubectl -n ansible-operator-system logs deployment.apps/ansible-operator-controller-manager -c manager + + - name: Wait for a bit + run: sleep 60 + + - name: Install socat + run: | + sudo apt update + sudo apt install socat + + - name: Forward the local port 27017 to k8 + run: kubectl port-forward mongodb-sample-0 27017:27017 --address 0.0.0.0 & + + # - name: Get the pods (Debug) + # run: kubectl get pods --all-namespaces + + # - name: List forwards (Debug) + # run: kubectl get svc --all-namespaces + + - name: Copy the certs to the localhost + run: | + managerpod=$(kubectl get pods -n ansible-operator-system --no-headers | tr -s ' ' | cut -d ' ' -f 1) + kubectl cp ansible-operator-system/${managerpod}:/tmp/mongodb-sample.default/ca.crt ca.crt -c manager + kubectl cp ansible-operator-system/${managerpod}:/tmp/mongodb-sample.default/tls.key tls.key -c manager + + - name: Run mongo shell command to test x509 membership connectivity + run: | + kubectl -n ansible-operator-system exec -ti deployment.apps/ansible-operator-controller-manager -c manager -- \ + /usr/bin/mongo mongodb://mongodb-sample.default.svc.cluster.local \ + --tls \ + --tlsCAFile /tmp/mongodb-sample.default/ca.crt \ + --tlsCertificateKeyFile /tmp/mongodb-sample.default/tls.key \ + --authenticationMechanism MONGODB-X509 \ + --authenticationDatabase '$external' \ + --eval "db.adminCommand('listDatabases')" + + - name: Run mongo shell command to test x509 membership connectivity from localhost + run: | + /usr/bin/mongo mongodb://127.0.0.1 \ + --tls \ + --tlsCAFile ca.crt \ + --tlsCertificateKeyFile tls.key \ + --tlsAllowInvalidHostnames \ + --authenticationMechanism MONGODB-X509 \ + --authenticationDatabase '$external' \ + --eval "db.adminCommand('listDatabases')" + + # - name: Get the mongodb log + # run: kubectl logs mongodb-sample-0 + + - name: Set up Python 3.6 + uses: actions/setup-python@v1 + with: + python-version: "3.6" + + - name: Install ansible-base devel + uses: nick-invision/retry@v2 + with: + timeout_minutes: 3 + max_attempts: 3 + command: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check + + - name: Build the collection + run: ansible-galaxy collection build + working-directory: ansible_collections/community/mongodb + + - name: Rename the build artifact + run: mv community-mongodb-*.tar.gz community-mongodb-latest.tar.gz + working-directory: ansible_collections/community/mongodb + + - name: Install collection + run: ansible-galaxy collection install community-mongodb-*.tar.gz + working-directory: ansible_collections/community/mongodb + + - name: Install pymongo + uses: nick-invision/retry@v2 + with: + timeout_minutes: 3 + max_attempts: 3 + command: pip install pymongo + + # - name: Debug step + # run: netstat -tulpen + + - name: Run mongodb_user module with membership auth + run: ansible localhost -m community.mongodb.mongodb_user -a "login_host=localhost login_port=27017 login_database='$external' database='admin' password='secret' ssl=true ssl_ca_certs=ca.crt ssl_certfile=tls.key auth_mechanism=MONGODB-X509 name="test" state=present connection_options='tlsAllowInvalidHostnames=true'" + + - name: Run mongodb_info module with membership auth + run: ansible localhost -m community.mongodb.mongodb_info -a "login_host=localhost login_port=27017 login_database='$external' ssl=true ssl_ca_certs=ca.crt ssl_certfile=tls.key auth_mechanism=MONGODB-X509 connection_options='tlsAllowInvalidHostnames=true'" + + - name: Run mongodb_parameter module with membership auth + run: ansible localhost -m community.mongodb.mongodb_parameter -a "login_host=localhost login_port=27017 login_database='$external' param=syncdelay value=60 param_type=int ssl=true ssl_ca_certs=ca.crt ssl_certfile=tls.key auth_mechanism=MONGODB-X509 connection_options='tlsAllowInvalidHostnames=true'" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/.gitignore b/collections-debian-merged/ansible_collections/community/mongodb/.gitignore new file mode 100644 index 00000000..47137b90 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/.gitignore @@ -0,0 +1,3 @@ +venv/* +**/.DS_Store +*.tar.gz diff --git a/collections-debian-merged/ansible_collections/community/mongodb/CHANGELOG.rst b/collections-debian-merged/ansible_collections/community/mongodb/CHANGELOG.rst new file mode 100644 index 00000000..7952c588 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/CHANGELOG.rst @@ -0,0 +1,33 @@ +=============================== +Community.Mongodb Release Notes +=============================== + +.. contents:: Topics + + +v1.1.0 +====== + +New Modules +----------- + +- community.mongodb.mongodb_shell - Run commands via the MongoDB shell. + +v1.0.0 +====== + +New Modules +----------- + +- community.mongodb.mongodb_balancer - Manages the MongoDB Sharded Cluster Balancer. +- community.mongodb.mongodb_index - Creates or drops indexes on MongoDB collections. +- community.mongodb.mongodb_info - Gather information about MongoDB instance. +- community.mongodb.mongodb_maintenance - Enables or disables maintenance mode for a secondary member. +- community.mongodb.mongodb_oplog - Resizes the MongoDB oplog. +- community.mongodb.mongodb_parameter - Change an administrative parameter on a MongoDB server +- community.mongodb.mongodb_replicaset - Initialises a MongoDB replicaset. +- community.mongodb.mongodb_shard - Add or remove shards from a MongoDB Cluster +- community.mongodb.mongodb_shutdown - Cleans up all database resources and then terminates the mongod/mongos process. +- community.mongodb.mongodb_status - Validates the status of the cluster. +- community.mongodb.mongodb_stepdown - Step down the MongoDB node from a PRIMARY state. +- community.mongodb.mongodb_user - Adds or removes a user from a MongoDB database diff --git a/collections-debian-merged/ansible_collections/community/mongodb/COPYING b/collections-debian-merged/ansible_collections/community/mongodb/COPYING new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program 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. + + This program 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 this program. If not, see <https://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<https://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<https://www.gnu.org/licenses/why-not-lgpl.html>. diff --git a/collections-debian-merged/ansible_collections/community/mongodb/FILES.json b/collections-debian-merged/ansible_collections/community/mongodb/FILES.json new file mode 100644 index 00000000..d2b58458 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/FILES.json @@ -0,0 +1,2035 @@ +{ + "files": [ + { + "name": ".", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/lookup", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/lookup/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "plugins/lookup/mongodb.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5a9aec479c3878ac6f058f918eb7b04cee1fe3d27209f45617d02975d0889d04", + "format": 1 + }, + { + "name": "plugins/modules", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/modules/mongodb_shell.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7b8b86ddc31babd45f2d963ee77369374bbf23df0195f1e8f361d6d23b50a1bd", + "format": 1 + }, + { + "name": "plugins/modules/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_balancer.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "44eb459f1f3eb60b763315b0b26b528a164241bd1345fbeb03784971873b1c9d", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_status.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c1afb7410ce0565b86427771951ece94197ee7e154d43b27c3800c863092aec6", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_user.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6b616d0a2f13bd8fe9f5c36bbf09e797ce65e2a6d1cffe132e8ee225d7088f61", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_info.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c3a13fced0fda43f45df86ca3f86564de4b4b2c40f8e6c849c335156d4dbb575", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_replicaset.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "fc146152f3cf87f3ba5cbd0d85e35fff4d0809c1ede839baab42ff5b280d61f1", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_parameter.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2d3f8a2a04a4fb0937671ccc2911e59fe8b4b99a9b7c254a3648b2be865242ce", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_shutdown.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "bb0268d497a3cc07afdc1a4ffc68bbfe983cb78164d9e68757374c128efc345f", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_shard.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4103a898c8ca8012a16f92d34a0f4106a755fe505ce7c144e1ef987d44b22e39", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_stepdown.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "47aa6bf5010b9d0e2a80c4d81725551c6267c67093e69a4e2359f40e85b5409d", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_maintenance.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "733a73e5237dfc45a8160368bd58773754a633b6736b4992fe1cb16bea50195a", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_oplog.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a111ed16e775abc6b39dd7b55e6bb152d547811514b5ff661e2f91d4a9d60c3a", + "format": 1 + }, + { + "name": "plugins/modules/mongodb_index.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "614669cd55931fc0d4a54e82334558c4240c0cdbe32d15c2417c9bb75a170995", + "format": 1 + }, + { + "name": "plugins/doc_fragments", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/doc_fragments/ssl_options.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "453873b8c98d2426f6f621ee64874bbad7ad4915b5ad1db071f4a2b8bf80dece", + "format": 1 + }, + { + "name": "plugins/doc_fragments/login_options.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0b6e8b449af7c30d9c6ba304b8ee68dba5823a3b5926e4148e761d177061bb9d", + "format": 1 + }, + { + "name": "plugins/cache", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/cache/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "plugins/cache/mongodb.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8e91c4b5a6fed2147977e6fee7092e4ab58da92fbb36c205f866f03e28b55f40", + "format": 1 + }, + { + "name": "plugins/module_utils", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/module_utils/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "plugins/module_utils/mongodb_common.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e82e0bd1a178f3a579bc41e93f9bbc3f0f9a2d591512f7ce412bfa09fb8abf39", + "format": 1 + }, + { + "name": ".github", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": ".github/settings.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8c22b5bdca60981e51b0bb62b0f4be453ca8a500ba20cad0c14ed12786585da4", + "format": 1 + }, + { + "name": ".github/CODEOWNERS", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d4cfb5afd8df3da18f5ae080cb324df1764f93babed08e4d6e6b6f79e8c7a9cc", + "format": 1 + }, + { + "name": ".github/workflows", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": ".github/workflows/x509.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "53521ebe9aa24fd3b5d7b2e8c5ef0b6b23539217629cd5f2141023dc3ad35221", + "format": 1 + }, + { + "name": ".github/workflows/ansible-test.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4c0bb36975b0a1cd37e37f0f275d3a83d968d220924a8fe725b55fb6528ade5e", + "format": 1 + }, + { + "name": ".github/workflows/mongodb-cache.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5ecebf76195f6685011a2bcf06ad4f092ffa7f304bf72bd7be96f2e7fc01bc1a", + "format": 1 + }, + { + "name": ".github/workflows/documentation.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1677e156a8b8f23e0b03f37c8df0ba680e0e54cb32cc14e0f56cda2b07f7b5ea", + "format": 1 + }, + { + "name": ".github/workflows/publish_collection.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7906a250659c71bb285094e5e8b891d813dc7839fd7c2688f37448fb09dc5318", + "format": 1 + }, + { + "name": ".github/workflows/test-roles.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "da1508e24ac5857837a41161b942a7a76182f4bd896c541a8cbaa6fbbb4dd262", + "format": 1 + }, + { + "name": "roles", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_repository", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_repository/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "490d2ec6da3c9efb65c744c4072401af6aaaa98b93b17ab43e9e3abd58fa10d1", + "format": 1 + }, + { + "name": "roles/mongodb_repository/meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_repository/meta/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8ce2f64193caa9ec870f9b08d90160395aba8209875d843e413ba88773edc3d8", + "format": 1 + }, + { + "name": "roles/mongodb_repository/defaults", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_repository/defaults/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a5f5e0cac2230fda42941b1e1a9d019cc0aa9d0bf7b0e44ae4538c39ae2aa476", + "format": 1 + }, + { + "name": "roles/mongodb_repository/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_repository/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "99a596554f3a9ccd376265306d69718181e3984c9446b4c72a6bc70cfd86671c", + "format": 1 + }, + { + "name": "roles/mongodb_repository/tasks/RedHat.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e025f5782e85260c5bc9dc4e8aaf3f9031cd78f9ce3652c6da92a4d595a3b4d1", + "format": 1 + }, + { + "name": "roles/mongodb_repository/tasks/Debian.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "189bca5600b4e0ebad9eff0fd430f445c2810e59677c8cbcc6397dbbbfa4a0de", + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule/default", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule/default/Dockerfile.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c3590c6376fb22b3b9ab9677792758a339018cd2a03a209a9f2f0fd7777efab3", + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule/default/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b28684e292044b3014cbd669d8ad266d404467bd3ef5f68bc7fa7cc28591849b", + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule/default/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule/default/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b2ab993c67c685dcb0263ac2d93dd6c2367f22d7f74f46b493de461c0ac8fabf", + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule/default/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "70463000bc69eb511406abec33b630540c6edfca9d7fc0da805a2114503030b6", + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule/virtualbox", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule/virtualbox/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a1e71aa706b1fbacdf5b2518c12eb7b36200f090b6f093797a16fd123f5a888d", + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule/virtualbox/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule/virtualbox/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b2ab993c67c685dcb0263ac2d93dd6c2367f22d7f74f46b493de461c0ac8fabf", + "format": 1 + }, + { + "name": "roles/mongodb_repository/molecule/virtualbox/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5a5f16912a2d0b6e0181753ed289497aced10a44b49a19dafb57156a2c8ba6fb", + "format": 1 + }, + { + "name": "roles/mongodb_repository/.yamllint", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5845e18e9f23155f423207df9abac970aed687c638620bc2c9ee06706191054b", + "format": 1 + }, + { + "name": "roles/mongodb_install", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_install/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "763e511cc8b0863b89058749e4f7bc5c72a5f7e0e66e7c18d157a9b38a1fb036", + "format": 1 + }, + { + "name": "roles/mongodb_install/meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_install/meta/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8ce2f64193caa9ec870f9b08d90160395aba8209875d843e413ba88773edc3d8", + "format": 1 + }, + { + "name": "roles/mongodb_install/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_install/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "247e195bd03dde3fa288f45aa2545163e0a66e5804a01f3278100b6b0a0a3ae8", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/default", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/default/Dockerfile.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c3590c6376fb22b3b9ab9677792758a339018cd2a03a209a9f2f0fd7777efab3", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/default/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f11fa696ac80dea0d22ba3b6581e9f7c00a6e364ea55cef85ecdd9b9ccd96b5b", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/default/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/default/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "791632cbe2677e015f0410bf86ba7bb84408a931bd198b0451dc431239c20597", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/default/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ebb97c71ca2689c2592ada9a914eaf51a0a4fafd90655e6d66e92bfd1bc31bda", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/specific_mongodb_version", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/specific_mongodb_version/Dockerfile.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e79af0ac7684196dec7a4a692406de0efb4cd8856732a0568432e66e6e78f536", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/specific_mongodb_version/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "3b9fd51f7054e8da66e93e9c8c9c4d103ba20b4149348ff0e2563932358af993", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/specific_mongodb_version/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/specific_mongodb_version/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "dc70e6ecd50e92df89446fd88757f4f9429d8d26812bd8ba833d9e88ff8372d2", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/specific_mongodb_version/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5a2f333e36cb4717e63a24a548e74e053d6f26393f240e0516f93f006cf2a409", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/virtualbox", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/virtualbox/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "bf5def31b786e89acba3410fc82e88691494ed857c8e774d8d65de9878e5f9cd", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/virtualbox/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/virtualbox/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "791632cbe2677e015f0410bf86ba7bb84408a931bd198b0451dc431239c20597", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/virtualbox/prepare.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ba2fc1d013c2b62868161ec627cd7461b771b8b5341482d08fb4a2de1fcdecec", + "format": 1 + }, + { + "name": "roles/mongodb_install/molecule/virtualbox/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5a5f16912a2d0b6e0181753ed289497aced10a44b49a19dafb57156a2c8ba6fb", + "format": 1 + }, + { + "name": "roles/mongodb_install/.yamllint", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5845e18e9f23155f423207df9abac970aed687c638620bc2c9ee06706191054b", + "format": 1 + }, + { + "name": "roles/mongodb_linux", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_linux/vars", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_linux/vars/default.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a59cff154c4e16712dcd8940dea534b1504ad26e47e5ef5fd7df31b18263358e", + "format": 1 + }, + { + "name": "roles/mongodb_linux/vars/RedHat.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "11bc15a467aa60aee032b12c142403e7ff9442fe446696677a705c3bf4342d5c", + "format": 1 + }, + { + "name": "roles/mongodb_linux/vars/Debian.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6d9f7388e9fbfea244152eb8f560f3eb8b83767951f4057b3b60ad1583ed9659", + "format": 1 + }, + { + "name": "roles/mongodb_linux/vars/RedHat-8.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "92734c0fcbe1a3e25e701076340ca275087ce01667b2386e7eca26e1f66e8e62", + "format": 1 + }, + { + "name": "roles/mongodb_linux/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "63c1aafaf9e96e1b5af474e2ae294424374cd0ddc0f2b9168ee423bf577a38eb", + "format": 1 + }, + { + "name": "roles/mongodb_linux/files", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_linux/files/thp-disable.service", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1b9f839d1dbbb918acd201e94fe3a9bb9ddaafdbf9398059f8fb0817ecd823c3", + "format": 1 + }, + { + "name": "roles/mongodb_linux/meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_linux/meta/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8ce2f64193caa9ec870f9b08d90160395aba8209875d843e413ba88773edc3d8", + "format": 1 + }, + { + "name": "roles/mongodb_linux/defaults", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_linux/defaults/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8c1cb3f8cb7c88e5f9b94e95c798303831bd6d28cee2b24b42e1b8b5c3c77fc7", + "format": 1 + }, + { + "name": "roles/mongodb_linux/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_linux/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "700c643309da72ddae21386d53197d35687ed577e1682e012e7e07406884123d", + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/default", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/default/Dockerfile.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c3590c6376fb22b3b9ab9677792758a339018cd2a03a209a9f2f0fd7777efab3", + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/default/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4c2a0b84d10e12a7c53a760075b92df7a5a522362e5b6550640db1eb4d324acf", + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/default/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/default/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "40fed6d9ff7c68c509c58bb8be021b72321c1018d65e4c23e446940d0d84b8b9", + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/default/prepare.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5e59e3949c45e27709f362879432ab8b1ab0a43abeb32845ff6ccaa1c224675c", + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/default/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d631d17d64bb05d271dfea88411bbe1b7ff4d40ab38c348a3b94bfcf6df82b7d", + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/virtualbox", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/virtualbox/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "798d89e01169c82893f6a3ef1a0ac42ad2b8f35cb381c5e4f5287f1fc9eee0ad", + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/virtualbox/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/virtualbox/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b5bca5c519a8c7ef7861d947691b27fffa893a73f0d23c1b2c6d2ee3a4e8116a", + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/virtualbox/prepare.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c12d1950e2ea55c33142b03499ac06f8a7b8966bd442a4a4fda51b563f57156d", + "format": 1 + }, + { + "name": "roles/mongodb_linux/molecule/virtualbox/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "be802cbcde6a1b58339941acce77cb8fdea0b881b457a07faee5cb998586f995", + "format": 1 + }, + { + "name": "roles/mongodb_mongod", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/templates", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/templates/mongod.conf.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c145691b8d9454c19940a2abf18562d7cdc8e3ada6c62749d7586d29e5c974d8", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/vars", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/vars/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9ec2f09ee44ac84f5f80ba02826341522f3252e98ab7f4d2139bb65eb2bfbda3", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/vars/default.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "62ac9d1738f2f46aad935674158db36c9b6f24e3e3e6533e078fb85f64a3a83b", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/vars/RedHat.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "62ac9d1738f2f46aad935674158db36c9b6f24e3e3e6533e078fb85f64a3a83b", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/vars/Debian.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "84d1a080c42c20b06fe54a68dfd0d06f80fd7cfa8ad8ce639ab2710d6fb75caa", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/handlers", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/handlers/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "23e4b2fb51a28991df87511bc06d98482ba2aeb19cc7cc60a671b3023e5c2a6f", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/handlers/handlers.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "10a3ea67045f24af96af31a269d7974831d1d5a2c26fa1531595ae94e4bc33f1", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ae361289d9a0ce752f3ffe341aba6318d23b15527ae9e15ff54b06845653b754", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/meta/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f2fdfe683dcc02708e4b2cf21c5eb5166e04c29b8571f37b0e8cd086c4f1d5bb", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/defaults", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/defaults/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "196e7dd8207d0087f510c9ff1511d0ec843c0bcc4558eb65c80e4c663a5b7aa4", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "648afce460e0219807203accf49ead91defa6f969d90bd746fccee5d38fb31a3", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/tasks/redhat_docker.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6b4201bb672671cd5877dad9fdea53748536bbebdb23ec7844f25f2e80d94f81", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/default", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/default/Dockerfile.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c3590c6376fb22b3b9ab9677792758a339018cd2a03a209a9f2f0fd7777efab3", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/default/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e295057136bcc7ac039c31737f0ffc9a5f763e677ca31e03a536554f4bf8e8dc", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/default/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/default/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "dc24117a3dd0b6f0e419d67b189bfea2b49693ff07f7919f3614d06c40060c17", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/default/prepare.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4fb6fae4e50aca56e647f48c5c20de41dba010b04d25c9d40a4229febdeb0cf4", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/default/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d863b645121c74ca28e9e4141f6e15e559ca8cbca204dc4b1d764b641857f5ef", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/virtualbox", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/virtualbox/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "94b7e3936c464eb2fdc202bdcbff04fadd8df1a30c30d0396ef2aaa206dd9310", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/virtualbox/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/virtualbox/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "090ddb05ec05caaa2f45e19cf366b70eb940243bc7fd51847697f7322cfb19e5", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/virtualbox/prepare.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ae12c9b9a1dbec619aebf446375821b3180506c64b1219cecd03ced0bd471094", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/molecule/virtualbox/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5a5f16912a2d0b6e0181753ed289497aced10a44b49a19dafb57156a2c8ba6fb", + "format": 1 + }, + { + "name": "roles/mongodb_mongod/.yamllint", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5845e18e9f23155f423207df9abac970aed687c638620bc2c9ee06706191054b", + "format": 1 + }, + { + "name": "roles/mongodb_auth", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_auth/vars", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_auth/vars/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9bc68569a02f43f59c8596ba3a9394ee575341f5e82920a5f88c91570e226c0e", + "format": 1 + }, + { + "name": "roles/mongodb_auth/vars/default.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "42f9c7c54d0c65e47182857748e0063b187e47ddd5567ea9d3bc0efa2f8fdce9", + "format": 1 + }, + { + "name": "roles/mongodb_auth/vars/RedHat-7.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7f1b153188944e0831be2fac23387490b2d0a0e1bf140f79e02b191d0ffa5072", + "format": 1 + }, + { + "name": "roles/mongodb_auth/vars/RedHat-8.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9ab4933ea17b120510fc330bd19780af649f17151fc40836b198e66408e4851c", + "format": 1 + }, + { + "name": "roles/mongodb_auth/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "85927ca3b062e2f720e5b39edcd14bec51bb196ef06be66e0745744d8bc8db1c", + "format": 1 + }, + { + "name": "roles/mongodb_auth/meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_auth/meta/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "015dbab8c027c25d1f269803ec98e25374ad62db51f45836d4dd275352fbb6e4", + "format": 1 + }, + { + "name": "roles/mongodb_auth/defaults", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_auth/defaults/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "efa66846a160d6c4821c54d569d32e2826c289a890656b10d54b19c7355391a7", + "format": 1 + }, + { + "name": "roles/mongodb_auth/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_auth/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "894f58457cce01793520019e27244cb09a9363ea2b1bb12aa58bcb3d7f74fde3", + "format": 1 + }, + { + "name": "roles/mongodb_auth/tasks/mongodb_auth_user.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4eb8df342831f805080c4d0750bb6481491fc891644c005cd83b21279d4bd6d6", + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/default", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/default/Dockerfile.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c3590c6376fb22b3b9ab9677792758a339018cd2a03a209a9f2f0fd7777efab3", + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/default/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7c1c1d116b51b15d1ebb3d6c75d4554bb0b1f8f623e1cdbcbb7bd817ca4c6b01", + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/default/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/default/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "714cc12b962bd662a1b156047f82c425efbeead489c11b9e1d22c61e350a8f75", + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/default/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a48527332be95704508519cc22aff9519c7db88e2be04cdda9a3787831b9f116", + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/virtualbox", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/virtualbox/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e899b116c35ab6a386f7f437c63e9cf75968ecc0c06c0fd4f936c8fe8c1550f2", + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/virtualbox/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/virtualbox/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "714cc12b962bd662a1b156047f82c425efbeead489c11b9e1d22c61e350a8f75", + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/virtualbox/prepare.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ae12c9b9a1dbec619aebf446375821b3180506c64b1219cecd03ced0bd471094", + "format": 1 + }, + { + "name": "roles/mongodb_auth/molecule/virtualbox/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5a5f16912a2d0b6e0181753ed289497aced10a44b49a19dafb57156a2c8ba6fb", + "format": 1 + }, + { + "name": "roles/mongodb_auth/.yamllint", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5845e18e9f23155f423207df9abac970aed687c638620bc2c9ee06706191054b", + "format": 1 + }, + { + "name": "roles/mongodb_mongos", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/templates", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/templates/mongos.service.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2f5975a6a90d03609442704c1204851dd548b75f2289d58ecc64ba3c34feb4c8", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/templates/mongos.conf.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "95a66c49325c70cc24fb0b4f6a3385c0f4d692606c28302e0cfbad9e53e4403f", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/templates/mongos_pre.sh.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a8075bebea2ae681741a0dd81d96a83615ce40a4793ce65e3a8b11d886e160df", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/vars", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/vars/default.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1424644ecbf0273452371c01877d7483322c767fc0600df7d6bb53f509c14c66", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/vars/RedHat.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1424644ecbf0273452371c01877d7483322c767fc0600df7d6bb53f509c14c66", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/vars/Debian.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ec7fb76e494f9f5c196852c6da0b6a857cdbdd986b5a418d6d2ff2837073145f", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/handlers", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/handlers/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9a2bb94db94dbafcfd7f26854e756300befd25ebe37e7d11ba5fa3e72b0ac63e", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/handlers/handlers.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "da3befddc17957a9b0507c5ce1542eadb4f51ac289e9fec5156bbd546e23f3d4", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0db163e6beae46bc08aa61fffd3e974a78f1d721efe150c6f1f69d7b2c86aed9", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/meta/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8ce2f64193caa9ec870f9b08d90160395aba8209875d843e413ba88773edc3d8", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/defaults", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/defaults/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a7e16b8223f12644b1fe5c2872f58be48cd1050eb765b6f0a2aee114543b7750", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "57c4bca8d3d8c1fb26ebf52914063a9c663fc14eb9f059d7ecedf2919ed64fcd", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/default", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/default/Dockerfile.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c3590c6376fb22b3b9ab9677792758a339018cd2a03a209a9f2f0fd7777efab3", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/default/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9c225b0d7c50f185e33750331e8b6bf8bd9ad6824ea3e03236f2ba0410f29307", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/default/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/default/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "73d8d111cafce1366dd588129127c256fde1cf0452914722995ec31b6a7aa0cc", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/default/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "52244f0af416f2ee868639b88c903ee87668d4ee2a24478fe69d4773c81e12bf", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/virtualbox", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/virtualbox/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7c8970360ac175e823008edd99c9bf14cf4381b7e239691a26ff8a1b41358859", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/virtualbox/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/virtualbox/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "894ac9413e9227953fbc3f2feee6da697eb92645e1b94ad40be8d8983afd3193", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/virtualbox/prepare.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7502270acbe2c4aa2e4ce3b6b9a24ada70faa89299d4d73fd09c8a11351ea2dc", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/molecule/virtualbox/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "40c7b366520989d5e3512d0fbc85242dec769a53e849c8ee58e6f8ddf895244f", + "format": 1 + }, + { + "name": "roles/mongodb_mongos/.yamllint", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5845e18e9f23155f423207df9abac970aed687c638620bc2c9ee06706191054b", + "format": 1 + }, + { + "name": "roles/mongodb_selinux", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_selinux/vars", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_selinux/vars/default.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c7d66adb68db713835a648d401746453e5be04f7d4e2131de07a331a06700a5b", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/vars/Ubuntu-16.04.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e34d6876bf16c408a083e5e65005fe7756e93e5e1eebc38d1b592a011666879c", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/vars/RedHat-7.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f0f4c559b361e18038dd6af32b19418c1423ec98ecc210c07ddf4378a3d1e3c1", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/vars/Debian.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "208d9a4ef01b6c7f86842496b17a2c1c7ff6fd06ef608efea7149dcf27dcfcb7", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/vars/RedHat-8.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1d304f721b3447bff2844aa90fb11aba65e90153864b5abd2eb12f64571e61b4", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "99a291f3b754d75fad6c215b4b481aaa643cdfaa2c0b6f5b87b850731707ab08", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/files", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_selinux/files/compile_mongodb_selinux.sh", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "3e39949d3a137aee7f79368bdf1f367a31a155b030d36024f9e872bbbe1a4a65", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_selinux/meta/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8ce2f64193caa9ec870f9b08d90160395aba8209875d843e413ba88773edc3d8", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_selinux/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f39c6c04dbc9abf98cdc329f7d7c45eec66e74ad8ae262f148e9d148c8769226", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule/default", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule/default/Dockerfile.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c3590c6376fb22b3b9ab9677792758a339018cd2a03a209a9f2f0fd7777efab3", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule/default/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4a9fd1441f595120dba5a70e251db39ce412bb082aaf0c6193f68561a0a4aa34", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule/default/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule/default/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f95b987538d5ac35538ea41b06eb2cfe435d26f8c6d41845dc5fa112352471ae", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule/default/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "70463000bc69eb511406abec33b630540c6edfca9d7fc0da805a2114503030b6", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule/virtualbox", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule/virtualbox/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9566741408d12d8c408586477413035bf634033064d8b905a4ffacaf04dc181c", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule/virtualbox/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule/virtualbox/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "945f4d84522b6231ae80c46353f134c0f25bb7ea73e3ea2628bd897ac5a6f26b", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/molecule/virtualbox/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "be802cbcde6a1b58339941acce77cb8fdea0b881b457a07faee5cb998586f995", + "format": 1 + }, + { + "name": "roles/mongodb_selinux/.yamllint", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5845e18e9f23155f423207df9abac970aed687c638620bc2c9ee06706191054b", + "format": 1 + }, + { + "name": "roles/mongodb_config", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/templates", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/templates/configsrv.conf.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "675d66f29aa921b9c28870a7a1a7dc0db346b901f0a5650771d483cc1b0d9c79", + "format": 1 + }, + { + "name": "roles/mongodb_config/vars", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/vars/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9ec2f09ee44ac84f5f80ba02826341522f3252e98ab7f4d2139bb65eb2bfbda3", + "format": 1 + }, + { + "name": "roles/mongodb_config/vars/default.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0e37fe6e6b6cd10c0e88cc92b77c262849cc1f92a0b57d1cb5744141f2f31d5f", + "format": 1 + }, + { + "name": "roles/mongodb_config/vars/RedHat.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0e37fe6e6b6cd10c0e88cc92b77c262849cc1f92a0b57d1cb5744141f2f31d5f", + "format": 1 + }, + { + "name": "roles/mongodb_config/vars/Debian.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7b909986cc662e16382aaf03f5c091be8f4853e3143d36a2fe69286c60c9db1c", + "format": 1 + }, + { + "name": "roles/mongodb_config/handlers", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/handlers/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "23e4b2fb51a28991df87511bc06d98482ba2aeb19cc7cc60a671b3023e5c2a6f", + "format": 1 + }, + { + "name": "roles/mongodb_config/handlers/handlers.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "bc07bcd6e49c8e2052e42c866c843894523588df1a4d8bd838443fdf0dcb4570", + "format": 1 + }, + { + "name": "roles/mongodb_config/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "44bfbaec1da602efa01dc2571804d0d562f67985edb7d474adc9fd91c0a5573a", + "format": 1 + }, + { + "name": "roles/mongodb_config/meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/meta/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f2fdfe683dcc02708e4b2cf21c5eb5166e04c29b8571f37b0e8cd086c4f1d5bb", + "format": 1 + }, + { + "name": "roles/mongodb_config/defaults", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/defaults/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2d6da7ab219521ea1c7d1821073905e680bc1fdc949bdfc377566fe92b28ee97", + "format": 1 + }, + { + "name": "roles/mongodb_config/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4b2e1a92e194727a4eeac174e46dfb244ba16c605a8d8a8037a47cb1c6d7c2be", + "format": 1 + }, + { + "name": "roles/mongodb_config/tasks/redhat_docker.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6b4201bb672671cd5877dad9fdea53748536bbebdb23ec7844f25f2e80d94f81", + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/default", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/default/Dockerfile.j2", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c3590c6376fb22b3b9ab9677792758a339018cd2a03a209a9f2f0fd7777efab3", + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/default/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "30ebe3f1e0cd2f70a802dd3884f8c42f9e8416a99727db267678756ce40c45db", + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/default/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/default/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2d7ea388f9a7a21f69bc883a130a383aca15b2e7b57a19ffe32e3a5d16458960", + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/default/prepare.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4fb6fae4e50aca56e647f48c5c20de41dba010b04d25c9d40a4229febdeb0cf4", + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/default/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "62be04873a75787403aa8a3ca39d2061c9f388d921a956aa616f18c1c3ff666d", + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/virtualbox", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/virtualbox/playbook.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4933ae1729cc7bd77534313efdac3edecc8f1bcd9464635b6419bea9b0cfa222", + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/virtualbox/tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/virtualbox/tests/test_default.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c6a4a19296aa8de76930d65f5f151db1b1052409d6748e46a3270f17bb4f84f6", + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/virtualbox/prepare.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4487bc5ef1ce8ceae5df4fb74911c10b0b0f5c0bbb720f6297acf352bcd66d29", + "format": 1 + }, + { + "name": "roles/mongodb_config/molecule/virtualbox/molecule.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5a5f16912a2d0b6e0181753ed289497aced10a44b49a19dafb57156a2c8ba6fb", + "format": 1 + }, + { + "name": "roles/mongodb_config/.yamllint", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5845e18e9f23155f423207df9abac970aed687c638620bc2c9ee06706191054b", + "format": 1 + }, + { + "name": "README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "757e7c6d5ec22b5b720736916dff3ec610da32c04d7539e7300af7f446e7b1e1", + "format": 1 + }, + { + "name": "changelogs", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "changelogs/config.yaml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "34645d3006f70bba10f51672880483975df416540ff1e94948fb158e4ca64c68", + "format": 1 + }, + { + "name": "changelogs/changelog.yaml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "3e909803500b48f7a8a8b93fc323bd64e8fe93a5152795dcc9a6f829082f7dc3", + "format": 1 + }, + { + "name": "changelogs/.plugin-cache.yaml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "778d487f10a7b8b814a0df54f727f08e03f51ce9215eb13020dc90d9977e4e3f", + "format": 1 + }, + { + "name": "COPYING", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986", + "format": 1 + }, + { + "name": "meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "meta/runtime.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "df18179bb2f5447a56ac92261a911649b96821c0b2c08eea62d5cc6b0195203f", + "format": 1 + }, + { + "name": "requirements-3.5.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c99d4c779657b6c6e4edcc203de996e1a1419162542bede07f4262f4fd15b10d", + "format": 1 + }, + { + "name": "requirements-2.7.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c304de9f1056bf51ee933c9c7f28ee1df84206873a2a00e52419658860640e36", + "format": 1 + }, + { + "name": "docs", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": ".gitignore", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7f0232fa3f258eea77a8165918ef6b516fb43d1ba6a5af05d685fff42c0d1889", + "format": 1 + }, + { + "name": "requirements-3.8.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c99d4c779657b6c6e4edcc203de996e1a1419162542bede07f4262f4fd15b10d", + "format": 1 + }, + { + "name": "CHANGELOG.rst", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d5fc530f5186764d7fd33bd55d8c6eacf1a0c198e2dca13f47607bf12d0a1785", + "format": 1 + }, + { + "name": "requirements-3.6.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c99d4c779657b6c6e4edcc203de996e1a1419162542bede07f4262f4fd15b10d", + "format": 1 + } + ], + "format": 1 +}
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/community/mongodb/MANIFEST.json b/collections-debian-merged/ansible_collections/community/mongodb/MANIFEST.json new file mode 100644 index 00000000..98af960a --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/MANIFEST.json @@ -0,0 +1,40 @@ +{ + "collection_info": { + "namespace": "community", + "name": "mongodb", + "version": "1.2.0", + "authors": [ + "Ansible (https://github.com/ansible)", + "Rhys Campbell (https://github.com/rhysmeister)", + "Andrew Klychkov (https://github.com/Andersson007)", + "Marcos Diez (https://github.com/marcosdiez)", + "Elliott Foster (http://fourkitchens.com)", + "Loic Blot (http://www.infopro-digital.com/)", + "Matt Martz (https://github.com/sivel)" + ], + "readme": "README.md", + "tags": [ + "mongodb", + "database", + "nosql" + ], + "description": null, + "license": [], + "license_file": "COPYING", + "dependencies": { + "community.general": ">=1.0.0" + }, + "repository": "https://github.com/ansible-collections/community.mongodb", + "documentation": "https://github.com/ansible-collections/community.mongodb/tree/master/docs", + "homepage": "https://github.com/ansible-collections/community.mongodb", + "issues": "https://github.com/ansible-collections/community.mongodb" + }, + "file_manifest_file": { + "name": "FILES.json", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a28db0f0ec1bec6116ffe0c4a17db1de33745b923d9aea4eae92bebd2b7e859b", + "format": 1 + }, + "format": 1 +}
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/community/mongodb/README.md b/collections-debian-merged/ansible_collections/community/mongodb/README.md new file mode 100644 index 00000000..0637bab7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/README.md @@ -0,0 +1,109 @@ +# Mongodb Collection +|Category|Status| +|---|---| +|Github CI|![CI](https://github.com/ansible-collections/community.mongodb/workflows/CI/badge.svg)| +|Github Docs|![documentation](https://github.com/ansible-collections/community.mongodb/workflows/documentation/badge.svg)| +|Codecov|[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.mongodb)](https://codecov.io/gh/ansible-collections/community.mongodb)| +|CI Roles|![CI_roles](https://github.com/ansible-collections/community.mongodb/workflows/CI_roles/badge.svg)| +|MongoDB Clusters|![CI](https://github.com/rhysmeister/AutomatingMongoDBWithAnsible/workflows/CI/badge.svg)| +|Latest Build|![Build & Publish Collection](https://github.com/ansible-collections/community.mongodb/workflows/Build%20&%20Publish%20Collection/badge.svg)| + +This collection called `mongodb` aims at providing all Ansible modules allowing to interact with MongoDB. +The modules present in Ansible 2.9 are included in this collection and will benefit from the evolutions and quality requirements from this collection. + +As this is an independent collection, it can be released on its own release cadence. + +## Running the integration and unit tests + +* Requirements + * [Python 3.5+](https://www.python.org/) + * [pip](https://pypi.org/project/pip/) + * [virtualenv](https://virtualenv.pypa.io/en/latest/) or [pipenv](https://pypi.org/project/pipenv/) if you prefer. + * [git](https://git-scm.com/) + * [docker](https://www.docker.com/) + +* Useful Links + * [Pip & Virtual Environments](https://docs.python-guide.org/dev/virtualenvs/) + * [Ansible Integration Tests](https://docs.ansible.com/ansible/latest/dev_guide/testing_integration.html) + +The ansible-test tool requires a specific directory hierarchy to function correctly so please follow carefully. + +* Create the required directory structure. N-B. The ansible-test tool requires this format. + +```bash +mkdir -p git/ansible_collections/community +cd git/ansible_collections/community +``` + +* Clone the required projects. + +```bash +git clone https://github.com/ansible-collections/community.mongodb.git ./mongodb +git clone https://github.com/ansible-collections/community.general.git ./general +``` + +* Create and activate a virtual environment. + +```bash +virtualenv venv +source venv/bin/activate +``` + +* Change to the project directory. + +```bash +cd mongodb +``` + +* Install the devel branch of ansible-base. + +```bash +pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check +``` + +* Run integration tests for the mongodb_shard module. + +```bash +ansible-test integration --docker default -v --color --python 3.6 mongodb_shard +``` + +* Run integration tests for the mongodb_status module. + +```bash +ansible-test integration --docker default -v --color --python 3.6 mongodb_status +``` + +* Run integration tests for the mongodb_oplog module. + +```bash +ansible-test integration --docker ubuntu1804 -v --color --python 3.6 mongodb_oplog +``` + +* Run tests for everything in the collection. + +```bash +ansible-test integration --docker default -v --color --python 3.6 +``` + +* Run the units tests + +```bash +ansible-test units --docker default -v --color --python 3.6 +``` + +## GitHub workflow + +* Maintainers would be members of this GitHub Repo +* Branch protections could be used to enforce 1 (or 2) reviews from relevant maintainers [CODEOWNERS](.github/CODEOWNERS) + +## Contributing + +Any contribution is welcome and we only ask contributors to: +* Provide *at least* integration tests for any contribution. +* Create an issue for any significant contribution that would change a large portion of the codebase. + +## License + +GNU General Public License v3.0 or later + +See LICENCING to see the full text. diff --git a/collections-debian-merged/ansible_collections/community/mongodb/changelogs/.plugin-cache.yaml b/collections-debian-merged/ansible_collections/community/mongodb/changelogs/.plugin-cache.yaml new file mode 100644 index 00000000..fba131ea --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/changelogs/.plugin-cache.yaml @@ -0,0 +1,89 @@ +plugins: + become: {} + cache: + mongodb: + description: Use MongoDB for caching + name: mongodb + version_added: null + callback: {} + cliconf: {} + connection: {} + httpapi: {} + inventory: {} + lookup: + mongodb: + description: lookup info from MongoDB + name: mongodb + version_added: '2.3' + module: + mongodb_balancer: + description: Manages the MongoDB Sharded Cluster Balancer. + name: mongodb_balancer + namespace: '' + version_added: 1.0.0 + mongodb_index: + description: Creates or drops indexes on MongoDB collections. + name: mongodb_index + namespace: '' + version_added: 1.0.0 + mongodb_info: + description: Gather information about MongoDB instance. + name: mongodb_info + namespace: '' + version_added: 1.0.0 + mongodb_maintenance: + description: Enables or disables maintenance mode for a secondary member. + name: mongodb_maintenance + namespace: '' + version_added: 1.0.0 + mongodb_oplog: + description: Resizes the MongoDB oplog. + name: mongodb_oplog + namespace: '' + version_added: 1.0.0 + mongodb_parameter: + description: Change an administrative parameter on a MongoDB server + name: mongodb_parameter + namespace: '' + version_added: 1.0.0 + mongodb_replicaset: + description: Initialises a MongoDB replicaset. + name: mongodb_replicaset + namespace: '' + version_added: 1.0.0 + mongodb_shard: + description: Add or remove shards from a MongoDB Cluster + name: mongodb_shard + namespace: '' + version_added: 1.0.0 + mongodb_shell: + description: Run commands via the MongoDB shell. + name: mongodb_shell + namespace: '' + version_added: 1.1.0 + mongodb_shutdown: + description: Cleans up all database resources and then terminates the mongod/mongos + process. + name: mongodb_shutdown + namespace: '' + version_added: 1.0.0 + mongodb_status: + description: Validates the status of the cluster. + name: mongodb_status + namespace: '' + version_added: 1.0.0 + mongodb_stepdown: + description: Step down the MongoDB node from a PRIMARY state. + name: mongodb_stepdown + namespace: '' + version_added: 1.0.0 + mongodb_user: + description: Adds or removes a user from a MongoDB database + name: mongodb_user + namespace: '' + version_added: 1.0.0 + netconf: {} + shell: {} + strategy: {} + vars: {} +version: 1.1.0 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/changelogs/changelog.yaml b/collections-debian-merged/ansible_collections/community/mongodb/changelogs/changelog.yaml new file mode 100644 index 00000000..74f91af3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/changelogs/changelog.yaml @@ -0,0 +1,52 @@ +ancestor: null +releases: + 1.0.0: + modules: + - description: Manages the MongoDB Sharded Cluster Balancer. + name: mongodb_balancer + namespace: '' + - description: Creates or drops indexes on MongoDB collections. + name: mongodb_index + namespace: '' + - description: Gather information about MongoDB instance. + name: mongodb_info + namespace: '' + - description: Enables or disables maintenance mode for a secondary member. + name: mongodb_maintenance + namespace: '' + - description: Resizes the MongoDB oplog. + name: mongodb_oplog + namespace: '' + - description: Change an administrative parameter on a MongoDB server + name: mongodb_parameter + namespace: '' + - description: Initialises a MongoDB replicaset. + name: mongodb_replicaset + namespace: '' + - description: Add or remove shards from a MongoDB Cluster + name: mongodb_shard + namespace: '' + - description: Cleans up all database resources and then terminates the mongod/mongos + process. + name: mongodb_shutdown + namespace: '' + - description: Validates the status of the cluster. + name: mongodb_status + namespace: '' + - description: Step down the MongoDB node from a PRIMARY state. + name: mongodb_stepdown + namespace: '' + - description: Adds or removes a user from a MongoDB database + name: mongodb_user + namespace: '' + release_date: '2020-08-06' + 1.1.0: + modules: + - description: Run commands via the MongoDB shell. + name: mongodb_shell + namespace: '' + release_date: '2020-10-24' + 1.1.1: + bugfixes: + - 235 - Fix namespace. + release_date: '2020-11-04' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/changelogs/config.yaml b/collections-debian-merged/ansible_collections/community/mongodb/changelogs/config.yaml new file mode 100644 index 00000000..c87d4a7d --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/changelogs/config.yaml @@ -0,0 +1,31 @@ +changelog_filename_template: ../CHANGELOG.rst +changelog_filename_version_depth: 0 +changes_file: changelog.yaml +changes_format: combined +ignore_other_fragment_extensions: true +keep_fragments: false +mention_ancestor: true +new_plugins_after_name: removed_features +notesdir: fragments +prelude_section_name: release_summary +prelude_section_title: Release Summary +sections: +- - major_changes + - Major Changes +- - minor_changes + - Minor Changes +- - breaking_changes + - Breaking Changes / Porting Guide +- - deprecated_features + - Deprecated Features +- - removed_features + - Removed Features (previously deprecated) +- - security_fixes + - Security Fixes +- - bugfixes + - Bugfixes +- - known_issues + - Known Issues +title: Community.Mongodb +trivial_section_name: trivial +use_fqcn: true diff --git a/collections-debian-merged/ansible_collections/community/mongodb/meta/runtime.yml b/collections-debian-merged/ansible_collections/community/mongodb/meta/runtime.yml new file mode 100644 index 00000000..2ee3c9fa --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/meta/runtime.yml @@ -0,0 +1,2 @@ +--- +requires_ansible: '>=2.9.10' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/cache/__init__.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/cache/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/cache/__init__.py diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/cache/mongodb.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/cache/mongodb.py new file mode 100644 index 00000000..7a47bb97 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/cache/mongodb.py @@ -0,0 +1,200 @@ +# (c) 2018, Matt Martz <matt@sivel.net> +# 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) +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = ''' + cache: mongodb + name: mongodb + author: Matt Martz + short_description: Use MongoDB for caching + description: + - This cache uses per host records saved in MongoDB. + requirements: + - pymongo>=3 + options: + _uri: + description: + - MongoDB Connection String URI + required: False + env: + - name: ANSIBLE_CACHE_PLUGIN_CONNECTION + ini: + - key: fact_caching_connection + section: defaults + _prefix: + description: User defined prefix to use when creating the DB entries + default: ansible_facts + env: + - name: ANSIBLE_CACHE_PLUGIN_PREFIX + ini: + - key: fact_caching_prefix + section: defaults + _timeout: + default: 86400 + description: Expiration timeout in seconds for the cache plugin data. Set to 0 to never expire + env: + - name: ANSIBLE_CACHE_PLUGIN_TIMEOUT + ini: + - key: fact_caching_timeout + section: defaults + type: integer +''' + +import datetime + +from contextlib import contextmanager + +from ansible import constants as C +from ansible.errors import AnsibleError +from ansible.plugins.cache import BaseCacheModule +from ansible.utils.display import Display +from ansible.module_utils._text import to_native + + +try: + import pymongo +except ImportError: + raise AnsibleError("The 'pymongo' python module is required for the mongodb fact cache, 'pip install pymongo>=3.0'") + +display = Display() + + +class CacheModule(BaseCacheModule): + """ + A caching module backed by mongodb. + """ + def __init__(self, *args, **kwargs): + try: + super(CacheModule, self).__init__(*args, **kwargs) + self._connection = self.get_option('_uri') + self._timeout = int(self.get_option('_timeout')) + self._prefix = self.get_option('_prefix') + except KeyError: + self._connection = C.CACHE_PLUGIN_CONNECTION + self._timeout = int(C.CACHE_PLUGIN_TIMEOUT) + self._prefix = C.CACHE_PLUGIN_PREFIX + + self._cache = {} + self._managed_indexes = False + + def _ttl_index_exists(self, collection): + ''' + Returns true if an index named ttl exists + on the given collection. + ''' + exists = False + try: + indexes = collection.list_indexes() + for index in indexes: + if index["name"] == "ttl": + exists = True + break + except pymongo.errors.OperationFailure as excep: + raise AnsibleError('Error checking MongoDB index: %s' % to_native(excep)) + return exists + + def _manage_indexes(self, collection): + ''' + This function manages indexes on the mongo collection. + We only do this once, at run time based on _managed_indexes, + rather than per connection instantiation as that would be overkill + ''' + _timeout = self._timeout + if _timeout and _timeout > 0: + try: + collection.create_index( + 'date', + name='ttl', + expireAfterSeconds=_timeout + ) + except pymongo.errors.OperationFailure: + # We make it here when the fact_caching_timeout was set to a different value between runs + if self._ttl_index_exists(collection): + collection.drop_index('ttl') + return self._manage_indexes(collection) + else: + if self._ttl_index_exists(collection): + collection.drop_index('ttl') + + @contextmanager + def _collection(self): + ''' + This is a context manager for opening and closing mongo connections as needed. This exists as to not create a global + connection, due to pymongo not being fork safe (http://api.mongodb.com/python/current/faq.html#is-pymongo-fork-safe) + ''' + mongo = pymongo.MongoClient(self._connection) + try: + db = mongo.get_default_database() + except pymongo.errors.ConfigurationError: + # We'll fall back to using ``ansible`` as the database if one was not provided + # in the MongoDB Connection String URI + db = mongo['ansible'] + + # The collection is hard coded as ``cache``, there are no configuration options for this + collection = db['cache'] + if not self._managed_indexes: + # Only manage the indexes once per run, not per connection + self._manage_indexes(collection) + self._managed_indexes = True + + yield collection + + mongo.close() + + def _make_key(self, key): + return '%s%s' % (self._prefix, key) + + def get(self, key): + if key not in self._cache: + with self._collection() as collection: + value = collection.find_one({'_id': self._make_key(key)}) + self._cache[key] = value['data'] + + return self._cache.get(key) + + def set(self, key, value): + self._cache[key] = value + with self._collection() as collection: + collection.update_one( + {'_id': self._make_key(key)}, + { + '$set': { + '_id': self._make_key(key), + 'data': value, + 'date': datetime.datetime.utcnow() + } + }, + upsert=True + ) + + def keys(self): + with self._collection() as collection: + return [doc['_id'] for doc in collection.find({}, {'_id': True})] + + def contains(self, key): + with self._collection() as collection: + return bool(collection.count({'_id': self._make_key(key)})) + + def delete(self, key): + del self._cache[key] + with self._collection() as collection: + collection.delete_one({'_id': self._make_key(key)}) + + def flush(self): + with self._collection() as collection: + collection.delete_many({}) + + def copy(self): + with self._collection() as collection: + return dict((d['_id'], d['data']) for d in collection.find({})) + + def __getstate__(self): + return dict() + + def __setstate__(self, data): + self.__init__() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/doc_fragments/login_options.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/doc_fragments/login_options.py new file mode 100644 index 00000000..9d6cbdb0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/doc_fragments/login_options.py @@ -0,0 +1,39 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +class ModuleDocFragment(object): + # Standard documentation + DOCUMENTATION = r''' +options: + login_user: + description: + - The MongoDB user to login with. + - Required when I(login_password) is specified. + required: no + type: str + login_password: + description: + - The password used to authenticate with. + - Required when I(login_user) is specified. + required: no + type: str + login_database: + description: + - The database where login credentials are stored. + required: no + type: str + default: 'admin' + login_host: + description: + - The host running MongoDB instance to login to. + required: no + type: str + default: 'localhost' + login_port: + description: + - The MongoDB server port to login to. + required: no + type: int + default: 27017 +''' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/doc_fragments/ssl_options.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/doc_fragments/ssl_options.py new file mode 100644 index 00000000..f5fd59f3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/doc_fragments/ssl_options.py @@ -0,0 +1,69 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +class ModuleDocFragment(object): + # Standard documentation + DOCUMENTATION = r''' +options: + ssl: + description: + - Whether to use an SSL connection when connecting to the database. + required: no + type: bool + default: no + ssl_cert_reqs: + description: + - Specifies whether a certificate is required from the other side of the connection, + and whether it will be validated if provided. + required: no + type: str + default: 'CERT_REQUIRED' + choices: + - 'CERT_NONE' + - 'CERT_OPTIONAL' + - 'CERT_REQUIRED' + ssl_ca_certs: + description: + - The ssl_ca_certs option takes a path to a CA file. + required: no + type: str + ssl_crlfile: + description: + - The ssl_crlfile option takes a path to a CRL file. + required: no + type: str + ssl_certfile: + description: + - Present a client certificate using the ssl_certfile option. + required: no + type: str + ssl_keyfile: + description: + - Private key for the client certificate. + required: no + type: str + ssl_pem_passphrase: + description: + - Passphrase to decrypt encrypted private keys. + required: no + type: str + auth_mechanism: + description: + - Authentication type. + required: no + type: str + choices: + - 'SCRAM-SHA-256' + - 'SCRAM-SHA-1' + - 'MONGODB-X509' + - 'GSSAPI' + - 'PLAIN' + connection_options: + description: + - Additional connection options. + - Supply as a list of dicts or strings containing key value pairs seperated with '='. + required: no + type: list + elements: raw +''' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/lookup/__init__.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/lookup/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/lookup/__init__.py diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/lookup/mongodb.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/lookup/mongodb.py new file mode 100644 index 00000000..adb4daa5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/lookup/mongodb.py @@ -0,0 +1,268 @@ +# (c) 2016, Marcos Diez <marcos@unitron.com.br> +# https://github.com/marcosdiez/ +# +# 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/>. + +from __future__ import (absolute_import, division, print_function) + +__metaclass__ = type + +DOCUMENTATION = ''' + author: 'Marcos Diez <marcos (at) unitron.com.br>' + lookup: mongodb + name: mongodb + version_added: "2.3" + short_description: lookup info from MongoDB + description: + - 'The ``MongoDB`` lookup runs the *find()* command on a given *collection* on a given *MongoDB* server.' + - 'The result is a list of jsons, so slightly different from what PyMongo returns. In particular, *timestamps* are converted to epoch integers.' + options: + connect_string: + description: + - Can be any valid MongoDB connection string, supporting authentication, replica sets, etc. + - "More info at U(https://docs.mongodb.org/manual/reference/connection-string/)" + default: "mongodb://localhost/" + database: + description: + - Name of the database which the query will be made + required: True + collection: + description: + - Name of the collection which the query will be made + required: True + filter: + description: + - Criteria of the output + type: 'dict' + default: '{}' + projection: + description: + - Fields you want returned + type: dict + default: "{}" + skip: + description: + - How many results should be skipped + type: integer + limit: + description: + - How many results should be shown + type: integer + sort: + description: + - Sorting rules. + - Please use the strings C(ASCENDING) and C(DESCENDING) to set the order. + - Check the example for more information. + type: list + default: "[]" + extra_connection_parameters: + description: + - Extra connection parameters that to be sent to pymongo.MongoClient + - Check the example to see how to connect to mongo using an SSL certificate. + - "All possible parameters are here: U(https://api.mongodb.com/python/current/api/pymongo/mongo_client.html#pymongo.mongo_client.MongoClient)" + type: dict + default: "{}" + notes: + - "Please check https://api.mongodb.org/python/current/api/pymongo/collection.html?highlight=find#pymongo.collection.Collection.find for more details." + requirements: + - pymongo >= 2.4 (python library) +''' + +EXAMPLES = ''' +- hosts: localhost + gather_facts: false + vars: + mongodb_parameters: + #mandatory parameters + database: 'local' + collection: "startup_log" + #optional + connection_string: "mongodb://localhost/" + # connection_string: "mongodb://username:password@my.server.com:27017/" + # extra_connection_parameters: { "ssl" : True , "ssl_certfile": /etc/self_signed_certificate.pem" } + #optional query parameters, we accept any parameter from the normal mongodb query. + # filter: { "hostname": "u18" } + projection: { "pid": True , "_id" : False , "hostname" : True } + skip: 0 + limit: 1 + sort: [ [ "startTime" , "ASCENDING" ] , [ "age", "DESCENDING" ] ] + tasks: + - debug: msg="The PID from MongoDB is {{ lookup('mongodb', mongodb_parameters ).pid }}" + + - debug: msg="The HostName from the MongoDB server is {{ lookup('mongodb', mongodb_parameters ).hostname }}" + + - debug: msg="Mongo DB is stored at {{ lookup('mongodb', mongodb_parameters_inline )}}" + vars: + mongodb_parameters_inline: + database: 'local' + collection: "startup_log" + connection_string: "mongodb://localhost/" + limit: 1 + projection: { "cmdline.storage": True } + + # lookup syntax, does the same as below + - debug: msg="The hostname is {{ item.hostname }} and the pid is {{ item.pid }}" + loop: "{{ lookup('mongodb', mongodb_parameters, wantlist=True) }}" + + # query syntax, does the same as above + - debug: msg="The hostname is {{ item.hostname }} and the pid is {{ item.pid }}" + loop: "{{ query('mongodb', mongodb_parameters) }}" + + - name: "Raw output from the mongodb lookup (a json with pid and hostname )" + debug: msg="{{ lookup('mongodb', mongodb_parameters) }}" + + - name: "Yet another mongodb query, now with the parameters on the task itself" + debug: msg="pid={{item.pid}} hostname={{item.hostname}} version={{ item.buildinfo.version }}" + with_mongodb: + - database: 'local' + collection: "startup_log" + connection_string: "mongodb://localhost/" + limit: 1 + projection: { "pid": True , "hostname": True , "buildinfo.version": True } + + # Please notice this specific query may result more than one result. This is expected + - name: "Shows the whole output from mongodb" + debug: msg="{{ item }}" + with_mongodb: + - database: 'local' + collection: "startup_log" + connection_string: "mongodb://localhost/" + + +''' + +RETURN = """ + _list_of_jsons: + description: + - a list of JSONs with the results of the MongoDB query. + type: list +""" + +import datetime + +from ansible.module_utils.six import string_types, integer_types +from ansible.module_utils._text import to_native +from ansible.errors import AnsibleError +from ansible.plugins.lookup import LookupBase + +try: + from pymongo import ASCENDING, DESCENDING + from pymongo.errors import ConnectionFailure + from pymongo import MongoClient +except ImportError: + try: # for older PyMongo 2.2 + from pymongo import Connection as MongoClient + except ImportError: + pymongo_found = False + else: + pymongo_found = True +else: + pymongo_found = True + + +class LookupModule(LookupBase): + + def _fix_sort_parameter(self, sort_parameter): + if sort_parameter is None: + return sort_parameter + + if not isinstance(sort_parameter, list): + raise AnsibleError(u"Error. Sort parameters must be a list, not [ {0} ]".format(sort_parameter)) + + for item in sort_parameter: + self._convert_sort_string_to_constant(item) + + return sort_parameter + + def _convert_sort_string_to_constant(self, item): + original_sort_order = item[1] + sort_order = original_sort_order.upper() + if sort_order == u"ASCENDING": + item[1] = ASCENDING + elif sort_order == u"DESCENDING": + item[1] = DESCENDING + # else the user knows what s/he is doing and we won't predict. PyMongo will return an error if necessary + + def convert_mongo_result_to_valid_json(self, result): + if result is None: + return result + if isinstance(result, integer_types + (float, bool)): + return result + if isinstance(result, string_types): + return result + elif isinstance(result, list): + new_list = [] + for elem in result: + new_list.append(self.convert_mongo_result_to_valid_json(elem)) + return new_list + elif isinstance(result, dict): + new_dict = {} + for key in result.keys(): + value = result[key] # python2 and 3 compatible.... + new_dict[key] = self.convert_mongo_result_to_valid_json(value) + return new_dict + elif isinstance(result, datetime.datetime): + # epoch + return (result - datetime.datetime(1970, 1, 1)). total_seconds() + else: + # failsafe + return u"{0}".format(result) + + def run(self, terms, variables, **kwargs): + try: + return self._run_helper(terms) + except Exception as e: + print(u"There was an exception on the mongodb_lookup: {0}".format(to_native(e))) + raise e + + def _run_helper(self, terms): + if not pymongo_found: + raise AnsibleError(u"pymongo is required in the control node (this machine) for mongodb lookup.") + ret = [] + for term in terms: + for required_parameter in [u"database", u"collection"]: + if required_parameter not in term: + raise AnsibleError(u"missing mandatory parameter [{0}]".format(required_parameter)) + + connection_string = term.get(u'connection_string', u"mongodb://localhost") + database = term[u"database"] + collection = term[u'collection'] + extra_connection_parameters = term.get(u'extra_connection_parameters', {}) + + if u"extra_connection_parameters" in term: + del term[u"extra_connection_parameters"] + if u"connection_string" in term: + del term[u"connection_string"] + del term[u"database"] + del term[u"collection"] + + if u"sort" in term: + term[u"sort"] = self._fix_sort_parameter(term[u"sort"]) + + # all other parameters are sent to mongo, so we are future and past proof + + try: + client = MongoClient(connection_string, **extra_connection_parameters) + results = client[database][collection].find(**term) + + for result in results: + result = self.convert_mongo_result_to_valid_json(result) + ret.append(result) + + except ConnectionFailure as e: + raise AnsibleError(u'unable to connect to database: %s' % str(e)) + + return ret diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/module_utils/__init__.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/module_utils/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/module_utils/__init__.py diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/module_utils/mongodb_common.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/module_utils/mongodb_common.py new file mode 100644 index 00000000..a8ba655e --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/module_utils/mongodb_common.py @@ -0,0 +1,207 @@ +from __future__ import absolute_import, division, print_function +__metaclass__ = type +from ansible.module_utils.basic import AnsibleModule, missing_required_lib +from ansible.module_utils.six.moves import configparser +from distutils.version import LooseVersion +import traceback +import os +import ssl as ssl_lib + +MongoClient = None +PYMONGO_IMP_ERR = None +pymongo_found = None +PyMongoVersion = None +ConnectionFailure = None +OperationFailure = None + +try: + from pymongo.errors import ConnectionFailure + from pymongo.errors import OperationFailure + from pymongo import version as PyMongoVersion + from pymongo import MongoClient + pymongo_found = True +except ImportError: + PYMONGO_IMP_ERR = traceback.format_exc() + pymongo_found = False + + +def check_compatibility(module, srv_version, driver_version): + """Check the compatibility between the driver and the database. + + See: https://docs.mongodb.com/ecosystem/drivers/driver-compatibility-reference/#python-driver-compatibility + + Args: + module: Ansible module. + srv_version (LooseVersion): MongoDB server version. + driver_version (LooseVersion): Pymongo version. + """ + msg = 'pymongo driver version and MongoDB version are incompatible: ' + + if srv_version >= LooseVersion('4.2') and driver_version < LooseVersion('3.9'): + msg += 'you must use pymongo 3.9+ with MongoDB >= 4.2' + module.fail_json(msg=msg) + + elif srv_version >= LooseVersion('4.0') and driver_version < LooseVersion('3.7'): + msg += 'you must use pymongo 3.7+ with MongoDB >= 4.0' + module.fail_json(msg=msg) + + elif srv_version >= LooseVersion('3.6') and driver_version < LooseVersion('3.6'): + msg += 'you must use pymongo 3.6+ with MongoDB >= 3.6' + module.fail_json(msg=msg) + + elif srv_version >= LooseVersion('3.4') and driver_version < LooseVersion('3.4'): + msg += 'you must use pymongo 3.4+ with MongoDB >= 3.4' + module.fail_json(msg=msg) + + elif srv_version >= LooseVersion('3.2') and driver_version < LooseVersion('3.2'): + msg += 'you must use pymongo 3.2+ with MongoDB >= 3.2' + module.fail_json(msg=msg) + + elif srv_version >= LooseVersion('3.0') and driver_version <= LooseVersion('2.8'): + msg += 'you must use pymongo 2.8+ with MongoDB 3.0' + module.fail_json(msg=msg) + + elif srv_version >= LooseVersion('2.6') and driver_version <= LooseVersion('2.7'): + msg += 'you must use pymongo 2.7+ with MongoDB 2.6' + module.fail_json(msg=msg) + + +def load_mongocnf(): + config = configparser.RawConfigParser() + mongocnf = os.path.expanduser('~/.mongodb.cnf') + + try: + config.readfp(open(mongocnf)) + except (configparser.NoOptionError, IOError): + return False + + creds = dict( + user=config.get('client', 'user'), + password=config.get('client', 'pass') + ) + + return creds + + +def index_exists(client, database, collection, index_name): + """ + Returns true if an index on the collection exists with the given name + @client: MongoDB connection. + @database: MongoDB Database. + @collection: MongoDB collection. + @index_name: The index name. + """ + exists = False + indexes = client[database][collection].list_indexes() + for index in indexes: + if index["name"] == index_name: + exists = True + return exists + + +def create_index(client, database, collection, keys, options): + """ + Creates an index on the given collection + @client: MongoDB connection. + @database: MongoDB Database - str. + @collection: MongoDB collection - str. + @keys: Specification of index - dict. + """ + client[database][collection].create_index(list(keys.items()), + **options) + + +def drop_index(client, database, collection, index_name): + client[database][collection].drop_index(index_name) + + +def member_state(client): + """Check if a replicaset exists. + + Args: + client (cursor): Mongodb cursor on admin database. + + Returns: + str: member state i.e. PRIMARY, SECONDARY + """ + state = None + doc = client['admin'].command('replSetGetStatus') + for member in doc["members"]: + if "self" in member.keys(): + state = str(member['stateStr']) + return state + + +def mongodb_common_argument_spec(ssl_options=True): + """ + Returns a dict containing common options shared across the MongoDB modules. + """ + options = dict( + login_user=dict(type='str', required=False), + login_password=dict(type='str', required=False, no_log=True), + login_database=dict(type='str', required=False, default='admin'), + login_host=dict(type='str', required=False, default='localhost'), + login_port=dict(type='int', required=False, default=27017), + ) + ssl_options_dict = dict( + ssl=dict(type='bool', required=False, default=False), + ssl_cert_reqs=dict(type='str', + required=False, + default='CERT_REQUIRED', + choices=['CERT_NONE', + 'CERT_OPTIONAL', + 'CERT_REQUIRED']), + ssl_ca_certs=dict(type='str', default=None), + ssl_crlfile=dict(type='str', default=None), + ssl_certfile=dict(type='str', default=None), + ssl_keyfile=dict(type='str', default=None), + ssl_pem_passphrase=dict(type='str', default=None, no_log=True), + auth_mechanism=dict(type='str', + required=False, + default=None, + choices=['SCRAM-SHA-256', + 'SCRAM-SHA-1', + 'MONGODB-X509', + 'GSSAPI', + 'PLAIN']), + connection_options=dict(type='list', + elements='raw', + default=None) + ) + if ssl_options: + options.update(ssl_options_dict) + return options + + +def add_option_if_not_none(param_name, module, connection_params): + ''' + @param_name - The parameter name to check + @module - The ansible module object + @connection_params - Dict containing the connection params + ''' + if module.params[param_name] is not None: + connection_params[param_name] = module.params[param_name] + return connection_params + + +def ssl_connection_options(connection_params, module): + connection_params['ssl'] = True + if module.params['ssl_cert_reqs'] is not None: + connection_params['ssl_cert_reqs'] = getattr(ssl_lib, module.params['ssl_cert_reqs']) + connection_params = add_option_if_not_none('ssl_ca_certs', module, connection_params) + connection_params = add_option_if_not_none('ssl_crlfile', module, connection_params) + connection_params = add_option_if_not_none('ssl_certfile', module, connection_params) + connection_params = add_option_if_not_none('ssl_keyfile', module, connection_params) + connection_params = add_option_if_not_none('ssl_pem_passphrase', module, connection_params) + if module.params['auth_mechanism'] is not None: + connection_params['authMechanism'] = module.params['auth_mechanism'] + if module.params['connection_options'] is not None: + for item in module.params['connection_options']: + if isinstance(item, dict): + for key, value in item.items(): + connection_params[key] = value + elif isinstance(item, str) and "=" in item: + connection_params[item.split('=')[0]] = item.split('=')[1] + else: + raise ValueError("Invalid value supplied in connection_options: {0} .".format(str(item))) + return connection_params diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/__init__.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/__init__.py diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_balancer.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_balancer.py new file mode 100644 index 00000000..85c0e70f --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_balancer.py @@ -0,0 +1,511 @@ +#!/usr/bin/python + +# Copyright: (c) 2020, Rhys Campbell <rhys.james.campbell@googlemail.com> +# 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 +__metaclass__ = type + + +DOCUMENTATION = r''' +--- +module: mongodb_balancer +short_description: Manages the MongoDB Sharded Cluster Balancer. +description: + - Manages the MongoDB Sharded Cluster Balancer. + - Start or stop the balancer. + - Adjust the cluster chunksize. + - Enable or disable autosplit. + - Adds or remove a balancer window. +author: Rhys Campbell (@rhysmeister) +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + autosplit: + description: + - Disable or enable the autosplit flag in the config.settings collection. + required: false + type: bool + chunksize: + description: + - Control the size of chunks in the sharded cluster. + - Value should be given in MB. + required: false + type: int + state: + description: + - Manage the Balancer for the Cluster + required: false + type: str + choices: + - "started" + - "stopped" + default: "started" + mongos_process: + description: + - Provide a custom name for the mongos process. + - Most users can ignore this setting. + required: false + type: str + default: "mongos" + window: + description: + - Schedule the balancer window. + - Provide the following dictionary keys start, stop, state + - The state key should be "present" or "absent". + - The start and stop keys are ignored when state is "absent". + - start and stop should be strings in "HH:MM" format indicating the time bounds of the window. + type: raw + required: false +notes: + - Requires the pymongo Python package on the remote host, version 2.4.2+. This + can be installed using pip or the OS package manager. @see U(http://api.mongodb.org/python/current/installation.html) +requirements: + - pymongo +''' + +EXAMPLES = r''' +- name: Start the balancer + community.mongodb.mongodb_balancer: + state: started + +- name: Stop the balancer and disable autosplit + community.mongodb.mongodb_balancer: + state: stopped + autosplit: false + +- name: Enable autosplit + community.mongodb.mongodb_balancer: + autosplit: true + +- name: Change the default chunksize to 128MB + community.mongodb.mongodb_balancer: + chunksize: 128 + +- name: Add or update a balancing window + community.mongodb.mongodb_balancer: + window: + start: "23:00" + stop: "06:00" + state: "present" + +- name: Remove a balancing window + community.mongodb.mongodb_balancer: + window: + state: "absent" +''' + +RETURN = r''' +changed: + description: Whether the balancer state or autosplit changed. + returned: success + type: bool +old_balancer_state: + description: The previous state of the balancer + returned: When balancer state is changed + type: str +new_balancer_state: + description: The new state of the balancer. + returned: When balancer state is changed + type: str +old_autosplit: + description: The previous state of autosplit. + returned: When autosplit is changed. + type: str +new_autosplit: + description: The new state of autosplit. + returned: When autosplit is changed. + type: str +old_chunksize: + description: The previous value for chunksize. + returned: When chunksize is changed. + type: int +new_chunksize: + description: The new value for chunksize. + returned: When chunksize is changed. + type: int +msg: + description: A short description of what happened. + returned: failure + type: str +failed: + description: If something went wrong + returned: failed + type: bool +''' + +from copy import deepcopy + +import os +import ssl as ssl_lib +from distutils.version import LooseVersion +import time +import traceback + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_native +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + load_mongocnf, + mongodb_common_argument_spec, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + PyMongoVersion, + PYMONGO_IMP_ERR, + pymongo_found, + MongoClient +) + +has_ordereddict = False +try: + from collections import OrderedDict + has_ordereddict = True +except ImportError as excep: + try: + from ordereddict import OrderedDict + has_ordereddict = True + except ImportError as excep: + pass + + +def get_balancer_state(client): + ''' + Gets the state of the MongoDB balancer. The config.settings collection does + not exist until the balancer has been started for the first time + { "_id" : "balancer", "mode" : "full", "stopped" : false } + { "_id" : "autosplit", "enabled" : true } + ''' + balancer_state = None + result = client["config"].settings.find_one({"_id": "balancer"}) + if not result: + balancer_state = "stopped" + else: + if result['stopped'] is False: + balancer_state = "started" + else: + balancer_state = "stopped" + return balancer_state + + +def stop_balancer(client): + ''' + Stops MongoDB balancer + ''' + cmd_doc = OrderedDict([ + ('balancerStop', 1), + ('maxTimeMS', 60000) + ]) + client['admin'].command(cmd_doc) + time.sleep(1) + + +def start_balancer(client): + ''' + Starts MongoDB balancer + ''' + cmd_doc = OrderedDict([ + ('balancerStart', 1), + ('maxTimeMS', 60000) + ]) + client['admin'].command(cmd_doc) + time.sleep(1) + + +def enable_autosplit(client): + client["config"].settings.update({"_id": "autosplit"}, + {"$set": {"enabled": True}}, + upsert=True, + w="majority") + + +def disable_autosplit(client): + client["config"].settings.update({"_id": "autosplit"}, + {"$set": {"enabled": False}}, + upsert=True, + w="majority") + + +def get_autosplit(client): + autosplit = False + result = client["config"].settings.find_one({"_id": "autosplit"}) + if result is not None: + autosplit = result['enabled'] + return autosplit + + +def get_chunksize(client): + ''' + Default chunksize is 64MB + ''' + chunksize = None + result = client["config"].settings.find_one({"_id": "chunksize"}) + if not result: + chunksize = 64 + else: + chunksize = result['value'] + return chunksize + + +def set_chunksize(client, chunksize): + client["config"].settings.save({"_id": "chunksize", + "value": chunksize}) + + +def set_balancing_window(client, start, stop): + s = False + result = client["config"].settings.update_one({"_id": "balancer"}, + {"$set": { + "activeWindow": { + "start": start, + "stop": stop}}}, + upsert=True) + if result.modified_count == 1 or result.upserted_id is not None: + s = True + return s + + +def remove_balancing_window(client): + s = False + result = client["config"].settings.update_one({"_id": "balancer"}, + {"$unset": {"activeWindow": True}}) + if result.modified_count == 1: + s = True + return s + + +def balancing_window(client, start, stop): + s = False + if start is not None and stop is not None: + result = client["config"].settings.find_one({"_id": "balancer", + "activeWindow.start": start, + "activeWindow.stop": stop}) + else: + result = client["config"].settings.find_one({"_id": "balancer", "activeWindow": {"$exists": True}}) + if result: + s = True + return s + + +def validate_window(window, module): + if window is not None: + if 'state' not in window.keys(): + module.fail_json(msg="Balancing window state must be specified") + elif window['state'] not in ['present', 'absent']: + module.fail_json(msg="Balancing window state must be present or absent") + elif window['state'] == "present" \ + and ("start" not in window.keys() + or "stop" not in window.keys()): + module.fail_json(msg="Balancing window start and stop values must be specified") + return True + + +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + autosplit=dict(type='bool', default=None), + chunksize=dict(type='int', default=None), + mongos_process=dict(type='str', required=False, default="mongos"), + state=dict(type='str', default="started", choices=["started", "stopped"]), + window=dict(type='raw', default=None) + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['login_user', 'login_password']], + ) + + if not has_ordereddict: + module.fail_json(msg='Cannot import OrderedDict class. You can probably install with: pip install ordereddict') + + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_database = module.params['login_database'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + balancer_state = module.params['state'] + autosplit = module.params['autosplit'] + chunksize = module.params['chunksize'] + mongos_process = module.params['mongos_process'] + ssl = module.params['ssl'] + window = module.params['window'] + + # Validate window + validate_window(window, module) + + result = dict( + changed=False, + ) + + connection_params = dict( + host=login_host, + port=int(login_port), + ) + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + try: + client = MongoClient(**connection_params) + except Exception as excep: + module.fail_json(msg='Unable to connect to MongoDB: %s' % to_native(excep)) + + if login_user is None and login_password is None: + mongocnf_creds = load_mongocnf() + if mongocnf_creds is not False: + login_user = mongocnf_creds['user'] + login_password = mongocnf_creds['password'] + elif login_password is None or login_user is None: + module.fail_json(msg="When supplying login arguments, both 'login_user' and 'login_password' must be provided") + + try: + try: + client['admin'].command('listDatabases', 1.0) # if this throws an error we need to authenticate + except Exception as excep: + if excep.code == 13: + if login_user is not None and login_password is not None: + client.admin.authenticate(login_user, login_password, source=login_database) + else: + module.fail_json(msg='No credentials to authenticate: %s' % to_native(excep)) + else: + module.fail_json(msg='Unknown error: %s' % to_native(excep)) + except Exception as excep: + module.fail_json(msg='unable to connect to database: %s' % to_native(excep), exception=traceback.format_exc()) + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + except Exception as excep: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(excep)) + try: + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + except Exception as excep: + module.fail_json(msg='Unable to authenticate with MongoDB: %s' % to_native(excep)) + + changed = False + + cluster_balancer_state = None + cluster_autosplit = None + cluster_chunksize = None + old_balancer_state = None + new_balancer_state = None + old_autosplit = None + new_autosplit = None + old_chunksize = None + new_chunksize = None + + try: + + if client["admin"].command("serverStatus")["process"] != mongos_process: + module.fail_json(msg="Process running on {0}:{1} is not a {2}".format(login_host, login_port, mongos_process)) + + cluster_balancer_state = get_balancer_state(client) + if autosplit is not None: + cluster_autosplit = get_autosplit(client) + if chunksize is not None: + cluster_chunksize = get_chunksize(client) + + if module.check_mode: + if balancer_state != cluster_balancer_state: + old_balancer_state = cluster_balancer_state + new_balancer_state = balancer_state + changed = True + if (autosplit is not None + and autosplit != cluster_autosplit): + old_autosplit = cluster_autosplit + new_autosplit = autosplit + changed = True + if (chunksize is not None + and chunksize != cluster_chunksize): + old_chunksize = cluster_chunksize + new_chunksize = chunksize + changed = True + if window is not None: + if balancing_window(client, window.get('start'), window.get('stop')): + if window['state'] == "present": + pass + else: + changed = True + else: + if window['state'] == "present": + changed = True + else: + pass + else: + if balancer_state is not None \ + and balancer_state != cluster_balancer_state: + if balancer_state == "started": + start_balancer(client) + old_balancer_state = cluster_balancer_state + new_balancer_state = get_balancer_state(client) + changed = True + else: + stop_balancer(client) + old_balancer_state = cluster_balancer_state + new_balancer_state = get_balancer_state(client) + changed = True + if autosplit is not None \ + and autosplit != cluster_autosplit: + if autosplit: + enable_autosplit(client) + old_autosplit = cluster_autosplit + new_autosplit = autosplit + changed = True + else: + disable_autosplit(client) + old_autosplit = cluster_autosplit + new_autosplit = autosplit + changed = True + if (chunksize is not None + and chunksize != cluster_chunksize): + set_chunksize(client, chunksize) + old_chunksize = cluster_chunksize + new_chunksize = chunksize + changed = True + if window is not None: + if balancing_window(client, window.get('start'), window.get('stop')): + if window['state'] == "present": + pass + else: + remove_balancing_window(client) + changed = True + else: + if window['state'] == "present": + set_balancing_window(client, + window['start'], + window['stop']) + changed = True + else: + pass + except Exception as excep: + result["msg"] = "An error occurred: {0}".format(excep) + + result['changed'] = changed + if old_balancer_state is not None: + result['old_balancer_state'] = old_balancer_state + result['new_balancer_state'] = new_balancer_state + if old_autosplit is not None: + result['old_autosplit'] = old_autosplit + result['new_autosplit'] = new_autosplit + if old_chunksize is not None: + result['old_chunksize'] = old_chunksize + result['new_chunksize'] = new_chunksize + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_index.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_index.py new file mode 100644 index 00000000..d2db559c --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_index.py @@ -0,0 +1,442 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Rhys Campbell (@rhysmeister) <rhys.james.campbell@googlemail.com> +# 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 +__metaclass__ = type + + +DOCUMENTATION = r''' +--- +module: mongodb_index + +short_description: Creates or drops indexes on MongoDB collections. + +description: + - Creates or drops indexes on MongoDB collections. + - Supports multiple index options, i.e. unique, sparse and partial. + - Validates existence of indexes by name only. + +author: Rhys Campbell (@rhysmeister) +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + indexes: + description: + - List of indexes to create or drop + type: list + elements: raw + required: yes + replica_set: + description: + - Replica set to connect to (automatically connects to primary for writes). + type: str +notes: + - Requires the pymongo Python package on the remote host, version 2.4.2+. + +requirements: + - pymongo +''' + +EXAMPLES = r''' +- name: Create a single index on a collection + community.mongodb.mongodb_index: + login_user: admin + login_password: secret + indexes: + - database: mydb + collection: test + keys: + - username: 1 + last_login: -1 + options: + name: myindex + state: present + +- name: Drop an index on a collection + community.mongodb.mongodb_index: + login_user: admin + login_password: secret + indexes: + - database: mydb + collection: test + options: + name: myindex + state: absent + +- name: Create multiple indexes + community.mongodb.mongodb_index: + login_user: admin + login_password: secret + indexes: + - database: mydb + collection: test + keys: + - username: 1 + last_login: -1 + options: + name: myindex + state: present + - database: mydb + collection: test + keys: + - email: 1 + last_login: -1 + options: + name: myindex2 + state: present + +- name: Add a unique index + community.mongodb.mongodb_index: + login_port: 27017 + login_user: admin + login_password: secret + login_database: "admin" + indexes: + - database: "test" + collection: "rhys" + keys: + username: 1 + options: + name: myuniqueindex + unique: true + state: present + +- name: Add a ttl index + community.mongodb.mongodb_index: + login_port: 27017 + login_user: admin + login_password: secret + login_database: "admin" + indexes: + - database: "test" + collection: "rhys" + keys: + created: 1 + options: + name: myttlindex + expireAfterSeconds: 3600 + state: present + +- name: Add a sparse index + community.mongodb.mongodb_index: + login_port: 27017 + login_user: admin + login_password: secret + login_database: "admin" + indexes: + - database: "test" + collection: "rhys" + keys: + last_login: -1 + options: + name: mysparseindex + sparse: true + state: present + +- name: Add a partial index + community.mongodb.mongodb_index: + login_port: 27017 + login_user: admin + login_password: secret + login_database: "admin" + indexes: + - database: "test" + collection: "rhys" + keys: + last_login: -1 + options: + name: mypartialindex + partialFilterExpression: + rating: + $gt: 5 + state: present + +- name: Add a index in the background (background option is deprecated from 4.2+) + community.mongodb.mongodb_index: + login_port: 27017 + login_user: admin + login_password: secret + login_database: "admin" + indexes: + - database: "test" + collection: "rhys" + options: + name: idxbackground + keys: + username: -1 + backgroud: true + state: present + +- name: Check creating 5 index all with multiple options specified + community.mongodb.mongodb_index: + login_port: 27017 + login_user: admin + login_password: secret + login_database: "admin" + indexes: + - database: "test" + collection: "indextest" + options: + name: "idx_unq_username" + unique: true + keys: + username: -1 + state: present + - database: "test" + collection: "indextest" + options: + name: "idx_last_login" + sparse: true + keys: + last_login: -1 + state: present + - database: "test" + collection: "indextest" + options: + name: "myindex" + keys: + first_name: 1 + last_name: -1 + city: 1 + state: present + - database: "test" + collection: partialtest + options: + name: "idx_partialtest" + partialFilterExpression: + rating: + $gt: 5 + keys: + rating: -1 + title: 1 + state: present + - database: "test" + collection: "wideindex" + options: + name: "mywideindex" + keys: + email: -1 + username: 1 + first_name: 1 + last_name: 1 + dob: -1 + city: 1 + last_login: -1 + review_count: 1 + rating_count: 1 + last_post: -1 + state: present +''' + +RETURN = r''' +indexes_created: + description: List of indexes created. + returned: always + type: list + sample: ["myindex", "myindex2"] +indexes_dropped: + description: List of indexes dropped. + returned: always + type: list + sample: ["myindex", "myindex2"] +changed: + description: Indicates the module has changed something. + returned: When the module has changed something. + type: bool +failed: + description: Indicates the module has failed. + returned: When the module has encountered an error. + type: bool +''' + +from uuid import UUID + +from distutils.version import LooseVersion + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native +from ansible.module_utils.six import iteritems +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + mongodb_common_argument_spec, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import PyMongoVersion, PYMONGO_IMP_ERR, pymongo_found, MongoClient +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import index_exists, create_index, drop_index + + +def validate_module(module): + ''' + Runs validation rules specific the mongodb_index module + ''' + required_index_keys = [ + "database", + "collection", + "options", + "state", + ] + indexes = module.params['indexes'] + + if len(indexes) == 0: + module.fail_json(msg="One or more indexes must be specified") + if not all(isinstance(i, dict) for i in indexes): + module.fail_json(msg="Indexes must be supplied as dictionaries") + + # Ensure keys are present in index spec + for k in required_index_keys: + for i in indexes: + if k not in i.keys(): + module.fail_json(msg="Missing required index key {0}".format(k)) + + # Check index subkeys look correct + for i in indexes: + if not isinstance(i["database"], str): + module.fail_json(msg="database key should be str") + elif not isinstance(i["collection"], str): + module.fail_json(msg="collection key should be str") + elif i["state"] == "present" and "keys" not in i.keys(): + module.fail_json(msg="keys must be supplied when state is present") + elif i["state"] == "present" and not isinstance(i["keys"], dict): + module.fail_json(msg="keys key should be dict") + elif not isinstance(i["options"], dict): + module.fail_json(msg="options key should be dict") + elif "name" not in i["options"]: + module.fail_json(msg="The options dict must contain a name field") + elif i["state"] not in ["present", "absent"]: + module.fail_json(msg="state must be one of present or absent") + + +# ================ +# Module execution +# +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + indexes=dict(type='list', elements='raw', required=True), + replica_set=dict(type='str'), + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['login_user', 'login_password']], + ) + + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + validate_module(module) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_database = module.params['login_database'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + ssl = module.params['ssl'] + indexes = module.params['indexes'] + replica_set = module.params['replica_set'] + + connection_params = { + 'host': login_host, + 'port': login_port, + } + + if replica_set: + connection_params["replicaset"] = replica_set + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + client = MongoClient(**connection_params) + + if login_user: + try: + client.admin.authenticate(login_user, login_password, source=login_database) + except Exception as e: + module.fail_json(msg='Unable to authenticate: %s' % to_native(e)) + + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + except Exception as e: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(e)) + + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + + # Pre flight checks done + indexes_created = [] + indexes_dropped = [] + changed = None + for i in indexes: + try: + idx = index_exists(client, i["database"], i["collection"], i["options"]["name"]) + except Exception as excep: + module.fail_json(msg="Could not determine index status: {0}".format(str(excep))) + if module.check_mode: + if idx: + if i["state"] == "present": + changed = False + elif i["state"] == "absent": + indexes_dropped.append("{0}.{1}.{2}".format(i["database"], + i["collection"], + i["options"]["name"])) + changed = True + else: + if i["state"] == "present": + indexes_created.append("{0}.{1}.{2}".format(i["database"], + i["collection"], + i["options"]["name"])) + changed = True + elif i["state"] == "absent": + changed = False + else: + if idx: + if i["state"] == "present": + changed = False + elif i["state"] == "absent": + try: + drop_index(client, i["database"], i["collection"], + i["options"]["name"]) + indexes_dropped.append("{0}.{1}.{2}".format(i["database"], + i["collection"], + i["options"]["name"])) + changed = True + except Exception as excep: + module.fail_json(msg="Error dropping index: {0}".format(str(excep))) + + else: + if i["state"] == "present": + try: + create_index(client=client, + database=i["database"], + collection=i["collection"], + keys=i["keys"], + options=i["options"]) + indexes_created.append("{0}.{1}.{2}".format(i["database"], + i["collection"], + i["options"]["name"])) + changed = True + except Exception as excep: + module.fail_json(msg="Error creating index: {0}".format(str(excep))) + elif i["state"] == "absent": + changed = False + + module.exit_json(changed=changed, + indexes_created=indexes_created, + indexes_dropped=indexes_dropped) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_info.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_info.py new file mode 100644 index 00000000..19d46f97 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_info.py @@ -0,0 +1,343 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2020, Andrew Klychkov (@Andersson007) <aaklychkov@mail.ru> +# 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 +__metaclass__ = type + + +DOCUMENTATION = r''' +--- +module: mongodb_info + +short_description: Gather information about MongoDB instance. + +description: +- Gather information about MongoDB instance. + +author: Andrew Klychkov (@Andersson007) +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + filter: + description: + - Limit the collected information by comma separated string or YAML list. + - Allowable values are C(general), C(databases), C(total_size), C(parameters), C(users), C(roles). + - By default, collects all subsets. + - You can use '!' before value (for example, C(!users)) to exclude it from the information. + - If you pass including and excluding values to the filter, for example, I(filter=!general,users), + the excluding values, C(!general) in this case, will be ignored. + required: no + type: list + elements: str + +notes: + - Requires the pymongo Python package on the remote host, version 2.4.2+. + +requirements: + - pymongo +''' + +EXAMPLES = r''' +- name: Gather all supported information + community.mongodb.mongodb_info: + login_user: admin + login_password: secret + register: result + +- name: Show gathered info + debug: + msg: '{{ result }}' + +- name: Gather only information about databases and their total size + community.mongodb.mongodb_info: + login_user: admin + login_password: secret + filter: databases, total_size + +- name: Gather all information except parameters + community.mongodb.mongodb_info: + login_user: admin + login_password: secret + filter: '!parameters' +''' + +RETURN = r''' +general: + description: General instance information. + returned: always + type: dict + sample: {"allocator": "tcmalloc", "bits": 64, "storageEngines": ["biggie"], "version": "4.2.3", "maxBsonObjectSize": 16777216} +databases: + description: Database information. + returned: always + type: dict + sample: {"admin": {"empty": false, "sizeOnDisk": 245760}, "config": {"empty": false, "sizeOnDisk": 110592}} +total_size: + description: Total size of all databases in bytes. + returned: always + type: int + sample: 397312 +users: + description: User information. + returned: always + type: dict + sample: { "db": {"new_user": {"_id": "config.new_user", "mechanisms": ["SCRAM-SHA-1", "SCRAM-SHA-256"], "roles": []}}} +roles: + description: Role information. + returned: always + type: dict + sample: { "db": {"restore": {"inheritedRoles": [], "isBuiltin": true, "roles": []}}} +parameters: + description: Server parameters information. + returned: always + type: dict + sample: {"maxOplogTruncationPointsAfterStartup": 100, "maxOplogTruncationPointsDuringStartup": 100, "maxSessions": 1000000} +''' + +from uuid import UUID + +import ssl as ssl_lib +from distutils.version import LooseVersion + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native +from ansible.module_utils.six import iteritems +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + mongodb_common_argument_spec, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import PyMongoVersion, PYMONGO_IMP_ERR, pymongo_found, MongoClient + + +class MongoDbInfo(): + """Class for gathering MongoDB instance information. + + Args: + module (AnsibleModule): Object of AnsibleModule class. + client (pymongo): pymongo client object to interact with the database. + """ + def __init__(self, module, client): + self.module = module + self.client = client + self.admin_db = self.client.admin + self.info = { + 'general': {}, + 'databases': {}, + 'total_size': {}, + 'parameters': {}, + 'users': {}, + 'roles': {}, + } + + def get_info(self, filter_): + """Get MongoDB instance information and return it based on filter_. + + Args: + filter_ (list): List of collected subsets (e.g., general, users, etc.), + when it is empty, return all available information. + """ + self.__collect() + + inc_list = [] + exc_list = [] + + if filter_: + partial_info = {} + + for fi in filter_: + if fi.lstrip('!') not in self.info: + self.module.warn("filter element '%s' is not allowable, ignored" % fi) + continue + + if fi[0] == '!': + exc_list.append(fi.lstrip('!')) + + else: + inc_list.append(fi) + + if inc_list: + for i in self.info: + if i in inc_list: + partial_info[i] = self.info[i] + + else: + for i in self.info: + if i not in exc_list: + partial_info[i] = self.info[i] + + return partial_info + + else: + return self.info + + def __collect(self): + """Collect information.""" + # Get general info: + self.info['general'] = self.client.server_info() + + # Get parameters: + self.info['parameters'] = self.get_parameters_info() + + # Gather info about databases and their total size: + self.info['databases'], self.info['total_size'] = self.get_db_info() + + for dbname, val in iteritems(self.info['databases']): + # Gather info about users for each database: + self.info['users'].update(self.get_users_info(dbname)) + + # Gather info about roles for each database: + self.info['roles'].update(self.get_roles_info(dbname)) + + def get_roles_info(self, dbname): + """Gather information about roles. + + Args: + dbname (str): Database name to get role info from. + + Returns a dictionary with role information for the given db. + """ + db = self.client[dbname] + result = db.command({'rolesInfo': 1, 'showBuiltinRoles': True})['roles'] + + roles_dict = {} + for elem in result: + roles_dict[elem['role']] = {} + for key, val in iteritems(elem): + if key in ['role', 'db']: + continue + + roles_dict[elem['role']][key] = val + + return {dbname: roles_dict} + + def get_users_info(self, dbname): + """Gather information about users. + + Args: + dbname (str): Database name to get user info from. + + Returns a dictionary with user information for the given db. + """ + db = self.client[dbname] + result = db.command({'usersInfo': 1})['users'] + + users_dict = {} + for elem in result: + users_dict[elem['user']] = {} + for key, val in iteritems(elem): + if key in ['user', 'db']: + continue + + if isinstance(val, UUID): + val = val.hex + + users_dict[elem['user']][key] = val + + return {dbname: users_dict} + + def get_db_info(self): + """Gather information about databases. + + Returns a dictionary with database information. + """ + result = self.admin_db.command({'listDatabases': 1}) + total_size = int(result['totalSize']) + result = result['databases'] + + db_dict = {} + for elem in result: + db_dict[elem['name']] = {} + for key, val in iteritems(elem): + if key == 'name': + continue + + if key == 'sizeOnDisk': + val = int(val) + + db_dict[elem['name']][key] = val + + return db_dict, total_size + + def get_parameters_info(self): + """Gather parameters information. + + Returns a dictionary with parameters. + """ + return self.admin_db.command({'getParameter': '*'}) + + +# ================ +# Module execution +# + +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + filter=dict(type='list', elements='str', required=False) + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['login_user', 'login_password']], + ) + + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_database = module.params['login_database'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + ssl = module.params['ssl'] + filter_ = module.params['filter'] + + if filter_: + filter_ = [f.strip() for f in filter_] + + connection_params = { + 'host': login_host, + 'port': login_port, + } + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + client = MongoClient(**connection_params) + + if login_user: + try: + client.admin.authenticate(login_user, login_password, source=login_database) + except Exception as e: + module.fail_json(msg='Unable to authenticate: %s' % to_native(e)) + + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + except Exception as e: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(e)) + + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + + # Initialize an object and start main work: + mongodb = MongoDbInfo(module, client) + + module.exit_json(changed=False, **mongodb.get_info(filter_)) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_maintenance.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_maintenance.py new file mode 100644 index 00000000..0706dfd4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_maintenance.py @@ -0,0 +1,192 @@ +#!/usr/bin/python + +# Copyright: (c) 2020, Rhys Campbell <rhys.james.campbell@googlemail.com> +# 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 +__metaclass__ = type + + +DOCUMENTATION = r''' +--- +module: mongodb_maintenance +short_description: Enables or disables maintenance mode for a secondary member. +description: + - Enables or disables maintenance mode for a secondary member. + - Wrapper around the replSetMaintenance command. + - Performs no actions against a PRIMARY member. + - When enabled SECONDARY members will not service reads. +author: Rhys Campbell (@rhysmeister) +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + maintenance: + description: Enable or disable maintenance mode. + type: bool + default: false +notes: + - Requires the pymongo Python package on the remote host, version 2.4.2+. This + can be installed using pip or the OS package manager. @see U(http://api.mongodb.org/python/current/installation.html) +requirements: + - pymongo +''' + +EXAMPLES = r''' +- name: Enable maintenance mode + community.mongodb.mongodb_maintenance: + maintenance: true + +- name: Disable maintenance mode + community.mongodb.mongodb_maintenance: + maintenance: false +''' + +RETURN = r''' +changed: + description: Whether the member was placed into maintenance mode or not. + returned: success + type: bool +msg: + description: A short description of what happened. + returned: success + type: str +failed: + description: If something went wrong + returned: failed + type: bool +''' + +from copy import deepcopy + +import os +import ssl as ssl_lib +from distutils.version import LooseVersion + + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_native +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + load_mongocnf, + mongodb_common_argument_spec, + member_state, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import PyMongoVersion, PYMONGO_IMP_ERR, pymongo_found, MongoClient + + +def put_in_maint_mode(client): + client['admin'].command('replSetMaintenance', True) + + +def remove_maint_mode(client): + client['admin'].command('replSetMaintenance', False) + + +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + maintenance=dict(type='bool', default=False) + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['login_user', 'login_password']], + ) + + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_database = module.params['login_database'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + maintenance = module.params['maintenance'] + ssl = module.params['ssl'] + + result = dict( + changed=False, + ) + + connection_params = dict( + host=login_host, + port=int(login_port), + ) + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + try: + client = MongoClient(**connection_params) + except Exception as excep: + module.fail_json(msg='Unable to connect to MongoDB: %s' % to_native(excep)) + + if login_user is None and login_password is None: + mongocnf_creds = load_mongocnf() + if mongocnf_creds is not False: + login_user = mongocnf_creds['user'] + login_password = mongocnf_creds['password'] + elif login_password is None or login_user is None: + module.fail_json(msg="When supplying login arguments, both 'login_user' and 'login_password' must be provided") + + if login_user is not None and login_password is not None: + try: + client.admin.authenticate(login_user, login_password, source=login_database) + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + except Exception as excep: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(excep)) + + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + except Exception as excep: + module.fail_json(msg='Unable to authenticate with MongoDB: %s' % to_native(excep)) + + try: + state = member_state(client) + if state == "PRIMARY": + result["msg"] = "no action taken as member state was PRIMARY" + elif state == "SECONDARY": + if maintenance: + if module.check_mode: + result["changed"] = True + result["msg"] = "member was placed into maintenance mode" + else: + put_in_maint_mode(client) + result["changed"] = True + result["msg"] = "member was placed into maintenance mode" + else: + result["msg"] = "No action taken as maintenance parameter is false and member state is SECONDARY" + elif state == "RECOVERING": + if maintenance: + result["msg"] = "no action taken as member is already in a RECOVERING state" + else: + if module.check_mode: + result["changed"] = True + result["msg"] = "the member was removed from maintenance mode" + else: + remove_maint_mode(client) + result["changed"] = True + result["msg"] = "the member was removed from maintenance mode" + else: + result["msg"] = "no action taken as member state was {0}".format(state) + except Exception as excep: + module.fail_json(msg='module encountered an error: %s' % to_native(excep)) + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_oplog.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_oplog.py new file mode 100644 index 00000000..ce8c4477 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_oplog.py @@ -0,0 +1,252 @@ +#!/usr/bin/python + +# Copyright: (c) 2020, Rhys Campbell <rhys.james.campbell@googlemail.com> +# 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 +__metaclass__ = type + + +DOCUMENTATION = r''' +--- +module: mongodb_oplog +short_description: Resizes the MongoDB oplog. +description: + - Resizes the MongoDB oplog. + - This module should only be used with MongoDB 3.6 and above. + - Old MongoDB versions should use an alternative method. + - Consult U(https://docs.mongodb.com/manual/tutorial/change-oplog-size) for further info. +author: Rhys Campbell (@rhysmeister) +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + oplog_size_mb: + description: + - New size of the oplog in MB. + type: int + required: true + compact: + description: + - Runs compact against the oplog.rs collection in the local database to reclaim disk space. + - Performs no actions against PRIMARY members. + - The MongoDB user must have the compact role on the local database for this feature to work. + type: bool + default: false + required: false + ver: + description: + - Version of MongoDB this module is supported from. + - You probably don't want to modifiy this. + - Included here for internal testing. + type: str + default: "3.6" +notes: + - Requires the pymongo Python package on the remote host, version 2.4.2+. This + can be installed using pip or the OS package manager. @see U(http://api.mongodb.org/python/current/installation.html) +requirements: + - pymongo +''' + +EXAMPLES = r''' +- name: Resize oplog to 16 gigabytes, or 16000 megabytes + community.mongodb.mongodb_oplog: + oplog_size_mb: 16000 + +- name: Resize oplog to 8 gigabytes and compact secondaries to reclaim space + community.mongodb.mongodb_oplog: + oplog_size_mb: 8000 + compact: true +''' + +RETURN = r''' +changed: + description: Whether the member oplog was modified. + returned: success + type: bool +compacted: + description: Whether the member oplog was compacted. + returned: success + type: bool +msg: + description: A short description of what happened. + returned: success + type: str +failed: + description: If something went wrong + returned: failed + type: bool +''' + +from copy import deepcopy + +import os +import ssl as ssl_lib +from distutils.version import LooseVersion + + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_native +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + load_mongocnf, + mongodb_common_argument_spec, + member_state, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + PyMongoVersion, + PYMONGO_IMP_ERR, + pymongo_found, + MongoClient +) + +has_ordereddict = False +try: + from collections import OrderedDict + has_ordereddict = True +except ImportError as excep: + try: + from ordereddict import OrderedDict + has_ordereddict = True + except ImportError as excep: + pass + + +def get_olplog_size(client): + return int(client["local"].command("collStats", "oplog.rs")["maxSize"]) / 1024 / 1024 + + +def set_oplog_size(client, oplog_size_mb): + cmd_doc = OrderedDict([ + ('replSetResizeOplog', 1), + ('size', oplog_size_mb) + ]) + client["admin"].command(cmd_doc) + + +def compact_oplog(client): + client["local"].command("compact", "oplog.rs") + + +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + compact=dict(type='bool', default=False), + oplog_size_mb=dict(type='int', required=True), + ver=dict(type='str', default='3.6') + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['login_user', 'login_password']], + ) + + if not has_ordereddict: + module.fail_json(msg='Cannot import OrderedDict class. You can probably install with: pip install ordereddict') + + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_database = module.params['login_database'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + oplog_size_mb = float(module.params['oplog_size_mb']) # MongoDB 4.4 inists on a real + compact = module.params['compact'] + ver = module.params['ver'] + ssl = module.params['ssl'] + + result = dict( + changed=False, + ) + + connection_params = dict( + host=login_host, + port=int(login_port), + ) + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + try: + client = MongoClient(**connection_params) + except Exception as excep: + module.fail_json(msg='Unable to connect to MongoDB: %s' % to_native(excep)) + + if login_user is None and login_password is None: + mongocnf_creds = load_mongocnf() + if mongocnf_creds is not False: + login_user = mongocnf_creds['user'] + login_password = mongocnf_creds['password'] + elif login_password is None or login_user is None: + module.fail_json(msg="When supplying login arguments, both 'login_user' and 'login_password' must be provided") + + if login_user is not None and login_password is not None: + try: + client.admin.authenticate(login_user, login_password, source=login_database) + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + if srv_version < LooseVersion(ver): + module.fail_json(msg="This module does not support MongoDB {0}".format(srv_version)) + except Exception as excep: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(excep)) + + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + except Exception as excep: + module.fail_json(msg='Unable to authenticate with MongoDB: %s' % to_native(excep)) + + try: + current_oplog_size = get_olplog_size(client) + except Exception as excep: + module.fail_json(msg='Unable to get current oplog size: %s' % to_native(excep)) + if oplog_size_mb == current_oplog_size: + result["msg"] = "oplog_size_mb is already {0} mb".format(int(oplog_size_mb)) + result["compacted"] = False + else: + try: + state = member_state(client) + except Exception as excep: + module.fail_json(msg='Unable to get member state: %s' % to_native(excep)) + if module.check_mode: + result["changed"] = True + result["msg"] = "oplog has been resized from {0} mb to {1} mb".format(int(current_oplog_size), + int(oplog_size_mb)) + if state == "SECONDARY" and compact and current_oplog_size > oplog_size_mb: + result["compacted"] = True + else: + result["compacted"] = False + else: + try: + set_oplog_size(client, oplog_size_mb) + result["changed"] = True + result["msg"] = "oplog has been resized from {0} mb to {1} mb".format(int(current_oplog_size), + int(oplog_size_mb)) + except Exception as excep: + module.fail_json(msg='Unable to set oplog size: %s' % to_native(excep)) + if state == "SECONDARY" and compact and current_oplog_size > oplog_size_mb: + try: + compact_oplog(client) + result["compacted"] = True + except Exception as excep: + module.fail_json(msg='Error compacting member oplog: %s' % to_native(excep)) + else: + result["compacted"] = False + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_parameter.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_parameter.py new file mode 100644 index 00000000..646195bc --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_parameter.py @@ -0,0 +1,195 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2016, Loic Blot <loic.blot@unix-experience.fr> +# Sponsored by Infopro Digital. http://www.infopro-digital.com/ +# Sponsored by E.T.A.I. http://www.etai.fr/ +# +# 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 +__metaclass__ = type + + +DOCUMENTATION = r''' +--- +module: mongodb_parameter +short_description: Change an administrative parameter on a MongoDB server +description: + - Change an administrative parameter on a MongoDB server. +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + replica_set: + description: + - Replica set to connect to (automatically connects to primary for writes). + type: str + param: + description: + - MongoDB administrative parameter to modify. + type: str + required: true + value: + description: + - MongoDB administrative parameter value to set. + type: str + required: true + param_type: + description: + - Define the type of parameter value. + default: str + type: str + choices: [int, str] + +notes: + - Requires the pymongo Python package on the remote host, version 2.4.2+. + - This can be installed using pip or the OS package manager. + - See also U(http://api.mongodb.org/python/current/installation.html) +requirements: [ "pymongo" ] +author: "Loic Blot (@nerzhul)" +''' + +EXAMPLES = r''' +- name: Set MongoDB syncdelay to 60 (this is an int) + community.mongodb.mongodb_parameter: + param: syncdelay + value: 60 + param_type: int +''' + +RETURN = r''' +before: + description: value before modification + returned: success + type: str +after: + description: value after modification + returned: success + type: str +''' + +import os +from distutils.version import LooseVersion +import traceback + +from ansible.module_utils.basic import AnsibleModule, missing_required_lib +from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_native +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + load_mongocnf, + mongodb_common_argument_spec, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + PyMongoVersion, + PYMONGO_IMP_ERR, + pymongo_found, + MongoClient +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ConnectionFailure, OperationFailure + +# ========================================= +# Module execution. +# + + +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + replica_set=dict(default=None), + param=dict(required=True), + value=dict(required=True), + param_type=dict(default="str", choices=['str', 'int']) + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=False, + required_together=[['login_user', 'login_password']], + ) + + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + login_database = module.params['login_database'] + + replica_set = module.params['replica_set'] + ssl = module.params['ssl'] + + param = module.params['param'] + param_type = module.params['param_type'] + value = module.params['value'] + + connection_params = dict( + host=login_host, + port=int(login_port), + ) + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + # Verify parameter is coherent with specified type + try: + if param_type == 'int': + value = int(value) + except ValueError: + module.fail_json(msg="value '%s' is not %s" % (value, param_type)) + + try: + if replica_set: + client = MongoClient(replicaset=replica_set, **connection_params) + else: + client = MongoClient(**connection_params) + + if login_user is None and login_password is None: + mongocnf_creds = load_mongocnf() + if mongocnf_creds is not False: + login_user = mongocnf_creds['user'] + login_password = mongocnf_creds['password'] + elif login_password is None or login_user is None: + module.fail_json(msg='when supplying login arguments, both login_user and login_password must be provided') + + if login_user is not None and login_password is not None: + client.admin.authenticate(login_user, login_password, source=login_database) + + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + except Exception as e: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(e)) + + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + + except ConnectionFailure as e: + module.fail_json(msg='unable to connect to database: %s' % to_native(e), exception=traceback.format_exc()) + + db = client.admin + + try: + after_value = db.command("setParameter", **{param: value}) + except OperationFailure as e: + module.fail_json(msg="unable to change parameter: %s" % to_native(e), exception=traceback.format_exc()) + + if "was" not in after_value: + module.exit_json(changed=True, msg="Unable to determine old value, assume it changed.") + else: + module.exit_json(changed=(value != after_value["was"]), before=after_value["was"], + after=value) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_replicaset.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_replicaset.py new file mode 100644 index 00000000..cfb23311 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_replicaset.py @@ -0,0 +1,390 @@ +#!/usr/bin/python + +# Copyright: (c) 2018, Rhys Campbell <rhys.james.campbell@googlemail.com> +# 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 +__metaclass__ = type + + +DOCUMENTATION = r''' +--- +module: mongodb_replicaset +short_description: Initialises a MongoDB replicaset. +description: + - Initialises a MongoDB replicaset in a new deployment. + - Validates the replicaset name for existing deployments. + - Advanced replicaset member configuration possible (see examples). +author: Rhys Campbell (@rhysmeister) +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + replica_set: + description: + - Replicaset name. + type: str + default: rs0 + members: + description: + - Yaml list consisting of the replicaset members. + - Csv string will also be accepted i.e. mongodb1:27017,mongodb2:27017,mongodb3:27017. + - A dictionary can also be used to specify advanced replicaset member options. + - If a port number is not provided then 27017 is assumed. + type: list + elements: raw + validate: + description: + - Performs some basic validation on the provided replicaset config. + type: bool + default: yes + arbiter_at_index: + description: + - Identifies the position of the member in the array that is an arbiter. + type: int + chaining_allowed: + description: + - When I(settings.chaining_allowed=true), the replicaset allows secondary members to replicate from other + secondary members. + - When I(settings.chaining_allowed=false), secondaries can replicate only from the primary. + type: bool + default: yes + heartbeat_timeout_secs: + description: + - Number of seconds that the replicaset members wait for a successful heartbeat from each other. + - If a member does not respond in time, other members mark the delinquent member as inaccessible. + - The setting only applies when using I(protocol_version=0). When using I(protocol_version=1) the relevant + setting is I(settings.election_timeout_millis). + type: int + default: 10 + election_timeout_millis: + description: + - The time limit in milliseconds for detecting when a replicaset's primary is unreachable. + type: int + default: 10000 + protocol_version: + description: Version of the replicaset election protocol. + type: int + choices: [ 0, 1 ] + default: 1 +notes: +- Requires the pymongo Python package on the remote host, version 2.4.2+. This + can be installed using pip or the OS package manager. @see U(http://api.mongodb.org/python/current/installation.html) +requirements: +- pymongo +''' + +EXAMPLES = r''' +# Create a replicaset called 'rs0' with the 3 provided members +- name: Ensure replicaset rs0 exists + community.mongodb.mongodb_replicaset: + login_host: localhost + login_user: admin + login_password: admin + replica_set: rs0 + members: + - mongodb1:27017 + - mongodb2:27017 + - mongodb3:27017 + when: groups.mongod.index(inventory_hostname) == 0 + +# Create two single-node replicasets on the localhost for testing +- name: Ensure replicaset rs0 exists + community.mongodb.mongodb_replicaset: + login_host: localhost + login_port: 3001 + login_user: admin + login_password: secret + login_database: admin + replica_set: rs0 + members: localhost:3001 + validate: no + +- name: Ensure replicaset rs1 exists + community.mongodb.mongodb_replicaset: + login_host: localhost + login_port: 3002 + login_user: admin + login_password: secret + login_database: admin + replica_set: rs1 + members: localhost:3002 + validate: no + +- name: Create a replicaset and use a custom priority for each member + community.mongodb.mongodb_replicaset: + login_host: localhost + login_user: admin + login_password: admin + replica_set: rs0 + members: + - host: "localhost:3001" + priority: 1 + - host: "localhost:3002" + priority: 0.5 + - host: "localhost:3003" + priority: 0.5 + when: groups.mongod.index(inventory_hostname) == 0 + +- name: Create replicaset rs1 with options and member tags + community.mongodb.mongodb_replicaset: + login_host: localhost + login_port: 3001 + login_database: admin + replica_set: rs1 + members: + - host: "localhost:3001" + priority: 1 + tags: + dc: "east" + usage: "production" + - host: "localhost:3002" + priority: 1 + tags: + dc: "east" + usage: "production" + - host: "localhost:3003" + priority: 0 + hidden: true + slaveDelay: 3600 + tags: + dc: "west" + usage: "reporting" +''' + +RETURN = r''' +mongodb_replicaset: + description: The name of the replicaset that has been created. + returned: success + type: str +''' + +from copy import deepcopy + +import os +import ssl as ssl_lib +from distutils.version import LooseVersion + + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_native +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + load_mongocnf, + mongodb_common_argument_spec, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import PyMongoVersion, PYMONGO_IMP_ERR, pymongo_found, MongoClient + + +def replicaset_find(client): + """Check if a replicaset exists. + + Args: + client (cursor): Mongodb cursor on admin database. + + Returns: + dict: when user exists, False otherwise. + """ + doc = client['admin'].command('isMaster') + if 'setName' in doc.keys(): + return str(doc['setName']) + return False + + +def replicaset_add(module, client, replica_set, members, arbiter_at_index, protocol_version, + chaining_allowed, heartbeat_timeout_secs, election_timeout_millis): + + try: + from collections import OrderedDict + except ImportError as excep: + try: + from ordereddict import OrderedDict + except ImportError as excep: + module.fail_json(msg='Cannot import OrderedDict class. You can probably install with: pip install ordereddict: %s' + % to_native(excep)) + + members_dict_list = [] + index = 0 + settings = { + "chainingAllowed": bool(chaining_allowed), + } + if protocol_version == 0: + settings['heartbeatTimeoutSecs'] = heartbeat_timeout_secs + else: + settings['electionTimeoutMillis'] = election_timeout_millis + for member in members: + if isinstance(member, str): + if ':' not in member: # No port supplied. Assume 27017 + member += ":27017" + members_dict_list.append(OrderedDict([("_id", int(index)), ("host", member)])) + if index == arbiter_at_index: + members_dict_list[index]['arbiterOnly'] = True + index += 1 + elif isinstance(member, dict): + hostname = member["host"] + if ':' not in hostname: + hostname += ":27017" + members_dict_list.append(OrderedDict([("_id", int(index)), ("host", hostname)])) + for key in list(member.keys()): + if key != "host": + members_dict_list[index][key] = member[key] + if index == arbiter_at_index: + members_dict_list[index]['arbiterOnly'] = True + index += 1 + else: + raise ValueError("member should be a str or dict. Instead found: {0}".format(str(type(members)))) + + conf = OrderedDict([("_id", replica_set), + ("protocolVersion", protocol_version), + ("members", members_dict_list), + ("settings", settings)]) + try: + client["admin"].command('replSetInitiate', conf) + except Exception as excep: + raise Exception("Some problem {0} | {1}".format(str(excep), str(conf))) + + +def replicaset_remove(module, client, replica_set): + raise NotImplementedError + # exists = replicaset_find(client, replica_set) + # if exists: + # if module.check_mode: + # module.exit_json(changed=True, replica_set=replica_set) + # db = client[db_name] + # db.remove_user(replica_set) + # else: + # module.exit_json(changed=False, user=user) + + +# ========================================= +# Module execution. +# + + +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + arbiter_at_index=dict(type='int'), + chaining_allowed=dict(type='bool', default=True), + election_timeout_millis=dict(type='int', default=10000), + heartbeat_timeout_secs=dict(type='int', default=10), + members=dict(type='list', elements='raw'), + protocol_version=dict(type='int', default=1, choices=[0, 1]), + replica_set=dict(type='str', default="rs0"), + validate=dict(type='bool', default=True) + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['login_user', 'login_password']], + ) + + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_database = module.params['login_database'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + replica_set = module.params['replica_set'] + members = module.params['members'] + arbiter_at_index = module.params['arbiter_at_index'] + validate = module.params['validate'] + ssl = module.params['ssl'] + protocol_version = module.params['protocol_version'] + chaining_allowed = module.params['chaining_allowed'] + heartbeat_timeout_secs = module.params['heartbeat_timeout_secs'] + election_timeout_millis = module.params['election_timeout_millis'] + + if validate: + if len(members) <= 2 or len(members) % 2 == 0: + module.fail_json(msg="MongoDB Replicaset validation failed. Invalid number of replicaset members.") + if arbiter_at_index is not None and len(members) - 1 < arbiter_at_index: + module.fail_json(msg="MongoDB Replicaset validation failed. Invalid arbiter index.") + + result = dict( + changed=False, + replica_set=replica_set, + ) + + connection_params = dict( + host=login_host, + port=int(login_port), + ) + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + try: + client = MongoClient(**connection_params) + except Exception as e: + module.fail_json(msg='Unable to connect to database: %s' % to_native(e)) + + try: + rs = replicaset_find(client) + except Exception as e: + module.fail_json(msg='Unable to connect to query replicaset: %s' % to_native(e)) + + if isinstance(rs, str): + if replica_set == rs: + result['changed'] = False + result['replica_set'] = rs + module.exit_json(**result) + else: + module.fail_json(msg="The replica_set name of {0} does not match the expected: {1}".format(rs, replica_set)) + else: # replicaset does not exit + + # Some validation stuff + if len(replica_set) == 0: + module.fail_json(msg="Parameter replica_set must not be an empty string") + + if module.check_mode is False: + try: + # If we have auth details use then otherwise attempt without + if login_user is None and login_password is None: + mongocnf_creds = load_mongocnf() + if mongocnf_creds is not False: + login_user = mongocnf_creds['user'] + login_password = mongocnf_creds['password'] + elif login_password is None or login_user is None: + module.fail_json(msg="When supplying login arguments, both 'login_user' and 'login_password' must be provided") + + if login_user is not None and login_password is not None: + try: + client.admin.authenticate(login_user, login_password, source=login_database) + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + except Exception as e: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(e)) + + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + except Exception as excep: + module.fail_json(msg='Unable to authenticate with MongoDB: %s' % to_native(excep)) + replicaset_add(module, client, replica_set, members, + arbiter_at_index, protocol_version, + chaining_allowed, heartbeat_timeout_secs, + election_timeout_millis) + result['changed'] = True + except Exception as e: + module.fail_json(msg='Unable to create replica_set: %s' % to_native(e)) + else: + result['changed'] = True + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_shard.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_shard.py new file mode 100644 index 00000000..3587135d --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_shard.py @@ -0,0 +1,369 @@ +#!/usr/bin/python + +# (c) 2018, Rhys Campbell <rhys.james.campbell@googlemail.com> +# 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 +__metaclass__ = type + + +DOCUMENTATION = ''' +--- +module: mongodb_shard +short_description: Add or remove shards from a MongoDB Cluster +description: + - Add or remove shards from a MongoDB Cluster. +author: Rhys Campbell (@rhysmeister) +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + shard: + description: + - The shard connection string. + - Should be supplied in the form <replicaset>/host:port as detailed in U(https://docs.mongodb.com/manual/tutorial/add-shards-to-shard-cluster/). + - For example rs0/example1.mongodb.com:27017. + required: true + type: str + sharded_databases: + description: + - Enable sharding on the listed database. + - Can be supplied as a string or a list of strings. + - Sharding cannot be disabled on a database. + required: false + type: raw + mongos_process: + description: + - Provide a custom name for the mongos process you are connecting to. + - Most users can ignore this setting. + required: false + type: str + default: "mongos" + state: + description: + - Whether the shard should be present or absent from the Cluster. + required: false + type: str + default: present + choices: + - "absent" + - "present" + +notes: + - Requires the pymongo Python package on the remote host, version 2.4.2+. +requirements: [ pymongo ] +''' + +EXAMPLES = ''' +- name: Add a replicaset shard named rs1 with a member running on port 27018 on mongodb0.example.net + community.mongodb.mongodb_shard: + login_user: admin + login_password: admin + shard: "rs1/mongodb0.example.net:27018" + state: present + +- name: Add a standalone mongod shard running on port 27018 of mongodb0.example.net + community.mongodb.mongodb_shard: + login_user: admin + login_password: admin + shard: "mongodb0.example.net:27018" + state: present + +- name: To remove a shard called 'rs1' + community.mongodb.mongodb_shard: + login_user: admin + login_password: admin + shard: rs1 + state: absent + +# Single node shard running on localhost +- name: Ensure shard rs0 exists + community.mongodb.mongodb_shard: + login_user: admin + login_password: secret + shard: "rs0/localhost:3001" + state: present + +# Single node shard running on localhost +- name: Ensure shard rs1 exists + community.mongodb.mongodb_shard: + login_user: admin + login_password: secret + shard: "rs1/localhost:3002" + state: present + +# Enable sharding on a few databases when creating the shard +- name: To remove a shard called 'rs1' + community.mongodb.mongodb_shard: + login_user: admin + login_password: admin + shard: rs1 + sharded_databases: + - db1 + - db2 + state: present +''' + +RETURN = ''' +mongodb_shard: + description: The name of the shard to create. + returned: success + type: str +sharded_enabled: + description: Databases that have had sharding enabled during module execution. + returned: success when sharding is enabled + type: list +''' + +import os +import ssl as ssl_lib +from distutils.version import LooseVersion +import traceback +import time + + +from ansible.module_utils.basic import AnsibleModule, missing_required_lib +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_native +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + load_mongocnf, + mongodb_common_argument_spec, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + PyMongoVersion, + PYMONGO_IMP_ERR, + pymongo_found, + MongoClient +) + + +def shard_find(client, shard): + """Check if a shard exists. + + Args: + client (cursor): Mongodb cursor on admin database. + shard (str): shard to check. + + Returns: + dict: when user exists, False otherwise. + """ + if '/' in shard: + s = shard.split('/')[0] + else: + s = shard + for shard in client["config"].shards.find({"_id": s}): + return shard + return False + + +def shard_add(client, shard): + try: + sh = client["admin"].command('addShard', shard) + except Exception as excep: + raise excep + return sh + + +def shard_remove(client, shard): + try: + sh = client["admin"].command('removeShard', shard) + except Exception as excep: + raise excep + return sh + + +def sharded_dbs(client): + ''' + Returns the sharded databases + Args: + client (cursor): Mongodb cursor on admin database. + Returns: + a list of database names that are sharded + ''' + sharded_databases = [] + for entry in client["config"].databases.find({"partitioned": True}, {"_id": 1}): + sharded_databases.append(entry["_id"]) + return sharded_databases + + +def enable_database_sharding(client, database): + ''' + Enables sharding on a database + Args: + client (cursor): Mongodb cursor on admin database. + Returns: + true on success, false on failure + ''' + s = False + db = client["admin"].command('enableSharding', database) + if db: + s = True + return s + + +def any_dbs_to_shard(client, sharded_databases): + ''' + Return a list of databases that need to have sharding enabled + sharded_databases - Provided by module + cluster_sharded_databases - List of sharded dbs from the mongos + ''' + dbs_to_shard = [] + cluster_sharded_databases = sharded_dbs(client) + for db in sharded_databases: + if db not in cluster_sharded_databases: + dbs_to_shard.append(db) + return dbs_to_shard + + +# ========================================= +# Module execution. +# + + +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + mongos_process=dict(type='str', required=False, default="mongos"), + shard=dict(type='str', required=True), + sharded_databases=dict(type="raw", required=False), + state=dict(type='str', required=False, default='present', choices=['absent', 'present']) + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['login_user', 'login_password']], + ) + + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_database = module.params['login_database'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + ssl = module.params['ssl'] + shard = module.params['shard'] + state = module.params['state'] + sharded_databases = module.params['sharded_databases'] + mongos_process = module.params['mongos_process'] + + try: + connection_params = { + "host": login_host, + "port": int(login_port) + } + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + client = MongoClient(**connection_params) + + try: + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + except Exception as e: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(e)) + + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + except Exception as excep: + if excep.code == 13: + if login_user is not None and login_password is not None: + client.admin.authenticate(login_user, login_password, source=login_database) + check_compatibility(module, client) + else: + raise excep + else: + raise excep + + if login_user is None and login_password is None: + mongocnf_creds = load_mongocnf() + if mongocnf_creds is not False: + login_user = mongocnf_creds['user'] + login_password = mongocnf_creds['password'] + elif login_password is None or login_user is None: + module.fail_json(msg='when supplying login arguments, both login_user and login_password must be provided') + + try: + client['admin'].command('listDatabases', 1.0) # if this throws an error we need to authenticate + except Exception as excep: + if excep.code == 13: + if login_user is not None and login_password is not None: + client.admin.authenticate(login_user, login_password, source=login_database) + else: + raise excep + else: + raise excep + + except Exception as e: + module.fail_json(msg='unable to connect to database: %s' % to_native(e), exception=traceback.format_exc()) + + try: + if client["admin"].command("serverStatus")["process"] != mongos_process: + module.fail_json(msg="Process running on {0}:{1} is not a {2}".format(login_host, login_port, mongos_process)) + shard_created = False + dbs_to_shard = [] + + if sharded_databases is not None: + if isinstance(sharded_databases, str): + sharded_databases = list(sharded_databases) + dbs_to_shard = any_dbs_to_shard(client, sharded_databases) + + if module.check_mode: + if state == "present": + changed = False + if not shard_find(client, shard) or len(dbs_to_shard) > 0: + changed = True + elif state == "absent": + if not shard_find(client, shard): + changed = False + else: + changed = True + else: + if state == "present": + if not shard_find(client, shard): + shard_add(client, shard) + changed = True + else: + changed = False + if len(dbs_to_shard) > 0: + for db in dbs_to_shard: + enable_database_sharding(client, db) + changed = True + elif state == "absent": + if shard_find(client, shard): + shard_remove(client, shard) + changed = True + else: + changed = False + except Exception as e: + action = "add" + if state == "absent": + action = "remove" + module.fail_json(msg='Unable to {0} shard: %s'.format(action) % to_native(e), exception=traceback.format_exc()) + + result = { + "changed": changed, + "shard": shard, + } + if len(dbs_to_shard) > 0: + result['sharded_enabled'] = dbs_to_shard + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_shell.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_shell.py new file mode 100644 index 00000000..59d927ec --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_shell.py @@ -0,0 +1,365 @@ +#!/usr/bin/python + +# 2020 Rhys Campbell <rhys.james.campbell@googlemail.com> +# https://github.com/rhysmeister +# 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 + + +DOCUMENTATION = ''' +--- +module: mongodb_shell +author: Rhys Campbell (@rhysmeister) +short_description: Run commands via the MongoDB shell. +requirements: + - mongo +description: + - Run commands via the MongoDB shell. + - Commands provided with the eval parameter or included in a Javascript file. + - Attempts to parse returned data into a format that Ansible can use. + +extends_documentation_fragment: + - community.mongodb.login_options + +options: + mongo_cmd: + description: + - The MongoDB shell command. + type: str + default: "mongo" + db: + description: + - The database to run commands against + type: str + required: false + default: "test" + file: + description: + - Path to a file containing MongoDB commands. + type: str + eval: + description: + - A MongoDB command to run. + type: str + nodb: + description: + - Specify a non-default encoding for output. + type: bool + default: false + norc: + description: + - Prevents the shell from sourcing and evaluating ~/.mongorc.js on start up. + type: bool + default: false + quiet: + description: + - Silences output from the shell during the connection process.. + type: bool + default: true + debug: + description: + - show additional debug info. + type: bool + default: false + transform: + description: + - Transform the output returned to the user. + - auto - Attempt to automatically decide the best tranformation. + - split - Split output on a character. + - json - parse as json. + - raw - Return the raw output. + type: str + choices: + - "auto" + - "split" + - "json" + - "raw" + default: "auto" + split_char: + description: + - Used by the split action in the transform stage. + type: str + default: " " + stringify: + description: + - Wraps the command in eval in JSON.stringify(<js cmd>). + - Useful for escaping documents that are returned in Extended JSON format. + type: bool + default: false + additional_args: + description: + - Additional arguments to supply to the mongo command. + - Supply as key-value pairs. + - If the parameter is a valueless flag supply an empty string as the value. + type: raw + idempotent: + description: + - Provides a form of pseudo-idempotency to the module. + - We perform a hash calculation on the contents of the eval key or the file name provided in the file key. + - When the command is first execute a filed called <hash>.success will be created. + - The module will not rerun the command if this file exists and idempotent is set to true. + type: bool + default: false +''' + +EXAMPLES = ''' +- name: Run the listDatabases command + community.mongodb.mongodb_shell: + login_user: user + login_password: secret + eval: "db.adminCommand('listDatabases')" + +- name: List collections and stringify the output + community.mongodb.mongodb_shell: + login_user: user + login_password: secret + eval: "db.adminCommand('listCollections')" + stringify: yes + +- name: Run the showBuiltinRoles command + community.mongodb.mongodb_shell: + login_user: user + login_password: secret + eval: "db.getRoles({showBuiltinRoles: true})" + +- name: Run a js file containing MongoDB commands with pseudo-idempotency + community.mongodb.mongodb_shell: + login_user: user + login_password: secret + file: "/path/to/mongo/file.js" + idempotent: yes + +- name: Provide a couple of additional cmd args + community.mongodb.mongodb_shell: + login_user: user + login_password: secret + eval: "db.adminCommand('listDatabases')" + additional_args: + verbose: True + networkMessageCompressors: "snappy" +''' + +RETURN = ''' +file: + description: JS file that was executed successfully. + returned: When a js file is used. + type: str +msg: + description: A message indicating what has happened. + returned: always + type: str +transformed_output: + description: Output from the mongo command. We attempt to parse this into a list or json where possible. + returned: on success + type: list +changed: + description: Change status. + returned: always + type: bool +failed: + description: Something went wrong. + returned: on failure + type: bool +out: + description: Raw stdout from mongo. + returned: when debug is set to true + type: str +err: + description: Raw stderr from mongo. + returned: when debug is set to true + type: str +rc: + description: Return code from mongo. + returned: when debug is set to true + type: int +''' + +from ansible.module_utils.basic import AnsibleModule, load_platform_subclass +import socket +import re +import time +import json +import os +__metaclass__ = type + +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + mongodb_common_argument_spec +) + + +def add_arg_to_cmd(cmd_list, param_name, param_value, is_bool=False): + """ + @cmd_list - List of cmd args. + @param_name - Param name / flag. + @param_value - Value of the parameter + @is_bool - Flag is a boolean and has no value. + """ + if is_bool is False and param_value is not None: + cmd_list.append(param_name) + if param_name == "--eval": + cmd_list.append("\"{0}\"".format(param_value)) + else: + cmd_list.append(param_value) + elif is_bool is True: + cmd_list.append(param_name) + return cmd_list + + +def transform_output(output, transform_type, split_char): + if transform_type == "auto": # determine what transform_type to perform + if output.strip().startswith("{") or output.strip().startswith("["): + transform_type = "json" + elif isinstance(output.strip().split(None), list): # Splits on whitespace + transform_type = "split" + split_char = None + elif isinstance(output.strip().split(","), list): + transform_type = "split" + split_char = "," + elif isinstance(output.strip().split(" "), list): + transform_type = "split" + split_char = " " + elif isinstance(output.strip().split("|"), list): + transform_type = "split" + split_char = "|" + elif isinstance(output.strip().split("\t"), list): + transform_type = "split" + split_char = "\t" + else: + tranform_type = "raw" + if transform_type == "json": + output = json.loads(output) + elif transform_type == "split": + output = output.strip().split(split_char) + elif transform_type == "raw": + output = output.strip() + return output + + +def get_hash_value(module): + ''' + Returns the hash value of either the provided file or eval command + ''' + hash_value = None + try: + import hashlib + except ImportError as excep: + module.fail_json(msg="Unable to import hashlib: {0}".format(excep.message)) + if module.params['file'] is not None: + hash_value = hashlib.md5(module.params['file'].encode('utf-8')).hexdigest() + else: + hash_value = hashlib.md5(module.params['eval'].encode('utf-8')).hexdigest() + return hash_value + + +def touch(fname, times=None): + with open(fname, 'a'): + os.utime(fname, times) + + +def main(): + argument_spec = mongodb_common_argument_spec(ssl_options=False) + argument_spec.update( + mongo_cmd=dict(type='str', default="mongo"), + file=dict(type='str', required=False), + eval=dict(type='str', required=False), + db=dict(type='str', required=False, default="test"), + nodb=dict(type='bool', required=False, default=False), + norc=dict(type='bool', required=False, default=False), + quiet=dict(type='bool', required=False, default=True), + debug=dict(type='bool', required=False, default=False), + transform=dict(type='str', choices=["auto", "split", "json", "raw"], default="auto"), + split_char=dict(type='str', default=" "), + stringify=dict(type='bool', default=False), + additional_args=dict(type='raw'), + idempotent=dict(type='bool', default=False) + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['login_user', 'login_password']], + mutually_exclusive=[["eval", "file"]] + ) + + args = [ + module.params['mongo_cmd'], + module.params['db'] + ] + + hash_value = get_hash_value(module) + + if module.params['idempotent']: + if os.path.isfile("{0}.success".format(hash_value)): + module.exit_json(changed=False, + msg="The file {0}.success was found meaning this " + "command has already successfully executed " + "on this MongoDB host.".format(hash_value)) + + if not module.params['file']: + if module.params['eval'].startswith("show "): + msg = "You cannot use any shell helper (e.g. use <dbname>, show dbs, etc.)"\ + " inside the eval parameter because they are not valid JavaScript." + module.fail_json(msg=msg) + if module.params['stringify']: + module.params['eval'] = "JSON.stringify({0})".format(module.params['eval']) + + args = add_arg_to_cmd(args, "--host", module.params['login_host']) + args = add_arg_to_cmd(args, "--port", module.params['login_port']) + args = add_arg_to_cmd(args, "--username", module.params['login_user']) + args = add_arg_to_cmd(args, "--password", module.params['login_password']) + args = add_arg_to_cmd(args, "--authenticationDatabase", module.params['login_database']) + args = add_arg_to_cmd(args, "--eval", module.params['eval']) + args = add_arg_to_cmd(args, "--nodb", None, module.params['nodb']) + args = add_arg_to_cmd(args, "--norc", None, module.params['norc']) + args = add_arg_to_cmd(args, "--quiet", None, module.params['quiet']) + + additional_args = module.params['additional_args'] + if additional_args is not None: + for key, value in additional_args.items(): + if isinstance(value, bool): + args.append(" --{0}".format(key)) + elif isinstance(value, str) or isinstance(value, int): + args.append(" --{0} {1}".format(key, value)) + if module.params['file']: + args.pop(1) + args.append(module.params['file']) + + rc = None + out = '' + err = '' + result = {} + cmd = " ".join(str(item) for item in args) + + (rc, out, err) = module.run_command(cmd, check_rc=False) + + if module.params['debug']: + result['out'] = out + result['err'] = err + result['rc'] = rc + result['cmd'] = cmd + + if rc != 0: + if err is None or err == "": + err = out + module.fail_json(msg=err.strip(), **result) + else: + result['changed'] = True + if module.params['idempotent']: + touch("{0}.success".format(hash_value)) + try: + output = transform_output(out, + module.params['transform'], + module.params['split_char']) + result['transformed_output'] = output + result['msg'] = "transform type was {0}".format(module.params['transform']) + if module.params['file'] is not None: + result['file'] = module.params['file'] + except Exception as excep: + result['msg'] = "Error tranforming output: {0}".format(str(excep)) + result['transformed_output'] = None + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_shutdown.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_shutdown.py new file mode 100644 index 00000000..4e555fe9 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_shutdown.py @@ -0,0 +1,183 @@ +#!/usr/bin/python + +# Copyright: (c) 2020, Rhys Campbell <rhys.james.campbell@googlemail.com> +# 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 +__metaclass__ = type + + +DOCUMENTATION = r''' +--- +module: mongodb_shutdown +short_description: Cleans up all database resources and then terminates the mongod/mongos process. +description: + - Cleans up all database resources and then terminates the process. +author: Rhys Campbell (@rhysmeister) +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + force: + description: + - Specify true to force the mongod to shut down. + - Force shutdown interrupts any ongoing operations on the mongod and may result in unexpected behavior. + type: bool + default: false + timeout: + description: + - The number of seconds the primary should wait for a secondary to catch up. + type: int + default: 10 +notes: +- Requires the pymongo Python package on the remote host, version 2.4.2+. This + can be installed using pip or the OS package manager. @see U(http://api.mongodb.org/python/current/installation.html) +requirements: + - pymongo +''' + +EXAMPLES = r''' +- name: Attempt to perform a clean shutdown + community.mongodb.mongodb_shutdown: + +- name: Force shutdown with a timeout of 60 seconds + mongodb_maintenance: + force: true + timeout: 60 +''' + +RETURN = r''' +changed: + description: Whether the member was shutdown. + returned: success + type: bool +msg: + description: A short description of what happened. + returned: success + type: str +failed: + description: If something went wrong + returned: failed + type: bool +''' + +from copy import deepcopy + +import os +import ssl as ssl_lib +from distutils.version import LooseVersion + + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_native +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + load_mongocnf, + mongodb_common_argument_spec, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import PyMongoVersion, PYMONGO_IMP_ERR, pymongo_found, MongoClient + + +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + force=dict(type='bool', default=False), + timeout=dict(type='int', default=10) + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['login_user', 'login_password']], + ) + + try: + from collections import OrderedDict + except ImportError as excep: + try: + from ordereddict import OrderedDict + except ImportError as excep: + module.fail_json(msg='Cannot import OrderedDict class. You can probably install with: pip install ordereddict: %s' + % to_native(excep)) + + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_database = module.params['login_database'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + force = module.params['force'] + timeout = module.params['timeout'] + ssl = module.params['ssl'] + + result = dict( + changed=False, + ) + + connection_params = dict( + host=login_host, + port=int(login_port), + ) + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + try: + client = MongoClient(**connection_params) + except Exception as excep: + module.fail_json(msg='Unable to connect to MongoDB: %s' % to_native(excep)) + + if login_user is None and login_password is None: + mongocnf_creds = load_mongocnf() + if mongocnf_creds is not False: + login_user = mongocnf_creds['user'] + login_password = mongocnf_creds['password'] + elif login_password is None or login_user is None: + module.fail_json(msg="When supplying login arguments, both 'login_user' and 'login_password' must be provided") + + if login_user is not None and login_password is not None: + try: + client.admin.authenticate(login_user, login_password, source=login_database) + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + except Exception as excep: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(excep)) + + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + except Exception as excep: + module.fail_json(msg='Unable to authenticate with MongoDB: %s' % to_native(excep)) + + try: + cmd_doc = OrderedDict([ + ('shutdown', 1), + ('force', force), + ('timeout', timeout) + ]) + client['admin'].command(cmd_doc) + result["changed"] = True + result["msg"] = "mongod process was terminated sucessfully" + except Exception as excep: + if "connection closed" in str(excep): + result["changed"] = True + result["msg"] = "mongod process was terminated sucessfully" + else: + result["msg"] = "An error occurred: {0}".format(excep) + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_status.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_status.py new file mode 100644 index 00000000..479fc3c6 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_status.py @@ -0,0 +1,349 @@ +#!/usr/bin/python + +# Copyright: (c) 2018, Rhys Campbell <rhys.james.campbell@googlemail.com> +# 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 +__metaclass__ = type + + +DOCUMENTATION = r''' +--- +module: mongodb_status +short_description: Validates the status of the cluster. +description: + - Validates the status of the cluster. + - The module expects all replicaset nodes to be PRIMARY, SECONDARY or ARBITER. + - Will wait until a timeout for the replicaset state to converge if required. + - Can also be used to lookup the current PRIMARY member (see examples). +author: Rhys Campbell (@rhysmeister) +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + replica_set: + description: + - Replicaset name. + type: str + default: rs0 + poll: + description: + - The maximum number of times to query for the replicaset status before the set converges or we fail. + type: int + default: 1 + interval: + description: + - The number of seconds to wait between polling executions. + type: int + default: 30 +notes: +- Requires the pymongo Python package on the remote host, version 2.4.2+. This + can be installed using pip or the OS package manager. @see U(http://api.mongodb.org/python/current/installation.html) +requirements: +- pymongo +''' + +EXAMPLES = r''' +- name: Check replicaset is healthy, fail if not after first attempt + community.mongodb.mongodb_status: + replica_set: rs0 + when: ansible_hostname == "mongodb1" + +- name: Wait for the replicaset rs0 to converge, check 5 times, 10 second interval between checks + community.mongodb.mongodb_status: + replica_set: rs0 + poll: 5 + interval: 10 + when: ansible_hostname == "mongodb1" + +# Get the replicaset status and then lookup the primary's hostname and save to a variable +- name: Ensure replicaset is stable before beginning + community.mongodb.mongodb_status: + login_user: "{{ admin_user }}" + login_password: "{{ admin_user_password }}" + poll: 3 + interval: 10 + register: rs + +- name: Lookup PRIMARY replicaset member + set_fact: + primary: "{{ item.key.split('.')[0] }}" + loop: "{{ lookup('dict', rs.replicaset) }}" + when: "'PRIMARY' in item.value" +''' + +RETURN = r''' +failed: + description: If the mnodule had failed or not. + returned: always + type: bool +iterations: + description: Number of times the module has queried the replicaset status. + returned: always + type: int +msg: + description: Status message. + returned: always + type: str +replicaset: + description: The last queried status of all the members of the replicaset if obtainable. + returned: always + type: dict +''' + + +from copy import deepcopy +import time + +import os +import ssl as ssl_lib +from distutils.version import LooseVersion +import traceback + + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_native +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + load_mongocnf, + mongodb_common_argument_spec, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import PyMongoVersion, PYMONGO_IMP_ERR, pymongo_found, MongoClient + + +def replicaset_status(client, module): + """ + Return the replicaset status document from MongoDB + # https://docs.mongodb.com/manual/reference/command/replSetGetStatus/ + """ + rs = client.admin.command('replSetGetStatus') + return rs + + +def replicaset_members(replicaset_document): + """ + Returns the members section of the MongoDB replicaset document + """ + return replicaset_document["members"] + + +def replicaset_friendly_document(members_document): + """ + Returns a version of the members document with + only the info this module requires: name & stateStr + """ + friendly_document = {} + + for member in members_document: + friendly_document[member["name"]] = member["stateStr"] + return friendly_document + + +def replicaset_statuses(members_document, module): + """ + Return a list of the statuses + """ + statuses = [] + for member in members_document: + statuses.append(members_document[member]) + return statuses + + +def replicaset_good(statuses, module): + """ + Returns true if the replicaset is in a "good" condition. + Good is defined as an odd number of servers >= 3, with + max one primary, and any even amount of + secondary and arbiter servers + """ + module.debug(msg=str(statuses)) + msg = "Unset" + status = None + valid_statuses = ["PRIMARY", "SECONDARY", "ARBITER"] + # Odd number of servers is good + if len(statuses) % 2 == 1: + if (statuses.count("PRIMARY") == 1 + and ((statuses.count("SECONDARY") + + statuses.count("ARBITER")) % 2 == 0) + and len(set(statuses) - set(valid_statuses)) == 0): + status = True + msg = "replicaset is in a converged state" + else: + status = False + msg = "replicaset is not currently in a converged state" + else: + msg = "Even number of servers currently in replicaset." + status = False + return status, msg + + +def replicaset_status_poll(client, module): + """ + client - MongoDB Client + poll - Number of times to poll + interval - interval between polling attempts + """ + iterations = 0 # How many times we have queried the cluster + failures = 0 # Number of failures when querying the replicaset + poll = module.params['poll'] + interval = module.params['interval'] + status = None + return_doc = {} + + while iterations < poll: + try: + iterations += 1 + replicaset_document = replicaset_status(client, module) + members = replicaset_members(replicaset_document) + friendly_document = replicaset_friendly_document(members) + statuses = replicaset_statuses(friendly_document, module) + status, msg = replicaset_good(statuses, module) + if status: # replicaset looks good + return_doc = {"failures": failures, + "poll": poll, + "iterations": iterations, + "msg": msg, + "replicaset": friendly_document} + break + else: + failures += 1 + return_doc = {"failures": failures, + "poll": poll, + "iterations": iterations, + "msg": msg, + "replicaset": friendly_document, + "failed": True} + if iterations == poll: + break + else: + time.sleep(interval) + except Exception as e: + failures += 1 + return_doc['failed'] = True + return_doc['msg'] = str(e) + status = False + if iterations == poll: + break + else: + time.sleep(interval) + + return_doc['failures'] = failures + return status, return_doc['msg'], return_doc + + +# ========================================= +# Module execution. +# + + +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + interval=dict(type='int', default=30), + poll=dict(type='int', default=1), + replica_set=dict(type='str', default="rs0"), + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=False, + required_together=[['login_user', 'login_password']], + ) + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_database = module.params['login_database'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + replica_set = module.params['replica_set'] + ssl = module.params['ssl'] + poll = module.params['poll'] + interval = module.params['interval'] + + result = dict( + failed=False, + replica_set=replica_set, + ) + + connection_params = dict( + host=login_host, + port=int(login_port), + ) + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + try: + client = MongoClient(**connection_params) + except Exception as e: + module.fail_json(msg='Unable to connect to database: %s' % to_native(e)) + + try: + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + except Exception as e: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(e)) + + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + except Exception as excep: + if excep.code != 13: + raise excep + if login_user is None or login_password is None: + raise excep + client.admin.authenticate(login_user, login_password, source=login_database) + check_compatibility(module, client) + + if login_user is None and login_password is None: + mongocnf_creds = load_mongocnf() + if mongocnf_creds is not False: + login_user = mongocnf_creds['user'] + login_password = mongocnf_creds['password'] + elif login_password is None or login_user is None: + module.fail_json(msg="When supplying login arguments, both 'login_user' and 'login_password' must be provided") + + try: + client['admin'].command('listDatabases', 1.0) # if this throws an error we need to authenticate + except Exception as excep: + if "not authorized on" in str(excep) or "command listDatabases requires authentication" in str(excep): + if login_user is not None and login_password is not None: + try: + client.admin.authenticate(login_user, login_password, source=login_database) + except Exception as excep: + module.fail_json(msg='unable to connect to database: %s' % to_native(excep), exception=traceback.format_exc()) + else: + module.fail_json(msg='unable to connect to database: %s' % to_native(excep), exception=traceback.format_exc()) + else: + module.fail_json(msg='unable to connect to database: %s' % to_native(excep), exception=traceback.format_exc()) + + if len(replica_set) == 0: + module.fail_json(msg="Parameter 'replica_set' must not be an empty string") + + try: + status, msg, return_doc = replicaset_status_poll(client, module) # Sort out the return doc + replicaset = return_doc['replicaset'] + iterations = return_doc['iterations'] + except Exception as e: + module.fail_json(msg='Unable to query replica_set info: %s' % str(e)) + + if status is False: + module.fail_json(msg=msg, replicaset=replicaset, iterations=iterations) + else: + module.exit_json(msg=msg, replicaset=replicaset, iterations=iterations) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_stepdown.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_stepdown.py new file mode 100644 index 00000000..48d2b085 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_stepdown.py @@ -0,0 +1,317 @@ +#!/usr/bin/python + +# Copyright: (c) 2020, Rhys Campbell <rhys.james.campbell@googlemail.com> +# 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 +__metaclass__ = type + + +DOCUMENTATION = r''' +--- +module: mongodb_stepdown +short_description: Step down the MongoDB node from a PRIMARY state. +description: > + Step down the MongoDB node from the PRIMARY state if it has that status. + Returns OK immediately if the member is already in the SECONDARY or ARBITER states. + Will wait until a timeout for the member state to reach SECONDARY or PRIMARY, + if the member state is currently STARTUP, RECOVERING, STARTUP2 or ROLLBACK, + before taking any needed action. +author: Rhys Campbell (@rhysmeister) +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + poll: + description: + - The maximum number of times query for the member status. + type: int + default: 1 + interval: + description: + - The number of seconds to wait between poll executions. + type: int + default: 30 + stepdown_seconds: + description: + - The number of seconds to step down the primary, during which time the stepdown member is ineligible for becoming primary. + type: int + default: 60 + secondary_catch_up: + description: + - The secondaryCatchUpPeriodSecs parameter for the stepDown command. + - The number of seconds that mongod will wait for an electable secondary to catch up to the primary. + type: int + default: 10 + force: + description: + - Optional. A boolean that determines whether the primary steps down if no electable and up-to-date secondary exists within the wait period. + type: bool + default: false +notes: + - Requires the pymongo Python package on the remote host, version 2.4.2+. This + can be installed using pip or the OS package manager. @see U(http://api.mongodb.org/python/current/installation.html) +requirements: + - pymongo +''' + +EXAMPLES = r''' +- name: Step down the current MongoDB member + community.mongodb.mongodb_stepdown: + login_user: admin + login_password: secret + +- name: Step down the current MongoDB member, poll a maximum of 5 times if member state is recovering + community.mongodb.mongodb_stepdown: + login_user: admin + login_password: secret + poll: 5 + interval: 10 +''' + +RETURN = r''' +failed: + description: If the module had failed or not. + returned: always + type: bool +iteration: + description: Number of times the module has queried the replicaset status. + returned: always + type: int +msg: + description: Status message. + returned: always + type: str +''' + + +from copy import deepcopy +import time + +import os +import ssl as ssl_lib +from distutils.version import LooseVersion +import traceback + + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_native +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + load_mongocnf, + mongodb_common_argument_spec, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import PyMongoVersion, PYMONGO_IMP_ERR, pymongo_found, MongoClient + + +def member_status(client): + """ + Return the member status string + # https://docs.mongodb.com/manual/reference/command/replSetGetStatus/ + """ + myStateStr = None + rs = client.admin.command('replSetGetStatus') + for member in rs["members"]: + if "self" in member.keys(): + myStateStr = member["stateStr"] + return myStateStr + + +def member_stepdown(client, module): + """ + client - MongoDB Client + module - Ansible module object + """ + + try: + from collections import OrderedDict + except ImportError as excep: + try: + from ordereddict import OrderedDict + except ImportError as excep: + module.fail_json(msg='Cannot import OrderedDict class. You can probably install with: pip install ordereddict: %s' + % to_native(excep)) + + iterations = 0 # How many times we have queried the member + failures = 0 # Number of failures when querying the replicaset + poll = module.params['poll'] + interval = module.params['interval'] + stepdown_seconds = module.params['stepdown_seconds'] + secondary_catch_up = module.params['secondary_catch_up'] + force = module.params['force'] + return_doc = {} + status = None + + while iterations < poll: + try: + iterations += 1 + return_doc['iterations'] = iterations + myStateStr = member_status(client) + if myStateStr == "PRIMARY": + # Run step down command + if module.check_mode: + return_doc["msg"] = "member was stepped down" + return_doc['changed'] = True + status = True + break + else: + cmd_doc = OrderedDict([ + ('replSetStepDown', stepdown_seconds), + ('secondaryCatchUpPeriodSecs', secondary_catch_up), + ('force', force) + ]) + try: + client.admin.command(cmd_doc) # For now we assume the stepDown was successful + except Exception as excep: + # 4.0 and below close the connection as part of the stepdown. + # This code should be removed once we support 4.2+ onwards + # https://tinyurl.com/yc79g9ay + if str(excep) == "connection closed": + pass + else: + raise excep + return_doc['changed'] = True + status = True + return_doc["msg"] = "member was stepped down" + break + elif myStateStr in ["SECONDARY", "ARBITER"]: + return_doc["msg"] = "member was already at {0} state".format(myStateStr) + return_doc['changed'] = False + status = True + break + elif myStateStr in ["STARTUP", "RECOVERING", "STARTUP2", "ROLLBACK"]: + time.sleep(interval) # Wait for interval + else: + return_doc["msg"] = "Unexpected member state {0}".format(myStateStr) + return_doc['changed'] = False + status = False + break + except Exception as e: + failures += 1 + return_doc['failed'] = True + return_doc['changed'] = False + return_doc['msg'] = str(e) + status = False + if iterations == poll: + break + else: + time.sleep(interval) + + return status, return_doc['msg'], return_doc + + +# ========================================= +# Module execution. +# + + +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + force=dict(type='bool', default=False), + interval=dict(type='int', default=30), + poll=dict(type='int', default=1), + secondary_catch_up=dict(type='int', default=10), + stepdown_seconds=dict(type='int', default=60) + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['login_user', 'login_password']], + ) + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_database = module.params['login_database'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + ssl = module.params['ssl'] + poll = module.params['poll'] + interval = module.params['interval'] + stepdown_seconds = module.params['stepdown_seconds'] + secondary_catch_up = module.params['secondary_catch_up'] + + result = dict( + failed=False, + ) + + connection_params = dict( + host=login_host, + port=int(login_port), + ) + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + try: + client = MongoClient(**connection_params) + except Exception as e: + module.fail_json(msg='Unable to connect to database: %s' % to_native(e)) + + try: + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + except Exception as e: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(e)) + + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + except Exception as excep: + if "not authorized on" not in str(excep) and "there are no users authenticated" not in str(excep): + raise excep + if login_user is None or login_password is None: + raise excep + client.admin.authenticate(login_user, login_password, source=login_database) + check_compatibility(module, client) + + if login_user is None and login_password is None: + mongocnf_creds = load_mongocnf() + if mongocnf_creds is not False: + login_user = mongocnf_creds['user'] + login_password = mongocnf_creds['password'] + elif login_password is None or login_user is None: + module.fail_json(msg="When supplying login arguments, both 'login_user' and 'login_password' must be provided") + + try: + client['admin'].command('listDatabases', 1.0) # if this throws an error we need to authenticate + except Exception as excep: + if "not authorized on" in str(excep) or "command listDatabases requires authentication" in str(excep): + if login_user is not None and login_password is not None: + try: + client.admin.authenticate(login_user, login_password, source=login_database) + except Exception as excep: + module.fail_json(msg='unable to connect to database: %s' % to_native(excep), exception=traceback.format_exc()) + else: + module.fail_json(msg='unable to connect to database: %s' % to_native(excep), exception=traceback.format_exc()) + else: + module.fail_json(msg='unable to connect to database: %s' % to_native(excep), exception=traceback.format_exc()) + + try: + status, msg, return_doc = member_stepdown(client, module) + iterations = return_doc['iterations'] + changed = return_doc['changed'] + except Exception as e: + module.fail_json(msg='Unable to query replica_set info: %s' % str(e)) + + if status is False: + module.fail_json(msg=msg, iterations=iterations, changed=changed) + else: + module.exit_json(msg=msg, iterations=iterations, changed=changed) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_user.py b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_user.py new file mode 100644 index 00000000..199038d8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/plugins/modules/mongodb_user.py @@ -0,0 +1,460 @@ +#!/usr/bin/python + +# (c) 2012, Elliott Foster <elliott@fourkitchens.com> +# Sponsored by Four Kitchens http://fourkitchens.com. +# (c) 2014, Epic Games, Inc. +# +# 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 +__metaclass__ = type + + +DOCUMENTATION = ''' +--- +module: mongodb_user +short_description: Adds or removes a user from a MongoDB database +description: + - Adds or removes a user from a MongoDB database. +version_added: "1.0.0" + +extends_documentation_fragment: + - community.mongodb.login_options + - community.mongodb.ssl_options + +options: + replica_set: + description: + - Replica set to connect to (automatically connects to primary for writes). + type: str + database: + description: + - The name of the database to add/remove the user from. + required: true + type: str + aliases: [db] + name: + description: + - The name of the user to add or remove. + required: true + aliases: [user] + type: str + password: + description: + - The password to use for the user. + type: str + aliases: [pass] + roles: + type: list + elements: raw + description: + - > + The database user roles valid values could either be one or more of the following strings: + 'read', 'readWrite', 'dbAdmin', 'userAdmin', 'clusterAdmin', 'readAnyDatabase', 'readWriteAnyDatabase', 'userAdminAnyDatabase', + 'dbAdminAnyDatabase' + - "Or the following dictionary '{ db: DATABASE_NAME, role: ROLE_NAME }'." + - "This param requires pymongo 2.5+. If it is a string, mongodb 2.4+ is also required. If it is a dictionary, mongo 2.6+ is required." + state: + description: + - The database user state. + default: present + choices: [absent, present] + type: str + update_password: + default: always + choices: [always, on_create] + description: + - C(always) will always update passwords and cause the module to return changed. + - C(on_create) will only set the password for newly created users. + - This must be C(always) to use the localhost exception when adding the first admin user. + type: str + create_for_localhost_exception: + type: path + description: + - This is parmeter is only useful for handling special treatment around the localhost exception. + - If C(login_user) is defined, then the localhost exception is not active and this parameter has no effect. + - If this file is NOT present (and C(login_user) is not defined), then touch this file after successfully adding the user. + - If this file is present (and C(login_user) is not defined), then skip this task. + +notes: + - Requires the pymongo Python package on the remote host, version 2.4.2+. This + can be installed using pip or the OS package manager. Newer mongo server versions require newer + pymongo versions. @see http://api.mongodb.org/python/current/installation.html +requirements: + - "pymongo" +author: + - "Elliott Foster (@elliotttf)" + - "Julien Thebault (@Lujeni)" +''' + +EXAMPLES = ''' +- name: Create 'burgers' database user with name 'bob' and password '12345'. + community.mongodb.mongodb_user: + database: burgers + name: bob + password: 12345 + state: present + +- name: Create a database user via SSL (MongoDB must be compiled with the SSL option and configured properly) + community.mongodb.mongodb_user: + database: burgers + name: bob + password: 12345 + state: present + ssl: True + +- name: Delete 'burgers' database user with name 'bob'. + community.mongodb.mongodb_user: + database: burgers + name: bob + state: absent + +- name: Define more users with various specific roles (if not defined, no roles is assigned, and the user will be added via pre mongo 2.2 style) + community.mongodb.mongodb_user: + database: burgers + name: ben + password: 12345 + roles: read + state: present + +- name: Define roles + community.mongodb.mongodb_user: + database: burgers + name: jim + password: 12345 + roles: readWrite,dbAdmin,userAdmin + state: present + +- name: Define roles + community.mongodb.mongodb_user: + database: burgers + name: joe + password: 12345 + roles: readWriteAnyDatabase + state: present + +- name: Add a user to database in a replica set, the primary server is automatically discovered and written to + community.mongodb.mongodb_user: + database: burgers + name: bob + replica_set: belcher + password: 12345 + roles: readWriteAnyDatabase + state: present + +# add a user 'oplog_reader' with read only access to the 'local' database on the replica_set 'belcher'. This is useful for oplog access (MONGO_OPLOG_URL). +# please notice the credentials must be added to the 'admin' database because the 'local' database is not synchronized and can't receive user credentials +# To login with such user, the connection string should be MONGO_OPLOG_URL="mongodb://oplog_reader:oplog_reader_password@server1,server2/local?authSource=admin" +# This syntax requires mongodb 2.6+ and pymongo 2.5+ +- name: Roles as a dictionary + community.mongodb.mongodb_user: + login_user: root + login_password: root_password + database: admin + user: oplog_reader + password: oplog_reader_password + state: present + replica_set: belcher + roles: + - db: local + role: read + +- name: Adding a user with X.509 Member Authentication + community.mongodb.mongodb_user: + login_host: "mongodb-host.test" + login_port: 27001 + login_database: "$external" + database: "admin" + name: "admin" + password: "test" + roles: + - dbAdminAnyDatabase + ssl: true + ssl_ca_certs: "/tmp/ca.crt" + ssl_certfile: "/tmp/tls.key" #cert and key in one file + state: present + auth_mechanism: "MONGODB-X509" + connection_options: + - "tlsAllowInvalidHostnames=true" +''' + +RETURN = ''' +user: + description: The name of the user to add or remove. + returned: success + type: str +''' + +import os +import ssl as ssl_lib +from distutils.version import LooseVersion +import traceback +from operator import itemgetter + + +from ansible.module_utils.basic import AnsibleModule, missing_required_lib +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_native, to_bytes +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import ( + check_compatibility, + missing_required_lib, + load_mongocnf, + mongodb_common_argument_spec, + ssl_connection_options +) +from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import PyMongoVersion, PYMONGO_IMP_ERR, pymongo_found, MongoClient + + +def user_find(client, user, db_name): + """Check if the user exists. + + Args: + client (cursor): Mongodb cursor on admin database. + user (str): User to check. + db_name (str): User's database. + + Returns: + dict: when user exists, False otherwise. + """ + for mongo_user in client[db_name].command('usersInfo')['users']: + if mongo_user['user'] == user: + # NOTE: there is no 'db' field in mongo 2.4. + if 'db' not in mongo_user: + return mongo_user + + if mongo_user["db"] in [db_name, "admin"]: # Workaround to make the condition works with AWS DocumentDB, since all users are in the admin database. + + return mongo_user + return False + + +def user_add(module, client, db_name, user, password, roles): + # pymongo's user_add is a _create_or_update_user so we won't know if it was changed or updated + # without reproducing a lot of the logic in database.py of pymongo + db = client[db_name] + + try: + exists = user_find(client, user, db_name) + except Exception as excep: + # We get this exception: "not authorized on admin to execute command" + # when auth is enabled on a new instance. The loalhost exception should + # allow us to create the first user. If the localhost exception does not apply, + # then user creation will also fail with unauthorized. So, ignore Unauthorized here. + if hasattr(excep, 'code') and excep.code == 13: # 13=Unauthorized + exists = False + else: + raise + + if exists: + user_add_db_command = 'updateUser' + else: + user_add_db_command = 'createUser' + + user_dict = {} + + if password is not None: + user_dict["pwd"] = password + if roles is not None: + user_dict["roles"] = roles + + db.command(user_add_db_command, user, **user_dict) + + +def user_remove(module, client, db_name, user): + exists = user_find(client, user, db_name) + if exists: + if module.check_mode: + module.exit_json(changed=True, user=user) + db = client[db_name] + db.command("dropUser", user) + else: + module.exit_json(changed=False, user=user) + + +def check_if_roles_changed(uinfo, roles, db_name): + # We must be aware of users which can read the oplog on a replicaset + # Such users must have access to the local DB, but since this DB does not store users credentials + # and is not synchronized among replica sets, the user must be stored on the admin db + # Therefore their structure is the following : + # { + # "_id" : "admin.oplog_reader", + # "user" : "oplog_reader", + # "db" : "admin", # <-- admin DB + # "roles" : [ + # { + # "role" : "read", + # "db" : "local" # <-- local DB + # } + # ] + # } + + def make_sure_roles_are_a_list_of_dict(roles, db_name): + output = list() + for role in roles: + if isinstance(role, (binary_type, text_type)): + new_role = {"role": role, "db": db_name} + output.append(new_role) + else: + output.append(role) + return output + + roles_as_list_of_dict = make_sure_roles_are_a_list_of_dict(roles, db_name) + uinfo_roles = uinfo.get('roles', []) + + if sorted(roles_as_list_of_dict, key=itemgetter('db')) == sorted(uinfo_roles, key=itemgetter('db')): + return False + return True + + +# ========================================= +# Module execution. +# + +def main(): + argument_spec = mongodb_common_argument_spec() + argument_spec.update( + database=dict(required=True, aliases=['db']), + name=dict(required=True, aliases=['user']), + password=dict(aliases=['pass'], no_log=True), + replica_set=dict(default=None), + roles=dict(default=None, type='list', elements='raw'), + state=dict(default='present', choices=['absent', 'present']), + update_password=dict(default="always", choices=["always", "on_create"], no_log=False), + create_for_localhost_exception=dict(default=None, type='path'), + ) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['login_user', 'login_password']], + ) + if not pymongo_found: + module.fail_json(msg=missing_required_lib('pymongo'), + exception=PYMONGO_IMP_ERR) + + login_user = module.params['login_user'] + login_password = module.params['login_password'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + login_database = module.params['login_database'] + create_for_localhost_exception = module.params['create_for_localhost_exception'] + b_create_for_localhost_exception = ( + to_bytes(create_for_localhost_exception, errors='surrogate_or_strict') + if create_for_localhost_exception is not None else None + ) + + replica_set = module.params['replica_set'] + db_name = module.params['database'] + user = module.params['name'] + password = module.params['password'] + ssl = module.params['ssl'] + roles = module.params['roles'] or [] + state = module.params['state'] + update_password = module.params['update_password'] + + try: + connection_params = { + "host": login_host, + "port": int(login_port), + } + + if replica_set: + connection_params["replicaset"] = replica_set + + if ssl: + connection_params = ssl_connection_options(connection_params, module) + + client = MongoClient(**connection_params) + + if login_user is None and login_password is None: + mongocnf_creds = load_mongocnf() + if mongocnf_creds is not False: + login_user = mongocnf_creds['user'] + login_password = mongocnf_creds['password'] + elif login_password is None or login_user is None: + module.fail_json(msg='when supplying login arguments, both login_user and login_password must be provided') + + if login_user is not None and login_password is not None: + client.admin.authenticate(login_user, login_password, source=login_database) + # Get server version: + try: + srv_version = LooseVersion(client.server_info()['version']) + except Exception as e: + module.fail_json(msg='Unable to get MongoDB server version: %s' % to_native(e)) + + # Get driver version:: + driver_version = LooseVersion(PyMongoVersion) + + # Check driver and server version compatibility: + check_compatibility(module, srv_version, driver_version) + elif LooseVersion(PyMongoVersion) >= LooseVersion('3.0'): + if db_name != "admin": + module.fail_json(msg='The localhost login exception only allows the first admin account to be created') + # else: this has to be the first admin user added + + except Exception as e: + module.fail_json(msg='unable to connect to database: %s' % to_native(e), exception=traceback.format_exc()) + + if state == 'present': + if password is None and update_password == 'always': + module.fail_json(msg='password parameter required when adding a user unless update_password is set to on_create') + + if login_user is None and create_for_localhost_exception is not None: + if os.path.exists(b_create_for_localhost_exception): + try: + client.close() + except Exception: + pass + module.exit_json(changed=False, user=user, skipped=True, msg="The path in create_for_localhost_exception exists.") + + try: + if update_password != 'always': + uinfo = user_find(client, user, db_name) + if uinfo: + password = None + if not check_if_roles_changed(uinfo, roles, db_name): + module.exit_json(changed=False, user=user) + + if module.check_mode: + module.exit_json(changed=True, user=user) + + user_add(module, client, db_name, user, password, roles) + except Exception as e: + module.fail_json(msg='Unable to add or update user: %s' % to_native(e), exception=traceback.format_exc()) + finally: + try: + client.close() + except Exception: + pass + # Here we can check password change if mongo provide a query for that : https://jira.mongodb.org/browse/SERVER-22848 + # newuinfo = user_find(client, user, db_name) + # if uinfo['role'] == newuinfo['role'] and CheckPasswordHere: + # module.exit_json(changed=False, user=user) + + if login_user is None and create_for_localhost_exception is not None: + # localhost exception applied. + try: + # touch the file + open(b_create_for_localhost_exception, 'wb').close() + except Exception as e: + module.fail_json( + changed=True, + msg='Added user but unable to touch create_for_localhost_exception file %s: %s' % (create_for_localhost_exception, to_native(e)), + exception=traceback.format_exc() + ) + + elif state == 'absent': + try: + user_remove(module, client, db_name, user) + except Exception as e: + module.fail_json(msg='Unable to remove user: %s' % to_native(e), exception=traceback.format_exc()) + finally: + try: + client.close() + except Exception: + pass + module.exit_json(changed=True, user=user) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/community/mongodb/requirements-2.7.txt b/collections-debian-merged/ansible_collections/community/mongodb/requirements-2.7.txt new file mode 100644 index 00000000..0a6e1a15 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/requirements-2.7.txt @@ -0,0 +1,9 @@ +ansible==2.9.13 +ansible-lint==4.2.0 +docker==4.1.0 +flake8==3.7.9 +molecule>=2.22,<3.0 +pytest==4.6.9 +python-vagrant==0.5.15 +# sh 1.13.1 causes molecule yamllint to fail. +sh<1.13 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/requirements-3.5.txt b/collections-debian-merged/ansible_collections/community/mongodb/requirements-3.5.txt new file mode 100644 index 00000000..ca86cbcf --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/requirements-3.5.txt @@ -0,0 +1,8 @@ +ansible==2.9.13 +ansible-lint==4.2.0 +docker==4.1.0 +flake8==3.7.9 +molecule>=2.22,<3.0 +pytest==5.3.4 +python-vagrant==0.5.15 +sh==1.13.1 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/requirements-3.6.txt b/collections-debian-merged/ansible_collections/community/mongodb/requirements-3.6.txt new file mode 100644 index 00000000..ca86cbcf --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/requirements-3.6.txt @@ -0,0 +1,8 @@ +ansible==2.9.13 +ansible-lint==4.2.0 +docker==4.1.0 +flake8==3.7.9 +molecule>=2.22,<3.0 +pytest==5.3.4 +python-vagrant==0.5.15 +sh==1.13.1 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/requirements-3.8.txt b/collections-debian-merged/ansible_collections/community/mongodb/requirements-3.8.txt new file mode 100644 index 00000000..ca86cbcf --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/requirements-3.8.txt @@ -0,0 +1,8 @@ +ansible==2.9.13 +ansible-lint==4.2.0 +docker==4.1.0 +flake8==3.7.9 +molecule>=2.22,<3.0 +pytest==5.3.4 +python-vagrant==0.5.15 +sh==1.13.1 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/.yamllint b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/.yamllint new file mode 100644 index 00000000..88276760 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/README.md b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/README.md new file mode 100644 index 00000000..3fc91610 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/README.md @@ -0,0 +1,56 @@ +mongodb_auth +============ + +This role to enables auth on MongoDB servers, adds the first admin user, and adds a list of other users. +If your mongo instance requires ssl or an alternative auth_mechanism, please use +[`module_defaults`](https://docs.ansible.com/ansible/latest/user_guide/playbooks_module_defaults.html) +to provide the default auth details for `community.mongodb.mongodb_user` (these defaults are ignored +when adding the initial admin user with the localhost exception). + +If running this on a MongoDB server that already has an admin user (ie when using this role to audit +an alternate install method), you must touch `/root/mongodb_admin.success` or you will get an error +when this role tries to add the admin user again. + +Role Variables +-------------- + +mongod_host: The domain or ip to use to communicate with mongod. Default localhost. +mongod_port: The port used by the mongod process. Default 27017. +mongod_package: The mongod package to install. Default mongodb-org-server. +authorization: Enable authorization. Default enabled. +mongodb_admin_db: MongoDB admin database (for adding users). Default admin. +mongodb_admin_user: MongoDB admin username. Default admin. +mongodb_admin_pwd: MongoDB admin password. Defaults to value of mongodb_admin_default_pwd. +mongodb_admin_default_pwd: MongoDB admin password (for parent roles to override without overriding user's password). Default admin. +mongodb_users: List of additional users to add. Each user dict should include fields: db, user, pwd, roles +mongodb_force_update_password: Whether or not to force a password update for any users in mongodb_users. Setting this to yes will result in 'changed' on every run, even if the password is the same. Setting this to no only adds a password when creating the user. + +IMPORTANT NOTE: It is expected that mongodb_admin_user & mongodb_admin_pwd values be overridden in your own file protected by Ansible Vault. Any production environments should protect these values. For more information see [Ansible Vault](https://docs.ansible.com/ansible/latest/user_guide/vault.html) + +Dependencies +------------ + +mongodb_repository + +Example Playbook +---------------- + +Install MongoDB preparing hosts for a Sharded Cluster. + +```yaml + - hosts: servers + roles: + - { role: mongodb_repository } + - { role: mongodb_mongod, mongod_port: 27018, sharding: true } + - { role: mongodb_auth, mongod_port: 27018, mongod_host: 127.0.0.1, mongodb_admin_pwd: f00b@r } +``` + +License +------- + +BSD + +Author Information +------------------ + +Jacob Floyd (https://github.com/cognifloyd) diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/defaults/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/defaults/main.yml new file mode 100644 index 00000000..2612ee7b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/defaults/main.yml @@ -0,0 +1,27 @@ +--- +# defaults file for mongodb_auth +mongod_port: 27017 +mongod_package: "mongodb-org-server" + +authorization: "enabled" + +# when adding auth, the login credentials to use +mongodb_admin_user: admin +# For production use - please change the admin password! +mongodb_admin_pwd: "{{ mongodb_default_admin_pwd }}" +# The default is separate so other roles can provide a default without overriding a user provided password. +mongodb_default_admin_pwd: admin +# allow for alternate admin roles (eg userAdminAnyDatabase) +mongodb_admin_roles: "root" + +# Additional users to add. +mongodb_users: [] +# - db: somedatabase +# user: someuser +# pwd: "S0meP@ss" +# roles: readWrite + +# whether or not to force a password update for any users in mongodb_users +# Setting this to yes will result in 'changed' on every run, even if the password is the same. +# See the comment in tasks/main.yml for more details. +mongodb_force_update_password: no diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/meta/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/meta/main.yml new file mode 100644 index 00000000..c2ab9e8b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/meta/main.yml @@ -0,0 +1,30 @@ +--- +galaxy_info: + author: Jacob Floyd + description: Configure auth on MongoDB servers + + license: BSD + + min_ansible_version: 2.9 + + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/Dockerfile.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/Dockerfile.j2 new file mode 100644 index 00000000..935dd3d7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/Dockerfile.j2 @@ -0,0 +1,39 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +{% if item.env is defined %} +{% for var, value in item.env.items() %} +{% if value %} +ENV {{ var }} {{ value }} +{% endif %} +{% endfor %} +{% endif %} +# Add systemd-sysv package for Debian to get systemd working (and procps for sysctl) and netbase for firewalld +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 systemd-sysv procps netbase && apt-get clean; \ + elif [ $(command -v dnf) ] && grep -q 'platform:el8' /etc/os-release ; then dnf makecache && dnf update -y && dnf --assumeyes install python3 sudo python3-devel bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && rm -Rf /usr/share/doc && rm -Rf /usr/share/man && dnf clean all && cp /bin/true /sbin/agetty; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi + +{% if item.image == 'centos:8' %} +# Stuff for systemd https://hub.docker.com/_/centos +RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \ + systemd-tmpfiles-setup.service ] || rm -f $i; done); \ + rm -f /lib/systemd/system/multi-user.target.wants/*;\ + rm -f /etc/systemd/system/*.wants/*;\ + rm -f /lib/systemd/system/local-fs.target.wants/*; \ + rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ + rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ + rm -f /lib/systemd/system/basic.target.wants/*;\ + rm -f /lib/systemd/system/anaconda.target.wants/*; + +VOLUME [ "/sys/fs/cgroup" ] +CMD ["/sbin/init"] +{% endif %} diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/molecule.yml new file mode 100644 index 00000000..783a1cdd --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/molecule.yml @@ -0,0 +1,50 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos_7 + image: centos:7 + command: /sbin/init + privileged: True + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - name: centos_8 + image: centos:8 + command: /sbin/init + privileged: True + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - name: ubuntu_16 + image: ubuntu:16.04 + command: /sbin/init + privileged: True + - name: ubuntu_18 + image: ubuntu:18.04 + command: /sbin/init + privileged: True + - name: debian_buster + image: debian:buster + command: /sbin/init + privileged: True + - name: debian_stretch + image: debian:stretch + command: /sbin/init + privileged: True +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/playbook.yml new file mode 100644 index 00000000..ca136e75 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/playbook.yml @@ -0,0 +1,65 @@ +--- +- name: Converge + hosts: all + become: yes + vars: + # for this test, each machine is an isolated mongod instance + replicaset: false + sharding: false + + # initially disable authorization on some hosts + hosts_with_auth_disabled: + - ubuntu_18 + - debian_buster + + # add some users for some of the hosts + hosts_with_extra_user: + - centos_8 + - ubuntu_16 + - debian_buster + mongodb_users_empty: [] + mongodb_users_full: + - db: somedatabase + user: someuser + pwd: "S0meP@ss" + roles: readWrite + - db: somedatabase + user: otheruser + pwd: "0th3rP@ss" + roles: readWrite + mongodb_users: "{% if inventory_hostname in hosts_with_extra_user %}{{ mongodb_users_full }}{% else %}{{ mongodb_users_empty }}{% endif %}" + + roles: + - role: mongodb_repository + tags: molecule-idempotence-notest + - role: mongodb_mongod + authorization: "{% if inventory_hostname in hosts_with_auth_disabled %}disabled{% else %}enabled{% endif %}" + tags: molecule-idempotence-notest # avoids false positive where replacing conf file disables authorization again + + tasks: + - name: Add EPEL repo to CentOS 7 to allow installing pip package + become: yes + yum: + name: "https://dl.fedoraproject.org/pub/epel/epel-release-latest-{{ ansible_facts.distribution_major_version }}.noarch.rpm" + state: present + when: inventory_hostname == 'centos_7' + + - name: Install python stuff + package: + name: + - "python{% if needs_3 %}3{% endif %}-setuptools" + - "python{% if needs_3 %}3{% endif %}-pip" + vars: + needs_3: "{{ ansible_facts.python.version.major == 3 }}" + + - name: Install pymongo + pip: + name: pymongo + + - name: Enable mongo auth + include_role: + name: mongodb_auth + + - name: Install MongoDB Shell + package: + name: mongodb-org-shell diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/tests/test_default.py new file mode 100644 index 00000000..933015a0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/default/tests/test_default.py @@ -0,0 +1,56 @@ +import os +import yaml + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ["MOLECULE_INVENTORY_FILE"] +).get_hosts("all") + + +def include_vars(host): + ansible = host.ansible("include_vars", + 'file="../../defaults/main.yml"', + False, + False) + return ansible + + +def test_mongod_cnf_file(host): + f = host.file("/etc/mongod.conf") + + assert f.exists + assert yaml.safe_load(f.content)["security"]["authorization"] == "enabled" + + +def test_mongod_service(host): + mongod_service = include_vars(host)["ansible_facts"].get("mongod_service", "mongod") + s = host.service(mongod_service) + + assert s.is_running + assert s.is_enabled + + +def test_mongod_port(host): + port = include_vars(host)["ansible_facts"].get("mongod_port", 27017) + s = host.socket("tcp://0.0.0.0:{0}".format(port)) + assert s.is_listening + + +def test_mongo_shell_connectivity(host): + """ + Tests that we can connect to mongos via the shell annd run a cmd + """ + facts = include_vars(host)["ansible_facts"] + port = facts.get("mongod_port", 27017) + user = facts.get("mongod_admin_user", "admin") + pwd = facts.get("mongod_default_admin_pwd", "admin") + + cmd = host.run( + "mongo admin --username {user} --password {pwd} --port {port} --eval 'db.runCommand({{listDatabases: 1}})'".format( + user=user, pwd=pwd, port=port + ) + ) + + assert cmd.rc == 0 + assert "admin" in cmd.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/molecule.yml new file mode 100644 index 00000000..14d29680 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/molecule.yml @@ -0,0 +1,54 @@ +--- +dependency: + name: galaxy +driver: + name: vagrant + provider: + name: virtualbox +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos-7 + box: centos/7 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-16 + box: ubuntu/xenial64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-18 + box: ubuntu/bionic64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-buster + box: debian/buster64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-stretch + box: debian/contrib-stretch64 # Standard debian/stretch64 had issues: Unable to locate package linux-headers-4.9.0-9-amd64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/playbook.yml new file mode 100644 index 00000000..5a0e4614 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/playbook.yml @@ -0,0 +1,66 @@ +--- +- name: Converge + hosts: all + become: yes + vars: + # for this test, each machine is an isolated mongod instance + replicaset: false + sharding: false + + # initially disable authorization on some hosts + hosts_with_auth_disabled: + - ubuntu_18 + - debian_buster + + # add some users for some of the hosts + hosts_with_extra_user: + - centos_8 + - ubuntu_16 + - debian_buster + mongodb_users_empty: [] + mongodb_users_full: + - db: somedatabase + user: someuser + pwd: "S0meP@ss" + roles: readWrite + - db: somedatabase + user: otheruser + pwd: "0th3rP@ss" + roles: readWrite + mongodb_users: "{% if inventory_hostname in hosts_with_extra_user %}{{ mongodb_users_full }}{% else %}{{ mongodb_users_empty }}{% endif %}" + + roles: + - role: mongodb_repository + tags: molecule-idempotence-notest + - role: mongodb_mongod + vars: + authorization: "{% if inventory_hostname in hosts_with_auth_disabled %}disabled{% else %}enabled{% endif %}" + tags: molecule-idempotence-notest # avoids false positive where replacing conf file disables authorization again + + tasks: + - name: Add EPEL repo to CentOS 7 to allow installing pip package + become: yes + yum: + name: "https://dl.fedoraproject.org/pub/epel/epel-release-latest-{{ ansible_facts.distribution_major_version }}.noarch.rpm" + state: present + when: inventory_hostname == 'centos_7' + + - name: Install python stuff + package: + name: + - "python{% if needs_3 %}3{% endif %}-setuptools" + - "python{% if needs_3 %}3{% endif %}-pip" + vars: + needs_3: "{{ ansible_facts.python.version.major == 3 }}" + + - name: Install pymongo + pip: + name: pymongo + + - name: Enable mongo auth + include_role: + name: mongodb_auth + + - name: Install MongoDB Shell + package: + name: mongodb-org-shell diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/prepare.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/prepare.yml new file mode 100644 index 00000000..0f186973 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/prepare.yml @@ -0,0 +1,40 @@ +--- +- name: Prepare + hosts: all + become: yes + vars: + avahi_packages_redhat: + - "avahi" + - "nss-mdns" + avahi_packages_debian: + - "avahi-daemon" + - "avahi-discover" + - "libnss-mdns" + tasks: + + - name: Ensure epel is available + yum: + name: epel-release + state: present + when: ansible_os_family == "RedHat" + + - name: Install avahi packages + package: + name: "{{ avahi_packages_redhat }}" + state: present + when: ansible_os_family == "RedHat" + + - name: Install avahi packages + package: + name: "{{ avahi_packages_debian }}" + state: present + when: ansible_os_family == "Debian" + + # debian-stretch seems to require a reboot for avahi-daemon to run + - name: Reboot host + reboot: + + - name: Ensure avahi-daemon is started + service: + name: avahi-daemon + state: started diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/tests/test_default.py new file mode 100644 index 00000000..933015a0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/molecule/virtualbox/tests/test_default.py @@ -0,0 +1,56 @@ +import os +import yaml + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ["MOLECULE_INVENTORY_FILE"] +).get_hosts("all") + + +def include_vars(host): + ansible = host.ansible("include_vars", + 'file="../../defaults/main.yml"', + False, + False) + return ansible + + +def test_mongod_cnf_file(host): + f = host.file("/etc/mongod.conf") + + assert f.exists + assert yaml.safe_load(f.content)["security"]["authorization"] == "enabled" + + +def test_mongod_service(host): + mongod_service = include_vars(host)["ansible_facts"].get("mongod_service", "mongod") + s = host.service(mongod_service) + + assert s.is_running + assert s.is_enabled + + +def test_mongod_port(host): + port = include_vars(host)["ansible_facts"].get("mongod_port", 27017) + s = host.socket("tcp://0.0.0.0:{0}".format(port)) + assert s.is_listening + + +def test_mongo_shell_connectivity(host): + """ + Tests that we can connect to mongos via the shell annd run a cmd + """ + facts = include_vars(host)["ansible_facts"] + port = facts.get("mongod_port", 27017) + user = facts.get("mongod_admin_user", "admin") + pwd = facts.get("mongod_default_admin_pwd", "admin") + + cmd = host.run( + "mongo admin --username {user} --password {pwd} --port {port} --eval 'db.runCommand({{listDatabases: 1}})'".format( + user=user, pwd=pwd, port=port + ) + ) + + assert cmd.rc == 0 + assert "admin" in cmd.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/tasks/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/tasks/main.yml new file mode 100644 index 00000000..4ead377c --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/tasks/main.yml @@ -0,0 +1,94 @@ +--- +# tasks file for mongodb_auth +- name: Include OS-specific vars + include_vars: + file: "{{ lookup('first_found', params) }}" + vars: + params: + paths: + - "vars" + files: + - "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version }}.yml" + - "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml" + - "{{ ansible_facts.distribution }}.yml" + - "{{ ansible_facts.os_family }}.yml" + - default.yml + +- name: Ensure mongod and pyyaml packages are installed + package: + name: + - "{{ mongod_package }}" + # pyyaml is used to validate yaml files on change + - "{{ pyyaml_package }}" + register: _pkg + until: _pkg is succeeded + retries: 5 + +- name: Warn about default credentials + when: mongodb_admin_pwd == mongodb_default_admin_pwd + debug: + msg: "[WARNING] Using default admin credentials for mongodb admin account! Please change them!" + +- name: Add mongo admin user with localhost exception + community.mongodb.mongodb_user: + state: present + + # on_create triggers additional queries that are not compatible with localhost exception + update_password: always + + name: "{{ mongodb_admin_user }}" + password: "{{ mongodb_admin_pwd }}" + database: admin + roles: "{{ mongodb_admin_roles }}" + + login_host: localhost + login_port: "{{ mongod_port | string }}" # silence implicit int->str conversion warning + create_for_localhost_exception: /root/mongodb_admin.success + module_defaults: + community.mongodb.mongodb_user: {} + +- name: Enable security section in mongod.conf + lineinfile: + path: /etc/mongod.conf + regexp: |- + ^[#'"\s]*security['"]?\s*: + line: 'security:' + validate: | + {{ mongodb_python }} -c ' + import yaml, io + if "security" not in yaml.safe_load(io.open("%s")): + exit(1) + ' + +- name: Enable authentication in mongod.conf + lineinfile: + path: /etc/mongod.conf + insertafter: '^security:' + # two space indentation (the default) assumed + line: ' authorization: {{ authorization }}' + regexp: |- + ^[#'"\s]+authorization['"]?\s*: + validate: | + {{ mongodb_python }} -c ' + import yaml, io + if yaml.safe_load(io.open("%s"))["security"]["authorization"] != "{{ authorization }}": + exit(1) + ' + register: _enable_mongo_auth + +# This is a task instead of a handler so we can add users right away +- name: Restart mongodb to enable auth before adding additional users + # This allows us to safely assume auth is already enabled when adding more users + when: _enable_mongo_auth is changed + service: + name: mongod + state: restarted + +- name: Add additional mongo users + include_tasks: mongodb_auth_user.yml + loop: "{{ mongodb_users }}" + loop_control: + loop_var: _mongodb_user + # using loop_control: label does not obscure the password in output for verbosity > 1 + # So, loop over an include where the task name will include the username + db, but the loop var won't print out. + no_log: yes diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/tasks/mongodb_auth_user.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/tasks/mongodb_auth_user.yml new file mode 100644 index 00000000..285a0dc8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/tasks/mongodb_auth_user.yml @@ -0,0 +1,29 @@ +--- +- name: "Add mongo auth user - {{ _mongodb_user.user }} on {{ _mongodb_user.db }}" + community.mongodb.mongodb_user: + state: present + + # NOTE: on_create is idempotent, always is not. + # With `update_password: on_create`, mongodb_user checks to see if the user + # (a) exists on the db, and (b) has the same roles, + # and then it only adds the user if it's not there or the roles have changed. + # With `update_password: always`, mongodb_user cannot tell if the password + # needs to be changed without attempting a login with those credentials. + # But mongodb_user does not currently implement such a check. + # A comment in mongodb_user points to https://jira.mongodb.org/browse/SERVER-22848 + update_password: "{{ mongodb_force_update_password|ternary('always', 'on_create') }}" + + name: "{{ _mongodb_user.user }}" + password: "{{ _mongodb_user.pwd }}" + database: "{{ _mongodb_user.db }}" + roles: "{{ _mongodb_user.roles|default('readWrite') }}" + + login_host: localhost + login_port: "{{ mongod_port | string }}" # silence implicit int->str conversion warning + login_user: "{{ mongodb_admin_user }}" + login_password: "{{ mongodb_admin_pwd }}" + login_database: admin + # to provide additional auth details (eg for ssl* or auth_mechanism, set module_defaults in playbook) + # module_defaults: + # community.mongodb.mongodb_user: + # auth_mechanism: ... diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/RedHat-7.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/RedHat-7.yml new file mode 100644 index 00000000..190d2622 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/RedHat-7.yml @@ -0,0 +1,2 @@ +--- +pyyaml_package: PyYAML diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/RedHat-8.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/RedHat-8.yml new file mode 100644 index 00000000..ba3964da --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/RedHat-8.yml @@ -0,0 +1,2 @@ +--- +pyyaml_package: python3-pyyaml diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/default.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/default.yml new file mode 100644 index 00000000..af98d755 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/default.yml @@ -0,0 +1,2 @@ +--- +pyyaml_package: "python{% if ansible_facts.python.version.major == 3 %}3{% endif %}-yaml" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/main.yml new file mode 100644 index 00000000..458cdc63 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_auth/vars/main.yml @@ -0,0 +1,2 @@ +--- +mongodb_python: "{{ ansible_python_interpreter | default( (ansible_python|default({})).get('executable', 'python') ) }}" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/.yamllint b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/.yamllint new file mode 100644 index 00000000..88276760 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/README.md b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/README.md new file mode 100644 index 00000000..4c177d38 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/README.md @@ -0,0 +1,50 @@ +mongodb_config +============== + +A simple role to aid in setting up a CSRS Config Server Replicaset for a MongoDB sharded cluster. + +Role Variables +-------------- + +* `config_port`: The port used by the mongos process. Default 27019. +* `mongod_service`: The name of the mongod service. Default mongod. +* `mongodb_user`: The Linux OS user for MongoDB. Default mongod. +* `mongodb_group`: The Linux OS user group for MongoDB. Default mongod. +* `pid_file`: The pid file for mongos. Default /run/mongodb/mongos.pid. +* `bind_ip`: The IP address mongos will bind to. Default 0.0.0.0. +* `config_repl_set_name`: The replicaset name for the config servers. Default cfg. +* `authorization`: Enable authorization. Default enabled. +* `openssl_keyfile_content`: The kexfile content that MongoDB uses to authenticate within a replicaset. Generate with cmd: openssl rand -base64 756. +* `mongod_package`: The name of the mongod installation package. Default mongodb-org-server. +replicaset: When enabled add a replication section to the configuration. Default true. +* `mongod_config_template`: If defined allows to override path to mongod config template with custom configuration. Default "mongod.conf.j2" +* `skip_restart`: If set to `true` will skip restarting mongod service when config file or the keyfile content changes. Default `true`. + +Dependencies +------------ + +mongodb_repository + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables +passed in as parameters) is always nice for users too: + + +```yaml + - hosts: servers + roles: + - { role: mongodb_repository } + - { role: mongodb_config, config_repl_set_name: "mycustomrs" } +``` + +License +------- + +BSD + +Author Information +------------------ + +Rhys Campbell (https://github.com/rhysmeister) diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/defaults/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/defaults/main.yml new file mode 100644 index 00000000..5bf772a2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/defaults/main.yml @@ -0,0 +1,28 @@ +--- +# defaults file for mongodb_config +pid_file: /var/run/mongodb/mongod.pid +bind_ip: 0.0.0.0 +# config_port is in vars to facilitate molecule tests +config_repl_set_name: cfg +authorization: enabled +openssl_keyfile_content: | + Z2CeA9BMcoY5AUWoegjv/XWL2MA1SQcL4HvmRjYaTjSp/xosJy+LL2X3OQb1xVWC + rO2e6Tu6A3R4muunitI6Vr0IKeU5UbTpR0N4hSU6HDrV9z2PIEWlkQqKh01ZRLEY + V3hR73acj0jA8eWIWeiV039d18jvMb8X2h8409lfcD6PPJJGjyaC8S4LY/TrsK2z + tx+l/vqOOAMhGB5mEMjx1LXUMsRG9ot6vFu9I5LPd1A4q9xw9jddYK5C6YTLccun + ZyCDsv7ImkCprV0+0vhTyxIEnfaNtvOlWypuvmRr/DEyd2NPowd1n6C+rgk8gs1t + SGLCZP93gXza0rIoQzHtuf5pOJK9qyKjuNtuuLa/KFsida8a69JXn7fmS0IIja0m + Ir0OrQ2Ta3n4VbQwQo97BWODWmkgzz0mUd6VmMps5zLsCW1vVqYFQHuAAbLekW0q + 8JRm8OQ6n2hp8j4zYd3/Qw7vqsVj8sHicNB0bCW29b64H4f2J/AcUA/cm0xSUQyb + +myeCB4vWvydh5AfFVnw7sXvzU6egaYRomdmrl59QrTDneJu13hwzIchsFparoWJ + XjpldopGeDaJLU18ga7MSL02ozB+EoJ14DJxQU7E5MQk7fDMPeitXKZ8ymxb7LeA + k0Rtc/JQM8aDLoRklhLZRRARBrv1RLo8DM8CB2q4s+FwVU4QJl7mFyiwk3eTN6sN + PTgFRo3/dHsEA2OwGG+hnGFGnoYf2mkECR5jqai83CXgva9v2rPNjDTJYHpmd3I0 + fNijueXZZdzUA58y8mcoSGVYdRhr0g8jaWQ12PZEgX5Nnlekh5GHG0j8HT4qj/0Y + D3xVuE3WvrhldY5EOsaTt2ZXZx5REmJDIW1KcnvQKiVDJ2QzP5xdXYA0hh3TdTVE + sb4UreMw/WyBpANiICMlJRBgSd0f0VGMlYzLX2BL14YpNnLhmoQqKzfBN6v2XAEG + mJfrCUVuP1nBEklk23lYkNi/ohe+aodNjdN+2DHp42sGZHYP +mongod_package: "mongodb-org-server" +replicaset: true +mongod_config_template: "configsrv.conf.j2" +skip_restart: true diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/handlers/handlers.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/handlers/handlers.yml new file mode 100644 index 00000000..8b654cea --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/handlers/handlers.yml @@ -0,0 +1,10 @@ +--- + +- name: Restart mongod service + service: + name: "{{ mongod_service }}" + state: restarted + +- name: Wait for port to become active + wait_for: + port: "{{ config_port }}" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/handlers/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/handlers/main.yml new file mode 100644 index 00000000..d1a7a569 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/handlers/main.yml @@ -0,0 +1,5 @@ +--- + +- name: Restart mongod service + import_tasks: handlers.yml + when: not skip_restart diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/meta/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/meta/main.yml new file mode 100644 index 00000000..1d46e31c --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/meta/main.yml @@ -0,0 +1,58 @@ +--- +galaxy_info: + author: Rhys Campbell + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + + min_ansible_version: 1.2 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # Optionally specify the branch Galaxy will use when accessing the GitHub + # repo for this role. During role install, if no tags are available, + # Galaxy will use this branch. During import Galaxy will access files on + # this branch. If Travis integration is configured, only notifications for this + # branch will be accepted. Otherwise, in all cases, the repo's default branch + # (usually master) will be used. + # github_branch: + + # + # platforms is a list of platforms, and each platform has a name and a list of versions. + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] +# List your role dependencies here, one per line. Be sure to remove the '[]' above, +# if you add dependencies to this list. diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/Dockerfile.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/Dockerfile.j2 new file mode 100644 index 00000000..935dd3d7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/Dockerfile.j2 @@ -0,0 +1,39 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +{% if item.env is defined %} +{% for var, value in item.env.items() %} +{% if value %} +ENV {{ var }} {{ value }} +{% endif %} +{% endfor %} +{% endif %} +# Add systemd-sysv package for Debian to get systemd working (and procps for sysctl) and netbase for firewalld +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 systemd-sysv procps netbase && apt-get clean; \ + elif [ $(command -v dnf) ] && grep -q 'platform:el8' /etc/os-release ; then dnf makecache && dnf update -y && dnf --assumeyes install python3 sudo python3-devel bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && rm -Rf /usr/share/doc && rm -Rf /usr/share/man && dnf clean all && cp /bin/true /sbin/agetty; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi + +{% if item.image == 'centos:8' %} +# Stuff for systemd https://hub.docker.com/_/centos +RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \ + systemd-tmpfiles-setup.service ] || rm -f $i; done); \ + rm -f /lib/systemd/system/multi-user.target.wants/*;\ + rm -f /etc/systemd/system/*.wants/*;\ + rm -f /lib/systemd/system/local-fs.target.wants/*; \ + rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ + rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ + rm -f /lib/systemd/system/basic.target.wants/*;\ + rm -f /lib/systemd/system/anaconda.target.wants/*; + +VOLUME [ "/sys/fs/cgroup" ] +CMD ["/sbin/init"] +{% endif %} diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/molecule.yml new file mode 100644 index 00000000..528c2be0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/molecule.yml @@ -0,0 +1,74 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos_7 + hostname: centos_7 + image: centos:7 + command: /sbin/init + privileged: True + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + networks: + - name: "mymongo" + network_mode: "mymongo" + - name: centos_8 + hostname: centos_8 + image: centos:8 + command: /sbin/init + privileged: True + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + networks: + - name: "mymongo" + network_mode: "mymongo" + - name: ubuntu_16 + hostname: ubuntu_16 + image: ubuntu:16.04 + command: /sbin/init + privileged: True + networks: + - name: "mymongo" + network_mode: "mymongo" + - name: ubuntu_18 + hostname: ubuntu_18 + image: ubuntu:18.04 + command: /sbin/init + privileged: True + networks: + - name: "mymongo" + network_mode: "mymongo" + - name: debian_buster + hostname: debian_buster + image: debian:buster + command: /sbin/init + privileged: True + networks: + - name: "mymongo" + network_mode: "mymongo" + - name: debian_stretch + hostname: debian_stretch + image: debian:stretch + command: /sbin/init + privileged: True + networks: + - name: "mymongo" + network_mode: "mymongo" +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/playbook.yml new file mode 100644 index 00000000..ba4749b7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/playbook.yml @@ -0,0 +1,38 @@ +--- +- name: Converge + hosts: all + roles: + - role: mongodb_repository + tags: molecule-idempotence-notest + - role: mongodb_config + + tasks: + + - name: Install python stuff + package: + name: ["python-setuptools", "python-pip"] + when: ansible_hostname == "ubuntu_16" + + - name: Install pymongo + pip: + name: pymongo + when: ansible_hostname == "ubuntu_16" + + - name: Install MongoDB Shell + package: + name: mongodb-org-shell + + - name: Init config server replicaset + community.mongodb.mongodb_replicaset: + login_host: localhost + login_port: 27019 + replica_set: cfg + validate: no + members: + - centos_7:27019 + - centos_8:27019 + - ubuntu_16:27019 + - ubuntu_18:27019 + #- debian_stretch:27019 # need odd number, so drop stretch + - debian_buster:27019 + when: ansible_hostname == "ubuntu_16" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/prepare.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/prepare.yml new file mode 100644 index 00000000..abdf26a2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/prepare.yml @@ -0,0 +1,10 @@ +--- +- name: Prepare + hosts: all + + tasks: + + - name: Create is_docker.txt file + file: + path: is_docker.txt + state: touch diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/tests/test_default.py new file mode 100644 index 00000000..25db94ea --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/default/tests/test_default.py @@ -0,0 +1,67 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def include_vars(host): + if host.system_info.distribution == "redhat" \ + or host.system_info.distribution == "centos": + ansible = host.ansible('include_vars', + 'file="../../vars/RedHat.yml"', + False, + False) + if host.system_info.distribution == "debian" \ + or host.system_info.distribution == "ubuntu": + ansible = host.ansible('include_vars', + 'file="../../vars/Debian.yml"', + False, + False) + return ansible + + +def test_mongod_cnf_file(host): + mongodb_user = include_vars(host)['ansible_facts']['mongodb_user'] + mongodb_group = include_vars(host)['ansible_facts']['mongodb_group'] + f = host.file('/etc/mongod.conf') + + assert f.exists + assert f.user == mongodb_user + assert f.group == mongodb_group + + +def test_mongod_service(host): + mongod_service = include_vars(host)['ansible_facts']['mongod_service'] + s = host.service(mongod_service) + + assert s.is_running + assert s.is_enabled + + +def test_mongod_port(host): + port = include_vars(host)['ansible_facts']['config_port'] + s = host.socket("tcp://0.0.0.0:{0}".format(port)) + + assert s.is_listening + + +def test_mongod_replicaset(host): + ''' + Ensure that the MongoDB config replicaset has been created successfully + ''' + port = include_vars(host)['ansible_facts']['config_port'] + cmd = "mongo --port {0} --eval 'rs.status()'".format(port) + # We only want to run this once + if host.ansible.get_variables()['inventory_hostname'] == "ubuntu_16": + r = host.run(cmd) + + assert "cfg" in r.stdout + assert "centos_7:{0}".format(port) in r.stdout + assert "centos_8:{0}".format(port) in r.stdout + assert "ubuntu_16:{0}".format(port) in r.stdout + assert "ubuntu_18:{0}".format(port) in r.stdout + assert "debian_buster:{0}".format(port) in r.stdout + # assert "debian_stretch:{0}".format(port) in r.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/molecule.yml new file mode 100644 index 00000000..14d29680 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/molecule.yml @@ -0,0 +1,54 @@ +--- +dependency: + name: galaxy +driver: + name: vagrant + provider: + name: virtualbox +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos-7 + box: centos/7 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-16 + box: ubuntu/xenial64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-18 + box: ubuntu/bionic64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-buster + box: debian/buster64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-stretch + box: debian/contrib-stretch64 # Standard debian/stretch64 had issues: Unable to locate package linux-headers-4.9.0-9-amd64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/playbook.yml new file mode 100644 index 00000000..92cefb0c --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/playbook.yml @@ -0,0 +1,38 @@ +--- +- name: Converge + hosts: all + become: yes + + roles: + - role: mongodb_repository + tags: molecule-idempotence-notest + - role: mongodb_config + + tasks: + + - name: Install python stuff + package: + name: ["python-setuptools", "python-pip"] + when: ansible_hostname == "ubuntu-16" + + - name: Install pymongo + pip: + name: pymongo + when: ansible_hostname == "ubuntu-16" + + - name: Install MongoDB Shell + package: + name: mongodb-org-shell + + - name: Init config server replicaset + community.mongodb.mongodb_replicaset: + login_host: localhost + login_port: 27019 + replica_set: cfg + members: + - ubuntu-16.local:27019 + - ubuntu-18.local:27019 + - debian-stretch.local:27019 + - debian-buster.local:27019 + - centos-7.local:27019 + when: ansible_hostname == "ubuntu-16" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/prepare.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/prepare.yml new file mode 100644 index 00000000..acf089f2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/prepare.yml @@ -0,0 +1,39 @@ +--- +- name: Prepare + hosts: all + become: yes + vars: + avahi_packages_redhat: + - "avahi" + - "nss-mdns" + avahi_packages_debian: + - "avahi-daemon" + - "avahi-discover" + - "libnss-mdns" + tasks: + + - name: Ensure epel is available + yum: + name: epel-release + state: present + when: ansible_os_family == "RedHat" + + - name: Install avahi packages + package: + name: "{{ avahi_packages_redhat }}" + state: present + when: ansible_os_family == "RedHat" + + - name: Install avahi packages + package: + name: "{{ avahi_packages_debian }}" + state: present + when: ansible_os_family == "Debian" + + - name: Reboot host for avahi-daemon + reboot: + + - name: Ensure avahi-daemon is started + service: + name: avahi-daemon + state: started diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/tests/test_default.py new file mode 100644 index 00000000..944004d2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/molecule/virtualbox/tests/test_default.py @@ -0,0 +1,66 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def include_vars(host): + if host.system_info.distribution == "redhat" \ + or host.system_info.distribution == "centos": + ansible = host.ansible('include_vars', + 'file="../../vars/RedHat.yml"', + False, + False) + if host.system_info.distribution == "debian" \ + or host.system_info.distribution == "ubuntu": + ansible = host.ansible('include_vars', + 'file="../../vars/Debian.yml"', + False, + False) + return ansible + + +def test_mongod_cnf_file(host): + mongodb_user = include_vars(host)['ansible_facts']['mongodb_user'] + mongodb_group = include_vars(host)['ansible_facts']['mongodb_group'] + f = host.file('/etc/mongod.conf') + + assert f.exists + assert f.user == mongodb_user + assert f.group == mongodb_group + + +def test_mongod_service(host): + mongod_service = include_vars(host)['ansible_facts']['mongod_service'] + s = host.service(mongod_service) + + assert s.is_running + assert s.is_enabled + + +def test_mongod_port(host): + port = include_vars(host)['ansible_facts']['config_port'] + s = host.socket("tcp://0.0.0.0:{0}".format(port)) + + assert s.is_listening + + +def test_mongod_cfg_replicaset(host): + ''' + Ensure that the MongoDB config replicaset has been created successfully + ''' + port = include_vars(host)['ansible_facts']['config_port'] + cmd = "mongo --port {0} --eval 'rs.status()'".format(port) + # We only want to run this once + if host.ansible.get_variables()['inventory_hostname'] == "ubuntu_16": + r = host.run(cmd) + + assert "cfg" in r.stdout + assert "ubuntu-16.local:{0}".format(port) in r.stdout + assert "ubuntu-18.local:{0}".format(port) in r.stdout + assert "debian-buster.local:{0}".format(port) in r.stdout + assert "debian-stretch.local:{0}".format(port) in r.stdout + assert "centos-7.local:{0}".format(port) in r.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/tasks/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/tasks/main.yml new file mode 100644 index 00000000..03d72f86 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/tasks/main.yml @@ -0,0 +1,74 @@ +--- +# tasks file for mongodb_config +- name: Include OS-specific vars + include_vars: + file: "{{ lookup('first_found', params) }}" + vars: + params: + paths: + - "vars" + files: + - "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version }}.yml" + - "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml" + - "{{ ansible_facts.distribution }}.yml" + - "{{ ansible_facts.os_family }}.yml" + - default.yml + +- name: Check if we are in docker + stat: + path: is_docker.txt + register: is_docker + +- name: Ensure mongod package is installed + package: + name: "{{ mongod_package }}" + register: _pkg + until: _pkg is succeeded + retries: 5 + +- name: Ensure db_path dir exists + file: + path: "{{ db_path }}" + state: directory + owner: "{{ mongodb_user }}" + group: "{{ mongodb_group }}" + +- name: Copy config file + template: + src: "{{ mongod_config_template }}" + dest: /etc/mongod.conf + owner: "{{ mongodb_user }}" + group: "{{ mongodb_group }}" + notify: + - Restart mongod service + +- name: Copy keyfile to host + copy: + content: | + {{ openssl_keyfile_content }} + dest: /etc/keyfile + owner: "{{ mongodb_user }}" + group: "{{ mongodb_group }}" + mode: 0400 + notify: + - Restart mongod service + +- name: Check for github override + set_fact: + x_github_override: "{{ lookup('env', 'X_GITHUB_OVERRIDE') | default('0', True) }}" + +- name: Start mongod service + service: + name: "{{ mongod_service }}" + state: started + enabled: yes + when: not (ansible_facts.os_family == 'RedHat' + and ansible_facts.distribution_major_version|int == 8 + and is_docker.stat.exists) + +- name: Include tasks for RedHat 8 docker issue + import_tasks: redhat_docker.yml + when: + - ansible_facts.os_family == 'RedHat' + - ansible_facts.distribution_major_version|int == 8 + - is_docker.stat.exists diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/tasks/redhat_docker.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/tasks/redhat_docker.yml new file mode 100644 index 00000000..d08c66a1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/tasks/redhat_docker.yml @@ -0,0 +1,18 @@ +--- +- name: Comment out PIDFile in systemd file + lineinfile: + path: /etc/systemd/system/multi-user.target.wants/mongod.service + regexp: '^PIDFile.*' + state: absent + register: systemd + +- name: Reload systemd + systemd: + daemon_reload: yes + when: systemd is changed + +- name: Start mongod service + service: + name: "{{ mongod_service }}" + state: started + enabled: yes diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/templates/configsrv.conf.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/templates/configsrv.conf.j2 new file mode 100644 index 00000000..8b6c7b35 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/templates/configsrv.conf.j2 @@ -0,0 +1,46 @@ +# mongod.conf + +# for documentation of all options, see: +# http://docs.mongodb.org/manual/reference/configuration-options/ + +# where to write logging data. +systemLog: + destination: file + logAppend: true + path: /var/log/mongodb/mongod.log + +# Where and how to store data. +storage: + dbPath: {{ db_path }} + journal: + enabled: true + engine: "wiredTiger" + +# how the process runs +processManagement: +{% if ansible_facts.os_family == "RedHat" %} # Breaks Ubuntu / Debian + fork: true + pidFilePath: /var/run/mongodb/mongod.pid +{% endif %} + timeZoneInfo: /usr/share/zoneinfo + +# network interfaces +net: + port: {{ config_port }} + bindIp: {{ bind_ip }} + +{% if authorization == "enabled" %} +security: + authorization: {{ authorization }} + keyFile: /etc/keyfile +{% endif %} + +#operationProfiling: + +{% if replicaset %} +replication: + replSetName: {{ config_repl_set_name }} +{% endif %} + +sharding: + clusterRole: configsvr diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/Debian.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/Debian.yml new file mode 100644 index 00000000..a71c483b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/Debian.yml @@ -0,0 +1,6 @@ +--- +config_port: 27019 +mongodb_user: "mongodb" +mongodb_group: "mongodb" +mongod_service: "mongod" +db_path: /var/lib/mongodb diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/RedHat.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/RedHat.yml new file mode 100644 index 00000000..a0426a95 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/RedHat.yml @@ -0,0 +1,6 @@ +--- +config_port: 27019 +mongodb_user: "mongod" +mongodb_group: "mongod" +mongod_service: "mongod" +db_path: /var/lib/mongo diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/default.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/default.yml new file mode 100644 index 00000000..a0426a95 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/default.yml @@ -0,0 +1,6 @@ +--- +config_port: 27019 +mongodb_user: "mongod" +mongodb_group: "mongod" +mongod_service: "mongod" +db_path: /var/lib/mongo diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/main.yml new file mode 100644 index 00000000..28ce3d22 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_config/vars/main.yml @@ -0,0 +1,2 @@ +--- +is_redhat_8_in_docker: "{{ ansible_facts.os_family == 'RedHat' and ansible_facts.distribution_major_version|int == 8 and ansible_facts.virtualization_type == 'docker' }}" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/.yamllint b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/.yamllint new file mode 100644 index 00000000..88276760 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/README.md b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/README.md new file mode 100644 index 00000000..a3d149f5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/README.md @@ -0,0 +1,33 @@ +mongodb_install +=============== + +Install MongoDB packages on Debian and RedHat based platforms. Installs the mongodb-org meta-package which then installs the following packages: mongodb-org-server, mongodb-org-shell, mongodb-org-mongos, mongodb-org-tools. + +Role Variables +-------------- + +specific_mongodb_version - Install a specific version of mongodb i.e. 4.4.1. The specified version must be available in the system repositories. By default this variable is undefined. + +Dependencies +------------ +mongodb_repository + +Example Playbook +---------------- + +```yaml + - hosts: servers + roles: + - mongodb_repository + - mongodb_install +``` + +License +------- + +BSD + +Author Information +------------------ + +Rhys Campbell (https://github.com/rhysmeister) diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/meta/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/meta/main.yml new file mode 100644 index 00000000..ba43fdd2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/meta/main.yml @@ -0,0 +1,58 @@ +--- +galaxy_info: + author: your name + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + + min_ansible_version: 1.2 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # Optionally specify the branch Galaxy will use when accessing the GitHub + # repo for this role. During role install, if no tags are available, + # Galaxy will use this branch. During import Galaxy will access files on + # this branch. If Travis integration is configured, only notifications for this + # branch will be accepted. Otherwise, in all cases, the repo's default branch + # (usually master) will be used. + # github_branch: + + # + # platforms is a list of platforms, and each platform has a name and a list of versions. + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] +# List your role dependencies here, one per line. Be sure to remove the '[]' above, +# if you add dependencies to this list. diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/Dockerfile.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/Dockerfile.j2 new file mode 100644 index 00000000..935dd3d7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/Dockerfile.j2 @@ -0,0 +1,39 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +{% if item.env is defined %} +{% for var, value in item.env.items() %} +{% if value %} +ENV {{ var }} {{ value }} +{% endif %} +{% endfor %} +{% endif %} +# Add systemd-sysv package for Debian to get systemd working (and procps for sysctl) and netbase for firewalld +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 systemd-sysv procps netbase && apt-get clean; \ + elif [ $(command -v dnf) ] && grep -q 'platform:el8' /etc/os-release ; then dnf makecache && dnf update -y && dnf --assumeyes install python3 sudo python3-devel bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && rm -Rf /usr/share/doc && rm -Rf /usr/share/man && dnf clean all && cp /bin/true /sbin/agetty; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi + +{% if item.image == 'centos:8' %} +# Stuff for systemd https://hub.docker.com/_/centos +RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \ + systemd-tmpfiles-setup.service ] || rm -f $i; done); \ + rm -f /lib/systemd/system/multi-user.target.wants/*;\ + rm -f /etc/systemd/system/*.wants/*;\ + rm -f /lib/systemd/system/local-fs.target.wants/*; \ + rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ + rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ + rm -f /lib/systemd/system/basic.target.wants/*;\ + rm -f /lib/systemd/system/anaconda.target.wants/*; + +VOLUME [ "/sys/fs/cgroup" ] +CMD ["/sbin/init"] +{% endif %} diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/molecule.yml new file mode 100644 index 00000000..65d86499 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/molecule.yml @@ -0,0 +1,42 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos_7 + image: centos:7 + - name: centos_8 + image: centos:8 + - name: ubuntu_16 + image: ubuntu:16.04 + privileged: yes + command: "/sbin/init" + - name: ubuntu_18 + image: ubuntu:18.04 + privileged: yes + command: "/sbin/init" + - name: debian_buster + image: debian:buster + privileged: yes + command: "/sbin/init" + - name: debian_stretch + image: debian:stretch + privileged: yes + command: "/sbin/init" +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/playbook.yml new file mode 100644 index 00000000..cfcf732b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/playbook.yml @@ -0,0 +1,7 @@ +--- +- name: Converge + hosts: all + roles: + - role: mongodb_repository + tags: molecule-idempotence-notest + - role: mongodb_install diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/tests/test_default.py new file mode 100644 index 00000000..b8a23ad4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/default/tests/test_default.py @@ -0,0 +1,31 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def test_mongod_available(host): + cmd = host.run("mongod --version") + assert cmd.rc == 0 + assert "db version" in cmd.stdout + + +def test_mongo_available(host): + cmd = host.run("mongo --version") + assert cmd.rc == 0 + assert "MongoDB shell version" in cmd.stdout + + +def test_mongos_available(host): + cmd = host.run("mongos --version") + assert cmd.rc == 0 + assert "mongos version" in cmd.stdout + + +def test_mongodump_available(host): + cmd = host.run("mongodump --version") + assert cmd.rc == 0 + assert "mongodump version" in cmd.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/Dockerfile.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/Dockerfile.j2 new file mode 100644 index 00000000..0de39e63 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/Dockerfile.j2 @@ -0,0 +1,22 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +{% if item.env is defined %} +{% for var, value in item.env.items() %} +{% if value %} +ENV {{ var }} {{ value }} +{% endif %} +{% endfor %} +{% endif %} + +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 && apt-get clean; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/molecule.yml new file mode 100644 index 00000000..6fe3b428 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/molecule.yml @@ -0,0 +1,32 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos_7 + image: centos:7 + - name: ubuntu_16 + image: ubuntu:16.04 + - name: ubuntu_18 + image: ubuntu:18.04 + - name: debian_buster + image: debian:buster + - name: debian_stretch + image: debian:stretch +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/playbook.yml new file mode 100644 index 00000000..f3386712 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/playbook.yml @@ -0,0 +1,8 @@ +--- +- name: Converge + hosts: all + vars: + specific_mongodb_version: "4.2.2" + roles: + - role: mongodb_repository + - role: mongodb_install diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/tests/test_default.py new file mode 100644 index 00000000..1b369fbf --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/specific_mongodb_version/tests/test_default.py @@ -0,0 +1,37 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def test_mongod_available(host): + cmd = host.run("mongod --version") + assert cmd.rc == 0 + assert "db version" in cmd.stdout + + +def test_mongo_available(host): + cmd = host.run("mongo --version") + assert cmd.rc == 0 + assert "MongoDB shell version" in cmd.stdout + + +def test_mongos_available(host): + cmd = host.run("mongos --version") + assert cmd.rc == 0 + assert "mongos version" in cmd.stdout + + +def test_mongodump_available(host): + cmd = host.run("mongodump --version") + assert cmd.rc == 0 + assert "mongodump version" in cmd.stdout + + +def test_specific_mongodb_version(host): + cmd = host.run("mongod --version") + assert cmd.rc == 0 + assert "4.2.2" in cmd.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/molecule.yml new file mode 100644 index 00000000..14d29680 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/molecule.yml @@ -0,0 +1,54 @@ +--- +dependency: + name: galaxy +driver: + name: vagrant + provider: + name: virtualbox +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos-7 + box: centos/7 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-16 + box: ubuntu/xenial64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-18 + box: ubuntu/bionic64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-buster + box: debian/buster64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-stretch + box: debian/contrib-stretch64 # Standard debian/stretch64 had issues: Unable to locate package linux-headers-4.9.0-9-amd64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/playbook.yml new file mode 100644 index 00000000..1b64ffc5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/playbook.yml @@ -0,0 +1,8 @@ +--- +- name: Converge + hosts: all + become: yes + roles: + - role: mongodb_repository + tags: molecule-idempotence-notest + - role: mongodb_install diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/prepare.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/prepare.yml new file mode 100644 index 00000000..98711356 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/prepare.yml @@ -0,0 +1,43 @@ +--- +- name: Prepare + hosts: all + become: yes + vars: + avahi_packages_redhat: + - "avahi" + - "nss-mdns" + avahi_packages_debian: + - "avahi-daemon" + - "avahi-discover" + - "libnss-mdns" + tasks: + + - name: Ensure epel is available + yum: + name: epel-release + state: present + when: ansible_os_family == "RedHat" + + - name: Install avahi packages + package: + name: "{{ avahi_packages_redhat }}" + state: present + when: ansible_os_family == "RedHat" + + - name: Install avahi packages + package: + name: "{{ avahi_packages_debian }}" + state: present + when: ansible_os_family == "Debian" + + # debian-stretch seems to require a reboot for avahi-daemon to run + - name: Reboot host + reboot: + + - name: Ensure services are started + service: + name: "{{ item }}" + state: started + with_items: + #- dbus + - avahi-daemon diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/tests/test_default.py new file mode 100644 index 00000000..b8a23ad4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/molecule/virtualbox/tests/test_default.py @@ -0,0 +1,31 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def test_mongod_available(host): + cmd = host.run("mongod --version") + assert cmd.rc == 0 + assert "db version" in cmd.stdout + + +def test_mongo_available(host): + cmd = host.run("mongo --version") + assert cmd.rc == 0 + assert "MongoDB shell version" in cmd.stdout + + +def test_mongos_available(host): + cmd = host.run("mongos --version") + assert cmd.rc == 0 + assert "mongos version" in cmd.stdout + + +def test_mongodump_available(host): + cmd = host.run("mongodump --version") + assert cmd.rc == 0 + assert "mongodump version" in cmd.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/tasks/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/tasks/main.yml new file mode 100644 index 00000000..59d5cdc6 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_install/tasks/main.yml @@ -0,0 +1,41 @@ +--- +# tasks file for mongodb_install +- name: Install MongoDB Packages + package: + name: mongodb-org + state: present + when: specific_mongodb_version is not defined + register: _pkg + until: _pkg is succeeded + retries: 5 + +- name: Install MongoDB Packages (Specific version) + package: + name: "mongodb-org-{{ specific_mongodb_version }}" + state: present + when: + - specific_mongodb_version is defined + - ansible_facts.os_family == "RedHat" + register: _pkg + until: _pkg is succeeded + retries: 5 + +# apt silliness: +# In order to upgrade/downgrade to a specific version of mongodb-org, +# we must also specifiy version of mongodb-org deps. +# https://dba.stackexchange.com/questions/197336/how-to-install-specific-mongo-version-from-the-ppa +- name: Install MongoDB Packages (Specific version) + package: + name: + - "mongodb-org={{ specific_mongodb_version }}" + - "mongodb-org-server={{ specific_mongodb_version }}" + - "mongodb-org-shell={{ specific_mongodb_version }}" + - "mongodb-org-mongos={{ specific_mongodb_version }}" + - "mongodb-org-tools={{ specific_mongodb_version }}" + state: present + when: + - specific_mongodb_version is defined + - ansible_facts.os_family == "Debian" + register: _pkg + until: _pkg is succeeded + retries: 5 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/README.md b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/README.md new file mode 100644 index 00000000..7cc37be4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/README.md @@ -0,0 +1,42 @@ +mongodb_linux +============= + +A simple role to configure Linux Operating System settings, for Debian and RedHat systems, as advised in the [MongoDB Production Notes](https://docs.mongodb.com/manual/administration/production-notes/). + +A brief description of what we do in this role: + +* Set swappiness. +* Ensure NTP (or equivalent) service is installed and running. +* Ensure GNU C Library is the latest available. +* Disable NUMA reclaim zone. +* Add script to disable transparent-huge-pages and setup as a service. +* Set pam limits. +* Set various sysctl values. + +Role Variables +-------------- + +swappiness: OS swappiness value. Default "1". +ntp_package: Name of ntp package. Default ntp. +ntp_service: Name of ntp service. Default ntpd. + +* On RedHat 8 and higher systems ntp_package and ntp_service are set to chrony and chronyd respectively. + +Example Playbook +---------------- + +```yaml + - hosts: servers + roles: + - mongodb_linux +``` + +License +------- + +BSD + +Author Information +------------------ + +Rhys Campbell (https://github.com/rhysmeister) diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/defaults/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/defaults/main.yml new file mode 100644 index 00000000..7b2a0a68 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/defaults/main.yml @@ -0,0 +1,10 @@ +--- +# defaults file for mongodb_linux + +# swappiness is 0-100; 60 is the default on many distros. +# 0=disable swapping; 1=swap only to avoid OOM; 60=swap often; 100=swap aggressively +swappiness: "1" + +nproc_and_nofile_limit: 64000 +# TODO: mongo suggests infinity here +memlock_limit: 1024 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/files/thp-disable.service b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/files/thp-disable.service new file mode 100644 index 00000000..3602ed7b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/files/thp-disable.service @@ -0,0 +1,9 @@ +[Unit] +Description=Disable Transparent Huge Pages + +[Service] +Type=oneshot +ExecStart=/usr/bin/env sh -c "echo 'never' > /sys/kernel/mm/transparent_hugepage/enabled && echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag" + +[Install] +WantedBy=multi-user.target diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/meta/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/meta/main.yml new file mode 100644 index 00000000..ba43fdd2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/meta/main.yml @@ -0,0 +1,58 @@ +--- +galaxy_info: + author: your name + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + + min_ansible_version: 1.2 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # Optionally specify the branch Galaxy will use when accessing the GitHub + # repo for this role. During role install, if no tags are available, + # Galaxy will use this branch. During import Galaxy will access files on + # this branch. If Travis integration is configured, only notifications for this + # branch will be accepted. Otherwise, in all cases, the repo's default branch + # (usually master) will be used. + # github_branch: + + # + # platforms is a list of platforms, and each platform has a name and a list of versions. + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] +# List your role dependencies here, one per line. Be sure to remove the '[]' above, +# if you add dependencies to this list. diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/Dockerfile.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/Dockerfile.j2 new file mode 100644 index 00000000..935dd3d7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/Dockerfile.j2 @@ -0,0 +1,39 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +{% if item.env is defined %} +{% for var, value in item.env.items() %} +{% if value %} +ENV {{ var }} {{ value }} +{% endif %} +{% endfor %} +{% endif %} +# Add systemd-sysv package for Debian to get systemd working (and procps for sysctl) and netbase for firewalld +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 systemd-sysv procps netbase && apt-get clean; \ + elif [ $(command -v dnf) ] && grep -q 'platform:el8' /etc/os-release ; then dnf makecache && dnf update -y && dnf --assumeyes install python3 sudo python3-devel bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && rm -Rf /usr/share/doc && rm -Rf /usr/share/man && dnf clean all && cp /bin/true /sbin/agetty; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi + +{% if item.image == 'centos:8' %} +# Stuff for systemd https://hub.docker.com/_/centos +RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \ + systemd-tmpfiles-setup.service ] || rm -f $i; done); \ + rm -f /lib/systemd/system/multi-user.target.wants/*;\ + rm -f /etc/systemd/system/*.wants/*;\ + rm -f /lib/systemd/system/local-fs.target.wants/*; \ + rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ + rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ + rm -f /lib/systemd/system/basic.target.wants/*;\ + rm -f /lib/systemd/system/anaconda.target.wants/*; + +VOLUME [ "/sys/fs/cgroup" ] +CMD ["/sbin/init"] +{% endif %} diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/molecule.yml new file mode 100644 index 00000000..d8b69358 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/molecule.yml @@ -0,0 +1,68 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos_7 + image: centos:7 + command: /sbin/init + privileged: True + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + networks: + - name: "mongodb_linux" + network_mode: "mongodb_linux" + - name: centos_8 + image: centos:8 + command: /sbin/init + privileged: True + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + networks: + - name: "mongodb_linux" + network_mode: "mongodb_linux" + - name: ubuntu_16 + image: ubuntu:16.04 + command: /sbin/init + privileged: True + networks: + - name: "mongodb_linux" + network_mode: "mongodb_linux" + - name: ubuntu_18 + image: ubuntu:18.04 + command: /sbin/init + privileged: True + networks: + - name: "mongodb_linux" + network_mode: "mongodb_linux" + - name: debian_buster + image: debian:buster + command: /sbin/init + privileged: True + networks: + - name: "mongodb_linux" + network_mode: "mongodb_linux" + - name: debian_stretch + image: debian:stretch + command: /sbin/init + privileged: True + networks: + - name: "mongodb_linux" + network_mode: "mongodb_linux" +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/playbook.yml new file mode 100644 index 00000000..89bccd5e --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/playbook.yml @@ -0,0 +1,5 @@ +--- +- name: Converge + hosts: all + roles: + - role: mongodb_linux diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/prepare.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/prepare.yml new file mode 100644 index 00000000..cdadcdbe --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/prepare.yml @@ -0,0 +1,11 @@ +--- +- name: Prepare + hosts: all + become: yes + + tasks: + + - name: Create is_docker.txt file + file: + path: is_docker.txt + state: touch diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/tests/test_default.py new file mode 100644 index 00000000..9b80de32 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/default/tests/test_default.py @@ -0,0 +1,75 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def test_ntp_package(host): + ntp = host.package("ntp") + chrony = host.package("chrony") + assert ntp.is_installed or chrony.is_installed + + +def test_ntpd_service(host): + ntpd = host.service("ntpd") + + if ntpd.is_running: + assert ntpd.is_enabled + else: + ntp = host.service("ntp") + if ntp.is_running: + assert ntp.is_enabled + else: + chronyd = host.service("chronyd") + assert chronyd.is_running + assert chronyd.is_enabled + + +def test_swappiness_value(host): + cmd = host.run("cat /proc/sys/vm/swappiness") + + assert cmd.rc == 0 + assert cmd.stdout.strip() == "1" + + +def test_thp_service_file(host): + f = host.file("/etc/systemd/system/disable-transparent-huge-pages.service") + + assert f.exists + assert f.user == "root" + assert f.group == "root" + + +def test_thp_service(host): + ''' + Validates the service actually works + ''' + switches = ["/sys/kernel/mm/transparent_hugepage/enabled", + "/sys/kernel/mm/transparent_hugepage/defrag"] + + f = host.file("is_docker.txt") + + if not f.exists: + for d in switches: + cmd = host.run("cat {0}".format(d)) + + assert cmd.rc == 0 + assert "[never]" in cmd.stdout + + +def test_limit_file(host): + f = host.file("/etc/security/limits.conf") + + assert f.exists + assert f.user == "root" + assert f.group == "root" + + assert f.contains("mongodb hard nproc 64000") + assert f.contains("mongodb hard nofile 64000") + assert f.contains("mongodb soft nproc 64000") + assert f.contains("mongodb soft nofile 64000") + assert f.contains("mongodb hard memlock 1024") + assert f.contains("mongodb soft memlock 1024") diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/molecule.yml new file mode 100644 index 00000000..bcaaf4c4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/molecule.yml @@ -0,0 +1,36 @@ +--- +dependency: + name: galaxy +driver: + name: vagrant + provider: + name: virtualbox +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos-7 + box: centos/7 + - name: centos-8 + box: generic/centos8 + - name: ubuntu-16 + box: ubuntu/xenial64 + - name: ubuntu-18 + box: ubuntu/bionic64 + - name: debian-buster + box: debian/buster64 + - name: debian-stretch + box: debian/contrib-stretch64 # Standard debian/stretch64 had issues: Unable to locate package linux-headers-4.9.0-9-amd64 +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/playbook.yml new file mode 100644 index 00000000..8e9d4e75 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/playbook.yml @@ -0,0 +1,7 @@ +--- +- name: Converge + hosts: all + become: yes + + roles: + - role: mongodb_linux diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/prepare.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/prepare.yml new file mode 100644 index 00000000..58b16460 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/prepare.yml @@ -0,0 +1,12 @@ +--- +- name: Prepare + hosts: all + become: yes + + tasks: + + - name: Ensure epel-release is installed + package: + name: epel-release + state: present + when: ansible_os_family == "RedHat" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/tests/test_default.py new file mode 100644 index 00000000..b16522ff --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/molecule/virtualbox/tests/test_default.py @@ -0,0 +1,73 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def test_ntp_package(host): + ntp = host.package("ntp") + chrony = host.package("chrony") + assert ntp.is_installed or chrony.is_installed + + +def test_ntpd_service(host): + ntpd = host.service("ntpd") + + if ntpd.is_running: + assert ntpd.is_enabled + else: + ntp = host.service("ntp") + if ntp.is_running: + assert ntp.is_enabled + else: + chronyd = host.service("chronyd") + assert chronyd.is_running + assert chronyd.is_enabled + + +def test_swappiness_value(host): + cmd = host.run("cat /proc/sys/vm/swappiness") + + assert cmd.rc == 0 + assert cmd.stdout.strip() == "1" + + +def test_thp_service_file(host): + f = host.file("/etc/systemd/system/disable-transparent-huge-pages.service") + + assert f.exists + assert f.user == "root" + assert f.group == "root" + + +def test_thp_service(host): + ''' + Validates the service actually works + ''' + switches = ["/sys/kernel/mm/transparent_hugepage/enabled", + "/sys/kernel/mm/transparent_hugepage/defrag"] + + if host.ansible("setup")["ansible_facts"]["ansible_virtualization_type"] not in ['docker', 'container']: + for d in switches: + cmd = host.run("cat {0}".format(d)) + + assert cmd.rc == 0 + assert "[never]" in cmd.stdout + + +def test_limit_file(host): + f = host.file("/etc/security/limits.conf") + + assert f.exists + assert f.user == "root" + assert f.group == "root" + + assert f.contains("mongodb hard nproc 64000") + assert f.contains("mongodb hard nofile 64000") + assert f.contains("mongodb soft nproc 64000") + assert f.contains("mongodb soft nofile 64000") + assert f.contains("mongodb hard memlock 1024") + assert f.contains("mongodb soft memlock 1024") diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/tasks/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/tasks/main.yml new file mode 100644 index 00000000..7d5beeb7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/tasks/main.yml @@ -0,0 +1,139 @@ +--- +# tasks file for mongodb_linux + +- name: Include OS-specific vars + include_vars: + file: "{{ lookup('first_found', params) }}" + vars: + params: + paths: + - "vars" + files: + - "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version }}.yml" + - "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml" + - "{{ ansible_facts.distribution }}.yml" + - "{{ ansible_facts.os_family }}.yml" + - default.yml + +- name: Check if we are in docker + stat: + path: is_docker.txt + register: is_docker + +# Tasks based on: https://docs.mongodb.com/manual/administration/production-notes/ + +- name: Set swappiness + sysctl: + name: vm.swappiness + value: "{{ swappiness }}" + state: present + +- name: Ensure ntp service is installed + package: + name: "{{ ntp_package }}" + state: present + register: _pkg + until: _pkg is succeeded + retries: 5 + +- name: Update perms on chrony pid dir on RedHat 8 + file: + path: /run/chrony/ + owner: root + group: root + state: directory + when: + - ansible_facts.os_family == "RedHat" + - ansible_facts.distribution_major_version|int >= 8 + +- name: Ensure ntp service is configured + service: + name: "{{ ntp_service }}" + state: started + enabled: yes + +- name: Ensure GNU C Library is the latest + package: + name: "{{ gnu_c_lib }}" + state: latest + register: _pkg + until: _pkg is succeeded + retries: 5 + +- name: Ensure NUMA zone reclaim is disabled + sysctl: + name: vm.zone_reclaim_mode + value: 0 + state: present + reload: yes + when: not is_docker.stat.exists + +# https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/ +- name: Ensure thp-disable service exists + copy: + src: thp-disable.service + dest: /etc/systemd/system/disable-transparent-huge-pages.service + owner: root + group: root + register: thp + +- name: Reload systemd + systemd: + daemon_reexec: yes + when: thp is changed + +- name: Check if disable-transparent-huge-pages service is already run + shell: cat /sys/kernel/mm/transparent_hugepage/enabled | grep -o "never" + register: _huge_page_status + ignore_errors: yes + changed_when: _huge_page_status.stdout == "" + +- name: Enable disable-transparent-huge-pages service + service: + name: disable-transparent-huge-pages + state: started + enabled: yes + when: (not is_docker.stat.exists) and (_huge_page_status.stdout == "") + +# Tasks based on: https://docs.mongodb.com/manual/reference/ulimit/ + +- name: Set pam limits (nproc and nofile) + pam_limits: + domain: "{{ item[0] }}" + limit_type: "{{ item[1] }}" + limit_item: "{{ item[2] }}" + value: "{{ item[3] }}" + with_nested: + - ["root", "mongodb"] + - ["hard", "soft"] + - ["nproc", "nofile"] + - ["{{ nproc_and_nofile_limit }}"] + +- name: Set pam limits (memlock) + pam_limits: + domain: "{{ item[0] }}" + limit_type: "{{ item[1] }}" + limit_item: "{{ item[2] }}" + value: "{{ item[3] }}" + with_nested: + - ["root", "mongodb"] + - ["hard", "soft"] + - ["memlock"] + - ["{{ memlock_limit }}"] + +# Other tuning settings + +- name: Set sysctl values + sysctl: + name: "{{ item['name'] }}" + value: "{{ item['value'] }}" + state: present + loop: + # TODO: These may need to be configurable for different usage patterns. + - { "name": "vm.dirty_ratio", "value": "15" } + - { "name": "vm.dirty_background_ratio", "value": "5" } + - { "name": "net.core.somaxconn ", "value": "4096" } + - { "name": "net.ipv4.tcp_fin_timeout", "value": "30" } + - { "name": "net.ipv4.tcp_keepalive_intvl", "value": "30" } + - { "name": "net.ipv4.tcp_keepalive_time", "value": "120" } + - { "name": "net.ipv4.tcp_max_syn_backlog ", "value": "4096" } diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/Debian.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/Debian.yml new file mode 100644 index 00000000..375c7983 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/Debian.yml @@ -0,0 +1,5 @@ +--- +# Packages for Debian distros +ntp_package: ntp +ntp_service: ntp +gnu_c_lib: libc6 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/RedHat-8.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/RedHat-8.yml new file mode 100644 index 00000000..bc70604b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/RedHat-8.yml @@ -0,0 +1,5 @@ +--- +# Packages for RedHat-8 distros +ntp_package: chrony +ntp_service: chronyd +gnu_c_lib: glibc diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/RedHat.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/RedHat.yml new file mode 100644 index 00000000..57ebecc8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/RedHat.yml @@ -0,0 +1,5 @@ +--- +# Packages for RedHat distros +ntp_package: ntp +ntp_service: ntpd +gnu_c_lib: glibc diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/default.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/default.yml new file mode 100644 index 00000000..0f0db5a7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_linux/vars/default.yml @@ -0,0 +1,5 @@ +--- +# Packages (default fallthrough) +ntp_package: ntp +ntp_service: ntpd +gnu_c_lib: libc6 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/.yamllint b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/.yamllint new file mode 100644 index 00000000..88276760 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/README.md b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/README.md new file mode 100644 index 00000000..ae8dea5b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/README.md @@ -0,0 +1,52 @@ +mongodb_mongod +============== + +A simple role to aid in the setup of a MongoDB replicaset. + +Role Variables +-------------- + +* `mongod_port`: The port used by the mongod process. Default 27017. +* `mongod_service`: The name of the mongod service. Default mongod. +* `mongodb_user`: The Linux OS user for MongoDB. Default mongod. +* `mongodb_group`: The Linux OS user group for MongoDB. Default mongod. +* `bind_ip`: The IP address mongos will bind to. Default 0.0.0.0. +* `repl_set_name`: The name of the replicaset the member will participate in. Default rs0. +* `authorization`: Enable authorization. Default enabled. +* `openssl_keyfile_content`: The keyfile content that MongoDB uses to authenticate within a replicaset. Generate with cmd: openssl rand -base64 756. +* `mongodb_admin_user`: MongoDB admin username. Default admin. +* `mongodb_admin_pwd`: MongoDB admin password. Default admin. +* `mongod_package`: The mongod package to install. Default mongodb-org-server. +* `replicaset`: When enabled add a replication section to the configuration. Default true. +* `sharding`: If this replicaset member will form part of a sharded cluster. Default false. +* `mongod_config_template`: If defined allows to override path to mongod config template with custom configuration. Default "mongod.conf.j2" +* `skip_restart`: If set to `true` will skip restarting mongod service when config file or the keyfile content changes. Default `true`. + +IMPORTANT NOTE: It is expected that `mongodb_admin_user` & `mongodb_admin_pwd` values be overridden in your own file protected by Ansible Vault. These values are primary included here for Molecule/Travis CI integration. Any production environments should protect these values. For more information see [Ansible Vault](https://docs.ansible.com/ansible/latest/user_guide/vault.html) + +Dependencies +------------ + +mongodb_repository + +Example Playbook +---------------- + +Install MongoDB preparing hosts for a Sharded Cluster. + +```yaml + - hosts: servers + roles: + - { role: mongodb_repository } + - { role: mongodb_mongod, mongod_port: 27018, sharding: true } +``` + +License +------- + +BSD + +Author Information +------------------ + +Rhys Campbell (https://github.com/rhysmeister) diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/defaults/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/defaults/main.yml new file mode 100644 index 00000000..c15d6f4a --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/defaults/main.yml @@ -0,0 +1,30 @@ +--- +# defaults file for mongodb_mongod +mongod_port: 27017 +bind_ip: 0.0.0.0 +repl_set_name: rs0 +authorization: "enabled" +openssl_keyfile_content: | + Z2CeA9BMcoY5AUWoegjv/XWL2MA1SQcL4HvmRjYaTjSp/xosJy+LL2X3OQb1xVWC + rO2e6Tu6A3R4muunitI6Vr0IKeU5UbTpR0N4hSU6HDrV9z2PIEWlkQqKh01ZRLEY + V3hR73acj0jA8eWIWeiV039d18jvMb8X2h8409lfcD6PPJJGjyaC8S4LY/TrsK2z + tx+l/vqOOAMhGB5mEMjx1LXUMsRG9ot6vFu9I5LPd1A4q9xw9jddYK5C6YTLccun + ZyCDsv7ImkCprV0+0vhTyxIEnfaNtvOlWypuvmRr/DEyd2NPowd1n6C+rgk8gs1t + SGLCZP93gXza0rIoQzHtuf5pOJK9qyKjuNtuuLa/KFsida8a69JXn7fmS0IIja0m + Ir0OrQ2Ta3n4VbQwQo97BWODWmkgzz0mUd6VmMps5zLsCW1vVqYFQHuAAbLekW0q + 8JRm8OQ6n2hp8j4zYd3/Qw7vqsVj8sHicNB0bCW29b64H4f2J/AcUA/cm0xSUQyb + +myeCB4vWvydh5AfFVnw7sXvzU6egaYRomdmrl59QrTDneJu13hwzIchsFparoWJ + XjpldopGeDaJLU18ga7MSL02ozB+EoJ14DJxQU7E5MQk7fDMPeitXKZ8ymxb7LeA + k0Rtc/JQM8aDLoRklhLZRRARBrv1RLo8DM8CB2q4s+FwVU4QJl7mFyiwk3eTN6sN + PTgFRo3/dHsEA2OwGG+hnGFGnoYf2mkECR5jqai83CXgva9v2rPNjDTJYHpmd3I0 + fNijueXZZdzUA58y8mcoSGVYdRhr0g8jaWQ12PZEgX5Nnlekh5GHG0j8HT4qj/0Y + D3xVuE3WvrhldY5EOsaTt2ZXZx5REmJDIW1KcnvQKiVDJ2QzP5xdXYA0hh3TdTVE + sb4UreMw/WyBpANiICMlJRBgSd0f0VGMlYzLX2BL14YpNnLhmoQqKzfBN6v2XAEG + mJfrCUVuP1nBEklk23lYkNi/ohe+aodNjdN+2DHp42sGZHYP +mongodb_admin_user: admin +mongodb_admin_pwd: admin +mongod_package: "mongodb-org-server" +replicaset: true +sharding: false +mongod_config_template: "mongod.conf.j2" +skip_restart: true diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/handlers/handlers.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/handlers/handlers.yml new file mode 100644 index 00000000..1bbd837c --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/handlers/handlers.yml @@ -0,0 +1,10 @@ +--- + +- name: Restart mongod service + service: + name: "{{ mongod_service }}" + state: restarted + +- name: Wait for port to become active + wait_for: + port: "{{ mongod_port }}" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/handlers/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/handlers/main.yml new file mode 100644 index 00000000..d1a7a569 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/handlers/main.yml @@ -0,0 +1,5 @@ +--- + +- name: Restart mongod service + import_tasks: handlers.yml + when: not skip_restart diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/meta/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/meta/main.yml new file mode 100644 index 00000000..1d46e31c --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/meta/main.yml @@ -0,0 +1,58 @@ +--- +galaxy_info: + author: Rhys Campbell + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + + min_ansible_version: 1.2 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # Optionally specify the branch Galaxy will use when accessing the GitHub + # repo for this role. During role install, if no tags are available, + # Galaxy will use this branch. During import Galaxy will access files on + # this branch. If Travis integration is configured, only notifications for this + # branch will be accepted. Otherwise, in all cases, the repo's default branch + # (usually master) will be used. + # github_branch: + + # + # platforms is a list of platforms, and each platform has a name and a list of versions. + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] +# List your role dependencies here, one per line. Be sure to remove the '[]' above, +# if you add dependencies to this list. diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/Dockerfile.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/Dockerfile.j2 new file mode 100644 index 00000000..935dd3d7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/Dockerfile.j2 @@ -0,0 +1,39 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +{% if item.env is defined %} +{% for var, value in item.env.items() %} +{% if value %} +ENV {{ var }} {{ value }} +{% endif %} +{% endfor %} +{% endif %} +# Add systemd-sysv package for Debian to get systemd working (and procps for sysctl) and netbase for firewalld +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 systemd-sysv procps netbase && apt-get clean; \ + elif [ $(command -v dnf) ] && grep -q 'platform:el8' /etc/os-release ; then dnf makecache && dnf update -y && dnf --assumeyes install python3 sudo python3-devel bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && rm -Rf /usr/share/doc && rm -Rf /usr/share/man && dnf clean all && cp /bin/true /sbin/agetty; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi + +{% if item.image == 'centos:8' %} +# Stuff for systemd https://hub.docker.com/_/centos +RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \ + systemd-tmpfiles-setup.service ] || rm -f $i; done); \ + rm -f /lib/systemd/system/multi-user.target.wants/*;\ + rm -f /etc/systemd/system/*.wants/*;\ + rm -f /lib/systemd/system/local-fs.target.wants/*; \ + rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ + rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ + rm -f /lib/systemd/system/basic.target.wants/*;\ + rm -f /lib/systemd/system/anaconda.target.wants/*; + +VOLUME [ "/sys/fs/cgroup" ] +CMD ["/sbin/init"] +{% endif %} diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/molecule.yml new file mode 100644 index 00000000..2f0e4ac8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/molecule.yml @@ -0,0 +1,68 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos_7 + image: centos:7 + command: /sbin/init + privileged: True + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + networks: + - name: "mongod" + network_mode: "mongod" + - name: centos_8 + image: centos:8 + command: /sbin/init + privileged: True + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + networks: + - name: "mongod" + network_mode: "mongod" + - name: ubuntu_16 + image: ubuntu:16.04 + command: /sbin/init + privileged: True + networks: + - name: "mongod" + network_mode: "mongod" + - name: ubuntu_18 + image: ubuntu:18.04 + command: /sbin/init + privileged: True + networks: + - name: "mongod" + network_mode: "mongod" + - name: debian_buster + image: debian:buster + command: /sbin/init + privileged: True + networks: + - name: "mongod" + network_mode: "mongod" + - name: debian_stretch + image: debian:stretch + command: /sbin/init + privileged: True + networks: + - name: "mongod" + network_mode: "mongod" +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/playbook.yml new file mode 100644 index 00000000..038632a4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/playbook.yml @@ -0,0 +1,37 @@ +--- +- name: Converge + hosts: all + roles: + - role: mongodb_repository + tags: molecule-idempotence-notest + - role: mongodb_mongod + + tasks: + + - name: Install python stuff + package: + name: ["python-setuptools", "python-pip"] + when: ansible_hostname == "ubuntu_16" + + - name: Install pymongo + pip: + name: pymongo + when: ansible_hostname == "ubuntu_16" + + - name: Install MongoDB Shell + package: + name: mongodb-org-shell + + - name: Initialise replicaset + community.mongodb.mongodb_replicaset: + login_host: localhost + replica_set: rs0 + validate: yes + members: + - centos_7:27017 + - centos_8:27017 + - ubuntu_16:27017 + - ubuntu_18:27017 + #- debian_stretch:27017 # need odd number, so drop stretch + - debian_buster:27017 + when: ansible_hostname == "ubuntu_16" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/prepare.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/prepare.yml new file mode 100644 index 00000000..abdf26a2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/prepare.yml @@ -0,0 +1,10 @@ +--- +- name: Prepare + hosts: all + + tasks: + + - name: Create is_docker.txt file + file: + path: is_docker.txt + state: touch diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/tests/test_default.py new file mode 100644 index 00000000..9eb482bd --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/default/tests/test_default.py @@ -0,0 +1,71 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def include_vars(host): + if host.system_info.distribution == "redhat" \ + or host.system_info.distribution == "centos": + ansible = host.ansible('include_vars', + 'file="../../vars/RedHat.yml"', + False, + False) + if host.system_info.distribution == "debian" \ + or host.system_info.distribution == "ubuntu": + ansible = host.ansible('include_vars', + 'file="../../vars/Debian.yml"', + False, + False) + return ansible + + +def test_mongod_cnf_file(host): + mongodb_user = include_vars(host)['ansible_facts']['mongodb_user'] + mongodb_group = include_vars(host)['ansible_facts']['mongodb_group'] + f = host.file('/etc/mongod.conf') + + assert f.exists + assert f.user == mongodb_user + assert f.group == mongodb_group + + +def test_mongod_service(host): + mongod_service = include_vars(host)['ansible_facts']['mongod_service'] + s = host.service(mongod_service) + + assert s.is_running + assert s.is_enabled + + +def test_mongod_port(host): + try: + port = include_vars(host)['ansible_facts']['mongod_port'] + except KeyError: + port = 27017 + s = host.socket("tcp://0.0.0.0:{0}".format(port)) + assert s.is_listening + + +def test_mongod_replicaset(host): + ''' + Ensure that the MongoDB replicaset has been created successfully + ''' + try: + port = include_vars(host)['ansible_facts']['mongod_port'] + except KeyError: + port = 27017 + cmd = "mongo --port {0} --eval 'rs.status()'".format(port) + # We only want to run this once + if host.ansible.get_variables()['inventory_hostname'] == "ubuntu_16": + r = host.run(cmd) + assert "rs0" in r.stdout + assert "centos_7:{0}".format(port) in r.stdout + assert "centos_8:{0}".format(port) in r.stdout + assert "ubuntu_16:{0}".format(port) in r.stdout + assert "ubuntu_18:{0}".format(port) in r.stdout + assert "debian_buster:{0}".format(port) in r.stdout + # assert "debian_stretch:{0}".format(port) in r.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/molecule.yml new file mode 100644 index 00000000..14d29680 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/molecule.yml @@ -0,0 +1,54 @@ +--- +dependency: + name: galaxy +driver: + name: vagrant + provider: + name: virtualbox +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos-7 + box: centos/7 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-16 + box: ubuntu/xenial64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-18 + box: ubuntu/bionic64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-buster + box: debian/buster64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-stretch + box: debian/contrib-stretch64 # Standard debian/stretch64 had issues: Unable to locate package linux-headers-4.9.0-9-amd64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/playbook.yml new file mode 100644 index 00000000..6a31e1fc --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/playbook.yml @@ -0,0 +1,34 @@ +--- +- name: Converge + hosts: all + become: yes + + roles: + - role: mongodb_repository + tags: molecule-idempotence-notest + - role: mongodb_mongod + + tasks: + + - name: Install python stuff + package: + name: ["python-setuptools", "python-pip"] + when: ansible_hostname == "ubuntu-16" + + - name: Install pymongo + pip: + name: pymongo + when: ansible_hostname == "ubuntu-16" + + - name: Initialise replicaset + community.mongodb.mongodb_replicaset: + login_host: localhost + replica_set: rs0 + validate: yes + members: + - ubuntu-16.local:27017 + - ubuntu-18.local:27017 + - debian-stretch.local:27017 + - debian-buster.local:27017 + - centos-7.local:27017 + when: ansible_hostname == "ubuntu-16" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/prepare.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/prepare.yml new file mode 100644 index 00000000..0f186973 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/prepare.yml @@ -0,0 +1,40 @@ +--- +- name: Prepare + hosts: all + become: yes + vars: + avahi_packages_redhat: + - "avahi" + - "nss-mdns" + avahi_packages_debian: + - "avahi-daemon" + - "avahi-discover" + - "libnss-mdns" + tasks: + + - name: Ensure epel is available + yum: + name: epel-release + state: present + when: ansible_os_family == "RedHat" + + - name: Install avahi packages + package: + name: "{{ avahi_packages_redhat }}" + state: present + when: ansible_os_family == "RedHat" + + - name: Install avahi packages + package: + name: "{{ avahi_packages_debian }}" + state: present + when: ansible_os_family == "Debian" + + # debian-stretch seems to require a reboot for avahi-daemon to run + - name: Reboot host + reboot: + + - name: Ensure avahi-daemon is started + service: + name: avahi-daemon + state: started diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/tests/test_default.py new file mode 100644 index 00000000..d7e79cfc --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/molecule/virtualbox/tests/test_default.py @@ -0,0 +1,72 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def include_vars(host): + if host.system_info.distribution == "redhat" \ + or host.system_info.distribution == "centos": + ansible = host.ansible('include_vars', + 'file="../../vars/RedHat.yml"', + False, + False) + if host.system_info.distribution == "debian" \ + or host.system_info.distribution == "ubuntu": + ansible = host.ansible('include_vars', + 'file="../../vars/Debian.yml"', + False, + False) + return ansible + + +def test_mongod_cnf_file(host): + mongodb_user = include_vars(host)['ansible_facts']['mongodb_user'] + mongodb_group = include_vars(host)['ansible_facts']['mongodb_group'] + f = host.file('/etc/mongod.conf') + + assert f.exists + assert f.user == mongodb_user + assert f.group == mongodb_group + + +def test_mongod_service(host): + mongod_service = include_vars(host)['ansible_facts']['mongod_service'] + s = host.service(mongod_service) + + assert s.is_running + assert s.is_enabled + + +def test_mongod_port(host): + try: + port = include_vars(host)['ansible_facts']['mongod_port'] + except KeyError: + port = 27017 + s = host.socket("tcp://0.0.0.0:{0}".format(port)) + + assert s.is_listening + + +def test_mongod_replicaset(host): + ''' + Ensure that the MongoDB replicaset has been created successfully + ''' + try: + port = include_vars(host)['ansible_facts']['mongod_port'] + except KeyError: + port = 27017 + cmd = "mongo --port {0} --eval 'rs.status()'".format(port) + # We only want to run this once + if host.ansible.get_variables()['inventory_hostname'] == "ubuntu_16": + r = host.run(cmd) + + assert "rs0" in r.stdout + assert "ubuntu-16:{0}".format(port) in r.stdout + assert "ubuntu-18:{0}".format(port) in r.stdout + assert "debian-stretch:{0}".format(port) in r.stdout + assert "debian-buster:{0}".format(port) in r.stdout + assert "centos-7:{0}".format(port) in r.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/tasks/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/tasks/main.yml new file mode 100644 index 00000000..881a1491 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/tasks/main.yml @@ -0,0 +1,75 @@ +--- +# tasks file for mongodb_mongod +- name: Include OS-specific vars + include_vars: + file: "{{ lookup('first_found', params) }}" + vars: + params: + paths: + - "vars" + files: + - "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version }}.yml" + - "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml" + - "{{ ansible_facts.distribution }}.yml" + - "{{ ansible_facts.os_family }}.yml" + - default.yml + +- name: Check if we are in docker + stat: + path: is_docker.txt + register: is_docker + +- name: Ensure mongod package is installed + package: + name: "{{ mongod_package }}" + register: _pkg + until: _pkg is succeeded + retries: 5 + +- name: Ensure db_path dir exists + file: + path: "{{ db_path }}" + state: directory + owner: "{{ mongodb_user }}" + group: "{{ mongodb_group }}" + +- name: Copy config file + template: + src: "{{ mongod_config_template }}" + dest: /etc/mongod.conf + owner: "{{ mongodb_user }}" + group: "{{ mongodb_group }}" + notify: + - Restart mongod service + +- name: Copy keyfile to host + copy: + content: | + {{ openssl_keyfile_content }} + dest: /etc/keyfile + owner: "{{ mongodb_user }}" + group: "{{ mongodb_group }}" + mode: 0400 + when: authorization == "enabled" + notify: + - Restart mongod service + +- name: Check for github override + set_fact: + x_github_override: "{{ lookup('env', 'X_GITHUB_OVERRIDE') | default('0', True) }}" + +- name: Start mongod service + service: + name: "{{ mongod_service }}" + state: started + enabled: yes + when: not (ansible_facts.os_family == 'RedHat' + and ansible_facts.distribution_major_version|int == 8 + and is_docker.stat.exists) + +- name: Include tasks for RedHat 8 docker issue + import_tasks: redhat_docker.yml + when: + - ansible_facts.os_family == 'RedHat' + - ansible_facts.distribution_major_version|int == 8 + - is_docker.stat.exists diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/tasks/redhat_docker.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/tasks/redhat_docker.yml new file mode 100644 index 00000000..d08c66a1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/tasks/redhat_docker.yml @@ -0,0 +1,18 @@ +--- +- name: Comment out PIDFile in systemd file + lineinfile: + path: /etc/systemd/system/multi-user.target.wants/mongod.service + regexp: '^PIDFile.*' + state: absent + register: systemd + +- name: Reload systemd + systemd: + daemon_reload: yes + when: systemd is changed + +- name: Start mongod service + service: + name: "{{ mongod_service }}" + state: started + enabled: yes diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/templates/mongod.conf.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/templates/mongod.conf.j2 new file mode 100644 index 00000000..a4300e5e --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/templates/mongod.conf.j2 @@ -0,0 +1,53 @@ +# mongod.conf + +# for documentation of all options, see: +# http://docs.mongodb.org/manual/reference/configuration-options/ + +# where to write logging data. +systemLog: + destination: file + logAppend: true + path: /var/log/mongodb/mongod.log + +# Where and how to store data. +storage: + dbPath: {{ db_path }} + journal: + enabled: true + engine: "wiredTiger" + + +# how the process runs +processManagement: +{% if ansible_facts.os_family == "RedHat" %} # Breaks Ubuntu / Debian + fork: true +{% if not is_redhat_8_in_docker %} + pidFilePath: /var/run/mongodb/mongod.pid +{% endif %} +{% endif %} + timeZoneInfo: /usr/share/zoneinfo + +# network interfaces +net: + port: {{ mongod_port }} + bindIp: {{ bind_ip }} + +{% if authorization == "enabled" %} +security: + authorization: {{ authorization }} +{% if replicaset or sharding %} + keyFile: /etc/keyfile +{% endif %} +{% endif %} + +#operationProfiling: + +{% if replicaset %} +replication: + replSetName: {{ repl_set_name }} +{% endif %} + +{% if sharding %} +sharding: + clusterRole: shardsvr +{% endif %} diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/Debian.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/Debian.yml new file mode 100644 index 00000000..6b8eaa66 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/Debian.yml @@ -0,0 +1,5 @@ +--- +mongodb_user: "mongodb" +mongodb_group: "mongodb" +mongod_service: "mongod" +db_path: /var/lib/mongodb diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/RedHat.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/RedHat.yml new file mode 100644 index 00000000..a48bb4c2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/RedHat.yml @@ -0,0 +1,5 @@ +--- +mongodb_user: "mongod" +mongodb_group: "mongod" +mongod_service: "mongod" +db_path: /var/lib/mongo diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/default.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/default.yml new file mode 100644 index 00000000..a48bb4c2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/default.yml @@ -0,0 +1,5 @@ +--- +mongodb_user: "mongod" +mongodb_group: "mongod" +mongod_service: "mongod" +db_path: /var/lib/mongo diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/main.yml new file mode 100644 index 00000000..28ce3d22 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongod/vars/main.yml @@ -0,0 +1,2 @@ +--- +is_redhat_8_in_docker: "{{ ansible_facts.os_family == 'RedHat' and ansible_facts.distribution_major_version|int == 8 and ansible_facts.virtualization_type == 'docker' }}" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/.yamllint b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/.yamllint new file mode 100644 index 00000000..88276760 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/README.md b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/README.md new file mode 100644 index 00000000..b2a9aaf2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/README.md @@ -0,0 +1,53 @@ +mongodb_mongos +============== + +A role to setup a mongos server for a MongoDB sharded cluster. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should +be mentioned here. For instance, if the role uses the EC2 module, it may be a +good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +* `mongos_port`: The port used by the mongos process. Default 27017. +* `mongos_service`: The name of the mongos service. Default mongos. +* `mongodb_user`: The Linux OS user for MongoDB. Default mongod. +* `mongodb_group`: The Linux OS user group for MongoDB. Default mongod. +* `pid_file`: The pid file for mongos. Default /run/mongodb/mongos.pid. +* `bind_ip`: The IP address mongos will bind to. Default 0.0.0.0. +* `mypy`: Python interpretor. Default python +* `mongos_package`: The name of the mongos installation package. Default mongodb-org-mongos. +* `config_repl_set_name`: The name of the config server replicaset. Default cfg. +* `config_servers`: "config1:27019, config2:27019, config3:27019" +* `openssl_keyfile_content`: The kexfile content that MongoDB uses to authenticate within a replicaset. Generate with cmd: openssl rand -base64 756. +* `mongos_config_template`: If defined allows to override path to mongod config template with custom configuration. Default "mongos.conf.j2" +* `skip_restart`: If set to `true` will skip restarting mongos service when config file or the keyfile content changes. Default `true`. + +Dependencies +------------ + +mongodb_repository + +Example Playbook +---------------- + +```yaml + - hosts: servers + roles: + - mongodb_repository + - mongodb_mongos +``` + +License +------- + +BSD + +Author Information +------------------ + +Rhys Campbell (https://github.com/rhysmeister) diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/defaults/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/defaults/main.yml new file mode 100644 index 00000000..abed36e3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/defaults/main.yml @@ -0,0 +1,28 @@ +--- +# defaults file for mongodb_mongos +pid_file: /run/mongodb/mongos.pid +bind_ip: 0.0.0.0 +# mongos_port in vars to facilitate molecule tests +mypy: python +mongos_package: "mongodb-org-mongos" +config_repl_set_name: cfg +config_servers: "config1:27019, config2:27019, config3:27019" +openssl_keyfile_content: | + Z2CeA9BMcoY5AUWoegjv/XWL2MA1SQcL4HvmRjYaTjSp/xosJy+LL2X3OQb1xVWC + rO2e6Tu6A3R4muunitI6Vr0IKeU5UbTpR0N4hSU6HDrV9z2PIEWlkQqKh01ZRLEY + V3hR73acj0jA8eWIWeiV039d18jvMb8X2h8409lfcD6PPJJGjyaC8S4LY/TrsK2z + tx+l/vqOOAMhGB5mEMjx1LXUMsRG9ot6vFu9I5LPd1A4q9xw9jddYK5C6YTLccun + ZyCDsv7ImkCprV0+0vhTyxIEnfaNtvOlWypuvmRr/DEyd2NPowd1n6C+rgk8gs1t + SGLCZP93gXza0rIoQzHtuf5pOJK9qyKjuNtuuLa/KFsida8a69JXn7fmS0IIja0m + Ir0OrQ2Ta3n4VbQwQo97BWODWmkgzz0mUd6VmMps5zLsCW1vVqYFQHuAAbLekW0q + 8JRm8OQ6n2hp8j4zYd3/Qw7vqsVj8sHicNB0bCW29b64H4f2J/AcUA/cm0xSUQyb + +myeCB4vWvydh5AfFVnw7sXvzU6egaYRomdmrl59QrTDneJu13hwzIchsFparoWJ + XjpldopGeDaJLU18ga7MSL02ozB+EoJ14DJxQU7E5MQk7fDMPeitXKZ8ymxb7LeA + k0Rtc/JQM8aDLoRklhLZRRARBrv1RLo8DM8CB2q4s+FwVU4QJl7mFyiwk3eTN6sN + PTgFRo3/dHsEA2OwGG+hnGFGnoYf2mkECR5jqai83CXgva9v2rPNjDTJYHpmd3I0 + fNijueXZZdzUA58y8mcoSGVYdRhr0g8jaWQ12PZEgX5Nnlekh5GHG0j8HT4qj/0Y + D3xVuE3WvrhldY5EOsaTt2ZXZx5REmJDIW1KcnvQKiVDJ2QzP5xdXYA0hh3TdTVE + sb4UreMw/WyBpANiICMlJRBgSd0f0VGMlYzLX2BL14YpNnLhmoQqKzfBN6v2XAEG + mJfrCUVuP1nBEklk23lYkNi/ohe+aodNjdN+2DHp42sGZHYP +mongos_config_template: "mongos.conf.j2" +skip_restart: true diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/handlers/handlers.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/handlers/handlers.yml new file mode 100644 index 00000000..7d74ce9d --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/handlers/handlers.yml @@ -0,0 +1,10 @@ +--- + +- name: Restart mongos service + service: + name: "{{ mongos_service }}" + state: restarted + +- name: Wait for port to become active + wait_for: + port: "{{ mongos_port }}" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/handlers/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/handlers/main.yml new file mode 100644 index 00000000..00c4f25c --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/handlers/main.yml @@ -0,0 +1,4 @@ +--- +- name: Restart mongos service + import_tasks: handlers.yml + when: not skip_restart diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/meta/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/meta/main.yml new file mode 100644 index 00000000..ba43fdd2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/meta/main.yml @@ -0,0 +1,58 @@ +--- +galaxy_info: + author: your name + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + + min_ansible_version: 1.2 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # Optionally specify the branch Galaxy will use when accessing the GitHub + # repo for this role. During role install, if no tags are available, + # Galaxy will use this branch. During import Galaxy will access files on + # this branch. If Travis integration is configured, only notifications for this + # branch will be accepted. Otherwise, in all cases, the repo's default branch + # (usually master) will be used. + # github_branch: + + # + # platforms is a list of platforms, and each platform has a name and a list of versions. + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] +# List your role dependencies here, one per line. Be sure to remove the '[]' above, +# if you add dependencies to this list. diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/Dockerfile.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/Dockerfile.j2 new file mode 100644 index 00000000..935dd3d7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/Dockerfile.j2 @@ -0,0 +1,39 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +{% if item.env is defined %} +{% for var, value in item.env.items() %} +{% if value %} +ENV {{ var }} {{ value }} +{% endif %} +{% endfor %} +{% endif %} +# Add systemd-sysv package for Debian to get systemd working (and procps for sysctl) and netbase for firewalld +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 systemd-sysv procps netbase && apt-get clean; \ + elif [ $(command -v dnf) ] && grep -q 'platform:el8' /etc/os-release ; then dnf makecache && dnf update -y && dnf --assumeyes install python3 sudo python3-devel bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && rm -Rf /usr/share/doc && rm -Rf /usr/share/man && dnf clean all && cp /bin/true /sbin/agetty; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi + +{% if item.image == 'centos:8' %} +# Stuff for systemd https://hub.docker.com/_/centos +RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \ + systemd-tmpfiles-setup.service ] || rm -f $i; done); \ + rm -f /lib/systemd/system/multi-user.target.wants/*;\ + rm -f /etc/systemd/system/*.wants/*;\ + rm -f /lib/systemd/system/local-fs.target.wants/*; \ + rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ + rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ + rm -f /lib/systemd/system/basic.target.wants/*;\ + rm -f /lib/systemd/system/anaconda.target.wants/*; + +VOLUME [ "/sys/fs/cgroup" ] +CMD ["/sbin/init"] +{% endif %} diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/molecule.yml new file mode 100644 index 00000000..2f7b7d39 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/molecule.yml @@ -0,0 +1,76 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + # centos_7 and debian_stretch disabled to reduce test time + #- name: centos_7 + # image: centos:7 + # command: /sbin/init + # privileged: True + # volumes: + # - /sys/fs/cgroup:/sys/fs/cgroup:ro + # networks: + # - name: "mymongos" + # network_mode: "mymongos" + - name: centos_8 + image: centos:8 + command: /sbin/init + privileged: True + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + networks: + - name: "mymongos" + network_mode: "mymongos" + - name: ubuntu_16 + image: ubuntu:16.04 + command: /sbin/init + privileged: True + networks: + - name: "mymongos" + network_mode: "mymongos" + - name: ubuntu_18 + image: ubuntu:18.04 + command: /sbin/init + privileged: True + networks: + - name: "mymongos" + network_mode: "mymongos" + - name: debian_buster + image: debian:buster + command: /sbin/init + privileged: True + networks: + - name: "mymongos" + network_mode: "mymongos" + #- name: debian_stretch + # image: debian:stretch + # command: /sbin/init + # privileged: True + # networks: + # - name: "mymongos" + # network_mode: "mymongos" + - name: config1 + image: ubuntu:16.04 + command: /sbin/init + privileged: True + networks: + - name: "mymongos" + network_mode: "mymongos" +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/playbook.yml new file mode 100644 index 00000000..12706d4f --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/playbook.yml @@ -0,0 +1,63 @@ +--- +- name: Converge + hosts: all + become: yes + + vars: + admin_user: "admin" + admin_user_password: "admin" + + roles: + - role: mongodb_repository + tags: molecule-idempotence-notest + - role: mongodb_install + when: "'config' in ansible_hostname" + tags: molecule-idempotence-notest + - role: mongodb_config + when: "'config' in ansible_hostname" + tags: molecule-idempotence-notest + - role: mongodb_mongos + when: "'config' not in ansible_hostname" + + tasks: + + - name: Install python stuff + package: + name: ["python-setuptools", "python-pip"] + when: ansible_hostname == "config1" + + - name: Install pymongo + pip: + name: pymongo + when: ansible_hostname == "config1" + + - name: Install MongoDB Shell + package: + name: mongodb-org-shell + + - name: Init config server replicaset + community.mongodb.mongodb_replicaset: + login_host: localhost + login_port: "27019" + replica_set: cfg + validate: no + members: + - config1:27019 + when: ansible_hostname == "config1" + + - name: Restart the mongos service + service: + name: mongos + state: started + when: "'config' not in ansible_hostname" + + - name: Add MongoDB Admin User using localhost exception on the mongos + community.mongodb.mongodb_user: + name: "{{ admin_user }}" + password: "{{ admin_user_password }}" + login_port: "27019" + database: admin + roles: + - "root" + create_for_localhost_exception: /root/mongodb_admin.success + when: ansible_hostname == "config1" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/tests/test_default.py new file mode 100644 index 00000000..0a421179 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/default/tests/test_default.py @@ -0,0 +1,65 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def include_vars(host): + if host.system_info.distribution == "redhat" \ + or host.system_info.distribution == "centos": + ansible = host.ansible('include_vars', + 'file="../../vars/RedHat.yml"', + False, + False) + if host.system_info.distribution == "debian" \ + or host.system_info.distribution == "ubuntu": + ansible = host.ansible('include_vars', + 'file="../../vars/Debian.yml"', + False, + False) + return ansible + + +def test_mongod_cnf_file(host): + if host.ansible.get_variables()['inventory_hostname'] != 'config1': + mongodb_user = include_vars(host)['ansible_facts']['mongodb_user'] + mongodb_group = include_vars(host)['ansible_facts']['mongodb_group'] + f = host.file('/etc/mongos.conf') + + assert f.exists + assert f.user == mongodb_user + assert f.group == mongodb_group + + +def test_mongod_service(host): + + if host.ansible.get_variables()['inventory_hostname'] != 'config1': + mongos_service = include_vars(host)['ansible_facts']['mongos_service'] + s = host.service(mongos_service) + + assert s.is_running + assert s.is_enabled + + +def test_mongod_port(host): + if host.ansible.get_variables()['inventory_hostname'] != 'config1': + port = include_vars(host)['ansible_facts']['mongos_port'] + s = host.socket("tcp://0.0.0.0:{0}".format(port)) + + assert s.is_listening + + +def test_mongos_shell_connectivity(host): + ''' + Tests that we can connect to mongos via the shell annd run a cmd + ''' + if host.ansible.get_variables()['inventory_hostname'] != 'config1': + port = include_vars(host)['ansible_facts']['mongos_port'] + cmd = host.run("mongo admin --username admin --password admin --port {0} --eval 'db.runCommand({{listDatabases: 1}})'".format(port)) + + assert cmd.rc == 0 + assert "config" in cmd.stdout + assert "admin" in cmd.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/molecule.yml new file mode 100644 index 00000000..f790062c --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/molecule.yml @@ -0,0 +1,60 @@ +--- +dependency: + name: galaxy +driver: + name: vagrant + provider: + name: virtualbox +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos-7 + box: centos/7 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-16 + box: ubuntu/xenial64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-18 + box: ubuntu/bionic64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-buster + box: debian/buster64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-stretch + box: debian/contrib-stretch64 # Standard debian/stretch64 had issues: Unable to locate package linux-headers-4.9.0-9-amd64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: config1 + box: debian/contrib-stretch64 # Standard debian/stretch64 had issues: Unable to locate package linux-headers-4.9.0-9-amd64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/playbook.yml new file mode 100644 index 00000000..4b097947 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/playbook.yml @@ -0,0 +1,70 @@ +--- +- name: Converge + hosts: all + become: yes + + vars: + admin_user: "admin" + admin_user_password: "admin" + + roles: + - role: mongodb_repository + tags: molecule-idempotence-notest + - role: mongodb_install + when: "'config' in ansible_hostname" + tags: molecule-idempotence-notest + - role: mongodb_config + when: "'config' in ansible_hostname" + tags: molecule-idempotence-notest + - role: mongodb_mongos + when: "'config' not in ansible_hostname" + + tasks: + + - name: Install python stuff + package: + name: ["python-setuptools", "python-pip"] + when: ansible_hostname == "config1" + + - name: Install pymongo + pip: + name: pymongo + when: ansible_hostname == "config1" + + - name: Install MongoDB Shell + package: + name: mongodb-org-shell + + - name: Init config server replicaset + community.mongodb.mongodb_replicaset: + login_host: localhost + login_port: 27019 + replica_set: cfg + validate: no + members: + - config1.local:27019 + when: ansible_hostname == "config1" + + - name: Set add .local prefix to service name + lineinfile: + path: /etc/mongos.conf + regexp: " *configDB: *" + line: ' configDB: "cfg/config1.local:27019"' + when: "'config' not in ansible_hostname" + + - name: Restart the mongos service + service: + name: mongos + state: restarted + when: "'config' not in ansible_hostname" + + - name: Add MongoDB Admin User using localhost exception on the mongos + community.mongodb.mongodb_user: + name: "{{ admin_user }}" + password: "{{ admin_user_password }}" + login_port: "27019" + database: admin + roles: + - "root" + create_for_localhost_exception: /root/mongodb_admin.success + when: ansible_hostname == "config1" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/prepare.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/prepare.yml new file mode 100644 index 00000000..d56f58bb --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/prepare.yml @@ -0,0 +1,48 @@ +--- +- name: Prepare + hosts: all + become: yes + vars: + avahi_packages_redhat: + - "avahi" + - "nss-mdns" + avahi_packages_debian: + - "avahi-daemon" + - "avahi-discover" + - "libnss-mdns" + + tasks: + + - name: Run apt update + shell: apt update + when: ansible_os_family == "Debian" + + - name: Ensure epel is available + yum: + name: epel-release + state: present + when: ansible_os_family == "RedHat" + + - name: Install avahi packages + package: + name: "{{ avahi_packages_redhat }}" + state: present + when: ansible_os_family == "RedHat" + + - name: Install avahi packages + package: + name: "{{ avahi_packages_debian }}" + state: present + when: ansible_os_family == "Debian" + + # debian-stretch seems to require a reboot for avahi-daemon to run + - name: Reboot host + reboot: + + - name: Ensure services are started + service: + name: "{{ item }}" + state: started + with_items: + #- dbus + - avahi-daemon diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/tests/test_default.py new file mode 100644 index 00000000..9f50a354 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/molecule/virtualbox/tests/test_default.py @@ -0,0 +1,65 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def include_vars(host): + if host.system_info.distribution == "redhat" \ + or host.system_info.distribution == "centos": + ansible = host.ansible('include_vars', + 'file="../../vars/RedHat.yml"', + False, + False) + if host.system_info.distribution == "debian" \ + or host.system_info.distribution == "ubuntu": + ansible = host.ansible('include_vars', + 'file="../../vars/Debian.yml"', + False, + False) + return ansible + + +def test_mongod_cnf_file(host): + if host.ansible.get_variables()['inventory_hostname'] != 'config1': + mongodb_user = include_vars(host)['ansible_facts']['mongodb_user'] + mongodb_group = include_vars(host)['ansible_facts']['mongodb_group'] + f = host.file('/etc/mongos.conf') + + assert f.exists + assert f.user == mongodb_user + assert f.group == mongodb_group + + +def test_mongod_service(host): + + if host.ansible.get_variables()['inventory_hostname'] != 'config1': + mongos_service = include_vars(host)['ansible_facts']['mongos_service'] + s = host.service(mongos_service) + + assert s.is_running + assert s.is_enabled + + +def test_mongod_port(host): + if host.ansible.get_variables()['inventory_hostname'] != 'config1': + port = include_vars(host)['ansible_facts']['mongos_port'] + s = host.socket("tcp://0.0.0.0:{0}".format(port)) + + assert s.is_listening + + +def test_mongos_shell_connectivity(host): + ''' + Tests that we can connect to mongos via the shell annd run a cmd + ''' + if host.ansible.get_variables()['inventory_hostname'] != 'config1': + port = include_vars(host)['ansible_facts']['mongos_port'] + cmd = host.run("mongo admin -username admin --password admin --port {0} --eval 'db.runCommand({{listDatabases: 1}})'".format(port)) + + assert cmd.rc == 0 + assert "config" in cmd.stdout + assert "admin" in cmd.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/tasks/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/tasks/main.yml new file mode 100644 index 00000000..cabc76df --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/tasks/main.yml @@ -0,0 +1,87 @@ +--- +# tasks file for mongodb_mongos +- name: Include OS-specific vars + include_vars: + file: "{{ lookup('first_found', params) }}" + vars: + params: + paths: + - "vars" + files: + - "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version }}.yml" + - "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml" + - "{{ ansible_facts.distribution }}.yml" + - "{{ ansible_facts.os_family }}.yml" + - default.yml + +- name: Create mongodb_group + group: + name: "{{ mongodb_group }}" + system: yes + +- name: Create mongodb_user + user: + name: "{{ mongodb_user }}" + group: "{{ mongodb_group }}" + system: yes + createhome: no + +- name: Copy keyfile to host + copy: + content: | + {{ openssl_keyfile_content }} + dest: /etc/keyfile + owner: "{{ mongodb_user }}" + group: "{{ mongodb_group }}" + mode: 0400 + notify: + - Restart mongos service + +- name: Ensure /usr/local/bin/ directory exists + file: + path: /usr/local/bin/ + state: directory + recurse: yes + +- name: Ensure mongos service pre start script exists + template: + src: mongos_pre.sh.j2 + dest: /usr/local/bin/mongos_pre.sh + owner: "{{ mongodb_user }}" + group: "{{ mongodb_group }}" + mode: 0755 + +- name: Ensure mongos.service file exists + template: + src: mongos.service.j2 + dest: /etc/systemd/system/mongos.service + owner: root + group: root + register: sysd + +- name: Run systemctl daemon-reload + systemd: + daemon_reload: yes + when: sysd is changed + +- name: Ensure mongos.conf file exists + template: + src: "{{ mongos_config_template }}" + dest: /etc/mongos.conf + owner: "{{ mongodb_user }}" + group: "{{ mongodb_group }}" + notify: + - Restart mongos service + +- name: Ensure mongos package is installed + package: + name: "{{ mongos_package }}" + register: _pkg + until: _pkg is succeeded + retries: 5 + +- name: Start mongos service + service: + name: "{{ mongos_service }}" + state: started + enabled: yes diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/templates/mongos.conf.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/templates/mongos.conf.j2 new file mode 100644 index 00000000..2b1d0112 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/templates/mongos.conf.j2 @@ -0,0 +1,14 @@ +systemLog: + destination: file + path: /var/log/mongodb/mongos.log + logAppend: true + logRotate: reopen +net: + bindIp: {{ bind_ip }} + port: {{ mongos_port }} +sharding: + configDB: "{{ config_repl_set_name }}/{{ config_servers }}" +processManagement: + timeZoneInfo: /usr/share/zoneinfo +security: + keyFile: /etc/keyfile diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/templates/mongos.service.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/templates/mongos.service.j2 new file mode 100644 index 00000000..6f1a11bc --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/templates/mongos.service.j2 @@ -0,0 +1,22 @@ +[Unit] +Description=mongos +After=syslog.target +After=network.target + +[Service] +User={{ mongodb_user }} +Group={{ mongodb_group }} +PIDFile={{ pid_file }} +PermissionsStartOnly=true +ExecStartPre=/usr/local/bin/mongos_pre.sh +ExecStart=/usr/bin/mongos --quiet \ + --config /etc/mongos.conf +LimitFSIZE=infinity +LimitCPU=infinity +LimitAS=infinity +LimitNOFILE=64000 +LimitNPROC=64000 +TasksAccounting=false + +[Install] +WantedBy=multi-user.target diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/templates/mongos_pre.sh.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/templates/mongos_pre.sh.j2 new file mode 100644 index 00000000..ea58c81a --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/templates/mongos_pre.sh.j2 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +if [ ! -d /var/log/mongodb ]; then + mkdir -p /var/log/mongodb && chown {{ mongodb_user }}:{{ mongodb_group }} /var/log/mongodb +fi diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/vars/Debian.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/vars/Debian.yml new file mode 100644 index 00000000..02e64683 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/vars/Debian.yml @@ -0,0 +1,5 @@ +--- +mongodb_user: "mongodb" +mongodb_group: "mongodb" +mongos_port: 27017 +mongos_service: "mongos" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/vars/RedHat.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/vars/RedHat.yml new file mode 100644 index 00000000..47197a81 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/vars/RedHat.yml @@ -0,0 +1,5 @@ +--- +mongodb_user: "mongod" +mongodb_group: "mongod" +mongos_port: 27017 +mongos_service: "mongos" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/vars/default.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/vars/default.yml new file mode 100644 index 00000000..47197a81 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_mongos/vars/default.yml @@ -0,0 +1,5 @@ +--- +mongodb_user: "mongod" +mongodb_group: "mongod" +mongos_port: 27017 +mongos_service: "mongos" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/.yamllint b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/.yamllint new file mode 100644 index 00000000..88276760 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/README.md b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/README.md new file mode 100644 index 00000000..27af13ad --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/README.md @@ -0,0 +1,31 @@ +mongodb_repository +================== + +Configures a repository for MongoDB on Debian and RedHat based platforms. + +Role Variables +-------------- + +mongodb_version: Version of MongoDB. Default "4.2". +debian_packages: Packages needs on Debian systems for this role. + +Example Playbook +---------------- + +Set mongodb_version to 4.0. + +```yaml + - hosts: servers + roles: + - { role: mongodb_repository, mongodb_version: "4.0" } +``` + +License +------- + +BSD + +Author Information +------------------ + +Rhys Campbell (https://github.com/rhysmeister) diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/defaults/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/defaults/main.yml new file mode 100644 index 00000000..5534901f --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/defaults/main.yml @@ -0,0 +1,6 @@ +--- +mongodb_version: "4.2" +debian_packages: + - apt-transport-https + - curl + - gnupg diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/meta/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/meta/main.yml new file mode 100644 index 00000000..ba43fdd2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/meta/main.yml @@ -0,0 +1,58 @@ +--- +galaxy_info: + author: your name + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + + min_ansible_version: 1.2 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # Optionally specify the branch Galaxy will use when accessing the GitHub + # repo for this role. During role install, if no tags are available, + # Galaxy will use this branch. During import Galaxy will access files on + # this branch. If Travis integration is configured, only notifications for this + # branch will be accepted. Otherwise, in all cases, the repo's default branch + # (usually master) will be used. + # github_branch: + + # + # platforms is a list of platforms, and each platform has a name and a list of versions. + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] +# List your role dependencies here, one per line. Be sure to remove the '[]' above, +# if you add dependencies to this list. diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/Dockerfile.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/Dockerfile.j2 new file mode 100644 index 00000000..935dd3d7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/Dockerfile.j2 @@ -0,0 +1,39 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +{% if item.env is defined %} +{% for var, value in item.env.items() %} +{% if value %} +ENV {{ var }} {{ value }} +{% endif %} +{% endfor %} +{% endif %} +# Add systemd-sysv package for Debian to get systemd working (and procps for sysctl) and netbase for firewalld +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 systemd-sysv procps netbase && apt-get clean; \ + elif [ $(command -v dnf) ] && grep -q 'platform:el8' /etc/os-release ; then dnf makecache && dnf update -y && dnf --assumeyes install python3 sudo python3-devel bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && rm -Rf /usr/share/doc && rm -Rf /usr/share/man && dnf clean all && cp /bin/true /sbin/agetty; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi + +{% if item.image == 'centos:8' %} +# Stuff for systemd https://hub.docker.com/_/centos +RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \ + systemd-tmpfiles-setup.service ] || rm -f $i; done); \ + rm -f /lib/systemd/system/multi-user.target.wants/*;\ + rm -f /etc/systemd/system/*.wants/*;\ + rm -f /lib/systemd/system/local-fs.target.wants/*; \ + rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ + rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ + rm -f /lib/systemd/system/basic.target.wants/*;\ + rm -f /lib/systemd/system/anaconda.target.wants/*; + +VOLUME [ "/sys/fs/cgroup" ] +CMD ["/sbin/init"] +{% endif %} diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/molecule.yml new file mode 100644 index 00000000..403ff875 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/molecule.yml @@ -0,0 +1,34 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos_7 + image: centos:7 + - name: centos_8 + image: centos:8 + - name: ubuntu_16 + image: ubuntu:16.04 + - name: ubuntu_18 + image: ubuntu:18.04 + - name: debian_buster + image: debian:buster + - name: debian_stretch + image: debian:stretch +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/playbook.yml new file mode 100644 index 00000000..75a509d1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/playbook.yml @@ -0,0 +1,5 @@ +--- +- name: Converge + hosts: all + roles: + - role: mongodb_repository diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/tests/test_default.py new file mode 100644 index 00000000..bfe613a4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/default/tests/test_default.py @@ -0,0 +1,67 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def include_vars(host): + ansible = host.ansible('include_vars', + 'file="../../defaults/main.yml"', + False, + False) + return ansible + + +def get_mongodb_version(host): + return include_vars(host)['ansible_facts']['mongodb_version'] + + +def test_redhat_mongodb_repository_file(host): + # with capsys.disabled(): #Disable autocapture of output and send to stdout N.B capsys must be passed into function + # print(include_vars(host)['ansible_facts']) + mongodb_version = get_mongodb_version(host) + if host.system_info.distribution == "redhat" \ + or host.system_info.distribution == "centos": + f = host.file("/etc/yum.repos.d/mongodb-{0}.repo".format(mongodb_version)) + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + assert f.mode == 0o644 + assert f.md5sum == "71c3a725d5aad794793a4b599f7564c0" + + +def test_redhat_yum_search(host): + mongodb_version = get_mongodb_version(host) + if host.system_info.distribution == "redhat" \ + or host.system_info.distribution == "centos": + cmd = host.run("yum search mongodb --disablerepo='*' \ + --enablerepo='mongodb-{0}'".format(mongodb_version)) + + assert cmd.rc == 0 + assert "MongoDB database server" in cmd.stdout + + +def test_debian_cassandra_repository_file(host): + mongodb_version = get_mongodb_version(host) + if host.system_info.distribution == "debian" \ + or host.system_info.distribution == "ubuntu": + f = host.file("/etc/apt/sources.list.d/mongodb-{0}.list".format(mongodb_version)) + + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + assert f.mode == 0o644 + assert "repo.mongodb.org" in f.content_string + assert mongodb_version in f.content_string + + +def test_debian_apt_search(host): + if host.system_info.distribution == "debian" \ + or host.system_info.distribution == "ubuntu": + cmd = host.run("apt search mongodb") + + assert cmd.rc == 0 + assert "mongodb-org-server" in cmd.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/virtualbox/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/virtualbox/molecule.yml new file mode 100644 index 00000000..14d29680 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/virtualbox/molecule.yml @@ -0,0 +1,54 @@ +--- +dependency: + name: galaxy +driver: + name: vagrant + provider: + name: virtualbox +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos-7 + box: centos/7 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-16 + box: ubuntu/xenial64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: ubuntu-18 + box: ubuntu/bionic64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-buster + box: debian/buster64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true + - name: debian-stretch + box: debian/contrib-stretch64 # Standard debian/stretch64 had issues: Unable to locate package linux-headers-4.9.0-9-amd64 + interfaces: + - network_name: private_network + type: dhcp + auto_config: true +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/virtualbox/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/virtualbox/playbook.yml new file mode 100644 index 00000000..d49d9e23 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/virtualbox/playbook.yml @@ -0,0 +1,6 @@ +--- +- name: Converge + hosts: all + become: yes + roles: + - role: mongodb_repository diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/virtualbox/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/virtualbox/tests/test_default.py new file mode 100644 index 00000000..bfe613a4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/molecule/virtualbox/tests/test_default.py @@ -0,0 +1,67 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def include_vars(host): + ansible = host.ansible('include_vars', + 'file="../../defaults/main.yml"', + False, + False) + return ansible + + +def get_mongodb_version(host): + return include_vars(host)['ansible_facts']['mongodb_version'] + + +def test_redhat_mongodb_repository_file(host): + # with capsys.disabled(): #Disable autocapture of output and send to stdout N.B capsys must be passed into function + # print(include_vars(host)['ansible_facts']) + mongodb_version = get_mongodb_version(host) + if host.system_info.distribution == "redhat" \ + or host.system_info.distribution == "centos": + f = host.file("/etc/yum.repos.d/mongodb-{0}.repo".format(mongodb_version)) + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + assert f.mode == 0o644 + assert f.md5sum == "71c3a725d5aad794793a4b599f7564c0" + + +def test_redhat_yum_search(host): + mongodb_version = get_mongodb_version(host) + if host.system_info.distribution == "redhat" \ + or host.system_info.distribution == "centos": + cmd = host.run("yum search mongodb --disablerepo='*' \ + --enablerepo='mongodb-{0}'".format(mongodb_version)) + + assert cmd.rc == 0 + assert "MongoDB database server" in cmd.stdout + + +def test_debian_cassandra_repository_file(host): + mongodb_version = get_mongodb_version(host) + if host.system_info.distribution == "debian" \ + or host.system_info.distribution == "ubuntu": + f = host.file("/etc/apt/sources.list.d/mongodb-{0}.list".format(mongodb_version)) + + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + assert f.mode == 0o644 + assert "repo.mongodb.org" in f.content_string + assert mongodb_version in f.content_string + + +def test_debian_apt_search(host): + if host.system_info.distribution == "debian" \ + or host.system_info.distribution == "ubuntu": + cmd = host.run("apt search mongodb") + + assert cmd.rc == 0 + assert "mongodb-org-server" in cmd.stdout diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/tasks/Debian.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/tasks/Debian.yml new file mode 100644 index 00000000..e6b8159d --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/tasks/Debian.yml @@ -0,0 +1,30 @@ +--- +# tasks file for mongodb_repository (Debian os_family) +- name: Install debian packages + apt: + name: "{{ debian_packages }}" + state: present + register: _apt + until: _apt is succeeded + retries: 5 + +- name: Add apt key for MongoDB repository + apt_key: + url: "https://www.mongodb.org/static/pgp/server-{{ mongodb_version }}.asc" + state: present + register: _apt + until: _apt is succeeded + retries: 5 + +- name: Ensure MongoDB apt repository exists + apt_repository: + repo: "deb{{ repo_opts }} https://repo.mongodb.org/apt/{{ ansible_facts.distribution|lower }} {{ ansible_facts.distribution_release }}/mongodb-org/{{ mongodb_version }} {{ component }}" + state: present + filename: "mongodb-{{ mongodb_version }}" + vars: + # include initial space in repo_opts + repo_opts: "{% if ansible_facts.distribution == 'Ubuntu' %} [ arch=amd64,arm64 ]{% endif %}" + component: "{% if ansible_facts.distribution == 'Ubuntu' %}multiverse{% else %}main{% endif %}" + register: _apt + until: _apt is succeeded + retries: 5 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/tasks/RedHat.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/tasks/RedHat.yml new file mode 100644 index 00000000..6a110e97 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/tasks/RedHat.yml @@ -0,0 +1,20 @@ +--- +# tasks file for mongodb_repository (RedHat os_family) +- name: Add mongodb.org gpgkey + rpm_key: + key: https://www.mongodb.org/static/pgp/server-{{ mongodb_version }}.asc + state: present + register: _yum + until: _yum is succeeded + retries: 5 + +- name: Ensure MongoDB yum repository exists + yum_repository: + name: "mongodb-{{ mongodb_version }}" + description: "Official MongoDB {{ mongodb_version }} yum repo" + baseurl: "https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/{{ mongodb_version }}/x86_64/" + gpgcheck: true + gpgkey: "https://www.mongodb.org/static/pgp/server-{{ mongodb_version }}.asc" + register: _yum + until: _yum is succeeded + retries: 5 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/tasks/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/tasks/main.yml new file mode 100644 index 00000000..bf77da35 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_repository/tasks/main.yml @@ -0,0 +1,4 @@ +--- +# tasks file for mongodb_repository +- name: Include OS-specific tasks + include_tasks: "{{ ansible_facts.os_family }}.yml" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/.yamllint b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/.yamllint new file mode 100644 index 00000000..88276760 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/README.md b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/README.md new file mode 100644 index 00000000..5f5b9f45 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/README.md @@ -0,0 +1,29 @@ +mongodb_linux +============= + +Configures SeLinux as per the instructions located at https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/ + + +Role Variables +-------------- + +required_packages: Package required for this role. Currently checkpolicy & policycoreutils-python. + +Example Playbook +---------------- + +```yaml + - hosts: servers + roles: + - "mongodb_selinux" +``` + +License +------- + +BSD + +Author Information +------------------ + +Rhys Campbell (https://github.com/rhysmeister) diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/files/compile_mongodb_selinux.sh b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/files/compile_mongodb_selinux.sh new file mode 100644 index 00000000..c403b584 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/files/compile_mongodb_selinux.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e; +set -u; + +checkmodule -M -m -o /root/mongodb_cgroup_memory.mod /root/mongodb_cgroup_memory.te +semodule_package -o /root/mongodb_cgroup_memory.pp -m /root/mongodb_cgroup_memory.mod +semodule -i /root/mongodb_cgroup_memory.pp +touch /root/mongodb_selinux.success; diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/meta/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/meta/main.yml new file mode 100644 index 00000000..ba43fdd2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/meta/main.yml @@ -0,0 +1,58 @@ +--- +galaxy_info: + author: your name + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + + min_ansible_version: 1.2 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # Optionally specify the branch Galaxy will use when accessing the GitHub + # repo for this role. During role install, if no tags are available, + # Galaxy will use this branch. During import Galaxy will access files on + # this branch. If Travis integration is configured, only notifications for this + # branch will be accepted. Otherwise, in all cases, the repo's default branch + # (usually master) will be used. + # github_branch: + + # + # platforms is a list of platforms, and each platform has a name and a list of versions. + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] +# List your role dependencies here, one per line. Be sure to remove the '[]' above, +# if you add dependencies to this list. diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/Dockerfile.j2 b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/Dockerfile.j2 new file mode 100644 index 00000000..935dd3d7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/Dockerfile.j2 @@ -0,0 +1,39 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +{% if item.env is defined %} +{% for var, value in item.env.items() %} +{% if value %} +ENV {{ var }} {{ value }} +{% endif %} +{% endfor %} +{% endif %} +# Add systemd-sysv package for Debian to get systemd working (and procps for sysctl) and netbase for firewalld +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 systemd-sysv procps netbase && apt-get clean; \ + elif [ $(command -v dnf) ] && grep -q 'platform:el8' /etc/os-release ; then dnf makecache && dnf update -y && dnf --assumeyes install python3 sudo python3-devel bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && rm -Rf /usr/share/doc && rm -Rf /usr/share/man && dnf clean all && cp /bin/true /sbin/agetty; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi + +{% if item.image == 'centos:8' %} +# Stuff for systemd https://hub.docker.com/_/centos +RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \ + systemd-tmpfiles-setup.service ] || rm -f $i; done); \ + rm -f /lib/systemd/system/multi-user.target.wants/*;\ + rm -f /etc/systemd/system/*.wants/*;\ + rm -f /lib/systemd/system/local-fs.target.wants/*; \ + rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ + rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ + rm -f /lib/systemd/system/basic.target.wants/*;\ + rm -f /lib/systemd/system/anaconda.target.wants/*; + +VOLUME [ "/sys/fs/cgroup" ] +CMD ["/sbin/init"] +{% endif %} diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/molecule.yml new file mode 100644 index 00000000..403ff875 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/molecule.yml @@ -0,0 +1,34 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos_7 + image: centos:7 + - name: centos_8 + image: centos:8 + - name: ubuntu_16 + image: ubuntu:16.04 + - name: ubuntu_18 + image: ubuntu:18.04 + - name: debian_buster + image: debian:buster + - name: debian_stretch + image: debian:stretch +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/playbook.yml new file mode 100644 index 00000000..94943c2a --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/playbook.yml @@ -0,0 +1,5 @@ +--- +- name: Converge + hosts: all + roles: + - role: mongodb_selinux diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/tests/test_default.py new file mode 100644 index 00000000..70c02eb6 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/default/tests/test_default.py @@ -0,0 +1,13 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def test_mongodb_cgroup_module_installed(host): + cmd = host.run("semodule --list-modules | grep mongodb_cgroup_memory") + + assert cmd.rc == 0 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/virtualbox/molecule.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/virtualbox/molecule.yml new file mode 100644 index 00000000..bcaaf4c4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/virtualbox/molecule.yml @@ -0,0 +1,36 @@ +--- +dependency: + name: galaxy +driver: + name: vagrant + provider: + name: virtualbox +lint: + name: yamllint + options: + config-data: + line-length: disable +platforms: + - name: centos-7 + box: centos/7 + - name: centos-8 + box: generic/centos8 + - name: ubuntu-16 + box: ubuntu/xenial64 + - name: ubuntu-18 + box: ubuntu/bionic64 + - name: debian-buster + box: debian/buster64 + - name: debian-stretch + box: debian/contrib-stretch64 # Standard debian/stretch64 had issues: Unable to locate package linux-headers-4.9.0-9-amd64 +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: false +verifier: + name: testinfra + lint: + name: flake8 + options: + ignore: 'E501' diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/virtualbox/playbook.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/virtualbox/playbook.yml new file mode 100644 index 00000000..929837d5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/virtualbox/playbook.yml @@ -0,0 +1,6 @@ +--- +- name: Converge + hosts: all + become: yes + roles: + - role: mongodb_selinux diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/virtualbox/tests/test_default.py b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/virtualbox/tests/test_default.py new file mode 100644 index 00000000..1cee4af9 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/molecule/virtualbox/tests/test_default.py @@ -0,0 +1,14 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE'] +).get_hosts('all') + + +def test_mongodb_cgroup_module_installed(host): + with host.sudo(): + cmd = host.run("semodule --list-modules | grep mongodb_cgroup_memory") + + assert cmd.rc == 0 diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/tasks/main.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/tasks/main.yml new file mode 100644 index 00000000..981e8ba8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/tasks/main.yml @@ -0,0 +1,44 @@ +--- +# tasks file for mongodb_selinux +- name: Include OS-specific vars + include_vars: + file: "{{ lookup('first_found', params) }}" + vars: + params: + paths: + - "vars" + files: + - "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version }}.yml" + - "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml" + - "{{ ansible_facts.distribution }}.yml" + - "{{ ansible_facts.os_family }}.yml" + - default.yml + +- name: Install required packages + package: + name: "{{ required_packages }}" + register: _pkg + until: _pkg is succeeded + retries: 5 + +- name: Copy custom MongoDB SeLinux Policy to Host + copy: + content: | + module mongodb_cgroup_memory 1.0; + + require { + type cgroup_t; + type mongod_t; + class dir search; + class file { getattr open read }; + } + + #============= mongod_t ============== + allow mongod_t cgroup_t:dir search; + allow mongod_t cgroup_t:file { getattr open read }; + dest: /root/mongodb_cgroup_memory.te + +- name: Compile & Install MongoDB Policy + script: files/compile_mongodb_selinux.sh + args: + creates: /root/mongodb_selinux.success diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/Debian.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/Debian.yml new file mode 100644 index 00000000..838b5143 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/Debian.yml @@ -0,0 +1,9 @@ +--- +# defaults file for mongodb_selinux +required_packages: + - "checkpolicy" + - "policycoreutils-python-utils" + - "selinux-policy-mls" + - "selinux-policy-default" + - "selinux-policy-src" + - "selinux-policy-doc" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/RedHat-7.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/RedHat-7.yml new file mode 100644 index 00000000..2b36fa9e --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/RedHat-7.yml @@ -0,0 +1,9 @@ +--- +# defaults file for mongodb_selinux +required_packages: + - "checkpolicy" + - "policycoreutils-python" + - "selinux-policy-mls" + - "selinux-policy" + - "selinux-policy-doc" + - "selinux-policy-targeted" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/RedHat-8.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/RedHat-8.yml new file mode 100644 index 00000000..71aaccb1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/RedHat-8.yml @@ -0,0 +1,9 @@ +--- +# defaults file for mongodb_selinux +required_packages: + - "checkpolicy" + - "policycoreutils-python-utils" + - "selinux-policy-mls" + - "selinux-policy" + - "selinux-policy-doc" + - "selinux-policy-targeted" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/Ubuntu-16.04.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/Ubuntu-16.04.yml new file mode 100644 index 00000000..281472a8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/Ubuntu-16.04.yml @@ -0,0 +1,9 @@ +--- +# defaults file for mongodb_selinux +required_packages: + - "checkpolicy" + - "policycoreutils" + - "selinux-policy-mls" + - "selinux-policy-default" + - "selinux-policy-src" + - "selinux-policy-doc" diff --git a/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/default.yml b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/default.yml new file mode 100644 index 00000000..bb5fce4a --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/mongodb/roles/mongodb_selinux/vars/default.yml @@ -0,0 +1,5 @@ +--- +# defaults file for mongodb_selinux +required_packages: + - "checkpolicy" + - "policycoreutils-python" |