mirror of
https://github.com/ansible-collections/community.routeros.git
synced 2025-08-01 00:35:02 +02:00
Compare commits
76 commits
Author | SHA1 | Date | |
---|---|---|---|
|
7395011b0c | ||
|
8edc8018a7 | ||
|
e78df4a4cf | ||
|
c9d15bc43a | ||
|
008b5f893a | ||
|
b70b4a72b3 | ||
|
1f38be9e56 | ||
|
e988b18acf | ||
|
6e9d2e1379 | ||
|
1c182725ce | ||
|
9099fcd698 | ||
|
852e21a2f2 | ||
|
bb7eadbc9f | ||
|
d9be02bdb8 | ||
|
3475751b30 | ||
|
6008397375 | ||
|
b751d79a98 | ||
|
aa83116c78 | ||
|
4571d777de | ||
|
c7b2275f2c | ||
|
49e4b83594 | ||
|
88806047e3 | ||
|
221a697af9 | ||
|
ab1026504c | ||
|
bfd6b0bb13 | ||
|
f5b952751e | ||
|
5b81c157fe | ||
|
08152376de | ||
|
3af45c33f1 | ||
|
e52978b6d2 | ||
|
d1db4bec92 | ||
|
180e87fd5d | ||
|
81237dbde4 | ||
|
770e4d2c8d | ||
|
4b9925ac23 | ||
|
e286d768c0 | ||
|
9dba8082f9 | ||
|
3a34752296 | ||
|
a920caa16a | ||
|
9d382a1b10 | ||
|
2b1be7f011 | ||
|
8736996317 | ||
|
30a79061f3 | ||
|
ab446b4449 | ||
|
be9a7ed3ad | ||
|
6aaead1d4a | ||
|
ffc928242b | ||
|
f54244b7d0 | ||
|
3ba33ccd99 | ||
|
e302fed6cf | ||
|
9e4b6c197d | ||
|
a9f787fd76 | ||
|
f6d50f8cc5 | ||
|
388366542d | ||
|
575af30d88 | ||
|
85d24d180e | ||
|
11454b802e | ||
|
364ef6c5fe | ||
|
1466c9f984 | ||
|
dcdca90dd0 | ||
|
4241179471 | ||
|
71882863a5 | ||
|
44e6bb6f7a | ||
|
2a3460827d | ||
|
1e0c582b98 | ||
|
539119c57d | ||
|
77de6d90bf | ||
|
995ab18e7b | ||
|
a7340eae1a | ||
|
0bf4b3ef8c | ||
|
c3e57efa9d | ||
|
8dbad9a8d4 | ||
|
c27c1906aa | ||
|
249b1a92e2 | ||
|
14d89a3cfa | ||
|
d44262d820 |
94 changed files with 2548 additions and 2191 deletions
6
.git-blame-ignore-revs
Normal file
6
.git-blame-ignore-revs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
# Reformat YAML: https://github.com/ansible-collections/community.routeros/pull/369
|
||||||
|
08152376de116e7d933d19ee25318f7a2eb222ae
|
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
|
@ -9,3 +9,7 @@ updates:
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
|
groups:
|
||||||
|
ci:
|
||||||
|
patterns:
|
||||||
|
- "*"
|
||||||
|
|
146
.github/workflows/ansible-test.yml
vendored
146
.github/workflows/ansible-test.yml
vendored
|
@ -1,146 +0,0 @@
|
||||||
---
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
# For the comprehensive list of the inputs supported by the ansible-community/ansible-test-gh-action GitHub Action, see
|
|
||||||
# https://github.com/marketplace/actions/ansible-test
|
|
||||||
|
|
||||||
name: CI
|
|
||||||
on:
|
|
||||||
# Run CI against all pushes (direct commits, also merged PRs), Pull Requests
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- stable-*
|
|
||||||
pull_request:
|
|
||||||
# Run CI once per day (at 05:15 UTC)
|
|
||||||
schedule:
|
|
||||||
- cron: '15 5 * * *'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
sanity:
|
|
||||||
name: Sanity (Ⓐ${{ matrix.ansible }})
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
ansible:
|
|
||||||
# It's important that Sanity is tested against all stable-X.Y branches
|
|
||||||
# Testing against `devel` may fail as new tests are added.
|
|
||||||
- stable-2.15
|
|
||||||
- stable-2.16
|
|
||||||
- stable-2.17
|
|
||||||
- stable-2.18
|
|
||||||
- devel
|
|
||||||
# Ansible-test on various stable branches does not yet work well with cgroups v2.
|
|
||||||
# Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04
|
|
||||||
# image for these stable branches. The list of branches where this is necessary will
|
|
||||||
# shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28
|
|
||||||
# for the latest list.
|
|
||||||
runs-on: >-
|
|
||||||
${{ contains(fromJson(
|
|
||||||
'["stable-2.9", "stable-2.10", "stable-2.11"]'
|
|
||||||
), matrix.ansible) && 'ubuntu-20.04' || 'ubuntu-latest' }}
|
|
||||||
steps:
|
|
||||||
- name: Perform sanity testing
|
|
||||||
uses: felixfontein/ansible-test-gh-action@main
|
|
||||||
with:
|
|
||||||
ansible-core-github-repository-slug: ${{ contains(fromJson('["stable-2.9", "stable-2.10", "stable-2.11"]'), matrix.ansible) && 'ansible-community/eol-ansible' || 'ansible/ansible' }}
|
|
||||||
ansible-core-version: ${{ matrix.ansible }}
|
|
||||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
testing-type: sanity
|
|
||||||
test-deps: >-
|
|
||||||
git+https://github.com/ansible-collections/ansible.utils.git,main
|
|
||||||
git+https://github.com/ansible-collections/ansible.netcommon.git,main
|
|
||||||
|
|
||||||
units:
|
|
||||||
# Ansible-test on various stable branches does not yet work well with cgroups v2.
|
|
||||||
# Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04
|
|
||||||
# image for these stable branches. The list of branches where this is necessary will
|
|
||||||
# shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28
|
|
||||||
# for the latest list.
|
|
||||||
runs-on: >-
|
|
||||||
${{ contains(fromJson(
|
|
||||||
'["stable-2.9", "stable-2.10", "stable-2.11"]'
|
|
||||||
), matrix.ansible) && 'ubuntu-20.04' || 'ubuntu-latest' }}
|
|
||||||
name: Units (Ⓐ${{ matrix.ansible }})
|
|
||||||
strategy:
|
|
||||||
# As soon as the first unit test fails, cancel the others to free up the CI queue
|
|
||||||
fail-fast: true
|
|
||||||
matrix:
|
|
||||||
ansible:
|
|
||||||
- stable-2.16
|
|
||||||
- stable-2.17
|
|
||||||
- stable-2.18
|
|
||||||
- devel
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: >-
|
|
||||||
Perform unit testing against
|
|
||||||
Ansible version ${{ matrix.ansible }}
|
|
||||||
uses: felixfontein/ansible-test-gh-action@main
|
|
||||||
with:
|
|
||||||
ansible-core-github-repository-slug: ${{ contains(fromJson('["stable-2.9", "stable-2.10", "stable-2.11"]'), matrix.ansible) && 'ansible-community/eol-ansible' || 'ansible/ansible' }}
|
|
||||||
ansible-core-version: ${{ matrix.ansible }}
|
|
||||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
testing-type: units
|
|
||||||
test-deps: >-
|
|
||||||
git+https://github.com/ansible-collections/ansible.utils.git,main
|
|
||||||
git+https://github.com/ansible-collections/ansible.netcommon.git,main
|
|
||||||
|
|
||||||
integration:
|
|
||||||
# Ansible-test on various stable branches does not yet work well with cgroups v2.
|
|
||||||
# Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04
|
|
||||||
# image for these stable branches. The list of branches where this is necessary will
|
|
||||||
# shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28
|
|
||||||
# for the latest list.
|
|
||||||
runs-on: >-
|
|
||||||
${{ contains(fromJson(
|
|
||||||
'["stable-2.9", "stable-2.10", "stable-2.11"]'
|
|
||||||
), matrix.ansible) && 'ubuntu-20.04' || 'ubuntu-latest' }}
|
|
||||||
name: I (Ⓐ${{ matrix.ansible }}+py${{ matrix.python }})
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
ansible:
|
|
||||||
- devel
|
|
||||||
python:
|
|
||||||
- "3.10"
|
|
||||||
- "3.11"
|
|
||||||
- "3.12"
|
|
||||||
- "3.13"
|
|
||||||
include:
|
|
||||||
# 2.15
|
|
||||||
- ansible: stable-2.15
|
|
||||||
python: "2.7"
|
|
||||||
- ansible: stable-2.15
|
|
||||||
python: "3.6"
|
|
||||||
- ansible: stable-2.15
|
|
||||||
python: "3.7"
|
|
||||||
# 2.16
|
|
||||||
- ansible: stable-2.16
|
|
||||||
python: "3.10"
|
|
||||||
# 2.17
|
|
||||||
- ansible: stable-2.17
|
|
||||||
python: "3.8"
|
|
||||||
# 2.18
|
|
||||||
- ansible: stable-2.18
|
|
||||||
python: "3.9"
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: >-
|
|
||||||
Perform integration testing against
|
|
||||||
Ansible version ${{ matrix.ansible }}
|
|
||||||
under Python ${{ matrix.python }}
|
|
||||||
uses: felixfontein/ansible-test-gh-action@main
|
|
||||||
with:
|
|
||||||
ansible-core-github-repository-slug: ${{ contains(fromJson('["stable-2.9", "stable-2.10", "stable-2.11"]'), matrix.ansible) && 'ansible-community/eol-ansible' || 'ansible/ansible' }}
|
|
||||||
ansible-core-version: ${{ matrix.ansible }}
|
|
||||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
integration-continue-on-error: 'false'
|
|
||||||
integration-diff: 'false'
|
|
||||||
integration-retry-on-error: 'true'
|
|
||||||
test-deps: >-
|
|
||||||
git+https://github.com/ansible-collections/ansible.utils.git,main
|
|
||||||
git+https://github.com/ansible-collections/ansible.netcommon.git,main
|
|
||||||
target-python-version: ${{ matrix.python }}
|
|
||||||
testing-type: integration
|
|
2
.github/workflows/docs-pr.yml
vendored
2
.github/workflows/docs-pr.yml
vendored
|
@ -7,7 +7,7 @@ name: Collection Docs
|
||||||
concurrency:
|
concurrency:
|
||||||
group: docs-pr-${{ github.head_ref }}
|
group: docs-pr-${{ github.head_ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
on:
|
'on':
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
types: [opened, synchronize, reopened, closed]
|
types: [opened, synchronize, reopened, closed]
|
||||||
|
|
||||||
|
|
2
.github/workflows/docs-push.yml
vendored
2
.github/workflows/docs-push.yml
vendored
|
@ -7,7 +7,7 @@ name: Collection Docs
|
||||||
concurrency:
|
concurrency:
|
||||||
group: docs-push-${{ github.sha }}
|
group: docs-push-${{ github.sha }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
on:
|
'on':
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
|
158
.github/workflows/ee.yml
vendored
158
.github/workflows/ee.yml
vendored
|
@ -1,158 +0,0 @@
|
||||||
---
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
name: execution environment
|
|
||||||
on:
|
|
||||||
# Run CI against all pushes (direct commits, also merged PRs), Pull Requests
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- stable-*
|
|
||||||
pull_request:
|
|
||||||
# Run CI once per day (at 05:15 UTC)
|
|
||||||
# This ensures that even if there haven't been commits that we are still testing against latest version of ansible-builder
|
|
||||||
schedule:
|
|
||||||
- cron: '15 5 * * *'
|
|
||||||
|
|
||||||
env:
|
|
||||||
NAMESPACE: community
|
|
||||||
COLLECTION_NAME: routeros
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Build and test EE (${{ matrix.name }})
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
name:
|
|
||||||
- ''
|
|
||||||
ansible_core:
|
|
||||||
- ''
|
|
||||||
ansible_runner:
|
|
||||||
- ''
|
|
||||||
base_image:
|
|
||||||
- ''
|
|
||||||
pre_base:
|
|
||||||
- ''
|
|
||||||
extra_vars:
|
|
||||||
- ''
|
|
||||||
other_deps:
|
|
||||||
- ''
|
|
||||||
exclude:
|
|
||||||
- ansible_core: ''
|
|
||||||
include:
|
|
||||||
- name: ansible-core devel @ RHEL UBI 9
|
|
||||||
ansible_core: https://github.com/ansible/ansible/archive/devel.tar.gz
|
|
||||||
ansible_runner: ansible-runner
|
|
||||||
other_deps: |2
|
|
||||||
python_interpreter:
|
|
||||||
package_system: python3.11 python3.11-pip python3.11-wheel python3.11-cryptography
|
|
||||||
python_path: "/usr/bin/python3.11"
|
|
||||||
base_image: docker.io/redhat/ubi9:latest
|
|
||||||
pre_base: '"#"'
|
|
||||||
- name: ansible-core 2.15 @ Rocky Linux 9
|
|
||||||
ansible_core: https://github.com/ansible/ansible/archive/stable-2.15.tar.gz
|
|
||||||
ansible_runner: ansible-runner
|
|
||||||
base_image: quay.io/rockylinux/rockylinux:9
|
|
||||||
pre_base: '"#"'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
path: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }}
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.11'
|
|
||||||
|
|
||||||
- name: Install ansible-builder and ansible-navigator
|
|
||||||
run: pip install ansible-builder ansible-navigator
|
|
||||||
|
|
||||||
- name: Verify requirements
|
|
||||||
run: ansible-builder introspect --sanitize .
|
|
||||||
|
|
||||||
- name: Make sure galaxy.yml has version entry
|
|
||||||
run: >-
|
|
||||||
python -c
|
|
||||||
'import yaml ;
|
|
||||||
f = open("galaxy.yml", "rb") ;
|
|
||||||
data = yaml.safe_load(f) ;
|
|
||||||
f.close() ;
|
|
||||||
data["version"] = data.get("version") or "0.0.1" ;
|
|
||||||
f = open("galaxy.yml", "wb") ;
|
|
||||||
f.write(yaml.dump(data).encode("utf-8")) ;
|
|
||||||
f.close() ;
|
|
||||||
'
|
|
||||||
working-directory: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }}
|
|
||||||
|
|
||||||
- name: Build collection
|
|
||||||
run: |
|
|
||||||
ansible-galaxy collection build --output-path ../../../
|
|
||||||
working-directory: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }}
|
|
||||||
|
|
||||||
- name: Create files for building execution environment
|
|
||||||
run: |
|
|
||||||
COLLECTION_FILENAME="$(ls "${{ env.NAMESPACE }}-${{ env.COLLECTION_NAME }}"-*.tar.gz)"
|
|
||||||
|
|
||||||
# EE config
|
|
||||||
cat > execution-environment.yml <<EOF
|
|
||||||
---
|
|
||||||
version: 3
|
|
||||||
dependencies:
|
|
||||||
ansible_core:
|
|
||||||
package_pip: ${{ matrix.ansible_core }}
|
|
||||||
ansible_runner:
|
|
||||||
package_pip: ${{ matrix.ansible_runner }}
|
|
||||||
galaxy: requirements.yml
|
|
||||||
${{ matrix.other_deps }}
|
|
||||||
|
|
||||||
images:
|
|
||||||
base_image:
|
|
||||||
name: ${{ matrix.base_image }}
|
|
||||||
|
|
||||||
additional_build_files:
|
|
||||||
- src: ${COLLECTION_FILENAME}
|
|
||||||
dest: src
|
|
||||||
|
|
||||||
additional_build_steps:
|
|
||||||
prepend_base:
|
|
||||||
- ${{ matrix.pre_base }}
|
|
||||||
EOF
|
|
||||||
echo "::group::execution-environment.yml"
|
|
||||||
cat execution-environment.yml
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
# Requirements
|
|
||||||
cat > requirements.yml <<EOF
|
|
||||||
---
|
|
||||||
collections:
|
|
||||||
- name: src/${COLLECTION_FILENAME}
|
|
||||||
type: file
|
|
||||||
EOF
|
|
||||||
echo "::group::requirements.yml"
|
|
||||||
cat requirements.yml
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
- name: Build image based on ${{ matrix.base_image }}
|
|
||||||
run: |
|
|
||||||
ansible-builder build --verbosity 3 --tag test-ee:latest --container-runtime docker
|
|
||||||
|
|
||||||
- name: Show images
|
|
||||||
run: docker image ls
|
|
||||||
|
|
||||||
- name: Run basic tests
|
|
||||||
run: >
|
|
||||||
ansible-navigator run
|
|
||||||
--mode stdout
|
|
||||||
--container-engine docker
|
|
||||||
--pull-policy never
|
|
||||||
--set-environment-variable ANSIBLE_PRIVATE_ROLE_VARS=true
|
|
||||||
--execution-environment-image test-ee:latest
|
|
||||||
-v
|
|
||||||
all.yml
|
|
||||||
${{ matrix.extra_vars }}
|
|
||||||
working-directory: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }}/tests/ee
|
|
51
.github/workflows/extra-tests.yml
vendored
51
.github/workflows/extra-tests.yml
vendored
|
@ -1,51 +0,0 @@
|
||||||
---
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
name: extra-tests
|
|
||||||
on:
|
|
||||||
# Run CI against all pushes (direct commits, also merged PRs), Pull Requests
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- stable-*
|
|
||||||
pull_request:
|
|
||||||
# Run CI once per day (at 05:15 UTC)
|
|
||||||
# This ensures that even if there haven't been commits that we are still testing against latest version of ansible-test for each ansible-base version
|
|
||||||
schedule:
|
|
||||||
- cron: '15 5 * * *'
|
|
||||||
env:
|
|
||||||
NAMESPACE: community
|
|
||||||
COLLECTION_NAME: routeros
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
extra-sanity:
|
|
||||||
name: Extra Sanity
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
path: ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}}
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.11'
|
|
||||||
|
|
||||||
- name: Install ansible-core
|
|
||||||
run: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
|
|
||||||
|
|
||||||
- name: Install collection dependencies
|
|
||||||
run: |
|
|
||||||
git clone --depth=1 --single-branch https://github.com/ansible-collections/community.internal_test_tools.git ./ansible_collections/community/internal_test_tools
|
|
||||||
git clone --depth=1 --single-branch https://github.com/ansible-collections/ansible.netcommon.git ./ansible_collections/ansible/netcommon
|
|
||||||
git clone --depth=1 --single-branch https://github.com/ansible-collections/ansible.utils.git ./ansible_collections/ansible/utils
|
|
||||||
# NOTE: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
|
|
||||||
# run: ansible-galaxy collection install community.internal_test_tools ansible.netcommon -p .
|
|
||||||
|
|
||||||
- name: Run sanity tests
|
|
||||||
run: ../../community/internal_test_tools/tools/run.py --color
|
|
||||||
working-directory: ./ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}}
|
|
20
.github/workflows/import-galaxy.yml
vendored
20
.github/workflows/import-galaxy.yml
vendored
|
@ -1,20 +0,0 @@
|
||||||
---
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
name: import-galaxy
|
|
||||||
'on':
|
|
||||||
# Run CI against all pushes (direct commits, also merged PRs) to main, and all Pull Requests
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- stable-*
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
import-galaxy:
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
name: Test to import built collection artifact with Galaxy importer
|
|
||||||
uses: ansible-community/github-action-test-galaxy-import/.github/workflows/test-galaxy-import.yml@main
|
|
35
.github/workflows/nox.yml
vendored
Normal file
35
.github/workflows/nox.yml
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
name: nox
|
||||||
|
'on':
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- stable-*
|
||||||
|
pull_request:
|
||||||
|
# Run CI once per day (at 05:15 UTC)
|
||||||
|
schedule:
|
||||||
|
- cron: '15 5 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
nox:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: "Run extra sanity tests"
|
||||||
|
steps:
|
||||||
|
- name: Check out collection
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
- name: Run nox
|
||||||
|
uses: ansible-community/antsibull-nox@main
|
||||||
|
|
||||||
|
ansible-test:
|
||||||
|
uses: ansible-community/antsibull-nox/.github/workflows/reusable-nox-matrix.yml@main
|
||||||
|
with:
|
||||||
|
upload-codecov: true
|
||||||
|
secrets:
|
||||||
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
31
.github/workflows/reuse.yml
vendored
31
.github/workflows/reuse.yml
vendored
|
@ -1,31 +0,0 @@
|
||||||
---
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
name: Verify REUSE
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- stable-*
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- stable-*
|
|
||||||
# Run CI once per day (at 05:15 UTC)
|
|
||||||
schedule:
|
|
||||||
- cron: '15 5 * * *'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check:
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: REUSE Compliance Check
|
|
||||||
uses: fsfe/reuse-action@v4
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
/tests/output/
|
/tests/output/
|
||||||
/changelogs/.plugin-cache.yaml
|
/changelogs/.plugin-cache.yaml
|
||||||
|
/tests/integration/inventory
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
|
||||||
|
|
||||||
Files: changelogs/fragments/*
|
|
||||||
Copyright: Ansible Project
|
|
||||||
License: GPL-3.0-or-later
|
|
53
.yamllint
Normal file
53
.yamllint
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
# SPDX-FileCopyrightText: 2025 Felix Fontein <felix@fontein.de>
|
||||||
|
|
||||||
|
extends: default
|
||||||
|
|
||||||
|
ignore: |
|
||||||
|
/changelogs/
|
||||||
|
|
||||||
|
rules:
|
||||||
|
line-length:
|
||||||
|
max: 300
|
||||||
|
level: error
|
||||||
|
document-start:
|
||||||
|
present: true
|
||||||
|
document-end: false
|
||||||
|
truthy:
|
||||||
|
level: error
|
||||||
|
allowed-values:
|
||||||
|
- 'true'
|
||||||
|
- 'false'
|
||||||
|
indentation:
|
||||||
|
spaces: 2
|
||||||
|
indent-sequences: true
|
||||||
|
key-duplicates: enable
|
||||||
|
trailing-spaces: enable
|
||||||
|
new-line-at-end-of-file: disable
|
||||||
|
hyphens:
|
||||||
|
max-spaces-after: 1
|
||||||
|
empty-lines:
|
||||||
|
max: 2
|
||||||
|
max-start: 0
|
||||||
|
max-end: 0
|
||||||
|
commas:
|
||||||
|
max-spaces-before: 0
|
||||||
|
min-spaces-after: 1
|
||||||
|
max-spaces-after: 1
|
||||||
|
colons:
|
||||||
|
max-spaces-before: 0
|
||||||
|
max-spaces-after: 1
|
||||||
|
brackets:
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 0
|
||||||
|
braces:
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 1
|
||||||
|
octal-values:
|
||||||
|
forbid-implicit-octal: true
|
||||||
|
forbid-explicit-octal: true
|
||||||
|
comments:
|
||||||
|
min-spaces-from-content: 1
|
||||||
|
comments-indentation: false
|
54
.yamllint-docs
Normal file
54
.yamllint-docs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
---
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
# SPDX-FileCopyrightText: 2025 Felix Fontein <felix@fontein.de>
|
||||||
|
|
||||||
|
extends: default
|
||||||
|
|
||||||
|
ignore: |
|
||||||
|
/changelogs/
|
||||||
|
|
||||||
|
rules:
|
||||||
|
line-length:
|
||||||
|
max: 160
|
||||||
|
level: error
|
||||||
|
document-start:
|
||||||
|
present: false
|
||||||
|
document-end:
|
||||||
|
present: false
|
||||||
|
truthy:
|
||||||
|
level: error
|
||||||
|
allowed-values:
|
||||||
|
- 'true'
|
||||||
|
- 'false'
|
||||||
|
indentation:
|
||||||
|
spaces: 2
|
||||||
|
indent-sequences: true
|
||||||
|
key-duplicates: enable
|
||||||
|
trailing-spaces: enable
|
||||||
|
new-line-at-end-of-file: disable
|
||||||
|
hyphens:
|
||||||
|
max-spaces-after: 1
|
||||||
|
empty-lines:
|
||||||
|
max: 2
|
||||||
|
max-start: 0
|
||||||
|
max-end: 0
|
||||||
|
commas:
|
||||||
|
max-spaces-before: 0
|
||||||
|
min-spaces-after: 1
|
||||||
|
max-spaces-after: 1
|
||||||
|
colons:
|
||||||
|
max-spaces-before: 0
|
||||||
|
max-spaces-after: 1
|
||||||
|
brackets:
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 0
|
||||||
|
braces:
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 1
|
||||||
|
octal-values:
|
||||||
|
forbid-implicit-octal: true
|
||||||
|
forbid-explicit-octal: true
|
||||||
|
comments:
|
||||||
|
min-spaces-from-content: 1
|
||||||
|
comments-indentation: false
|
54
.yamllint-examples
Normal file
54
.yamllint-examples
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
---
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
# SPDX-FileCopyrightText: 2025 Felix Fontein <felix@fontein.de>
|
||||||
|
|
||||||
|
extends: default
|
||||||
|
|
||||||
|
ignore: |
|
||||||
|
/changelogs/
|
||||||
|
|
||||||
|
rules:
|
||||||
|
line-length:
|
||||||
|
max: 160
|
||||||
|
level: error
|
||||||
|
document-start:
|
||||||
|
present: true
|
||||||
|
document-end:
|
||||||
|
present: false
|
||||||
|
truthy:
|
||||||
|
level: error
|
||||||
|
allowed-values:
|
||||||
|
- 'true'
|
||||||
|
- 'false'
|
||||||
|
indentation:
|
||||||
|
spaces: 2
|
||||||
|
indent-sequences: true
|
||||||
|
key-duplicates: enable
|
||||||
|
trailing-spaces: enable
|
||||||
|
new-line-at-end-of-file: disable
|
||||||
|
hyphens:
|
||||||
|
max-spaces-after: 1
|
||||||
|
empty-lines:
|
||||||
|
max: 2
|
||||||
|
max-start: 0
|
||||||
|
max-end: 0
|
||||||
|
commas:
|
||||||
|
max-spaces-before: 0
|
||||||
|
min-spaces-after: 1
|
||||||
|
max-spaces-after: 1
|
||||||
|
colons:
|
||||||
|
max-spaces-before: 0
|
||||||
|
max-spaces-after: 1
|
||||||
|
brackets:
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 0
|
||||||
|
braces:
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 1
|
||||||
|
octal-values:
|
||||||
|
forbid-implicit-octal: true
|
||||||
|
forbid-explicit-octal: true
|
||||||
|
comments:
|
||||||
|
min-spaces-from-content: 1
|
||||||
|
comments-indentation: false
|
53
.yamllint-extra-docs
Normal file
53
.yamllint-extra-docs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
# SPDX-FileCopyrightText: 2025 Felix Fontein <felix@fontein.de>
|
||||||
|
|
||||||
|
extends: default
|
||||||
|
|
||||||
|
ignore: |
|
||||||
|
/changelogs/
|
||||||
|
|
||||||
|
rules:
|
||||||
|
line-length:
|
||||||
|
max: 160
|
||||||
|
level: error
|
||||||
|
document-start: disable
|
||||||
|
document-end:
|
||||||
|
present: false
|
||||||
|
truthy:
|
||||||
|
level: error
|
||||||
|
allowed-values:
|
||||||
|
- 'true'
|
||||||
|
- 'false'
|
||||||
|
indentation:
|
||||||
|
spaces: 2
|
||||||
|
indent-sequences: true
|
||||||
|
key-duplicates: enable
|
||||||
|
trailing-spaces: enable
|
||||||
|
new-line-at-end-of-file: disable
|
||||||
|
hyphens:
|
||||||
|
max-spaces-after: 1
|
||||||
|
empty-lines:
|
||||||
|
max: 2
|
||||||
|
max-start: 0
|
||||||
|
max-end: 0
|
||||||
|
commas:
|
||||||
|
max-spaces-before: 0
|
||||||
|
min-spaces-after: 1
|
||||||
|
max-spaces-after: 1
|
||||||
|
colons:
|
||||||
|
max-spaces-before: 0
|
||||||
|
max-spaces-after: 1
|
||||||
|
brackets:
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 0
|
||||||
|
braces:
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 1
|
||||||
|
octal-values:
|
||||||
|
forbid-implicit-octal: true
|
||||||
|
forbid-explicit-octal: true
|
||||||
|
comments:
|
||||||
|
min-spaces-from-content: 1
|
||||||
|
comments-indentation: false
|
499
CHANGELOG.md
499
CHANGELOG.md
|
@ -2,132 +2,297 @@
|
||||||
|
|
||||||
**Topics**
|
**Topics**
|
||||||
|
|
||||||
- <a href="#v3-0-0">v3\.0\.0</a>
|
- <a href="#v3-8-1">v3\.8\.1</a>
|
||||||
- <a href="#release-summary">Release Summary</a>
|
- <a href="#release-summary">Release Summary</a>
|
||||||
|
- <a href="#bugfixes">Bugfixes</a>
|
||||||
|
- <a href="#v3-8-0">v3\.8\.0</a>
|
||||||
|
- <a href="#release-summary-1">Release Summary</a>
|
||||||
|
- <a href="#minor-changes">Minor Changes</a>
|
||||||
|
- <a href="#v3-7-0">v3\.7\.0</a>
|
||||||
|
- <a href="#release-summary-2">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-1">Minor Changes</a>
|
||||||
|
- <a href="#v3-6-0">v3\.6\.0</a>
|
||||||
|
- <a href="#release-summary-3">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-2">Minor Changes</a>
|
||||||
|
- <a href="#v3-5-0">v3\.5\.0</a>
|
||||||
|
- <a href="#release-summary-4">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-3">Minor Changes</a>
|
||||||
|
- <a href="#v3-4-0">v3\.4\.0</a>
|
||||||
|
- <a href="#release-summary-5">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-4">Minor Changes</a>
|
||||||
|
- <a href="#bugfixes-1">Bugfixes</a>
|
||||||
|
- <a href="#v3-3-0">v3\.3\.0</a>
|
||||||
|
- <a href="#release-summary-6">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-5">Minor Changes</a>
|
||||||
|
- <a href="#v3-2-0">v3\.2\.0</a>
|
||||||
|
- <a href="#release-summary-7">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-6">Minor Changes</a>
|
||||||
|
- <a href="#v3-1-0">v3\.1\.0</a>
|
||||||
|
- <a href="#release-summary-8">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-7">Minor Changes</a>
|
||||||
|
- <a href="#bugfixes-2">Bugfixes</a>
|
||||||
|
- <a href="#v3-0-0">v3\.0\.0</a>
|
||||||
|
- <a href="#release-summary-9">Release Summary</a>
|
||||||
- <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
|
- <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
|
||||||
- <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
|
- <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
|
||||||
- <a href="#v2-20-0">v2\.20\.0</a>
|
- <a href="#v2-20-0">v2\.20\.0</a>
|
||||||
- <a href="#release-summary-1">Release Summary</a>
|
|
||||||
- <a href="#minor-changes">Minor Changes</a>
|
|
||||||
- <a href="#v2-19-0">v2\.19\.0</a>
|
|
||||||
- <a href="#release-summary-2">Release Summary</a>
|
|
||||||
- <a href="#minor-changes-1">Minor Changes</a>
|
|
||||||
- <a href="#v2-18-0">v2\.18\.0</a>
|
|
||||||
- <a href="#release-summary-3">Release Summary</a>
|
|
||||||
- <a href="#minor-changes-2">Minor Changes</a>
|
|
||||||
- <a href="#deprecated-features">Deprecated Features</a>
|
|
||||||
- <a href="#bugfixes">Bugfixes</a>
|
|
||||||
- <a href="#v2-17-0">v2\.17\.0</a>
|
|
||||||
- <a href="#release-summary-4">Release Summary</a>
|
|
||||||
- <a href="#minor-changes-3">Minor Changes</a>
|
|
||||||
- <a href="#v2-16-0">v2\.16\.0</a>
|
|
||||||
- <a href="#release-summary-5">Release Summary</a>
|
|
||||||
- <a href="#minor-changes-4">Minor Changes</a>
|
|
||||||
- <a href="#v2-15-0">v2\.15\.0</a>
|
|
||||||
- <a href="#release-summary-6">Release Summary</a>
|
|
||||||
- <a href="#minor-changes-5">Minor Changes</a>
|
|
||||||
- <a href="#v2-14-0">v2\.14\.0</a>
|
|
||||||
- <a href="#release-summary-7">Release Summary</a>
|
|
||||||
- <a href="#minor-changes-6">Minor Changes</a>
|
|
||||||
- <a href="#v2-13-0">v2\.13\.0</a>
|
|
||||||
- <a href="#release-summary-8">Release Summary</a>
|
|
||||||
- <a href="#minor-changes-7">Minor Changes</a>
|
|
||||||
- <a href="#bugfixes-1">Bugfixes</a>
|
|
||||||
- <a href="#v2-12-0">v2\.12\.0</a>
|
|
||||||
- <a href="#release-summary-9">Release Summary</a>
|
|
||||||
- <a href="#minor-changes-8">Minor Changes</a>
|
|
||||||
- <a href="#v2-11-0">v2\.11\.0</a>
|
|
||||||
- <a href="#release-summary-10">Release Summary</a>
|
- <a href="#release-summary-10">Release Summary</a>
|
||||||
- <a href="#minor-changes-9">Minor Changes</a>
|
- <a href="#minor-changes-8">Minor Changes</a>
|
||||||
- <a href="#v2-10-0">v2\.10\.0</a>
|
- <a href="#v2-19-0">v2\.19\.0</a>
|
||||||
- <a href="#release-summary-11">Release Summary</a>
|
- <a href="#release-summary-11">Release Summary</a>
|
||||||
- <a href="#minor-changes-10">Minor Changes</a>
|
- <a href="#minor-changes-9">Minor Changes</a>
|
||||||
- <a href="#bugfixes-2">Bugfixes</a>
|
- <a href="#v2-18-0">v2\.18\.0</a>
|
||||||
- <a href="#v2-9-0">v2\.9\.0</a>
|
|
||||||
- <a href="#release-summary-12">Release Summary</a>
|
- <a href="#release-summary-12">Release Summary</a>
|
||||||
- <a href="#minor-changes-11">Minor Changes</a>
|
- <a href="#minor-changes-10">Minor Changes</a>
|
||||||
|
- <a href="#deprecated-features">Deprecated Features</a>
|
||||||
- <a href="#bugfixes-3">Bugfixes</a>
|
- <a href="#bugfixes-3">Bugfixes</a>
|
||||||
- <a href="#v2-8-3">v2\.8\.3</a>
|
- <a href="#v2-17-0">v2\.17\.0</a>
|
||||||
- <a href="#release-summary-13">Release Summary</a>
|
- <a href="#release-summary-13">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-11">Minor Changes</a>
|
||||||
|
- <a href="#v2-16-0">v2\.16\.0</a>
|
||||||
|
- <a href="#release-summary-14">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-12">Minor Changes</a>
|
||||||
|
- <a href="#v2-15-0">v2\.15\.0</a>
|
||||||
|
- <a href="#release-summary-15">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-13">Minor Changes</a>
|
||||||
|
- <a href="#v2-14-0">v2\.14\.0</a>
|
||||||
|
- <a href="#release-summary-16">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-14">Minor Changes</a>
|
||||||
|
- <a href="#v2-13-0">v2\.13\.0</a>
|
||||||
|
- <a href="#release-summary-17">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-15">Minor Changes</a>
|
||||||
|
- <a href="#bugfixes-4">Bugfixes</a>
|
||||||
|
- <a href="#v2-12-0">v2\.12\.0</a>
|
||||||
|
- <a href="#release-summary-18">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-16">Minor Changes</a>
|
||||||
|
- <a href="#v2-11-0">v2\.11\.0</a>
|
||||||
|
- <a href="#release-summary-19">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-17">Minor Changes</a>
|
||||||
|
- <a href="#v2-10-0">v2\.10\.0</a>
|
||||||
|
- <a href="#release-summary-20">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-18">Minor Changes</a>
|
||||||
|
- <a href="#bugfixes-5">Bugfixes</a>
|
||||||
|
- <a href="#v2-9-0">v2\.9\.0</a>
|
||||||
|
- <a href="#release-summary-21">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-19">Minor Changes</a>
|
||||||
|
- <a href="#bugfixes-6">Bugfixes</a>
|
||||||
|
- <a href="#v2-8-3">v2\.8\.3</a>
|
||||||
|
- <a href="#release-summary-22">Release Summary</a>
|
||||||
- <a href="#known-issues">Known Issues</a>
|
- <a href="#known-issues">Known Issues</a>
|
||||||
- <a href="#v2-8-2">v2\.8\.2</a>
|
- <a href="#v2-8-2">v2\.8\.2</a>
|
||||||
- <a href="#release-summary-14">Release Summary</a>
|
- <a href="#release-summary-23">Release Summary</a>
|
||||||
- <a href="#bugfixes-4">Bugfixes</a>
|
|
||||||
- <a href="#v2-8-1">v2\.8\.1</a>
|
|
||||||
- <a href="#release-summary-15">Release Summary</a>
|
|
||||||
- <a href="#bugfixes-5">Bugfixes</a>
|
|
||||||
- <a href="#v2-8-0">v2\.8\.0</a>
|
|
||||||
- <a href="#release-summary-16">Release Summary</a>
|
|
||||||
- <a href="#minor-changes-12">Minor Changes</a>
|
|
||||||
- <a href="#bugfixes-6">Bugfixes</a>
|
|
||||||
- <a href="#v2-7-0">v2\.7\.0</a>
|
|
||||||
- <a href="#release-summary-17">Release Summary</a>
|
|
||||||
- <a href="#minor-changes-13">Minor Changes</a>
|
|
||||||
- <a href="#bugfixes-7">Bugfixes</a>
|
- <a href="#bugfixes-7">Bugfixes</a>
|
||||||
- <a href="#v2-6-0">v2\.6\.0</a>
|
- <a href="#v2-8-1">v2\.8\.1</a>
|
||||||
- <a href="#release-summary-18">Release Summary</a>
|
- <a href="#release-summary-24">Release Summary</a>
|
||||||
- <a href="#minor-changes-14">Minor Changes</a>
|
|
||||||
- <a href="#bugfixes-8">Bugfixes</a>
|
- <a href="#bugfixes-8">Bugfixes</a>
|
||||||
- <a href="#v2-5-0">v2\.5\.0</a>
|
- <a href="#v2-8-0">v2\.8\.0</a>
|
||||||
- <a href="#release-summary-19">Release Summary</a>
|
- <a href="#release-summary-25">Release Summary</a>
|
||||||
- <a href="#minor-changes-15">Minor Changes</a>
|
- <a href="#minor-changes-20">Minor Changes</a>
|
||||||
- <a href="#bugfixes-9">Bugfixes</a>
|
- <a href="#bugfixes-9">Bugfixes</a>
|
||||||
- <a href="#v2-4-0">v2\.4\.0</a>
|
- <a href="#v2-7-0">v2\.7\.0</a>
|
||||||
- <a href="#release-summary-20">Release Summary</a>
|
- <a href="#release-summary-26">Release Summary</a>
|
||||||
- <a href="#minor-changes-16">Minor Changes</a>
|
- <a href="#minor-changes-21">Minor Changes</a>
|
||||||
- <a href="#bugfixes-10">Bugfixes</a>
|
- <a href="#bugfixes-10">Bugfixes</a>
|
||||||
|
- <a href="#v2-6-0">v2\.6\.0</a>
|
||||||
|
- <a href="#release-summary-27">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-22">Minor Changes</a>
|
||||||
|
- <a href="#bugfixes-11">Bugfixes</a>
|
||||||
|
- <a href="#v2-5-0">v2\.5\.0</a>
|
||||||
|
- <a href="#release-summary-28">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-23">Minor Changes</a>
|
||||||
|
- <a href="#bugfixes-12">Bugfixes</a>
|
||||||
|
- <a href="#v2-4-0">v2\.4\.0</a>
|
||||||
|
- <a href="#release-summary-29">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-24">Minor Changes</a>
|
||||||
|
- <a href="#bugfixes-13">Bugfixes</a>
|
||||||
- <a href="#known-issues-1">Known Issues</a>
|
- <a href="#known-issues-1">Known Issues</a>
|
||||||
- <a href="#v2-3-1">v2\.3\.1</a>
|
- <a href="#v2-3-1">v2\.3\.1</a>
|
||||||
- <a href="#release-summary-21">Release Summary</a>
|
- <a href="#release-summary-30">Release Summary</a>
|
||||||
- <a href="#known-issues-2">Known Issues</a>
|
- <a href="#known-issues-2">Known Issues</a>
|
||||||
- <a href="#v2-3-0">v2\.3\.0</a>
|
- <a href="#v2-3-0">v2\.3\.0</a>
|
||||||
- <a href="#release-summary-22">Release Summary</a>
|
- <a href="#release-summary-31">Release Summary</a>
|
||||||
- <a href="#minor-changes-17">Minor Changes</a>
|
- <a href="#minor-changes-25">Minor Changes</a>
|
||||||
- <a href="#bugfixes-11">Bugfixes</a>
|
- <a href="#bugfixes-14">Bugfixes</a>
|
||||||
- <a href="#v2-2-1">v2\.2\.1</a>
|
- <a href="#v2-2-1">v2\.2\.1</a>
|
||||||
- <a href="#release-summary-23">Release Summary</a>
|
- <a href="#release-summary-32">Release Summary</a>
|
||||||
- <a href="#bugfixes-12">Bugfixes</a>
|
- <a href="#bugfixes-15">Bugfixes</a>
|
||||||
- <a href="#v2-2-0">v2\.2\.0</a>
|
- <a href="#v2-2-0">v2\.2\.0</a>
|
||||||
- <a href="#release-summary-24">Release Summary</a>
|
- <a href="#release-summary-33">Release Summary</a>
|
||||||
- <a href="#minor-changes-18">Minor Changes</a>
|
- <a href="#minor-changes-26">Minor Changes</a>
|
||||||
- <a href="#bugfixes-13">Bugfixes</a>
|
- <a href="#bugfixes-16">Bugfixes</a>
|
||||||
- <a href="#new-modules">New Modules</a>
|
- <a href="#new-modules">New Modules</a>
|
||||||
- <a href="#v2-1-0">v2\.1\.0</a>
|
- <a href="#v2-1-0">v2\.1\.0</a>
|
||||||
- <a href="#release-summary-25">Release Summary</a>
|
- <a href="#release-summary-34">Release Summary</a>
|
||||||
- <a href="#minor-changes-19">Minor Changes</a>
|
- <a href="#minor-changes-27">Minor Changes</a>
|
||||||
- <a href="#bugfixes-14">Bugfixes</a>
|
- <a href="#bugfixes-17">Bugfixes</a>
|
||||||
- <a href="#new-modules-1">New Modules</a>
|
- <a href="#new-modules-1">New Modules</a>
|
||||||
- <a href="#v2-0-0">v2\.0\.0</a>
|
- <a href="#v2-0-0">v2\.0\.0</a>
|
||||||
- <a href="#release-summary-26">Release Summary</a>
|
- <a href="#release-summary-35">Release Summary</a>
|
||||||
- <a href="#minor-changes-20">Minor Changes</a>
|
- <a href="#minor-changes-28">Minor Changes</a>
|
||||||
- <a href="#breaking-changes--porting-guide-1">Breaking Changes / Porting Guide</a>
|
- <a href="#breaking-changes--porting-guide-1">Breaking Changes / Porting Guide</a>
|
||||||
- <a href="#bugfixes-15">Bugfixes</a>
|
- <a href="#bugfixes-18">Bugfixes</a>
|
||||||
- <a href="#new-plugins">New Plugins</a>
|
- <a href="#new-plugins">New Plugins</a>
|
||||||
- <a href="#filter">Filter</a>
|
- <a href="#filter">Filter</a>
|
||||||
- <a href="#v1-2-0">v1\.2\.0</a>
|
- <a href="#v1-2-0">v1\.2\.0</a>
|
||||||
- <a href="#release-summary-27">Release Summary</a>
|
- <a href="#release-summary-36">Release Summary</a>
|
||||||
- <a href="#minor-changes-21">Minor Changes</a>
|
- <a href="#minor-changes-29">Minor Changes</a>
|
||||||
- <a href="#bugfixes-16">Bugfixes</a>
|
|
||||||
- <a href="#v1-1-0">v1\.1\.0</a>
|
|
||||||
- <a href="#release-summary-28">Release Summary</a>
|
|
||||||
- <a href="#minor-changes-22">Minor Changes</a>
|
|
||||||
- <a href="#v1-0-1">v1\.0\.1</a>
|
|
||||||
- <a href="#release-summary-29">Release Summary</a>
|
|
||||||
- <a href="#bugfixes-17">Bugfixes</a>
|
|
||||||
- <a href="#v1-0-0">v1\.0\.0</a>
|
|
||||||
- <a href="#release-summary-30">Release Summary</a>
|
|
||||||
- <a href="#bugfixes-18">Bugfixes</a>
|
|
||||||
- <a href="#v0-1-1">v0\.1\.1</a>
|
|
||||||
- <a href="#release-summary-31">Release Summary</a>
|
|
||||||
- <a href="#bugfixes-19">Bugfixes</a>
|
- <a href="#bugfixes-19">Bugfixes</a>
|
||||||
|
- <a href="#v1-1-0">v1\.1\.0</a>
|
||||||
|
- <a href="#release-summary-37">Release Summary</a>
|
||||||
|
- <a href="#minor-changes-30">Minor Changes</a>
|
||||||
|
- <a href="#v1-0-1">v1\.0\.1</a>
|
||||||
|
- <a href="#release-summary-38">Release Summary</a>
|
||||||
|
- <a href="#bugfixes-20">Bugfixes</a>
|
||||||
|
- <a href="#v1-0-0">v1\.0\.0</a>
|
||||||
|
- <a href="#release-summary-39">Release Summary</a>
|
||||||
|
- <a href="#bugfixes-21">Bugfixes</a>
|
||||||
|
- <a href="#v0-1-1">v0\.1\.1</a>
|
||||||
|
- <a href="#release-summary-40">Release Summary</a>
|
||||||
|
- <a href="#bugfixes-22">Bugfixes</a>
|
||||||
- <a href="#v0-1-0">v0\.1\.0</a>
|
- <a href="#v0-1-0">v0\.1\.0</a>
|
||||||
- <a href="#release-summary-32">Release Summary</a>
|
- <a href="#release-summary-41">Release Summary</a>
|
||||||
- <a href="#minor-changes-23">Minor Changes</a>
|
- <a href="#minor-changes-31">Minor Changes</a>
|
||||||
|
|
||||||
|
<a id="v3-8-1"></a>
|
||||||
|
## v3\.8\.1
|
||||||
|
|
||||||
|
<a id="release-summary"></a>
|
||||||
|
### Release Summary
|
||||||
|
|
||||||
|
Bugfix release\.
|
||||||
|
|
||||||
|
<a id="bugfixes"></a>
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
* facts and api\_facts modules \- prevent deprecation warnings when used with ansible\-core 2\.19 \([https\://github\.com/ansible\-collections/community\.routeros/pull/384](https\://github\.com/ansible\-collections/community\.routeros/pull/384)\)\.
|
||||||
|
|
||||||
|
<a id="v3-8-0"></a>
|
||||||
|
## v3\.8\.0
|
||||||
|
|
||||||
|
<a id="release-summary-1"></a>
|
||||||
|
### Release Summary
|
||||||
|
|
||||||
|
Feature release\.
|
||||||
|
|
||||||
|
<a id="minor-changes"></a>
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
* api\_info\, api\_modify \- add <code>interface ethernet switch port\-isolation</code> which is supported since RouterOS 6\.43 \([https\://github\.com/ansible\-collections/community\.routeros/pull/375](https\://github\.com/ansible\-collections/community\.routeros/pull/375)\)\.
|
||||||
|
* api\_info\, api\_modify \- add <code>routing bfd configuration</code>\. Officially stabilized BFD support for BGP and OSPF is available since RouterOS 7\.11
|
||||||
|
\([https\://github\.com/ansible\-collections/community\.routeros/pull/375](https\://github\.com/ansible\-collections/community\.routeros/pull/375)\)\.
|
||||||
|
* api\_modify\, api\_info \- support API path <code>ip ipsec mode\-config</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/376](https\://github\.com/ansible\-collections/community\.routeros/pull/376)\)\.
|
||||||
|
|
||||||
|
<a id="v3-7-0"></a>
|
||||||
|
## v3\.7\.0
|
||||||
|
|
||||||
|
<a id="release-summary-2"></a>
|
||||||
|
### Release Summary
|
||||||
|
|
||||||
|
Feature release\.
|
||||||
|
|
||||||
|
<a id="minor-changes-1"></a>
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
* api\_find\_and\_modify \- allow to control whether <code>dynamic</code> and/or <code>builtin</code> entries are ignored with the new <code>ignore\_dynamic</code> and <code>ignore\_builtin</code> options \([https\://github\.com/ansible\-collections/community\.routeros/issues/372](https\://github\.com/ansible\-collections/community\.routeros/issues/372)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/373](https\://github\.com/ansible\-collections/community\.routeros/pull/373)\)\.
|
||||||
|
* api\_info\, api\_modify \- add <code>port\-cost\-mode</code> to <code>interface bridge</code> which is supported since RouterOS 7\.13 \([https\://github\.com/ansible\-collections/community\.routeros/pull/371](https\://github\.com/ansible\-collections/community\.routeros/pull/371)\)\.
|
||||||
|
|
||||||
|
<a id="v3-6-0"></a>
|
||||||
|
## v3\.6\.0
|
||||||
|
|
||||||
|
<a id="release-summary-3"></a>
|
||||||
|
### Release Summary
|
||||||
|
|
||||||
|
Feature release\.
|
||||||
|
|
||||||
|
<a id="minor-changes-2"></a>
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
* api\_info\, api\_modify \- add <code>mdns\-repeat\-ifaces</code> to <code>ip dns</code> for RouterOS 7\.16 and newer \([https\://github\.com/ansible\-collections/community\.routeros/pull/358](https\://github\.com/ansible\-collections/community\.routeros/pull/358)\)\.
|
||||||
|
* api\_info\, api\_modify \- field name change in <code>routing bgp connection</code> path implemented by RouterOS 7\.19 and newer \([https\://github\.com/ansible\-collections/community\.routeros/pull/360](https\://github\.com/ansible\-collections/community\.routeros/pull/360)\)\.
|
||||||
|
* api\_info\, api\_modify \- rename <code>is\-responder</code> property in <code>interface wireguard peers</code> to <code>responder</code> for RouterOS 7\.17 and newer \([https\://github\.com/ansible\-collections/community\.routeros/pull/364](https\://github\.com/ansible\-collections/community\.routeros/pull/364)\)\.
|
||||||
|
|
||||||
|
<a id="v3-5-0"></a>
|
||||||
|
## v3\.5\.0
|
||||||
|
|
||||||
|
<a id="release-summary-4"></a>
|
||||||
|
### Release Summary
|
||||||
|
|
||||||
|
Feature release\.
|
||||||
|
|
||||||
|
<a id="minor-changes-3"></a>
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
* api\_info\, api\_modify \- change default for <code>/ip/cloud/ddns\-enabled</code> for RouterOS 7\.17 and newer from <code>yes</code> to <code>auto</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/350](https\://github\.com/ansible\-collections/community\.routeros/pull/350)\)\.
|
||||||
|
|
||||||
|
<a id="v3-4-0"></a>
|
||||||
|
## v3\.4\.0
|
||||||
|
|
||||||
|
<a id="release-summary-5"></a>
|
||||||
|
### Release Summary
|
||||||
|
|
||||||
|
Feature and bugfix release\.
|
||||||
|
|
||||||
|
<a id="minor-changes-4"></a>
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
* api\_info\, api\_modify \- add support for the <code>ip dns forwarders</code> path implemented by RouterOS 7\.17 and newer \([https\://github\.com/ansible\-collections/community\.routeros/pull/343](https\://github\.com/ansible\-collections/community\.routeros/pull/343)\)\.
|
||||||
|
|
||||||
|
<a id="bugfixes-1"></a>
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
* api\_info\, api\_modify \- remove the primary key <code>action</code> from the <code>interface wifi provisioning</code> path\, since RouterOS also allows to create completely duplicate entries \([https\://github\.com/ansible\-collections/community\.routeros/issues/344](https\://github\.com/ansible\-collections/community\.routeros/issues/344)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/345](https\://github\.com/ansible\-collections/community\.routeros/pull/345)\)\.
|
||||||
|
|
||||||
|
<a id="v3-3-0"></a>
|
||||||
|
## v3\.3\.0
|
||||||
|
|
||||||
|
<a id="release-summary-6"></a>
|
||||||
|
### Release Summary
|
||||||
|
|
||||||
|
Feature release\.
|
||||||
|
|
||||||
|
<a id="minor-changes-5"></a>
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
* api\_info\, api\_modify \- add missing attribute <code>require\-message\-auth</code> for the <code>radius</code> path which exists since RouterOS version 7\.15 \([https\://github\.com/ansible\-collections/community\.routeros/issues/338](https\://github\.com/ansible\-collections/community\.routeros/issues/338)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/339](https\://github\.com/ansible\-collections/community\.routeros/pull/339)\)\.
|
||||||
|
* api\_info\, api\_modify \- add the <code>interface 6to4</code> path\. Used to manage IPv6 tunnels via tunnel\-brokers like HE\, where native IPv6 is not provided \([https\://github\.com/ansible\-collections/community\.routeros/pull/342](https\://github\.com/ansible\-collections/community\.routeros/pull/342)\)\.
|
||||||
|
* api\_info\, api\_modify \- add the <code>interface wireless access\-list</code> and <code>interface wireless connect\-list</code> paths \([https\://github\.com/ansible\-collections/community\.routeros/issues/284](https\://github\.com/ansible\-collections/community\.routeros/issues/284)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/340](https\://github\.com/ansible\-collections/community\.routeros/pull/340)\)\.
|
||||||
|
* api\_info\, api\_modify \- add the <code>use\-interface\-duid</code> option for <code>ipv6 dhcp\-client</code> path\. This option prevents issues with Fritzbox modems and routers\, when using virtual interfaces \(like VLANs\) may create duplicated records in hosts config\, this breaks original \"expose\-host\" function\. Also add the <code>script</code>\, <code>custom\-duid</code> and <code>validate\-server\-duid</code> as backport from 7\.15 version update \([https\://github\.com/ansible\-collections/community\.routeros/pull/341](https\://github\.com/ansible\-collections/community\.routeros/pull/341)\)\.
|
||||||
|
|
||||||
|
<a id="v3-2-0"></a>
|
||||||
|
## v3\.2\.0
|
||||||
|
|
||||||
|
<a id="release-summary-7"></a>
|
||||||
|
### Release Summary
|
||||||
|
|
||||||
|
Feature release\.
|
||||||
|
|
||||||
|
<a id="minor-changes-6"></a>
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
* api\_info\, api\_modify \- add support for the <code>routing filter community\-list</code> path implemented by RouterOS 7 and newer \([https\://github\.com/ansible\-collections/community\.routeros/pull/331](https\://github\.com/ansible\-collections/community\.routeros/pull/331)\)\.
|
||||||
|
|
||||||
|
<a id="v3-1-0"></a>
|
||||||
|
## v3\.1\.0
|
||||||
|
|
||||||
|
<a id="release-summary-8"></a>
|
||||||
|
### Release Summary
|
||||||
|
|
||||||
|
Bugfix and feature release\.
|
||||||
|
|
||||||
|
<a id="minor-changes-7"></a>
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
* api\_info\, api\_modify \- add missing fields <code>comment</code>\, <code>next\-pool</code> to <code>ip pool</code> path \([https\://github\.com/ansible\-collections/community\.routeros/pull/327](https\://github\.com/ansible\-collections/community\.routeros/pull/327)\)\.
|
||||||
|
|
||||||
|
<a id="bugfixes-2"></a>
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
* api\_info\, api\_modify \- fields <code>log</code> and <code>log\-prefix</code> in paths <code>ip firewall filter</code>\, <code>ip firewall mangle</code>\, <code>ip firewall nat</code>\, <code>ip firewall raw</code> now have the correct default values \([https\://github\.com/ansible\-collections/community\.routeros/pull/324](https\://github\.com/ansible\-collections/community\.routeros/pull/324)\)\.
|
||||||
|
|
||||||
<a id="v3-0-0"></a>
|
<a id="v3-0-0"></a>
|
||||||
## v3\.0\.0
|
## v3\.0\.0
|
||||||
|
|
||||||
<a id="release-summary"></a>
|
<a id="release-summary-9"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Major release that drops support for End of Life Python versions and fixes check mode for community\.routeros\.command\.
|
Major release that drops support for End of Life Python versions and fixes check mode for community\.routeros\.command\.
|
||||||
|
@ -145,12 +310,12 @@ Major release that drops support for End of Life Python versions and fixes check
|
||||||
<a id="v2-20-0"></a>
|
<a id="v2-20-0"></a>
|
||||||
## v2\.20\.0
|
## v2\.20\.0
|
||||||
|
|
||||||
<a id="release-summary-1"></a>
|
<a id="release-summary-10"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature release\.
|
Feature release\.
|
||||||
|
|
||||||
<a id="minor-changes"></a>
|
<a id="minor-changes-8"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- add new parameters from the RouterOS 7\.16 release \([https\://github\.com/ansible\-collections/community\.routeros/pull/323](https\://github\.com/ansible\-collections/community\.routeros/pull/323)\)\.
|
* api\_info\, api\_modify \- add new parameters from the RouterOS 7\.16 release \([https\://github\.com/ansible\-collections/community\.routeros/pull/323](https\://github\.com/ansible\-collections/community\.routeros/pull/323)\)\.
|
||||||
|
@ -161,12 +326,12 @@ Feature release\.
|
||||||
<a id="v2-19-0"></a>
|
<a id="v2-19-0"></a>
|
||||||
## v2\.19\.0
|
## v2\.19\.0
|
||||||
|
|
||||||
<a id="release-summary-2"></a>
|
<a id="release-summary-11"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature release\.
|
Feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-1"></a>
|
<a id="minor-changes-9"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- add support for the <code>ip dns adlist</code> path implemented by RouterOS 7\.15 and newer \([https\://github\.com/ansible\-collections/community\.routeros/pull/310](https\://github\.com/ansible\-collections/community\.routeros/pull/310)\)\.
|
* api\_info\, api\_modify \- add support for the <code>ip dns adlist</code> path implemented by RouterOS 7\.15 and newer \([https\://github\.com/ansible\-collections/community\.routeros/pull/310](https\://github\.com/ansible\-collections/community\.routeros/pull/310)\)\.
|
||||||
|
@ -178,12 +343,12 @@ Feature release\.
|
||||||
<a id="v2-18-0"></a>
|
<a id="v2-18-0"></a>
|
||||||
## v2\.18\.0
|
## v2\.18\.0
|
||||||
|
|
||||||
<a id="release-summary-3"></a>
|
<a id="release-summary-12"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature release\.
|
Feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-2"></a>
|
<a id="minor-changes-10"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info \- allow to restrict the output by limiting fields to specific values with the new <code>restrict</code> option \([https\://github\.com/ansible\-collections/community\.routeros/pull/305](https\://github\.com/ansible\-collections/community\.routeros/pull/305)\)\.
|
* api\_info \- allow to restrict the output by limiting fields to specific values with the new <code>restrict</code> option \([https\://github\.com/ansible\-collections/community\.routeros/pull/305](https\://github\.com/ansible\-collections/community\.routeros/pull/305)\)\.
|
||||||
|
@ -199,7 +364,7 @@ Feature release\.
|
||||||
|
|
||||||
* The collection deprecates support for all Ansible/ansible\-base/ansible\-core versions that are currently End of Life\, [according to the ansible\-core support matrix](https\://docs\.ansible\.com/ansible\-core/devel/reference\_appendices/release\_and\_maintenance\.html\#ansible\-core\-support\-matrix)\. This means that the next major release of the collection will no longer support Ansible 2\.9\, ansible\-base 2\.10\, ansible\-core 2\.11\, ansible\-core 2\.12\, ansible\-core 2\.13\, and ansible\-core 2\.14\.
|
* The collection deprecates support for all Ansible/ansible\-base/ansible\-core versions that are currently End of Life\, [according to the ansible\-core support matrix](https\://docs\.ansible\.com/ansible\-core/devel/reference\_appendices/release\_and\_maintenance\.html\#ansible\-core\-support\-matrix)\. This means that the next major release of the collection will no longer support Ansible 2\.9\, ansible\-base 2\.10\, ansible\-core 2\.11\, ansible\-core 2\.12\, ansible\-core 2\.13\, and ansible\-core 2\.14\.
|
||||||
|
|
||||||
<a id="bugfixes"></a>
|
<a id="bugfixes-3"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api\_modify\, api\_info \- change the default of <code>ingress\-filtering</code> in paths <code>interface bridge</code> and <code>interface bridge port</code> back to <code>false</code> for RouterOS before version 7 \([https\://github\.com/ansible\-collections/community\.routeros/pull/305](https\://github\.com/ansible\-collections/community\.routeros/pull/305)\)\.
|
* api\_modify\, api\_info \- change the default of <code>ingress\-filtering</code> in paths <code>interface bridge</code> and <code>interface bridge port</code> back to <code>false</code> for RouterOS before version 7 \([https\://github\.com/ansible\-collections/community\.routeros/pull/305](https\://github\.com/ansible\-collections/community\.routeros/pull/305)\)\.
|
||||||
|
@ -207,12 +372,12 @@ Feature release\.
|
||||||
<a id="v2-17-0"></a>
|
<a id="v2-17-0"></a>
|
||||||
## v2\.17\.0
|
## v2\.17\.0
|
||||||
|
|
||||||
<a id="release-summary-4"></a>
|
<a id="release-summary-13"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature release\.
|
Feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-3"></a>
|
<a id="minor-changes-11"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- add <code>system health settings</code> path \([https\://github\.com/ansible\-collections/community\.routeros/pull/294](https\://github\.com/ansible\-collections/community\.routeros/pull/294)\)\.
|
* api\_info\, api\_modify \- add <code>system health settings</code> path \([https\://github\.com/ansible\-collections/community\.routeros/pull/294](https\://github\.com/ansible\-collections/community\.routeros/pull/294)\)\.
|
||||||
|
@ -222,12 +387,12 @@ Feature release\.
|
||||||
<a id="v2-16-0"></a>
|
<a id="v2-16-0"></a>
|
||||||
## v2\.16\.0
|
## v2\.16\.0
|
||||||
|
|
||||||
<a id="release-summary-5"></a>
|
<a id="release-summary-14"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature release\.
|
Feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-4"></a>
|
<a id="minor-changes-12"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- add missing path <code>/ppp secret</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/286](https\://github\.com/ansible\-collections/community\.routeros/pull/286)\)\.
|
* api\_info\, api\_modify \- add missing path <code>/ppp secret</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/286](https\://github\.com/ansible\-collections/community\.routeros/pull/286)\)\.
|
||||||
|
@ -236,12 +401,12 @@ Feature release\.
|
||||||
<a id="v2-15-0"></a>
|
<a id="v2-15-0"></a>
|
||||||
## v2\.15\.0
|
## v2\.15\.0
|
||||||
|
|
||||||
<a id="release-summary-6"></a>
|
<a id="release-summary-15"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature release\.
|
Feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-5"></a>
|
<a id="minor-changes-13"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- Add RouterOS 7\.x support to <code>/mpls ldp</code> path \([https\://github\.com/ansible\-collections/community\.routeros/pull/271](https\://github\.com/ansible\-collections/community\.routeros/pull/271)\)\.
|
* api\_info\, api\_modify \- Add RouterOS 7\.x support to <code>/mpls ldp</code> path \([https\://github\.com/ansible\-collections/community\.routeros/pull/271](https\://github\.com/ansible\-collections/community\.routeros/pull/271)\)\.
|
||||||
|
@ -258,12 +423,12 @@ Feature release\.
|
||||||
<a id="v2-14-0"></a>
|
<a id="v2-14-0"></a>
|
||||||
## v2\.14\.0
|
## v2\.14\.0
|
||||||
|
|
||||||
<a id="release-summary-7"></a>
|
<a id="release-summary-16"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature release\.
|
Feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-6"></a>
|
<a id="minor-changes-14"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- add read\-only fields <code>installed\-version</code>\, <code>latest\-version</code> and <code>status</code> in <code>system package update</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/263](https\://github\.com/ansible\-collections/community\.routeros/pull/263)\)\.
|
* api\_info\, api\_modify \- add read\-only fields <code>installed\-version</code>\, <code>latest\-version</code> and <code>status</code> in <code>system package update</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/263](https\://github\.com/ansible\-collections/community\.routeros/pull/263)\)\.
|
||||||
|
@ -273,18 +438,18 @@ Feature release\.
|
||||||
<a id="v2-13-0"></a>
|
<a id="v2-13-0"></a>
|
||||||
## v2\.13\.0
|
## v2\.13\.0
|
||||||
|
|
||||||
<a id="release-summary-8"></a>
|
<a id="release-summary-17"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Bugfix and feature release\.
|
Bugfix and feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-7"></a>
|
<a id="minor-changes-15"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- make path <code>user group</code> modifiable and add <code>comment</code> attribute \([https\://github\.com/ansible\-collections/community\.routeros/issues/256](https\://github\.com/ansible\-collections/community\.routeros/issues/256)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/257](https\://github\.com/ansible\-collections/community\.routeros/pull/257)\)\.
|
* api\_info\, api\_modify \- make path <code>user group</code> modifiable and add <code>comment</code> attribute \([https\://github\.com/ansible\-collections/community\.routeros/issues/256](https\://github\.com/ansible\-collections/community\.routeros/issues/256)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/257](https\://github\.com/ansible\-collections/community\.routeros/pull/257)\)\.
|
||||||
* api\_modify\, api\_info \- add support for the <code>ip vrf</code> path in RouterOS 7 \([https\://github\.com/ansible\-collections/community\.routeros/pull/259](https\://github\.com/ansible\-collections/community\.routeros/pull/259)\)
|
* api\_modify\, api\_info \- add support for the <code>ip vrf</code> path in RouterOS 7 \([https\://github\.com/ansible\-collections/community\.routeros/pull/259](https\://github\.com/ansible\-collections/community\.routeros/pull/259)\)
|
||||||
|
|
||||||
<a id="bugfixes-1"></a>
|
<a id="bugfixes-4"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* facts \- fix date not getting removed for idempotent config export \([https\://github\.com/ansible\-collections/community\.routeros/pull/262](https\://github\.com/ansible\-collections/community\.routeros/pull/262)\)\.
|
* facts \- fix date not getting removed for idempotent config export \([https\://github\.com/ansible\-collections/community\.routeros/pull/262](https\://github\.com/ansible\-collections/community\.routeros/pull/262)\)\.
|
||||||
|
@ -292,12 +457,12 @@ Bugfix and feature release\.
|
||||||
<a id="v2-12-0"></a>
|
<a id="v2-12-0"></a>
|
||||||
## v2\.12\.0
|
## v2\.12\.0
|
||||||
|
|
||||||
<a id="release-summary-9"></a>
|
<a id="release-summary-18"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature release\.
|
Feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-8"></a>
|
<a id="minor-changes-16"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- add <code>interface ovpn\-client</code> path \([https\://github\.com/ansible\-collections/community\.routeros/issues/242](https\://github\.com/ansible\-collections/community\.routeros/issues/242)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/244](https\://github\.com/ansible\-collections/community\.routeros/pull/244)\)\.
|
* api\_info\, api\_modify \- add <code>interface ovpn\-client</code> path \([https\://github\.com/ansible\-collections/community\.routeros/issues/242](https\://github\.com/ansible\-collections/community\.routeros/issues/242)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/244](https\://github\.com/ansible\-collections/community\.routeros/pull/244)\)\.
|
||||||
|
@ -311,12 +476,12 @@ Feature release\.
|
||||||
<a id="v2-11-0"></a>
|
<a id="v2-11-0"></a>
|
||||||
## v2\.11\.0
|
## v2\.11\.0
|
||||||
|
|
||||||
<a id="release-summary-10"></a>
|
<a id="release-summary-19"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature and bugfix release\.
|
Feature and bugfix release\.
|
||||||
|
|
||||||
<a id="minor-changes-9"></a>
|
<a id="minor-changes-17"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- add missing DoH parameters <code>doh\-max\-concurrent\-queries</code>\, <code>doh\-max\-server\-connections</code>\, and <code>doh\-timeout</code> to the <code>ip dns</code> path \([https\://github\.com/ansible\-collections/community\.routeros/issues/230](https\://github\.com/ansible\-collections/community\.routeros/issues/230)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/235](https\://github\.com/ansible\-collections/community\.routeros/pull/235)\)
|
* api\_info\, api\_modify \- add missing DoH parameters <code>doh\-max\-concurrent\-queries</code>\, <code>doh\-max\-server\-connections</code>\, and <code>doh\-timeout</code> to the <code>ip dns</code> path \([https\://github\.com/ansible\-collections/community\.routeros/issues/230](https\://github\.com/ansible\-collections/community\.routeros/issues/230)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/235](https\://github\.com/ansible\-collections/community\.routeros/pull/235)\)
|
||||||
|
@ -331,12 +496,12 @@ Feature and bugfix release\.
|
||||||
<a id="v2-10-0"></a>
|
<a id="v2-10-0"></a>
|
||||||
## v2\.10\.0
|
## v2\.10\.0
|
||||||
|
|
||||||
<a id="release-summary-11"></a>
|
<a id="release-summary-20"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Bugfix and feature release\.
|
Bugfix and feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-10"></a>
|
<a id="minor-changes-18"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info \- add new <code>include\_read\_only</code> option to select behavior for read\-only values\. By default these are not returned \([https\://github\.com/ansible\-collections/community\.routeros/pull/213](https\://github\.com/ansible\-collections/community\.routeros/pull/213)\)\.
|
* api\_info \- add new <code>include\_read\_only</code> option to select behavior for read\-only values\. By default these are not returned \([https\://github\.com/ansible\-collections/community\.routeros/pull/213](https\://github\.com/ansible\-collections/community\.routeros/pull/213)\)\.
|
||||||
|
@ -360,7 +525,7 @@ Bugfix and feature release\.
|
||||||
* api\_modify \- add new <code>handle\_read\_only</code> and <code>handle\_write\_only</code> options to handle the module\'s behavior for read\-only and write\-only fields \([https\://github\.com/ansible\-collections/community\.routeros/pull/213](https\://github\.com/ansible\-collections/community\.routeros/pull/213)\)\.
|
* api\_modify \- add new <code>handle\_read\_only</code> and <code>handle\_write\_only</code> options to handle the module\'s behavior for read\-only and write\-only fields \([https\://github\.com/ansible\-collections/community\.routeros/pull/213](https\://github\.com/ansible\-collections/community\.routeros/pull/213)\)\.
|
||||||
* api\_modify\, api\_info \- support API paths <code>routing id</code>\, <code>routing bgp connection</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/220](https\://github\.com/ansible\-collections/community\.routeros/pull/220)\)\.
|
* api\_modify\, api\_info \- support API paths <code>routing id</code>\, <code>routing bgp connection</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/220](https\://github\.com/ansible\-collections/community\.routeros/pull/220)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-2"></a>
|
<a id="bugfixes-5"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- in the <code>snmp</code> path\, ensure that <code>engine\-id\-suffix</code> is only available on RouterOS 7\.10\+\, and that <code>engine\-id</code> is read\-only on RouterOS 7\.10\+ \([https\://github\.com/ansible\-collections/community\.routeros/issues/208](https\://github\.com/ansible\-collections/community\.routeros/issues/208)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/218](https\://github\.com/ansible\-collections/community\.routeros/pull/218)\)\.
|
* api\_info\, api\_modify \- in the <code>snmp</code> path\, ensure that <code>engine\-id\-suffix</code> is only available on RouterOS 7\.10\+\, and that <code>engine\-id</code> is read\-only on RouterOS 7\.10\+ \([https\://github\.com/ansible\-collections/community\.routeros/issues/208](https\://github\.com/ansible\-collections/community\.routeros/issues/208)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/218](https\://github\.com/ansible\-collections/community\.routeros/pull/218)\)\.
|
||||||
|
@ -368,18 +533,18 @@ Bugfix and feature release\.
|
||||||
<a id="v2-9-0"></a>
|
<a id="v2-9-0"></a>
|
||||||
## v2\.9\.0
|
## v2\.9\.0
|
||||||
|
|
||||||
<a id="release-summary-12"></a>
|
<a id="release-summary-21"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Bugfix and feature release\.
|
Bugfix and feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-11"></a>
|
<a id="minor-changes-19"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- add path <code>caps\-man channel</code> and enable path <code>caps\-man manager interface</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/193](https\://github\.com/ansible\-collections/community\.routeros/issues/193)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/194](https\://github\.com/ansible\-collections/community\.routeros/pull/194)\)\.
|
* api\_info\, api\_modify \- add path <code>caps\-man channel</code> and enable path <code>caps\-man manager interface</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/193](https\://github\.com/ansible\-collections/community\.routeros/issues/193)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/194](https\://github\.com/ansible\-collections/community\.routeros/pull/194)\)\.
|
||||||
* api\_info\, api\_modify \- add path <code>ip traffic\-flow target</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/191](https\://github\.com/ansible\-collections/community\.routeros/issues/191)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/192](https\://github\.com/ansible\-collections/community\.routeros/pull/192)\)\.
|
* api\_info\, api\_modify \- add path <code>ip traffic\-flow target</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/191](https\://github\.com/ansible\-collections/community\.routeros/issues/191)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/192](https\://github\.com/ansible\-collections/community\.routeros/pull/192)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-3"></a>
|
<a id="bugfixes-6"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api\_modify\, api\_info \- add missing parameter <code>engine\-id\-suffix</code> for the <code>snmp</code> path \([https\://github\.com/ansible\-collections/community\.routeros/issues/189](https\://github\.com/ansible\-collections/community\.routeros/issues/189)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/190](https\://github\.com/ansible\-collections/community\.routeros/pull/190)\)\.
|
* api\_modify\, api\_info \- add missing parameter <code>engine\-id\-suffix</code> for the <code>snmp</code> path \([https\://github\.com/ansible\-collections/community\.routeros/issues/189](https\://github\.com/ansible\-collections/community\.routeros/issues/189)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/190](https\://github\.com/ansible\-collections/community\.routeros/pull/190)\)\.
|
||||||
|
@ -387,7 +552,7 @@ Bugfix and feature release\.
|
||||||
<a id="v2-8-3"></a>
|
<a id="v2-8-3"></a>
|
||||||
## v2\.8\.3
|
## v2\.8\.3
|
||||||
|
|
||||||
<a id="release-summary-13"></a>
|
<a id="release-summary-22"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Maintenance release with updated documentation\.
|
Maintenance release with updated documentation\.
|
||||||
|
@ -408,12 +573,12 @@ for the rendered HTML version of the documentation of the latest release\.
|
||||||
<a id="v2-8-2"></a>
|
<a id="v2-8-2"></a>
|
||||||
## v2\.8\.2
|
## v2\.8\.2
|
||||||
|
|
||||||
<a id="release-summary-14"></a>
|
<a id="release-summary-23"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Bugfix release\.
|
Bugfix release\.
|
||||||
|
|
||||||
<a id="bugfixes-4"></a>
|
<a id="bugfixes-7"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api\_modify\, api\_info \- add missing parameter <code>tls</code> for the <code>tool e\-mail</code> path \([https\://github\.com/ansible\-collections/community\.routeros/issues/179](https\://github\.com/ansible\-collections/community\.routeros/issues/179)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/180](https\://github\.com/ansible\-collections/community\.routeros/pull/180)\)\.
|
* api\_modify\, api\_info \- add missing parameter <code>tls</code> for the <code>tool e\-mail</code> path \([https\://github\.com/ansible\-collections/community\.routeros/issues/179](https\://github\.com/ansible\-collections/community\.routeros/issues/179)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/180](https\://github\.com/ansible\-collections/community\.routeros/pull/180)\)\.
|
||||||
|
@ -421,12 +586,12 @@ Bugfix release\.
|
||||||
<a id="v2-8-1"></a>
|
<a id="v2-8-1"></a>
|
||||||
## v2\.8\.1
|
## v2\.8\.1
|
||||||
|
|
||||||
<a id="release-summary-15"></a>
|
<a id="release-summary-24"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Bugfix release\.
|
Bugfix release\.
|
||||||
|
|
||||||
<a id="bugfixes-5"></a>
|
<a id="bugfixes-8"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* facts \- do not crash in CLI output preprocessing in unexpected situations during line unwrapping \([https\://github\.com/ansible\-collections/community\.routeros/issues/170](https\://github\.com/ansible\-collections/community\.routeros/issues/170)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/177](https\://github\.com/ansible\-collections/community\.routeros/pull/177)\)\.
|
* facts \- do not crash in CLI output preprocessing in unexpected situations during line unwrapping \([https\://github\.com/ansible\-collections/community\.routeros/issues/170](https\://github\.com/ansible\-collections/community\.routeros/issues/170)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/177](https\://github\.com/ansible\-collections/community\.routeros/pull/177)\)\.
|
||||||
|
@ -434,12 +599,12 @@ Bugfix release\.
|
||||||
<a id="v2-8-0"></a>
|
<a id="v2-8-0"></a>
|
||||||
## v2\.8\.0
|
## v2\.8\.0
|
||||||
|
|
||||||
<a id="release-summary-16"></a>
|
<a id="release-summary-25"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Bugfix and feature release\.
|
Bugfix and feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-12"></a>
|
<a id="minor-changes-20"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_modify \- adapt data for API paths <code>ip dhcp\-server network</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/156](https\://github\.com/ansible\-collections/community\.routeros/pull/156)\)\.
|
* api\_modify \- adapt data for API paths <code>ip dhcp\-server network</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/156](https\://github\.com/ansible\-collections/community\.routeros/pull/156)\)\.
|
||||||
|
@ -449,7 +614,7 @@ Bugfix and feature release\.
|
||||||
* api\_modify \- support API paths <code>ip firewall layer7\-protocol</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/153](https\://github\.com/ansible\-collections/community\.routeros/pull/153)\)\.
|
* api\_modify \- support API paths <code>ip firewall layer7\-protocol</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/153](https\://github\.com/ansible\-collections/community\.routeros/pull/153)\)\.
|
||||||
* command \- workaround for extra characters in stdout in RouterOS versions between 6\.49 and 7\.1\.5 \([https\://github\.com/ansible\-collections/community\.routeros/issues/62](https\://github\.com/ansible\-collections/community\.routeros/issues/62)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/161](https\://github\.com/ansible\-collections/community\.routeros/pull/161)\)\.
|
* command \- workaround for extra characters in stdout in RouterOS versions between 6\.49 and 7\.1\.5 \([https\://github\.com/ansible\-collections/community\.routeros/issues/62](https\://github\.com/ansible\-collections/community\.routeros/issues/62)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/161](https\://github\.com/ansible\-collections/community\.routeros/pull/161)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-6"></a>
|
<a id="bugfixes-9"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- fix default and remove behavior for <code>dhcp\-options</code> in path <code>ip dhcp\-client</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/148](https\://github\.com/ansible\-collections/community\.routeros/issues/148)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/154](https\://github\.com/ansible\-collections/community\.routeros/pull/154)\)\.
|
* api\_info\, api\_modify \- fix default and remove behavior for <code>dhcp\-options</code> in path <code>ip dhcp\-client</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/148](https\://github\.com/ansible\-collections/community\.routeros/issues/148)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/154](https\://github\.com/ansible\-collections/community\.routeros/pull/154)\)\.
|
||||||
|
@ -459,17 +624,17 @@ Bugfix and feature release\.
|
||||||
<a id="v2-7-0"></a>
|
<a id="v2-7-0"></a>
|
||||||
## v2\.7\.0
|
## v2\.7\.0
|
||||||
|
|
||||||
<a id="release-summary-17"></a>
|
<a id="release-summary-26"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Bugfix and feature release\.
|
Bugfix and feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-13"></a>
|
<a id="minor-changes-21"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_modify\, api\_info \- support API paths <code>ip arp</code>\, <code>ip firewall raw</code>\, <code>ipv6 firewall raw</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/144](https\://github\.com/ansible\-collections/community\.routeros/pull/144)\)\.
|
* api\_modify\, api\_info \- support API paths <code>ip arp</code>\, <code>ip firewall raw</code>\, <code>ipv6 firewall raw</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/144](https\://github\.com/ansible\-collections/community\.routeros/pull/144)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-7"></a>
|
<a id="bugfixes-10"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api\_modify\, api\_info \- defaults corrected for fields in <code>interface wireguard peers</code> API path \([https\://github\.com/ansible\-collections/community\.routeros/pull/144](https\://github\.com/ansible\-collections/community\.routeros/pull/144)\)\.
|
* api\_modify\, api\_info \- defaults corrected for fields in <code>interface wireguard peers</code> API path \([https\://github\.com/ansible\-collections/community\.routeros/pull/144](https\://github\.com/ansible\-collections/community\.routeros/pull/144)\)\.
|
||||||
|
@ -477,18 +642,18 @@ Bugfix and feature release\.
|
||||||
<a id="v2-6-0"></a>
|
<a id="v2-6-0"></a>
|
||||||
## v2\.6\.0
|
## v2\.6\.0
|
||||||
|
|
||||||
<a id="release-summary-18"></a>
|
<a id="release-summary-27"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Regular bugfix and feature release\.
|
Regular bugfix and feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-14"></a>
|
<a id="minor-changes-22"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_modify\, api\_info \- add field <code>regexp</code> to <code>ip dns static</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/141](https\://github\.com/ansible\-collections/community\.routeros/issues/141)\)\.
|
* api\_modify\, api\_info \- add field <code>regexp</code> to <code>ip dns static</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/141](https\://github\.com/ansible\-collections/community\.routeros/issues/141)\)\.
|
||||||
* api\_modify\, api\_info \- support API paths <code>interface wireguard</code>\, <code>interface wireguard peers</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/143](https\://github\.com/ansible\-collections/community\.routeros/pull/143)\)\.
|
* api\_modify\, api\_info \- support API paths <code>interface wireguard</code>\, <code>interface wireguard peers</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/143](https\://github\.com/ansible\-collections/community\.routeros/pull/143)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-8"></a>
|
<a id="bugfixes-11"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api\_modify \- do not use <code>name</code> as a unique key in <code>ip dns static</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/141](https\://github\.com/ansible\-collections/community\.routeros/issues/141)\)\.
|
* api\_modify \- do not use <code>name</code> as a unique key in <code>ip dns static</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/141](https\://github\.com/ansible\-collections/community\.routeros/issues/141)\)\.
|
||||||
|
@ -497,17 +662,17 @@ Regular bugfix and feature release\.
|
||||||
<a id="v2-5-0"></a>
|
<a id="v2-5-0"></a>
|
||||||
## v2\.5\.0
|
## v2\.5\.0
|
||||||
|
|
||||||
<a id="release-summary-19"></a>
|
<a id="release-summary-28"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature and bugfix release\.
|
Feature and bugfix release\.
|
||||||
|
|
||||||
<a id="minor-changes-15"></a>
|
<a id="minor-changes-23"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\_info\, api\_modify \- support API paths <code>interface ethernet poe</code>\, <code>interface gre6</code>\, <code>interface vrrp</code> and also support all previously missing fields of entries in <code>ip dhcp\-server</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/137](https\://github\.com/ansible\-collections/community\.routeros/pull/137)\)\.
|
* api\_info\, api\_modify \- support API paths <code>interface ethernet poe</code>\, <code>interface gre6</code>\, <code>interface vrrp</code> and also support all previously missing fields of entries in <code>ip dhcp\-server</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/137](https\://github\.com/ansible\-collections/community\.routeros/pull/137)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-9"></a>
|
<a id="bugfixes-12"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api\_modify \- <code>address\-pool</code> field of entries in API path <code>ip dhcp\-server</code> is not required anymore \([https\://github\.com/ansible\-collections/community\.routeros/pull/137](https\://github\.com/ansible\-collections/community\.routeros/pull/137)\)\.
|
* api\_modify \- <code>address\-pool</code> field of entries in API path <code>ip dhcp\-server</code> is not required anymore \([https\://github\.com/ansible\-collections/community\.routeros/pull/137](https\://github\.com/ansible\-collections/community\.routeros/pull/137)\)\.
|
||||||
|
@ -515,12 +680,12 @@ Feature and bugfix release\.
|
||||||
<a id="v2-4-0"></a>
|
<a id="v2-4-0"></a>
|
||||||
## v2\.4\.0
|
## v2\.4\.0
|
||||||
|
|
||||||
<a id="release-summary-20"></a>
|
<a id="release-summary-29"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature release improving the <code>api\*</code> modules\.
|
Feature release improving the <code>api\*</code> modules\.
|
||||||
|
|
||||||
<a id="minor-changes-16"></a>
|
<a id="minor-changes-24"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api\* modules \- Add new option <code>force\_no\_cert</code> to connect with ADH ciphers \([https\://github\.com/ansible\-collections/community\.routeros/pull/124](https\://github\.com/ansible\-collections/community\.routeros/pull/124)\)\.
|
* api\* modules \- Add new option <code>force\_no\_cert</code> to connect with ADH ciphers \([https\://github\.com/ansible\-collections/community\.routeros/pull/124](https\://github\.com/ansible\-collections/community\.routeros/pull/124)\)\.
|
||||||
|
@ -541,7 +706,7 @@ Feature release improving the <code>api\*</code> modules\.
|
||||||
* api\_modify\, api\_info \- support for fields <code>blackhole</code>\, <code>pref\-src</code>\, <code>routing\-table</code>\, <code>suppress\-hw\-offload</code>\, <code>type</code>\, <code>vrf\-interface</code> in <code>ip route</code> path \([https\://github\.com/ansible\-collections/community\.routeros/pull/131](https\://github\.com/ansible\-collections/community\.routeros/pull/131)\)\.
|
* api\_modify\, api\_info \- support for fields <code>blackhole</code>\, <code>pref\-src</code>\, <code>routing\-table</code>\, <code>suppress\-hw\-offload</code>\, <code>type</code>\, <code>vrf\-interface</code> in <code>ip route</code> path \([https\://github\.com/ansible\-collections/community\.routeros/pull/131](https\://github\.com/ansible\-collections/community\.routeros/pull/131)\)\.
|
||||||
* api\_modify\, api\_info \- support paths <code>system ntp client servers</code> and <code>system ntp server</code> available in ROS7\, as well as new fields <code>servers</code>\, <code>mode</code>\, and <code>vrf</code> for <code>system ntp client</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/122](https\://github\.com/ansible\-collections/community\.routeros/pull/122)\)\.
|
* api\_modify\, api\_info \- support paths <code>system ntp client servers</code> and <code>system ntp server</code> available in ROS7\, as well as new fields <code>servers</code>\, <code>mode</code>\, and <code>vrf</code> for <code>system ntp client</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/122](https\://github\.com/ansible\-collections/community\.routeros/pull/122)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-10"></a>
|
<a id="bugfixes-13"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api\_modify \- <code>ip route</code> entry can be defined without the need of <code>gateway</code> field\, which is correct for unreachable/blackhole type of routes \([https\://github\.com/ansible\-collections/community\.routeros/pull/131](https\://github\.com/ansible\-collections/community\.routeros/pull/131)\)\.
|
* api\_modify \- <code>ip route</code> entry can be defined without the need of <code>gateway</code> field\, which is correct for unreachable/blackhole type of routes \([https\://github\.com/ansible\-collections/community\.routeros/pull/131](https\://github\.com/ansible\-collections/community\.routeros/pull/131)\)\.
|
||||||
|
@ -559,7 +724,7 @@ Feature release improving the <code>api\*</code> modules\.
|
||||||
<a id="v2-3-1"></a>
|
<a id="v2-3-1"></a>
|
||||||
## v2\.3\.1
|
## v2\.3\.1
|
||||||
|
|
||||||
<a id="release-summary-21"></a>
|
<a id="release-summary-30"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Maintenance release with improved documentation\.
|
Maintenance release with improved documentation\.
|
||||||
|
@ -572,19 +737,19 @@ Maintenance release with improved documentation\.
|
||||||
<a id="v2-3-0"></a>
|
<a id="v2-3-0"></a>
|
||||||
## v2\.3\.0
|
## v2\.3\.0
|
||||||
|
|
||||||
<a id="release-summary-22"></a>
|
<a id="release-summary-31"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature and bugfix release\.
|
Feature and bugfix release\.
|
||||||
|
|
||||||
<a id="minor-changes-17"></a>
|
<a id="minor-changes-25"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* The collection repository conforms to the [REUSE specification](https\://reuse\.software/spec/) except for the changelog fragments \([https\://github\.com/ansible\-collections/community\.routeros/pull/108](https\://github\.com/ansible\-collections/community\.routeros/pull/108)\)\.
|
* The collection repository conforms to the [REUSE specification](https\://reuse\.software/spec/) except for the changelog fragments \([https\://github\.com/ansible\-collections/community\.routeros/pull/108](https\://github\.com/ansible\-collections/community\.routeros/pull/108)\)\.
|
||||||
* api\* modules \- added <code>timeout</code> parameter \([https\://github\.com/ansible\-collections/community\.routeros/pull/109](https\://github\.com/ansible\-collections/community\.routeros/pull/109)\)\.
|
* api\* modules \- added <code>timeout</code> parameter \([https\://github\.com/ansible\-collections/community\.routeros/pull/109](https\://github\.com/ansible\-collections/community\.routeros/pull/109)\)\.
|
||||||
* api\_modify\, api\_info \- support API path <code>ip firewall mangle</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/110](https\://github\.com/ansible\-collections/community\.routeros/pull/110)\)\.
|
* api\_modify\, api\_info \- support API path <code>ip firewall mangle</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/110](https\://github\.com/ansible\-collections/community\.routeros/pull/110)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-11"></a>
|
<a id="bugfixes-14"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api\_modify\, api\_info \- make API path <code>ip dhcp\-server</code> support <code>script</code>\, and <code>ip firewall nat</code> support <code>in\-interface</code> and <code>in\-interface\-list</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/110](https\://github\.com/ansible\-collections/community\.routeros/pull/110)\)\.
|
* api\_modify\, api\_info \- make API path <code>ip dhcp\-server</code> support <code>script</code>\, and <code>ip firewall nat</code> support <code>in\-interface</code> and <code>in\-interface\-list</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/110](https\://github\.com/ansible\-collections/community\.routeros/pull/110)\)\.
|
||||||
|
@ -592,12 +757,12 @@ Feature and bugfix release\.
|
||||||
<a id="v2-2-1"></a>
|
<a id="v2-2-1"></a>
|
||||||
## v2\.2\.1
|
## v2\.2\.1
|
||||||
|
|
||||||
<a id="release-summary-23"></a>
|
<a id="release-summary-32"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Bugfix release\.
|
Bugfix release\.
|
||||||
|
|
||||||
<a id="bugfixes-12"></a>
|
<a id="bugfixes-15"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api\_modify\, api\_info \- make API path <code>ip dhcp\-server lease</code> support <code>server\=all</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/104](https\://github\.com/ansible\-collections/community\.routeros/issues/104)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/107](https\://github\.com/ansible\-collections/community\.routeros/pull/107)\)\.
|
* api\_modify\, api\_info \- make API path <code>ip dhcp\-server lease</code> support <code>server\=all</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/104](https\://github\.com/ansible\-collections/community\.routeros/issues/104)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/107](https\://github\.com/ansible\-collections/community\.routeros/pull/107)\)\.
|
||||||
|
@ -606,17 +771,17 @@ Bugfix release\.
|
||||||
<a id="v2-2-0"></a>
|
<a id="v2-2-0"></a>
|
||||||
## v2\.2\.0
|
## v2\.2\.0
|
||||||
|
|
||||||
<a id="release-summary-24"></a>
|
<a id="release-summary-33"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
New feature release\.
|
New feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-18"></a>
|
<a id="minor-changes-26"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* All software licenses are now in the <code>LICENSES/</code> directory of the collection root\. Moreover\, <code>SPDX\-License\-Identifier\:</code> is used to declare the applicable license for every file that is not automatically generated \([https\://github\.com/ansible\-collections/community\.routeros/pull/101](https\://github\.com/ansible\-collections/community\.routeros/pull/101)\)\.
|
* All software licenses are now in the <code>LICENSES/</code> directory of the collection root\. Moreover\, <code>SPDX\-License\-Identifier\:</code> is used to declare the applicable license for every file that is not automatically generated \([https\://github\.com/ansible\-collections/community\.routeros/pull/101](https\://github\.com/ansible\-collections/community\.routeros/pull/101)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-13"></a>
|
<a id="bugfixes-16"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* Include <code>LICENSES/BSD\-2\-Clause\.txt</code> file for the <code>routeros</code> module utils \([https\://github\.com/ansible\-collections/community\.routeros/pull/101](https\://github\.com/ansible\-collections/community\.routeros/pull/101)\)\.
|
* Include <code>LICENSES/BSD\-2\-Clause\.txt</code> file for the <code>routeros</code> module utils \([https\://github\.com/ansible\-collections/community\.routeros/pull/101](https\://github\.com/ansible\-collections/community\.routeros/pull/101)\)\.
|
||||||
|
@ -630,12 +795,12 @@ New feature release\.
|
||||||
<a id="v2-1-0"></a>
|
<a id="v2-1-0"></a>
|
||||||
## v2\.1\.0
|
## v2\.1\.0
|
||||||
|
|
||||||
<a id="release-summary-25"></a>
|
<a id="release-summary-34"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Feature and bugfix release with new modules\.
|
Feature and bugfix release with new modules\.
|
||||||
|
|
||||||
<a id="minor-changes-19"></a>
|
<a id="minor-changes-27"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* Added a <code>community\.routeros\.api</code> module defaults group\. Use with <code>group/community\.routeros\.api</code> to provide options for all API\-based modules \([https\://github\.com/ansible\-collections/community\.routeros/pull/89](https\://github\.com/ansible\-collections/community\.routeros/pull/89)\)\.
|
* Added a <code>community\.routeros\.api</code> module defaults group\. Use with <code>group/community\.routeros\.api</code> to provide options for all API\-based modules \([https\://github\.com/ansible\-collections/community\.routeros/pull/89](https\://github\.com/ansible\-collections/community\.routeros/pull/89)\)\.
|
||||||
|
@ -644,7 +809,7 @@ Feature and bugfix release with new modules\.
|
||||||
* api \- update <code>query</code> to accept symbolic parameters \([https\://github\.com/ansible\-collections/community\.routeros/pull/63](https\://github\.com/ansible\-collections/community\.routeros/pull/63)\)\.
|
* api \- update <code>query</code> to accept symbolic parameters \([https\://github\.com/ansible\-collections/community\.routeros/pull/63](https\://github\.com/ansible\-collections/community\.routeros/pull/63)\)\.
|
||||||
* api\* modules \- allow to set an encoding other than the default ASCII for communicating with the API \([https\://github\.com/ansible\-collections/community\.routeros/pull/95](https\://github\.com/ansible\-collections/community\.routeros/pull/95)\)\.
|
* api\* modules \- allow to set an encoding other than the default ASCII for communicating with the API \([https\://github\.com/ansible\-collections/community\.routeros/pull/95](https\://github\.com/ansible\-collections/community\.routeros/pull/95)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-14"></a>
|
<a id="bugfixes-17"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* query \- fix query function check for <code>\.id</code> vs\. <code>id</code> arguments to not conflict with routeros arguments like <code>identity</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/68](https\://github\.com/ansible\-collections/community\.routeros/pull/68)\, [https\://github\.com/ansible\-collections/community\.routeros/issues/67](https\://github\.com/ansible\-collections/community\.routeros/issues/67)\)\.
|
* query \- fix query function check for <code>\.id</code> vs\. <code>id</code> arguments to not conflict with routeros arguments like <code>identity</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/68](https\://github\.com/ansible\-collections/community\.routeros/pull/68)\, [https\://github\.com/ansible\-collections/community\.routeros/issues/67](https\://github\.com/ansible\-collections/community\.routeros/issues/67)\)\.
|
||||||
|
@ -659,12 +824,12 @@ Feature and bugfix release with new modules\.
|
||||||
<a id="v2-0-0"></a>
|
<a id="v2-0-0"></a>
|
||||||
## v2\.0\.0
|
## v2\.0\.0
|
||||||
|
|
||||||
<a id="release-summary-26"></a>
|
<a id="release-summary-35"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
A new major release with breaking changes in the behavior of <code>community\.routeros\.api</code> and <code>community\.routeros\.command</code>\.
|
A new major release with breaking changes in the behavior of <code>community\.routeros\.api</code> and <code>community\.routeros\.command</code>\.
|
||||||
|
|
||||||
<a id="minor-changes-20"></a>
|
<a id="minor-changes-28"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* api \- make validation of <code>WHERE</code> for <code>query</code> more strict \([https\://github\.com/ansible\-collections/community\.routeros/pull/53](https\://github\.com/ansible\-collections/community\.routeros/pull/53)\)\.
|
* api \- make validation of <code>WHERE</code> for <code>query</code> more strict \([https\://github\.com/ansible\-collections/community\.routeros/pull/53](https\://github\.com/ansible\-collections/community\.routeros/pull/53)\)\.
|
||||||
|
@ -678,7 +843,7 @@ A new major release with breaking changes in the behavior of <code>community\.ro
|
||||||
* api \- splitting commands no longer uses a naive split by whitespace\, but a more RouterOS CLI compatible splitting algorithm \([https\://github\.com/ansible\-collections/community\.routeros/pull/45](https\://github\.com/ansible\-collections/community\.routeros/pull/45)\)\.
|
* api \- splitting commands no longer uses a naive split by whitespace\, but a more RouterOS CLI compatible splitting algorithm \([https\://github\.com/ansible\-collections/community\.routeros/pull/45](https\://github\.com/ansible\-collections/community\.routeros/pull/45)\)\.
|
||||||
* command \- the module now always indicates that a change happens\. If this is not correct\, please use <code>changed\_when</code> to determine the correct changed status for a task \([https\://github\.com/ansible\-collections/community\.routeros/pull/50](https\://github\.com/ansible\-collections/community\.routeros/pull/50)\)\.
|
* command \- the module now always indicates that a change happens\. If this is not correct\, please use <code>changed\_when</code> to determine the correct changed status for a task \([https\://github\.com/ansible\-collections/community\.routeros/pull/50](https\://github\.com/ansible\-collections/community\.routeros/pull/50)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-15"></a>
|
<a id="bugfixes-18"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api \- improve splitting of <code>WHERE</code> queries \([https\://github\.com/ansible\-collections/community\.routeros/pull/47](https\://github\.com/ansible\-collections/community\.routeros/pull/47)\)\.
|
* api \- improve splitting of <code>WHERE</code> queries \([https\://github\.com/ansible\-collections/community\.routeros/pull/47](https\://github\.com/ansible\-collections/community\.routeros/pull/47)\)\.
|
||||||
|
@ -700,12 +865,12 @@ A new major release with breaking changes in the behavior of <code>community\.ro
|
||||||
<a id="v1-2-0"></a>
|
<a id="v1-2-0"></a>
|
||||||
## v1\.2\.0
|
## v1\.2\.0
|
||||||
|
|
||||||
<a id="release-summary-27"></a>
|
<a id="release-summary-36"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Bugfix and feature release\.
|
Bugfix and feature release\.
|
||||||
|
|
||||||
<a id="minor-changes-21"></a>
|
<a id="minor-changes-29"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* Avoid internal ansible\-core module\_utils in favor of equivalent public API available since at least Ansible 2\.9 \([https\://github\.com/ansible\-collections/community\.routeros/pull/38](https\://github\.com/ansible\-collections/community\.routeros/pull/38)\)\.
|
* Avoid internal ansible\-core module\_utils in favor of equivalent public API available since at least Ansible 2\.9 \([https\://github\.com/ansible\-collections/community\.routeros/pull/38](https\://github\.com/ansible\-collections/community\.routeros/pull/38)\)\.
|
||||||
|
@ -713,7 +878,7 @@ Bugfix and feature release\.
|
||||||
* api \- rename option <code>ssl</code> to <code>tls</code>\, and keep the old name as an alias \([https\://github\.com/ansible\-collections/community\.routeros/pull/37](https\://github\.com/ansible\-collections/community\.routeros/pull/37)\)\.
|
* api \- rename option <code>ssl</code> to <code>tls</code>\, and keep the old name as an alias \([https\://github\.com/ansible\-collections/community\.routeros/pull/37](https\://github\.com/ansible\-collections/community\.routeros/pull/37)\)\.
|
||||||
* fact \- add fact <code>ansible\_net\_config\_nonverbose</code> to get idempotent config \(no date\, no verbose\) \([https\://github\.com/ansible\-collections/community\.routeros/pull/23](https\://github\.com/ansible\-collections/community\.routeros/pull/23)\)\.
|
* fact \- add fact <code>ansible\_net\_config\_nonverbose</code> to get idempotent config \(no date\, no verbose\) \([https\://github\.com/ansible\-collections/community\.routeros/pull/23](https\://github\.com/ansible\-collections/community\.routeros/pull/23)\)\.
|
||||||
|
|
||||||
<a id="bugfixes-16"></a>
|
<a id="bugfixes-19"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api \- when using TLS/SSL\, remove explicit cipher configuration to insecure values\, which also makes it impossible to connect to newer RouterOS versions \([https\://github\.com/ansible\-collections/community\.routeros/pull/34](https\://github\.com/ansible\-collections/community\.routeros/pull/34)\)\.
|
* api \- when using TLS/SSL\, remove explicit cipher configuration to insecure values\, which also makes it impossible to connect to newer RouterOS versions \([https\://github\.com/ansible\-collections/community\.routeros/pull/34](https\://github\.com/ansible\-collections/community\.routeros/pull/34)\)\.
|
||||||
|
@ -721,12 +886,12 @@ Bugfix and feature release\.
|
||||||
<a id="v1-1-0"></a>
|
<a id="v1-1-0"></a>
|
||||||
## v1\.1\.0
|
## v1\.1\.0
|
||||||
|
|
||||||
<a id="release-summary-28"></a>
|
<a id="release-summary-37"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
This release allow dashes in usernames for SSH\-based modules\.
|
This release allow dashes in usernames for SSH\-based modules\.
|
||||||
|
|
||||||
<a id="minor-changes-22"></a>
|
<a id="minor-changes-30"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* command \- added support for a dash \(<code>\-</code>\) in username \([https\://github\.com/ansible\-collections/community\.routeros/pull/18](https\://github\.com/ansible\-collections/community\.routeros/pull/18)\)\.
|
* command \- added support for a dash \(<code>\-</code>\) in username \([https\://github\.com/ansible\-collections/community\.routeros/pull/18](https\://github\.com/ansible\-collections/community\.routeros/pull/18)\)\.
|
||||||
|
@ -735,12 +900,12 @@ This release allow dashes in usernames for SSH\-based modules\.
|
||||||
<a id="v1-0-1"></a>
|
<a id="v1-0-1"></a>
|
||||||
## v1\.0\.1
|
## v1\.0\.1
|
||||||
|
|
||||||
<a id="release-summary-29"></a>
|
<a id="release-summary-38"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Maintenance release with a bugfix for <code>api</code>\.
|
Maintenance release with a bugfix for <code>api</code>\.
|
||||||
|
|
||||||
<a id="bugfixes-17"></a>
|
<a id="bugfixes-20"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api \- remove <code>id to \.id</code> as default requirement which conflicts with RouterOS <code>id</code> configuration parameter \([https\://github\.com/ansible\-collections/community\.routeros/pull/15](https\://github\.com/ansible\-collections/community\.routeros/pull/15)\)\.
|
* api \- remove <code>id to \.id</code> as default requirement which conflicts with RouterOS <code>id</code> configuration parameter \([https\://github\.com/ansible\-collections/community\.routeros/pull/15](https\://github\.com/ansible\-collections/community\.routeros/pull/15)\)\.
|
||||||
|
@ -748,12 +913,12 @@ Maintenance release with a bugfix for <code>api</code>\.
|
||||||
<a id="v1-0-0"></a>
|
<a id="v1-0-0"></a>
|
||||||
## v1\.0\.0
|
## v1\.0\.0
|
||||||
|
|
||||||
<a id="release-summary-30"></a>
|
<a id="release-summary-39"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
This is the first production \(non\-prerelease\) release of <code>community\.routeros</code>\.
|
This is the first production \(non\-prerelease\) release of <code>community\.routeros</code>\.
|
||||||
|
|
||||||
<a id="bugfixes-18"></a>
|
<a id="bugfixes-21"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* routeros terminal plugin \- allow slashes in hostnames for terminal detection\. Without this\, slashes in hostnames will result in connection timeouts \([https\://github\.com/ansible\-collections/community\.network/pull/138](https\://github\.com/ansible\-collections/community\.network/pull/138)\)\.
|
* routeros terminal plugin \- allow slashes in hostnames for terminal detection\. Without this\, slashes in hostnames will result in connection timeouts \([https\://github\.com/ansible\-collections/community\.network/pull/138](https\://github\.com/ansible\-collections/community\.network/pull/138)\)\.
|
||||||
|
@ -761,12 +926,12 @@ This is the first production \(non\-prerelease\) release of <code>community\.rou
|
||||||
<a id="v0-1-1"></a>
|
<a id="v0-1-1"></a>
|
||||||
## v0\.1\.1
|
## v0\.1\.1
|
||||||
|
|
||||||
<a id="release-summary-31"></a>
|
<a id="release-summary-40"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
Small improvements and bugfixes over the initial release\.
|
Small improvements and bugfixes over the initial release\.
|
||||||
|
|
||||||
<a id="bugfixes-19"></a>
|
<a id="bugfixes-22"></a>
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
* api \- fix crash when the <code>ssl</code> parameter is used \([https\://github\.com/ansible\-collections/community\.routeros/pull/3](https\://github\.com/ansible\-collections/community\.routeros/pull/3)\)\.
|
* api \- fix crash when the <code>ssl</code> parameter is used \([https\://github\.com/ansible\-collections/community\.routeros/pull/3](https\://github\.com/ansible\-collections/community\.routeros/pull/3)\)\.
|
||||||
|
@ -774,12 +939,12 @@ Small improvements and bugfixes over the initial release\.
|
||||||
<a id="v0-1-0"></a>
|
<a id="v0-1-0"></a>
|
||||||
## v0\.1\.0
|
## v0\.1\.0
|
||||||
|
|
||||||
<a id="release-summary-32"></a>
|
<a id="release-summary-41"></a>
|
||||||
### Release Summary
|
### Release Summary
|
||||||
|
|
||||||
The <code>community\.routeros</code> continues the work on the Ansible RouterOS modules from their state in <code>community\.network</code> 1\.2\.0\. The changes listed here are thus relative to the modules <code>community\.network\.routeros\_\*</code>\.
|
The <code>community\.routeros</code> continues the work on the Ansible RouterOS modules from their state in <code>community\.network</code> 1\.2\.0\. The changes listed here are thus relative to the modules <code>community\.network\.routeros\_\*</code>\.
|
||||||
|
|
||||||
<a id="minor-changes-23"></a>
|
<a id="minor-changes-31"></a>
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|
||||||
* facts \- now also collecting data about BGP and OSPF \([https\://github\.com/ansible\-collections/community\.network/pull/101](https\://github\.com/ansible\-collections/community\.network/pull/101)\)\.
|
* facts \- now also collecting data about BGP and OSPF \([https\://github\.com/ansible\-collections/community\.network/pull/101](https\://github\.com/ansible\-collections/community\.network/pull/101)\)\.
|
||||||
|
|
136
CHANGELOG.rst
136
CHANGELOG.rst
|
@ -4,6 +4,142 @@ Community RouterOS Release Notes
|
||||||
|
|
||||||
.. contents:: Topics
|
.. contents:: Topics
|
||||||
|
|
||||||
|
v3.8.1
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Bugfix release.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- facts and api_facts modules - prevent deprecation warnings when used with ansible-core 2.19 (https://github.com/ansible-collections/community.routeros/pull/384).
|
||||||
|
|
||||||
|
v3.8.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Feature release.
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- api_info, api_modify - add ``interface ethernet switch port-isolation`` which is supported since RouterOS 6.43 (https://github.com/ansible-collections/community.routeros/pull/375).
|
||||||
|
- api_info, api_modify - add ``routing bfd configuration``. Officially stabilized BFD support for BGP and OSPF is available since RouterOS 7.11
|
||||||
|
(https://github.com/ansible-collections/community.routeros/pull/375).
|
||||||
|
- api_modify, api_info - support API path ``ip ipsec mode-config`` (https://github.com/ansible-collections/community.routeros/pull/376).
|
||||||
|
|
||||||
|
v3.7.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Feature release.
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- api_find_and_modify - allow to control whether ``dynamic`` and/or ``builtin`` entries are ignored with the new ``ignore_dynamic`` and ``ignore_builtin`` options (https://github.com/ansible-collections/community.routeros/issues/372, https://github.com/ansible-collections/community.routeros/pull/373).
|
||||||
|
- api_info, api_modify - add ``port-cost-mode`` to ``interface bridge`` which is supported since RouterOS 7.13 (https://github.com/ansible-collections/community.routeros/pull/371).
|
||||||
|
|
||||||
|
v3.6.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Feature release.
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- api_info, api_modify - add ``mdns-repeat-ifaces`` to ``ip dns`` for RouterOS 7.16 and newer (https://github.com/ansible-collections/community.routeros/pull/358).
|
||||||
|
- api_info, api_modify - field name change in ``routing bgp connection`` path implemented by RouterOS 7.19 and newer (https://github.com/ansible-collections/community.routeros/pull/360).
|
||||||
|
- api_info, api_modify - rename ``is-responder`` property in ``interface wireguard peers`` to ``responder`` for RouterOS 7.17 and newer (https://github.com/ansible-collections/community.routeros/pull/364).
|
||||||
|
|
||||||
|
v3.5.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Feature release.
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- api_info, api_modify - change default for ``/ip/cloud/ddns-enabled`` for RouterOS 7.17 and newer from ``yes`` to ``auto`` (https://github.com/ansible-collections/community.routeros/pull/350).
|
||||||
|
|
||||||
|
v3.4.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Feature and bugfix release.
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- api_info, api_modify - add support for the ``ip dns forwarders`` path implemented by RouterOS 7.17 and newer (https://github.com/ansible-collections/community.routeros/pull/343).
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- api_info, api_modify - remove the primary key ``action`` from the ``interface wifi provisioning`` path, since RouterOS also allows to create completely duplicate entries (https://github.com/ansible-collections/community.routeros/issues/344, https://github.com/ansible-collections/community.routeros/pull/345).
|
||||||
|
|
||||||
|
v3.3.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Feature release.
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- api_info, api_modify - add missing attribute ``require-message-auth`` for the ``radius`` path which exists since RouterOS version 7.15 (https://github.com/ansible-collections/community.routeros/issues/338, https://github.com/ansible-collections/community.routeros/pull/339).
|
||||||
|
- api_info, api_modify - add the ``interface 6to4`` path. Used to manage IPv6 tunnels via tunnel-brokers like HE, where native IPv6 is not provided (https://github.com/ansible-collections/community.routeros/pull/342).
|
||||||
|
- api_info, api_modify - add the ``interface wireless access-list`` and ``interface wireless connect-list`` paths (https://github.com/ansible-collections/community.routeros/issues/284, https://github.com/ansible-collections/community.routeros/pull/340).
|
||||||
|
- api_info, api_modify - add the ``use-interface-duid`` option for ``ipv6 dhcp-client`` path. This option prevents issues with Fritzbox modems and routers, when using virtual interfaces (like VLANs) may create duplicated records in hosts config, this breaks original "expose-host" function. Also add the ``script``, ``custom-duid`` and ``validate-server-duid`` as backport from 7.15 version update (https://github.com/ansible-collections/community.routeros/pull/341).
|
||||||
|
|
||||||
|
v3.2.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Feature release.
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- api_info, api_modify - add support for the ``routing filter community-list`` path implemented by RouterOS 7 and newer (https://github.com/ansible-collections/community.routeros/pull/331).
|
||||||
|
|
||||||
|
v3.1.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Bugfix and feature release.
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- api_info, api_modify - add missing fields ``comment``, ``next-pool`` to ``ip pool`` path (https://github.com/ansible-collections/community.routeros/pull/327).
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- api_info, api_modify - fields ``log`` and ``log-prefix`` in paths ``ip firewall filter``, ``ip firewall mangle``, ``ip firewall nat``, ``ip firewall raw`` now have the correct default values (https://github.com/ansible-collections/community.routeros/pull/324).
|
||||||
|
|
||||||
v3.0.0
|
v3.0.0
|
||||||
======
|
======
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
-->
|
-->
|
||||||
|
|
||||||
# Community RouterOS Collection
|
# Community RouterOS Collection
|
||||||
[](https://github.com/ansible-collections/community.routeros/actions)
|
[](https://docs.ansible.com/ansible/devel/collections/community/routeros/)
|
||||||
|
[](https://github.com/ansible-collections/community.routeros/actions)
|
||||||
[](https://codecov.io/gh/ansible-collections/community.routeros)
|
[](https://codecov.io/gh/ansible-collections/community.routeros)
|
||||||
[](https://api.reuse.software/info/github.com/ansible-collections/community.routeros)
|
[](https://api.reuse.software/info/github.com/ansible-collections/community.routeros)
|
||||||
|
|
||||||
|
@ -33,11 +34,11 @@ For more information about communication, see the [Ansible communication guide](
|
||||||
|
|
||||||
## Tested with Ansible
|
## Tested with Ansible
|
||||||
|
|
||||||
Tested with the current ansible-core 2.15, ansible-core 2.16, ansible-core 2.17, and ansible-core 2.18 releases and the current development version of ansible-core. Ansible 2.9, ansible-base 2.10, and ansible-core versions before 2.15.0 are not supported.
|
Tested with the current ansible-core 2.15, ansible-core 2.16, ansible-core 2.17, ansible-core 2.18, and ansible-core 2.19 releases and the current development version of ansible-core. Ansible 2.9, ansible-base 2.10, and ansible-core versions before 2.15.0 are not supported.
|
||||||
|
|
||||||
## External requirements
|
## External requirements
|
||||||
|
|
||||||
The exact requirements for every module are listed in the module documentation.
|
The exact requirements for every module are listed in the module documentation.
|
||||||
|
|
||||||
### Supported connections
|
### Supported connections
|
||||||
|
|
||||||
|
@ -207,4 +208,4 @@ See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/commu
|
||||||
|
|
||||||
Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.routeros/blob/main/LICENSES/BSD-2-Clause.txt).
|
Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.routeros/blob/main/LICENSES/BSD-2-Clause.txt).
|
||||||
|
|
||||||
All files have a machine readable `SDPX-License-Identifier:` comment denoting its respective license(s) or an equivalent entry in an accompanying `.license` file. Only changelog fragments (which will not be part of a release) are covered by a blanket statement in `.reuse/dep5`. This conforms to the [REUSE specification](https://reuse.software/spec/).
|
All files have a machine readable `SDPX-License-Identifier:` comment denoting its respective license(s) or an equivalent entry in an accompanying `.license` file. Only changelog fragments (which will not be part of a release) are covered by a blanket statement in `REUSE.toml`. This conforms to the [REUSE specification](https://reuse.software/spec/).
|
||||||
|
|
11
REUSE.toml
Normal file
11
REUSE.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
version = 1
|
||||||
|
|
||||||
|
[[annotations]]
|
||||||
|
path = "changelogs/fragments/**"
|
||||||
|
precedence = "aggregate"
|
||||||
|
SPDX-FileCopyrightText = "Ansible Project"
|
||||||
|
SPDX-License-Identifier = "GPL-3.0-or-later"
|
97
antsibull-nox.toml
Normal file
97
antsibull-nox.toml
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
[collection_sources]
|
||||||
|
"community.internal_test_tools" = "git+https://github.com/ansible-collections/community.internal_test_tools.git,main"
|
||||||
|
"community.netcommon" = "git+https://github.com/ansible-collections/ansible.netcommon.git,main"
|
||||||
|
"community.utils" = "git+https://github.com/ansible-collections/ansible.utils.git,main"
|
||||||
|
|
||||||
|
[sessions]
|
||||||
|
|
||||||
|
[sessions.lint]
|
||||||
|
run_isort = false
|
||||||
|
run_black = false
|
||||||
|
run_flake8 = false
|
||||||
|
run_pylint = false
|
||||||
|
run_yamllint = true
|
||||||
|
yamllint_config = ".yamllint"
|
||||||
|
yamllint_config_plugins = ".yamllint-docs"
|
||||||
|
yamllint_config_plugins_examples = ".yamllint-examples"
|
||||||
|
yamllint_config_extra_docs = ".yamllint-extra-docs"
|
||||||
|
run_mypy = false
|
||||||
|
|
||||||
|
[sessions.docs_check]
|
||||||
|
validate_collection_refs="all"
|
||||||
|
codeblocks_restrict_types = [
|
||||||
|
"ansible-output",
|
||||||
|
"ini",
|
||||||
|
"yaml",
|
||||||
|
"yaml+jinja",
|
||||||
|
]
|
||||||
|
codeblocks_restrict_type_exact_case = true
|
||||||
|
codeblocks_allow_without_type = false
|
||||||
|
codeblocks_allow_literal_blocks = false
|
||||||
|
|
||||||
|
[sessions.license_check]
|
||||||
|
|
||||||
|
[sessions.extra_checks]
|
||||||
|
run_no_unwanted_files = true
|
||||||
|
no_unwanted_files_module_extensions = [".py"]
|
||||||
|
no_unwanted_files_yaml_extensions = [".yml"]
|
||||||
|
run_action_groups = true
|
||||||
|
run_no_trailing_whitespace = true
|
||||||
|
no_trailing_whitespace_skip_directories = [
|
||||||
|
"tests/unit/plugins/modules/fixtures/",
|
||||||
|
]
|
||||||
|
run_avoid_characters = true
|
||||||
|
|
||||||
|
[[sessions.extra_checks.action_groups_config]]
|
||||||
|
name = "api"
|
||||||
|
pattern = "^api.*$"
|
||||||
|
exclusions = []
|
||||||
|
doc_fragment = "community.routeros.attributes.actiongroup_api"
|
||||||
|
|
||||||
|
[[sessions.extra_checks.avoid_character_group]]
|
||||||
|
name = "tab"
|
||||||
|
regex = "\\x09"
|
||||||
|
|
||||||
|
[sessions.build_import_check]
|
||||||
|
run_galaxy_importer = true
|
||||||
|
|
||||||
|
[sessions.ansible_test_sanity]
|
||||||
|
include_devel = true
|
||||||
|
|
||||||
|
[sessions.ansible_test_units]
|
||||||
|
include_devel = true
|
||||||
|
|
||||||
|
[sessions.ansible_test_integration_w_default_container]
|
||||||
|
include_devel = true
|
||||||
|
controller_python_versions_only = true
|
||||||
|
|
||||||
|
[sessions.ansible_test_integration_w_default_container.core_python_versions]
|
||||||
|
"2.15" = ["2.7", "3.6", "3.7"]
|
||||||
|
"2.16" = ["3.10"]
|
||||||
|
"2.17" = ["3.8"]
|
||||||
|
"2.18" = ["3.9"]
|
||||||
|
"2.19" = ["3.11"]
|
||||||
|
|
||||||
|
[[sessions.ee_check.execution_environments]]
|
||||||
|
name = "devel-ubi-9"
|
||||||
|
description = "ansible-core devel @ RHEL UBI 9"
|
||||||
|
test_playbooks = ["tests/ee/all.yml"]
|
||||||
|
config.images.base_image.name = "docker.io/redhat/ubi9:latest"
|
||||||
|
config.dependencies.ansible_core.package_pip = "https://github.com/ansible/ansible/archive/devel.tar.gz"
|
||||||
|
config.dependencies.ansible_runner.package_pip = "ansible-runner"
|
||||||
|
config.dependencies.python_interpreter.package_system = "python3.12 python3.12-pip python3.12-wheel python3.12-cryptography"
|
||||||
|
config.dependencies.python_interpreter.python_path = "/usr/bin/python3.12"
|
||||||
|
runtime_environment = {"ANSIBLE_PRIVATE_ROLE_VARS" = "true"}
|
||||||
|
|
||||||
|
[[sessions.ee_check.execution_environments]]
|
||||||
|
name = "2.15-rocky-9"
|
||||||
|
description = "ansible-core 2.15 @ Rocky Linux 9"
|
||||||
|
test_playbooks = ["tests/ee/all.yml"]
|
||||||
|
config.images.base_image.name = "quay.io/rockylinux/rockylinux:9"
|
||||||
|
config.dependencies.ansible_core.package_pip = "https://github.com/ansible/ansible/archive/stable-2.15.tar.gz"
|
||||||
|
config.dependencies.ansible_runner.package_pip = "ansible-runner"
|
||||||
|
runtime_environment = {"ANSIBLE_PRIVATE_ROLE_VARS" = "true"}
|
|
@ -809,3 +809,138 @@ releases:
|
||||||
fragments:
|
fragments:
|
||||||
- 3.0.0.yml
|
- 3.0.0.yml
|
||||||
release_date: '2024-10-20'
|
release_date: '2024-10-20'
|
||||||
|
3.1.0:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- api_info, api_modify - fields ``log`` and ``log-prefix`` in paths ``ip firewall
|
||||||
|
filter``, ``ip firewall mangle``, ``ip firewall nat``, ``ip firewall raw``
|
||||||
|
now have the correct default values (https://github.com/ansible-collections/community.routeros/pull/324).
|
||||||
|
minor_changes:
|
||||||
|
- api_info, api_modify - add missing fields ``comment``, ``next-pool`` to
|
||||||
|
``ip pool`` path (https://github.com/ansible-collections/community.routeros/pull/327).
|
||||||
|
release_summary: Bugfix and feature release.
|
||||||
|
fragments:
|
||||||
|
- 3.1.0.yml
|
||||||
|
- 324-fix-firewall-log-and-log-prefix.yaml
|
||||||
|
- 327-add-missing-ip-pool-fields.yml
|
||||||
|
release_date: '2024-12-02'
|
||||||
|
3.2.0:
|
||||||
|
changes:
|
||||||
|
minor_changes:
|
||||||
|
- api_info, api_modify - add support for the ``routing filter community-list``
|
||||||
|
path implemented by RouterOS 7 and newer (https://github.com/ansible-collections/community.routeros/pull/331).
|
||||||
|
release_summary: Feature release.
|
||||||
|
fragments:
|
||||||
|
- 3.2.0.yml
|
||||||
|
- 331-add-routing-filter-community-list.yml
|
||||||
|
release_date: '2024-12-30'
|
||||||
|
3.3.0:
|
||||||
|
changes:
|
||||||
|
minor_changes:
|
||||||
|
- api_info, api_modify - add missing attribute ``require-message-auth`` for
|
||||||
|
the ``radius`` path which exists since RouterOS version 7.15 (https://github.com/ansible-collections/community.routeros/issues/338,
|
||||||
|
https://github.com/ansible-collections/community.routeros/pull/339).
|
||||||
|
- api_info, api_modify - add the ``interface 6to4`` path. Used to manage IPv6
|
||||||
|
tunnels via tunnel-brokers like HE, where native IPv6 is not provided (https://github.com/ansible-collections/community.routeros/pull/342).
|
||||||
|
- api_info, api_modify - add the ``interface wireless access-list`` and ``interface
|
||||||
|
wireless connect-list`` paths (https://github.com/ansible-collections/community.routeros/issues/284,
|
||||||
|
https://github.com/ansible-collections/community.routeros/pull/340).
|
||||||
|
- api_info, api_modify - add the ``use-interface-duid`` option for ``ipv6
|
||||||
|
dhcp-client`` path. This option prevents issues with Fritzbox modems and
|
||||||
|
routers, when using virtual interfaces (like VLANs) may create duplicated
|
||||||
|
records in hosts config, this breaks original "expose-host" function. Also
|
||||||
|
add the ``script``, ``custom-duid`` and ``validate-server-duid`` as backport
|
||||||
|
from 7.15 version update (https://github.com/ansible-collections/community.routeros/pull/341).
|
||||||
|
release_summary: Feature release.
|
||||||
|
fragments:
|
||||||
|
- 3.3.0.yml
|
||||||
|
- 339-add-require-message-auth-for-radius.yml
|
||||||
|
- 340-add-interface-wireless-access-and-connect-list.yml
|
||||||
|
- 341-add-dhcpv6-client-use-interface-duid.yml
|
||||||
|
- 342-add-interface-6to4.yml
|
||||||
|
release_date: '2025-01-27'
|
||||||
|
3.4.0:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- api_info, api_modify - remove the primary key ``action`` from the ``interface
|
||||||
|
wifi provisioning`` path, since RouterOS also allows to create completely
|
||||||
|
duplicate entries (https://github.com/ansible-collections/community.routeros/issues/344,
|
||||||
|
https://github.com/ansible-collections/community.routeros/pull/345).
|
||||||
|
minor_changes:
|
||||||
|
- api_info, api_modify - add support for the ``ip dns forwarders`` path implemented
|
||||||
|
by RouterOS 7.17 and newer (https://github.com/ansible-collections/community.routeros/pull/343).
|
||||||
|
release_summary: Feature and bugfix release.
|
||||||
|
fragments:
|
||||||
|
- 3.4.0.yml
|
||||||
|
- 343-add-ip-dns-forwarders.yml
|
||||||
|
- 345-interface-wifi-provisioning.yml
|
||||||
|
release_date: '2025-02-24'
|
||||||
|
3.5.0:
|
||||||
|
changes:
|
||||||
|
minor_changes:
|
||||||
|
- api_info, api_modify - change default for ``/ip/cloud/ddns-enabled`` for
|
||||||
|
RouterOS 7.17 and newer from ``yes`` to ``auto`` (https://github.com/ansible-collections/community.routeros/pull/350).
|
||||||
|
release_summary: Feature release.
|
||||||
|
fragments:
|
||||||
|
- 3.5.0.yml
|
||||||
|
- 350-ip-cloud-ddns-enabled-auto.yml
|
||||||
|
release_date: '2025-03-22'
|
||||||
|
3.6.0:
|
||||||
|
changes:
|
||||||
|
minor_changes:
|
||||||
|
- api_info, api_modify - add ``mdns-repeat-ifaces`` to ``ip dns`` for RouterOS
|
||||||
|
7.16 and newer (https://github.com/ansible-collections/community.routeros/pull/358).
|
||||||
|
- api_info, api_modify - field name change in ``routing bgp connection`` path
|
||||||
|
implemented by RouterOS 7.19 and newer (https://github.com/ansible-collections/community.routeros/pull/360).
|
||||||
|
- api_info, api_modify - rename ``is-responder`` property in ``interface wireguard
|
||||||
|
peers`` to ``responder`` for RouterOS 7.17 and newer (https://github.com/ansible-collections/community.routeros/pull/364).
|
||||||
|
release_summary: Feature release.
|
||||||
|
fragments:
|
||||||
|
- 3.6.0.yml
|
||||||
|
- 358-mdns-repeat-ifaces.yml
|
||||||
|
- 360-bgp-connection-afi.yml
|
||||||
|
- 364-wireguard-responder.yml
|
||||||
|
release_date: '2025-04-21'
|
||||||
|
3.7.0:
|
||||||
|
changes:
|
||||||
|
minor_changes:
|
||||||
|
- api_find_and_modify - allow to control whether ``dynamic`` and/or ``builtin``
|
||||||
|
entries are ignored with the new ``ignore_dynamic`` and ``ignore_builtin``
|
||||||
|
options (https://github.com/ansible-collections/community.routeros/issues/372,
|
||||||
|
https://github.com/ansible-collections/community.routeros/pull/373).
|
||||||
|
- api_info, api_modify - add ``port-cost-mode`` to ``interface bridge`` which
|
||||||
|
is supported since RouterOS 7.13 (https://github.com/ansible-collections/community.routeros/pull/371).
|
||||||
|
release_summary: Feature release.
|
||||||
|
fragments:
|
||||||
|
- 3.7.0.yml
|
||||||
|
- 371-add-bridge-port-cost-mode.yml
|
||||||
|
- 373-api_find_and_modify-dynamic-builtin.yml
|
||||||
|
release_date: '2025-05-31'
|
||||||
|
3.8.0:
|
||||||
|
changes:
|
||||||
|
minor_changes:
|
||||||
|
- api_info, api_modify - add ``interface ethernet switch port-isolation``
|
||||||
|
which is supported since RouterOS 6.43 (https://github.com/ansible-collections/community.routeros/pull/375).
|
||||||
|
- 'api_info, api_modify - add ``routing bfd configuration``. Officially stabilized
|
||||||
|
BFD support for BGP and OSPF is available since RouterOS 7.11
|
||||||
|
|
||||||
|
(https://github.com/ansible-collections/community.routeros/pull/375).
|
||||||
|
|
||||||
|
'
|
||||||
|
- api_modify, api_info - support API path ``ip ipsec mode-config`` (https://github.com/ansible-collections/community.routeros/pull/376).
|
||||||
|
release_summary: Feature release.
|
||||||
|
fragments:
|
||||||
|
- 3.8.0.yml
|
||||||
|
- 375-port_isolation-and-routing_bfd_configuration.yml
|
||||||
|
- 376-ipsec-mode-config.yml
|
||||||
|
release_date: '2025-06-14'
|
||||||
|
3.8.1:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- facts and api_facts modules - prevent deprecation warnings when used with
|
||||||
|
ansible-core 2.19 (https://github.com/ansible-collections/community.routeros/pull/384).
|
||||||
|
release_summary: Bugfix release.
|
||||||
|
fragments:
|
||||||
|
- 3.8.1.yml
|
||||||
|
- 384-warnings.yml
|
||||||
|
release_date: '2025-07-26'
|
||||||
|
|
|
@ -7,9 +7,9 @@ changelog_filename_template: ../CHANGELOG.rst
|
||||||
changelog_filename_version_depth: 0
|
changelog_filename_version_depth: 0
|
||||||
changes_file: changelog.yaml
|
changes_file: changelog.yaml
|
||||||
changes_format: combined
|
changes_format: combined
|
||||||
|
ignore_other_fragment_extensions: true
|
||||||
keep_fragments: false
|
keep_fragments: false
|
||||||
mention_ancestor: true
|
mention_ancestor: true
|
||||||
flatmap: true
|
|
||||||
new_plugins_after_name: removed_features
|
new_plugins_after_name: removed_features
|
||||||
notesdir: fragments
|
notesdir: fragments
|
||||||
output_formats:
|
output_formats:
|
||||||
|
@ -40,3 +40,4 @@ use_fqcn: true
|
||||||
add_plugin_period: true
|
add_plugin_period: true
|
||||||
changelog_nice_yaml: true
|
changelog_nice_yaml: true
|
||||||
changelog_sort: version
|
changelog_sort: version
|
||||||
|
vcs: auto
|
||||||
|
|
1
changelogs/fragments/3.9.0.yml
Normal file
1
changelogs/fragments/3.9.0.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
release_summary: Feature release.
|
3
changelogs/fragments/380-ipv6-settings.yml
Normal file
3
changelogs/fragments/380-ipv6-settings.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
minor_changes:
|
||||||
|
- api_info, api_modify - add ``disable-link-local-address`` and ``stale-neighbor-timeout`` fields to ``ipv6 settings`` (https://github.com/ansible-collections/community.routeros/pull/380).
|
||||||
|
- api_info, api_modify - adjust neighbor limit fields in ``ipv6 settings`` to match RouterOS 7.18 and newer (https://github.com/ansible-collections/community.routeros/pull/380).
|
2
changelogs/fragments/381-logging-cef.yml
Normal file
2
changelogs/fragments/381-logging-cef.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- api_info, api modify - add ``remote-log-format``, ``remote-protocol``, and ``event-delimiter`` to ``system logging action`` (https://github.com/ansible-collections/community.routeros/pull/381).
|
2
changelogs/fragments/382-mangle-passthrough.yml
Normal file
2
changelogs/fragments/382-mangle-passthrough.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- api_info, api_modify - set ``passthrough`` default in ``ip firewall mangle`` to ``true`` for RouterOS 7.19 and newer (https://github.com/ansible-collections/community.routeros/pull/382).
|
7
changelogs/fragments/385-vrf-support-for-ovpn-server.yml
Normal file
7
changelogs/fragments/385-vrf-support-for-ovpn-server.yml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
minor_changes:
|
||||||
|
- api_info, api_modify - since RouterOS 7.17 VRF is supported for OVPN server.
|
||||||
|
It now supports multiple entries, while ``api_modify`` so far only accepted a single entry.
|
||||||
|
The ``interface ovpn-server server`` path now allows multiple entries
|
||||||
|
on RouterOS 7.17 and newer
|
||||||
|
(https://github.com/ansible-collections/community.routeros/pull/383).
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
bugfixes:
|
||||||
|
- routeros terminal plugin - fix ``terminal_stdout_re`` pattern to handle long system identities when connecting to RouterOS through SSH (https://github.com/ansible-collections/community.routeros/pull/386).
|
|
@ -57,7 +57,7 @@ This results in the following output:
|
||||||
}
|
}
|
||||||
|
|
||||||
PLAY RECAP *******************************************************************************************************
|
PLAY RECAP *******************************************************************************************************
|
||||||
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||||
|
|
||||||
Check out the documentation of the :ansplugin:`community.routeros.api module <community.routeros.api#module>` for details on the options.
|
Check out the documentation of the :ansplugin:`community.routeros.api module <community.routeros.api#module>` for details on the options.
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ When this playbook completed successfully, you should be able to use the HTTPS a
|
||||||
.. code-block:: yaml+jinja
|
.. code-block:: yaml+jinja
|
||||||
|
|
||||||
- community.routeros.api:
|
- community.routeros.api:
|
||||||
...
|
# ...
|
||||||
tls: true
|
tls: true
|
||||||
validate_certs: true
|
validate_certs: true
|
||||||
validate_cert_hostname: true
|
validate_cert_hostname: true
|
||||||
|
|
|
@ -66,22 +66,22 @@ With the above inventory, you can use the following playbook to execute ``/syste
|
||||||
gather_facts: false
|
gather_facts: false
|
||||||
tasks:
|
tasks:
|
||||||
|
|
||||||
- name: Gather system resources
|
- name: Gather system resources
|
||||||
community.routeros.command:
|
community.routeros.command:
|
||||||
commands:
|
commands:
|
||||||
- /system resource print
|
- /system resource print
|
||||||
register: system_resource_print
|
register: system_resource_print
|
||||||
|
|
||||||
- name: Show system resources
|
- name: Show system resources
|
||||||
debug:
|
debug:
|
||||||
var: system_resource_print.stdout_lines
|
var: system_resource_print.stdout_lines
|
||||||
|
|
||||||
- name: Gather facts
|
- name: Gather facts
|
||||||
community.routeros.facts:
|
community.routeros.facts:
|
||||||
|
|
||||||
- name: Show a fact
|
- name: Show a fact
|
||||||
debug:
|
debug:
|
||||||
msg: "First IP address: {{ ansible_net_all_ipv4_addresses[0] }}"
|
msg: "First IP address: {{ ansible_net_all_ipv4_addresses[0] }}"
|
||||||
|
|
||||||
This results in the following output:
|
This results in the following output:
|
||||||
|
|
||||||
|
@ -126,4 +126,4 @@ This results in the following output:
|
||||||
}
|
}
|
||||||
|
|
||||||
PLAY RECAP *******************************************************************************************************
|
PLAY RECAP *******************************************************************************************************
|
||||||
router : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
router : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
namespace: community
|
namespace: community
|
||||||
name: routeros
|
name: routeros
|
||||||
version: 3.0.0
|
version: 3.9.0
|
||||||
readme: README.md
|
readme: README.md
|
||||||
authors:
|
authors:
|
||||||
- Egor Zaitsev (github.com/heuels)
|
- Egor Zaitsev (github.com/heuels)
|
||||||
|
@ -16,7 +16,7 @@ authors:
|
||||||
description: Modules and plugins for MikroTik RouterOS
|
description: Modules and plugins for MikroTik RouterOS
|
||||||
license:
|
license:
|
||||||
- GPL-3.0-or-later
|
- GPL-3.0-or-later
|
||||||
#license_file: COPYING
|
# license_file: COPYING
|
||||||
tags:
|
tags:
|
||||||
- network
|
- network
|
||||||
- mikrotik
|
- mikrotik
|
||||||
|
|
53
noxfile.py
Normal file
53
noxfile.py
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
# The following metadata allows Python runners and nox to install the required
|
||||||
|
# dependencies for running this Python script:
|
||||||
|
#
|
||||||
|
# /// script
|
||||||
|
# dependencies = ["nox>=2025.02.09", "antsibull-nox"]
|
||||||
|
# ///
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import nox
|
||||||
|
|
||||||
|
|
||||||
|
# We try to import antsibull-nox, and if that doesn't work, provide a more useful
|
||||||
|
# error message to the user.
|
||||||
|
try:
|
||||||
|
import antsibull_nox
|
||||||
|
except ImportError:
|
||||||
|
print("You need to install antsibull-nox in the same Python environment as nox.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
IN_CI = os.environ.get("CI") == "true"
|
||||||
|
|
||||||
|
|
||||||
|
antsibull_nox.load_antsibull_nox_toml()
|
||||||
|
|
||||||
|
|
||||||
|
@nox.session(name="update-docs", default=True)
|
||||||
|
def update_docs_fragments(session: nox.Session) -> None:
|
||||||
|
"""
|
||||||
|
Update/check auto-generated parts of docs fragments.
|
||||||
|
"""
|
||||||
|
session.install("ansible-core")
|
||||||
|
prepare = antsibull_nox.sessions.prepare_collections(
|
||||||
|
session, install_in_site_packages=True
|
||||||
|
)
|
||||||
|
if not prepare:
|
||||||
|
return
|
||||||
|
data = ["python", "tests/update-docs.py"]
|
||||||
|
if IN_CI:
|
||||||
|
data.append("--lint")
|
||||||
|
session.run(*data)
|
||||||
|
|
||||||
|
|
||||||
|
# Allow to run the noxfile with `python noxfile.py`, `pipx run noxfile.py`, or similar.
|
||||||
|
# Requires nox >= 2025.02.09
|
||||||
|
if __name__ == "__main__":
|
||||||
|
nox.main()
|
|
@ -5,15 +5,14 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = r"""
|
||||||
---
|
|
||||||
author: "Egor Zaitsev (@heuels)"
|
author: "Egor Zaitsev (@heuels)"
|
||||||
name: routeros
|
name: routeros
|
||||||
short_description: Use routeros cliconf to run command on MikroTik RouterOS platform
|
short_description: Use routeros cliconf to run command on MikroTik RouterOS platform
|
||||||
description:
|
description:
|
||||||
- This routeros plugin provides low level abstraction apis for
|
- This routeros plugin provides low level abstraction APIs for sending and receiving CLI commands from MikroTik RouterOS
|
||||||
sending and receiving CLI commands from MikroTik RouterOS network devices.
|
network devices.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
|
|
|
@ -10,7 +10,7 @@ __metaclass__ = type
|
||||||
|
|
||||||
class ModuleDocFragment(object):
|
class ModuleDocFragment(object):
|
||||||
|
|
||||||
DOCUMENTATION = r'''
|
DOCUMENTATION = r"""
|
||||||
options:
|
options:
|
||||||
hostname:
|
hostname:
|
||||||
description:
|
description:
|
||||||
|
@ -43,17 +43,16 @@ options:
|
||||||
- ssl
|
- ssl
|
||||||
port:
|
port:
|
||||||
description:
|
description:
|
||||||
- RouterOS api port. If O(tls) is set, port will apply to TLS/SSL connection.
|
- RouterOS API port. If O(tls) is set, port will apply to TLS/SSL connection.
|
||||||
- Defaults are V(8728) for the HTTP API, and V(8729) for the HTTPS API.
|
- Defaults are V(8728) for the HTTP API, and V(8729) for the HTTPS API.
|
||||||
type: int
|
type: int
|
||||||
force_no_cert:
|
force_no_cert:
|
||||||
description:
|
description:
|
||||||
- Set to V(true) to connect without a certificate when O(tls=true).
|
- Set to V(true) to connect without a certificate when O(tls=true).
|
||||||
- See also O(validate_certs).
|
- See also O(validate_certs).
|
||||||
- B(Note:) this forces the use of anonymous Diffie-Hellman (ADH) ciphers. The protocol is susceptible
|
- B(Note:) this forces the use of anonymous Diffie-Hellman (ADH) ciphers. The protocol is susceptible to Man-in-the-Middle
|
||||||
to Man-in-the-Middle attacks, because the keys used in the exchange are not authenticated.
|
attacks, because the keys used in the exchange are not authenticated. Instead of simply connecting without a certificate
|
||||||
Instead of simply connecting without a certificate to "make things work" have a look at
|
to "make things work" have a look at O(validate_certs) and O(ca_path).
|
||||||
O(validate_certs) and O(ca_path).
|
|
||||||
type: bool
|
type: bool
|
||||||
default: false
|
default: false
|
||||||
version_added: 2.4.0
|
version_added: 2.4.0
|
||||||
|
@ -61,10 +60,9 @@ options:
|
||||||
description:
|
description:
|
||||||
- Set to V(false) to skip validation of TLS certificates.
|
- Set to V(false) to skip validation of TLS certificates.
|
||||||
- See also O(validate_cert_hostname). Only used when O(tls=true).
|
- See also O(validate_cert_hostname). Only used when O(tls=true).
|
||||||
- B(Note:) instead of simply deactivating certificate validations to "make things work",
|
- B(Note:) instead of simply deactivating certificate validations to "make things work", please consider creating your
|
||||||
please consider creating your own CA certificate and using it to sign certificates used
|
own CA certificate and using it to sign certificates used for your router. You can tell the module about your CA certificate
|
||||||
for your router. You can tell the module about your CA certificate with the O(ca_path)
|
with the O(ca_path) option.
|
||||||
option.
|
|
||||||
type: bool
|
type: bool
|
||||||
default: true
|
default: true
|
||||||
version_added: 1.2.0
|
version_added: 1.2.0
|
||||||
|
@ -93,10 +91,10 @@ requirements:
|
||||||
- Python >= 3.6 (for librouteros)
|
- Python >= 3.6 (for librouteros)
|
||||||
seealso:
|
seealso:
|
||||||
- ref: ansible_collections.community.routeros.docsite.api-guide
|
- ref: ansible_collections.community.routeros.docsite.api-guide
|
||||||
description: How to connect to RouterOS devices with the RouterOS API
|
description: How to connect to RouterOS devices with the RouterOS API.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
RESTRICT = r'''
|
RESTRICT = r"""
|
||||||
options:
|
options:
|
||||||
restrict:
|
restrict:
|
||||||
type: list
|
type: list
|
||||||
|
@ -115,24 +113,21 @@ options:
|
||||||
values:
|
values:
|
||||||
description:
|
description:
|
||||||
- The values of the field to limit to.
|
- The values of the field to limit to.
|
||||||
- >-
|
- 'Note that the types of the values are important. If you provide a string V("0"), and librouteros converts the
|
||||||
Note that the types of the values are important. If you provide a string V("0"),
|
value returned by the API to the integer V(0), then this will not match. If you are not sure, better include both
|
||||||
and librouteros converts the value returned by the API to the integer V(0),
|
variants: both the string and the integer.'
|
||||||
then this will not match. If you are not sure, better include both variants:
|
|
||||||
both the string and the integer.
|
|
||||||
type: list
|
type: list
|
||||||
elements: raw
|
elements: raw
|
||||||
regex:
|
regex:
|
||||||
description:
|
description:
|
||||||
- A regular expression matching values of the field to limit to.
|
- A regular expression matching values of the field to limit to.
|
||||||
- Note that all values will be converted to strings before matching.
|
- Note that all values will be converted to strings before matching.
|
||||||
- It is not possible to match disabled values with regular expressions.
|
- It is not possible to match disabled values with regular expressions. Set O(restrict[].match_disabled=true) if
|
||||||
Set O(restrict[].match_disabled=true) if you also want to match disabled values.
|
you also want to match disabled values.
|
||||||
type: str
|
type: str
|
||||||
invert:
|
invert:
|
||||||
description:
|
description:
|
||||||
- Invert the condition. This affects O(restrict[].match_disabled), O(restrict[].values),
|
- Invert the condition. This affects O(restrict[].match_disabled), O(restrict[].values), and O(restrict[].regex).
|
||||||
and O(restrict[].regex).
|
|
||||||
type: bool
|
type: bool
|
||||||
default: false
|
default: false
|
||||||
'''
|
"""
|
||||||
|
|
|
@ -11,88 +11,102 @@ __metaclass__ = type
|
||||||
class ModuleDocFragment(object):
|
class ModuleDocFragment(object):
|
||||||
|
|
||||||
# Standard documentation fragment
|
# Standard documentation fragment
|
||||||
DOCUMENTATION = r'''
|
DOCUMENTATION = r"""
|
||||||
options: {}
|
options: {}
|
||||||
attributes:
|
attributes:
|
||||||
check_mode:
|
check_mode:
|
||||||
description: Can run in C(check_mode) and return changed status prediction without modifying target.
|
description: Can run in C(check_mode) and return changed status prediction without modifying target.
|
||||||
diff_mode:
|
diff_mode:
|
||||||
description: Will return details on what has changed (or possibly needs changing in C(check_mode)), when in diff mode.
|
description: Will return details on what has changed (or possibly needs changing in C(check_mode)), when in diff mode.
|
||||||
platform:
|
platform:
|
||||||
description: Target OS/families that can be operated against.
|
description: Target OS/families that can be operated against.
|
||||||
support: N/A
|
support: N/A
|
||||||
'''
|
idempotent:
|
||||||
|
description:
|
||||||
|
- When run twice in a row outside check mode, with the same arguments, the second invocation indicates no change.
|
||||||
|
- This assumes that the system controlled/queried by the module has not changed in a relevant way.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Should be used together with the standard fragment
|
||||||
|
IDEMPOTENT_NOT_MODIFY_STATE = r"""
|
||||||
|
options: {}
|
||||||
|
attributes:
|
||||||
|
idempotent:
|
||||||
|
support: full
|
||||||
|
details:
|
||||||
|
- This action does not modify state.
|
||||||
|
"""
|
||||||
|
|
||||||
# Should be used together with the standard fragment
|
# Should be used together with the standard fragment
|
||||||
INFO_MODULE = r'''
|
INFO_MODULE = r'''
|
||||||
options: {}
|
options: {}
|
||||||
attributes:
|
attributes:
|
||||||
check_mode:
|
check_mode:
|
||||||
support: full
|
support: full
|
||||||
details:
|
details:
|
||||||
- This action does not modify state.
|
- This action does not modify state.
|
||||||
diff_mode:
|
diff_mode:
|
||||||
support: N/A
|
support: N/A
|
||||||
details:
|
details:
|
||||||
- This action does not modify state.
|
- This action does not modify state.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
ACTIONGROUP_API = r'''
|
ACTIONGROUP_API = r'''
|
||||||
options: {}
|
options: {}
|
||||||
attributes:
|
attributes:
|
||||||
action_group:
|
action_group:
|
||||||
description: Use C(group/community.routeros.api) in C(module_defaults) to set defaults for this module.
|
description: Use C(group/community.routeros.api) in C(module_defaults) to set defaults for this module.
|
||||||
support: full
|
support: full
|
||||||
membership:
|
membership:
|
||||||
- community.routeros.api
|
- community.routeros.api
|
||||||
'''
|
'''
|
||||||
|
|
||||||
CONN = r'''
|
CONN = r"""
|
||||||
options: {}
|
options: {}
|
||||||
attributes:
|
attributes:
|
||||||
become:
|
become:
|
||||||
description: Is usable alongside C(become) keywords.
|
description: Is usable alongside C(become) keywords.
|
||||||
connection:
|
connection:
|
||||||
description: Uses the target's configured connection information to execute code on it.
|
description: Uses the target's configured connection information to execute code on it.
|
||||||
delegation:
|
delegation:
|
||||||
description: Can be used in conjunction with C(delegate_to) and related keywords.
|
description: Can be used in conjunction with C(delegate_to) and related keywords.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
FACTS = r'''
|
FACTS = r"""
|
||||||
options: {}
|
options: {}
|
||||||
attributes:
|
attributes:
|
||||||
facts:
|
facts:
|
||||||
description: Action returns an C(ansible_facts) dictionary that will update existing host facts.
|
description: Action returns an C(ansible_facts) dictionary that will update existing host facts.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
# Should be used together with the standard fragment and the FACTS fragment
|
# Should be used together with the standard fragment and the FACTS fragment
|
||||||
FACTS_MODULE = r'''
|
FACTS_MODULE = r'''
|
||||||
options: {}
|
options: {}
|
||||||
attributes:
|
attributes:
|
||||||
check_mode:
|
check_mode:
|
||||||
support: full
|
support: full
|
||||||
details:
|
details:
|
||||||
- This action does not modify state.
|
- This action does not modify state.
|
||||||
diff_mode:
|
diff_mode:
|
||||||
support: N/A
|
support: N/A
|
||||||
details:
|
details:
|
||||||
- This action does not modify state.
|
- This action does not modify state.
|
||||||
facts:
|
facts:
|
||||||
support: full
|
support: full
|
||||||
'''
|
'''
|
||||||
|
|
||||||
FILES = r'''
|
FILES = r"""
|
||||||
options: {}
|
options: {}
|
||||||
attributes:
|
attributes:
|
||||||
safe_file_operations:
|
safe_file_operations:
|
||||||
description: Uses Ansible's strict file operation functions to ensure proper permissions and avoid data corruption.
|
description: Uses Ansible's strict file operation functions to ensure proper permissions and avoid data corruption.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
FLOW = r'''
|
FLOW = r"""
|
||||||
options: {}
|
options: {}
|
||||||
attributes:
|
attributes:
|
||||||
action:
|
action:
|
||||||
description: Indicates this has a corresponding action plugin so some parts of the options can be executed on the controller.
|
description: Indicates this has a corresponding action plugin so some parts of the options can be executed on the controller.
|
||||||
async:
|
async:
|
||||||
description: Supports being used with the C(async) keyword.
|
description: Supports being used with the C(async) keyword.
|
||||||
'''
|
"""
|
||||||
|
|
|
@ -20,6 +20,7 @@ DOCUMENTATION:
|
||||||
- Felix Fontein (@felixfontein)
|
- Felix Fontein (@felixfontein)
|
||||||
|
|
||||||
EXAMPLES: |
|
EXAMPLES: |
|
||||||
|
---
|
||||||
- name: Join arguments for a RouterOS CLI command
|
- name: Join arguments for a RouterOS CLI command
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
arguments: "{{ ['foo=bar', 'comment=foo is bar'] | community.routeros.join }}"
|
arguments: "{{ ['foo=bar', 'comment=foo is bar'] | community.routeros.join }}"
|
||||||
|
|
|
@ -30,6 +30,7 @@ DOCUMENTATION:
|
||||||
- Felix Fontein (@felixfontein)
|
- Felix Fontein (@felixfontein)
|
||||||
|
|
||||||
EXAMPLES: |
|
EXAMPLES: |
|
||||||
|
---
|
||||||
- name: Convert a list to a dictionary
|
- name: Convert a list to a dictionary
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
dictionary: "{{ ['foo=bar', 'comment=foo is bar'] | community.routeros.list_to_dict }}"
|
dictionary: "{{ ['foo=bar', 'comment=foo is bar'] | community.routeros.list_to_dict }}"
|
||||||
|
|
|
@ -19,9 +19,11 @@ DOCUMENTATION:
|
||||||
- Felix Fontein (@felixfontein)
|
- Felix Fontein (@felixfontein)
|
||||||
|
|
||||||
EXAMPLES: |
|
EXAMPLES: |
|
||||||
|
---
|
||||||
- name: Quote a RouterOS CLI command argument
|
- name: Quote a RouterOS CLI command argument
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
quoted: "{{ 'comment=this is a "comment"' | community.routeros.quote_argument }}"
|
quoted: >-
|
||||||
|
{{ 'comment=this is a "comment"' | community.routeros.quote_argument }}
|
||||||
# Should result in 'comment="this is a \"comment\""'
|
# Should result in 'comment="this is a \"comment\""'
|
||||||
|
|
||||||
RETURN:
|
RETURN:
|
||||||
|
|
|
@ -19,9 +19,11 @@ DOCUMENTATION:
|
||||||
- Felix Fontein (@felixfontein)
|
- Felix Fontein (@felixfontein)
|
||||||
|
|
||||||
EXAMPLES: |
|
EXAMPLES: |
|
||||||
|
---
|
||||||
- name: Quote a RouterOS CLI command argument's value
|
- name: Quote a RouterOS CLI command argument's value
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
quoted: "{{ 'this is a "comment"' | community.routeros.quote_argument_value }}"
|
quoted: >-
|
||||||
|
{{ 'this is a "comment"' | community.routeros.quote_argument_value }}
|
||||||
# Should result in '"this is a \"comment\""'
|
# Should result in '"this is a \"comment\""'
|
||||||
|
|
||||||
RETURN:
|
RETURN:
|
||||||
|
|
|
@ -19,9 +19,11 @@ DOCUMENTATION:
|
||||||
- Felix Fontein (@felixfontein)
|
- Felix Fontein (@felixfontein)
|
||||||
|
|
||||||
EXAMPLES: |
|
EXAMPLES: |
|
||||||
|
---
|
||||||
- name: Split command into list of arguments
|
- name: Split command into list of arguments
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
argument_list: "{{ 'foo=bar comment="foo is bar" baz' | community.routeros.split }}"
|
argument_list: >-
|
||||||
|
{{ 'foo=bar comment="foo is bar" baz' | community.routeros.split }}
|
||||||
# Should result in ['foo=bar', 'comment=foo is bar', 'baz']
|
# Should result in ['foo=bar', 'comment=foo is bar', 'baz']
|
||||||
|
|
||||||
RETURN:
|
RETURN:
|
||||||
|
|
|
@ -226,6 +226,25 @@ def join_path(path):
|
||||||
# 3. All bold attributes go into the `primary_keys` list -- this is not always true!
|
# 3. All bold attributes go into the `primary_keys` list -- this is not always true!
|
||||||
|
|
||||||
PATHS = {
|
PATHS = {
|
||||||
|
('interface', '6to4'): APIData(
|
||||||
|
unversioned=VersionedAPIData(
|
||||||
|
fully_understood=True,
|
||||||
|
primary_keys=('name', ),
|
||||||
|
fields={
|
||||||
|
'clamp-tcp-mss': KeyInfo(default=True),
|
||||||
|
'comment': KeyInfo(can_disable=True, remove_value=''),
|
||||||
|
'disabled': KeyInfo(default=False),
|
||||||
|
'dont-fragment': KeyInfo(default=False),
|
||||||
|
'dscp': KeyInfo(default='inherit'),
|
||||||
|
'ipsec-secret': KeyInfo(can_disable=True),
|
||||||
|
'keepalive': KeyInfo(default='10s,10', can_disable=True),
|
||||||
|
'local-address': KeyInfo(default='0.0.0.0'),
|
||||||
|
'mtu': KeyInfo(default='auto'),
|
||||||
|
'name': KeyInfo(),
|
||||||
|
'remote-address': KeyInfo(required=True),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
('interface', 'bonding'): APIData(
|
('interface', 'bonding'): APIData(
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
|
@ -262,6 +281,7 @@ PATHS = {
|
||||||
versioned_fields=[
|
versioned_fields=[
|
||||||
([('7.0', '<')], 'ingress-filtering', KeyInfo(default=False)),
|
([('7.0', '<')], 'ingress-filtering', KeyInfo(default=False)),
|
||||||
([('7.0', '>=')], 'ingress-filtering', KeyInfo(default=True)),
|
([('7.0', '>=')], 'ingress-filtering', KeyInfo(default=True)),
|
||||||
|
([('7.13', '>=')], 'port-cost-mode', KeyInfo(default='long')),
|
||||||
([('7.16', '>=')], 'forward-reserved-addresses', KeyInfo(default=False)),
|
([('7.16', '>=')], 'forward-reserved-addresses', KeyInfo(default=False)),
|
||||||
([('7.16', '>=')], 'max-learned-entries', KeyInfo(default='auto')),
|
([('7.16', '>=')], 'max-learned-entries', KeyInfo(default='auto')),
|
||||||
],
|
],
|
||||||
|
@ -632,13 +652,22 @@ PATHS = {
|
||||||
),
|
),
|
||||||
('ip', 'ipsec', 'mode-config'): APIData(
|
('ip', 'ipsec', 'mode-config'): APIData(
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
unknown_mechanism=True,
|
fully_understood=True,
|
||||||
# primary_keys=('default', ),
|
primary_keys=('name', ),
|
||||||
|
versioned_fields=[
|
||||||
|
([('6.43', '>=')], 'responder', KeyInfo(default=False)),
|
||||||
|
([('6.44', '>=')], 'address', KeyInfo(can_disable=True, remove_value='0.0.0.0')),
|
||||||
|
],
|
||||||
fields={
|
fields={
|
||||||
'default': KeyInfo(),
|
'address-pool': KeyInfo(can_disable=True, remove_value='none'),
|
||||||
|
'address-prefix-length': KeyInfo(),
|
||||||
|
'comment': KeyInfo(can_disable=True, remove_value=''),
|
||||||
'name': KeyInfo(),
|
'name': KeyInfo(),
|
||||||
'responder': KeyInfo(),
|
'split-dns': KeyInfo(can_disable=True, remove_value=''),
|
||||||
'use-responder-dns': KeyInfo(),
|
'split-include': KeyInfo(can_disable=True, remove_value=''),
|
||||||
|
'src-address-list': KeyInfo(can_disable=True, remove_value=''),
|
||||||
|
'static-dns': KeyInfo(can_disable=True, remove_value=''),
|
||||||
|
'system-dns': KeyInfo(default=False),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -708,7 +737,9 @@ PATHS = {
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
primary_keys=('name', ),
|
primary_keys=('name', ),
|
||||||
fields={
|
fields={
|
||||||
|
'comment': KeyInfo(),
|
||||||
'name': KeyInfo(),
|
'name': KeyInfo(),
|
||||||
|
'next-pool': KeyInfo(),
|
||||||
'ranges': KeyInfo(),
|
'ranges': KeyInfo(),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -893,6 +924,20 @@ PATHS = {
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
('routing', 'filter', 'community-list'): APIData(
|
||||||
|
versioned=[
|
||||||
|
('7', '>=', VersionedAPIData(
|
||||||
|
fully_understood=True,
|
||||||
|
fields={
|
||||||
|
'list': KeyInfo(required=True),
|
||||||
|
'comment': KeyInfo(can_disable=True, remove_value=''),
|
||||||
|
'disabled': KeyInfo(can_disable=True),
|
||||||
|
'communities': KeyInfo(can_disable=True),
|
||||||
|
'regexp': KeyInfo(can_disable=True),
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
('routing', 'ospf', 'instance'): APIData(
|
('routing', 'ospf', 'instance'): APIData(
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
|
@ -1508,13 +1553,19 @@ PATHS = {
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
versioned_fields=[
|
versioned_fields=[
|
||||||
([('7.16', '>=')], 'multipath-hash-policy', KeyInfo(default='l3')),
|
([('7.16', '>=')], 'multipath-hash-policy', KeyInfo(default='l3')),
|
||||||
|
([('7.17', '>=')], 'disable-link-local-address', KeyInfo(default=False)),
|
||||||
|
([('7.17', '>=')], 'stale-neighbor-timeout', KeyInfo(default=60)),
|
||||||
|
([('7.18', '>=')], 'allow-fast-path', KeyInfo(default=True)),
|
||||||
|
([('7.18', '<')], 'max-neighbor-entries', KeyInfo(default=8192)),
|
||||||
|
([('7.18', '>=')], 'min-neighbor-entries', KeyInfo()),
|
||||||
|
([('7.18', '>=')], 'soft-max-neighbor-entries', KeyInfo()),
|
||||||
|
([('7.18', '>=')], 'max-neighbor-entries', KeyInfo()),
|
||||||
],
|
],
|
||||||
fields={
|
fields={
|
||||||
'accept-redirects': KeyInfo(default='yes-if-forwarding-disabled'),
|
'accept-redirects': KeyInfo(default='yes-if-forwarding-disabled'),
|
||||||
'accept-router-advertisements': KeyInfo(default='yes-if-forwarding-disabled'),
|
'accept-router-advertisements': KeyInfo(default='yes-if-forwarding-disabled'),
|
||||||
'disable-ipv6': KeyInfo(default=False),
|
'disable-ipv6': KeyInfo(default=False),
|
||||||
'forward': KeyInfo(default=True),
|
'forward': KeyInfo(default=True),
|
||||||
'max-neighbor-entries': KeyInfo(default=8192),
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1613,23 +1664,46 @@ PATHS = {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
('interface', 'ovpn-server', 'server'): APIData(
|
('interface', 'ovpn-server', 'server'): APIData(
|
||||||
unversioned=VersionedAPIData(
|
versioned=[
|
||||||
single_value=True,
|
('7.17', '>=', VersionedAPIData(
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
fields={
|
fields={
|
||||||
'auth': KeyInfo(),
|
'auth': KeyInfo(),
|
||||||
'cipher': KeyInfo(),
|
'cipher': KeyInfo(),
|
||||||
'default-profile': KeyInfo(default='default'),
|
'default-profile': KeyInfo(default='default'),
|
||||||
'enabled': KeyInfo(default=False),
|
'enabled': KeyInfo(default=False),
|
||||||
'keepalive-timeout': KeyInfo(default=60),
|
'keepalive-timeout': KeyInfo(default=60),
|
||||||
'mac-address': KeyInfo(),
|
'mac-address': KeyInfo(),
|
||||||
'max-mtu': KeyInfo(default=1500),
|
'max-mtu': KeyInfo(default=1500),
|
||||||
'mode': KeyInfo(default='ip'),
|
'mode': KeyInfo(default='ip'),
|
||||||
'netmask': KeyInfo(default=24),
|
'name': KeyInfo(default=''),
|
||||||
'port': KeyInfo(default=1194),
|
'netmask': KeyInfo(default=24),
|
||||||
'require-client-certificate': KeyInfo(default=False),
|
'port': KeyInfo(default=1194),
|
||||||
},
|
'protocol': KeyInfo(default='tcp'),
|
||||||
),
|
'require-client-certificate': KeyInfo(default=False),
|
||||||
|
'vrf': KeyInfo(default='main'),
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
('7.17', '<', VersionedAPIData(
|
||||||
|
single_value=True,
|
||||||
|
fully_understood=True,
|
||||||
|
fields={
|
||||||
|
'auth': KeyInfo(),
|
||||||
|
'cipher': KeyInfo(),
|
||||||
|
'default-profile': KeyInfo(default='default'),
|
||||||
|
'enabled': KeyInfo(default=False),
|
||||||
|
'keepalive-timeout': KeyInfo(default=60),
|
||||||
|
'mac-address': KeyInfo(),
|
||||||
|
'max-mtu': KeyInfo(default=1500),
|
||||||
|
'mode': KeyInfo(default='ip'),
|
||||||
|
'name': KeyInfo(default=''),
|
||||||
|
'netmask': KeyInfo(default=24),
|
||||||
|
'port': KeyInfo(default=1194),
|
||||||
|
'protocol': KeyInfo(default='tcp'),
|
||||||
|
'require-client-certificate': KeyInfo(default=False),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
]
|
||||||
),
|
),
|
||||||
('interface', 'pppoe-server', 'server'): APIData(
|
('interface', 'pppoe-server', 'server'): APIData(
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
|
@ -2002,7 +2076,6 @@ PATHS = {
|
||||||
versioned=[
|
versioned=[
|
||||||
('7.13', '>=', VersionedAPIData(
|
('7.13', '>=', VersionedAPIData(
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
primary_keys=('action', ),
|
|
||||||
fields={
|
fields={
|
||||||
'action': KeyInfo(default='none'),
|
'action': KeyInfo(default='none'),
|
||||||
'address-ranges': KeyInfo(can_disable=True),
|
'address-ranges': KeyInfo(can_disable=True),
|
||||||
|
@ -2407,7 +2480,8 @@ PATHS = {
|
||||||
},
|
},
|
||||||
versioned_fields=[
|
versioned_fields=[
|
||||||
([('7.15', '>=')], 'name', KeyInfo()),
|
([('7.15', '>=')], 'name', KeyInfo()),
|
||||||
([('7.15', '>=')], 'is-responder', KeyInfo()),
|
([('7.15', '>='), ('7.17', '<')], 'is-responder', KeyInfo()),
|
||||||
|
([('7.17', '>=')], 'responder', KeyInfo()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -2529,6 +2603,30 @@ PATHS = {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
('interface', 'wireless', 'access-list'): APIData(
|
||||||
|
unversioned=VersionedAPIData(
|
||||||
|
fully_understood=True,
|
||||||
|
fields={
|
||||||
|
'allow-signal-out-of-range': KeyInfo(default='10s'),
|
||||||
|
'ap-tx-limit': KeyInfo(default=0),
|
||||||
|
'authentication': KeyInfo(default=True),
|
||||||
|
'client-tx-limit': KeyInfo(default=0),
|
||||||
|
'comment': KeyInfo(can_disable=True, remove_value=''),
|
||||||
|
'disabled': KeyInfo(default=False),
|
||||||
|
'forwarding': KeyInfo(default=True),
|
||||||
|
'interface': KeyInfo(default='any'),
|
||||||
|
'mac-address': KeyInfo(default='00:00:00:00:00:00'),
|
||||||
|
'management-protection-key': KeyInfo(default=''),
|
||||||
|
'private-algo': KeyInfo(default='none'),
|
||||||
|
'private-key': KeyInfo(default=''),
|
||||||
|
'private-pre-shared-key': KeyInfo(default=''),
|
||||||
|
'signal-range': KeyInfo(default='-120..120'),
|
||||||
|
'time': KeyInfo(),
|
||||||
|
'vlan-id': KeyInfo(default=1),
|
||||||
|
'vlan-mode': KeyInfo(default='default'),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
('interface', 'wireless', 'cap'): APIData(
|
('interface', 'wireless', 'cap'): APIData(
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
single_value=True,
|
single_value=True,
|
||||||
|
@ -2547,6 +2645,41 @@ PATHS = {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
('interface', 'wireless', 'connect-list'): APIData(
|
||||||
|
unversioned=VersionedAPIData(
|
||||||
|
fully_understood=True,
|
||||||
|
fields={
|
||||||
|
'3gpp': KeyInfo(default=''),
|
||||||
|
'allow-signal-out-of-range': KeyInfo(default='10s'),
|
||||||
|
'area-prefix': KeyInfo(default=''),
|
||||||
|
'comment': KeyInfo(can_disable=True, remove_value=''),
|
||||||
|
'connect': KeyInfo(default=True),
|
||||||
|
'disabled': KeyInfo(default=False),
|
||||||
|
'interface': KeyInfo(required=True),
|
||||||
|
'interworking': KeyInfo(default='any'),
|
||||||
|
'iw-asra': KeyInfo(default='any'),
|
||||||
|
'iw-authentication-types': KeyInfo(),
|
||||||
|
'iw-connection-capabilities': KeyInfo(),
|
||||||
|
'iw-esr': KeyInfo(default='any'),
|
||||||
|
'iw-hessid': KeyInfo(default='00:00:00:00:00:00'),
|
||||||
|
'iw-hotspot20': KeyInfo(default='any'),
|
||||||
|
'iw-hotspot20-dgaf': KeyInfo(default='any'),
|
||||||
|
'iw-internet': KeyInfo(default='any'),
|
||||||
|
'iw-ipv4-availability': KeyInfo(default='any'),
|
||||||
|
'iw-ipv6-availability': KeyInfo(default='any'),
|
||||||
|
'iw-network-type': KeyInfo(default='wildcard'),
|
||||||
|
'iw-realms': KeyInfo(),
|
||||||
|
'iw-roaming-ois': KeyInfo(default=''),
|
||||||
|
'iw-uesa': KeyInfo(default='any'),
|
||||||
|
'iw-venue': KeyInfo(default='any'),
|
||||||
|
'mac-address': KeyInfo(default='00:00:00:00:00:00'),
|
||||||
|
'security-profile': KeyInfo(default='none'),
|
||||||
|
'signal-range': KeyInfo(default='-120..120'),
|
||||||
|
'ssid': KeyInfo(default=''),
|
||||||
|
'wireless-protocol': KeyInfo(default='any'),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
('interface', 'wireless', 'security-profiles'): APIData(
|
('interface', 'wireless', 'security-profiles'): APIData(
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
|
@ -2684,8 +2817,11 @@ PATHS = {
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
single_value=True,
|
single_value=True,
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
|
versioned_fields=[
|
||||||
|
([('7.17', '<')], 'ddns-enabled', KeyInfo(default=False)),
|
||||||
|
([('7.17', '>=')], 'ddns-enabled', KeyInfo(default='auto')),
|
||||||
|
],
|
||||||
fields={
|
fields={
|
||||||
'ddns-enabled': KeyInfo(default=False),
|
|
||||||
'ddns-update-interval': KeyInfo(default='none'),
|
'ddns-update-interval': KeyInfo(default='none'),
|
||||||
'update-time': KeyInfo(default=True),
|
'update-time': KeyInfo(default=True),
|
||||||
},
|
},
|
||||||
|
@ -2871,6 +3007,7 @@ PATHS = {
|
||||||
([('7.8', '>=')], 'doh-max-concurrent-queries', KeyInfo(default=50)),
|
([('7.8', '>=')], 'doh-max-concurrent-queries', KeyInfo(default=50)),
|
||||||
([('7.8', '>=')], 'doh-max-server-connections', KeyInfo(default=5)),
|
([('7.8', '>=')], 'doh-max-server-connections', KeyInfo(default=5)),
|
||||||
([('7.8', '>=')], 'doh-timeout', KeyInfo(default='5s')),
|
([('7.8', '>=')], 'doh-timeout', KeyInfo(default='5s')),
|
||||||
|
([('7.16', '>=')], 'mdns-repeat-ifaces', KeyInfo()),
|
||||||
],
|
],
|
||||||
fields={
|
fields={
|
||||||
'allow-remote-requests': KeyInfo(),
|
'allow-remote-requests': KeyInfo(),
|
||||||
|
@ -2903,6 +3040,22 @@ PATHS = {
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
('ip', 'dns', 'forwarders'): APIData(
|
||||||
|
versioned=[
|
||||||
|
('7.17', '>=', VersionedAPIData(
|
||||||
|
fully_understood=True,
|
||||||
|
required_one_of=[['dns-servers', 'doh-servers']],
|
||||||
|
fields={
|
||||||
|
'comment': KeyInfo(can_disable=True, remove_value=''),
|
||||||
|
'disabled': KeyInfo(default=False),
|
||||||
|
'dns-servers': KeyInfo(default=''),
|
||||||
|
'doh-servers': KeyInfo(default=''),
|
||||||
|
'name': KeyInfo(required=True),
|
||||||
|
'verify-doh-cert': KeyInfo(default=True),
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
('ip', 'dns', 'static'): APIData(
|
('ip', 'dns', 'static'): APIData(
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
|
@ -2984,8 +3137,8 @@ PATHS = {
|
||||||
'jump-target': KeyInfo(can_disable=True),
|
'jump-target': KeyInfo(can_disable=True),
|
||||||
'layer7-protocol': KeyInfo(can_disable=True),
|
'layer7-protocol': KeyInfo(can_disable=True),
|
||||||
'limit': KeyInfo(can_disable=True),
|
'limit': KeyInfo(can_disable=True),
|
||||||
'log': KeyInfo(can_disable=True),
|
'log': KeyInfo(default=False),
|
||||||
'log-prefix': KeyInfo(can_disable=True),
|
'log-prefix': KeyInfo(default=''),
|
||||||
'nth': KeyInfo(can_disable=True),
|
'nth': KeyInfo(can_disable=True),
|
||||||
'out-bridge-port': KeyInfo(can_disable=True),
|
'out-bridge-port': KeyInfo(can_disable=True),
|
||||||
'out-bridge-port-list': KeyInfo(can_disable=True),
|
'out-bridge-port-list': KeyInfo(can_disable=True),
|
||||||
|
@ -3021,6 +3174,10 @@ PATHS = {
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
stratify_keys=('chain', ),
|
stratify_keys=('chain', ),
|
||||||
|
versioned_fields=[
|
||||||
|
([('7.19', '<')], 'passthrough', KeyInfo(can_disable=True)),
|
||||||
|
([('7.19', '>=')], 'passthrough', KeyInfo(default=True)),
|
||||||
|
],
|
||||||
fields={
|
fields={
|
||||||
'action': KeyInfo(),
|
'action': KeyInfo(),
|
||||||
'address-list': KeyInfo(can_disable=True),
|
'address-list': KeyInfo(can_disable=True),
|
||||||
|
@ -3055,8 +3212,8 @@ PATHS = {
|
||||||
'jump-target': KeyInfo(can_disable=True),
|
'jump-target': KeyInfo(can_disable=True),
|
||||||
'layer7-protocol': KeyInfo(can_disable=True),
|
'layer7-protocol': KeyInfo(can_disable=True),
|
||||||
'limit': KeyInfo(can_disable=True),
|
'limit': KeyInfo(can_disable=True),
|
||||||
'log': KeyInfo(can_disable=True),
|
'log': KeyInfo(default=False),
|
||||||
'log-prefix': KeyInfo(can_disable=True),
|
'log-prefix': KeyInfo(default=''),
|
||||||
'new-connection-mark': KeyInfo(can_disable=True),
|
'new-connection-mark': KeyInfo(can_disable=True),
|
||||||
'new-dscp': KeyInfo(can_disable=True),
|
'new-dscp': KeyInfo(can_disable=True),
|
||||||
'new-mss': KeyInfo(can_disable=True),
|
'new-mss': KeyInfo(can_disable=True),
|
||||||
|
@ -3072,7 +3229,6 @@ PATHS = {
|
||||||
'p2p': KeyInfo(can_disable=True),
|
'p2p': KeyInfo(can_disable=True),
|
||||||
'packet-mark': KeyInfo(can_disable=True),
|
'packet-mark': KeyInfo(can_disable=True),
|
||||||
'packet-size': KeyInfo(can_disable=True),
|
'packet-size': KeyInfo(can_disable=True),
|
||||||
'passthrough': KeyInfo(can_disable=True),
|
|
||||||
'per-connection-classifier': KeyInfo(can_disable=True),
|
'per-connection-classifier': KeyInfo(can_disable=True),
|
||||||
'port': KeyInfo(can_disable=True),
|
'port': KeyInfo(can_disable=True),
|
||||||
'priority': KeyInfo(can_disable=True),
|
'priority': KeyInfo(can_disable=True),
|
||||||
|
@ -3135,8 +3291,8 @@ PATHS = {
|
||||||
'jump-target': KeyInfo(can_disable=True),
|
'jump-target': KeyInfo(can_disable=True),
|
||||||
'layer7-protocol': KeyInfo(can_disable=True),
|
'layer7-protocol': KeyInfo(can_disable=True),
|
||||||
'limit': KeyInfo(can_disable=True),
|
'limit': KeyInfo(can_disable=True),
|
||||||
'log': KeyInfo(can_disable=True),
|
'log': KeyInfo(default=False),
|
||||||
'log-prefix': KeyInfo(can_disable=True),
|
'log-prefix': KeyInfo(default=''),
|
||||||
'nth': KeyInfo(can_disable=True),
|
'nth': KeyInfo(can_disable=True),
|
||||||
'out-bridge-port': KeyInfo(can_disable=True),
|
'out-bridge-port': KeyInfo(can_disable=True),
|
||||||
'out-bridge-port-list': KeyInfo(can_disable=True),
|
'out-bridge-port-list': KeyInfo(can_disable=True),
|
||||||
|
@ -3198,8 +3354,8 @@ PATHS = {
|
||||||
'ipv4-options': KeyInfo(can_disable=True),
|
'ipv4-options': KeyInfo(can_disable=True),
|
||||||
'jump-target': KeyInfo(can_disable=True),
|
'jump-target': KeyInfo(can_disable=True),
|
||||||
'limit': KeyInfo(can_disable=True),
|
'limit': KeyInfo(can_disable=True),
|
||||||
'log': KeyInfo(can_disable=True),
|
'log': KeyInfo(default=False),
|
||||||
'log-prefix': KeyInfo(can_disable=True),
|
'log-prefix': KeyInfo(default=''),
|
||||||
'nth': KeyInfo(can_disable=True),
|
'nth': KeyInfo(can_disable=True),
|
||||||
'out-bridge-port': KeyInfo(can_disable=True),
|
'out-bridge-port': KeyInfo(can_disable=True),
|
||||||
'out-bridge-port-list': KeyInfo(can_disable=True),
|
'out-bridge-port-list': KeyInfo(can_disable=True),
|
||||||
|
@ -3469,6 +3625,14 @@ PATHS = {
|
||||||
'request': KeyInfo(),
|
'request': KeyInfo(),
|
||||||
'use-peer-dns': KeyInfo(default=True),
|
'use-peer-dns': KeyInfo(default=True),
|
||||||
},
|
},
|
||||||
|
versioned_fields=[
|
||||||
|
# Mikrotik does not provide exact version in official changelogs.
|
||||||
|
# The 7.15 version is the earliest, found option in router config backups:
|
||||||
|
([('7.15', '>=')], 'script', KeyInfo(default='')),
|
||||||
|
([('7.15', '>=')], 'custom-duid', KeyInfo(default='')),
|
||||||
|
([('7.15', '>=')], 'use-interface-duid', KeyInfo(default=False)),
|
||||||
|
([('7.15', '>=')], 'validate-server-duid', KeyInfo(default=True)),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
('ipv6', 'dhcp-server'): APIData(
|
('ipv6', 'dhcp-server'): APIData(
|
||||||
|
@ -4002,6 +4166,9 @@ PATHS = {
|
||||||
'src-address': KeyInfo(default='0.0.0.0'),
|
'src-address': KeyInfo(default='0.0.0.0'),
|
||||||
'timeout': KeyInfo(default='300ms'),
|
'timeout': KeyInfo(default='300ms'),
|
||||||
},
|
},
|
||||||
|
versioned_fields=[
|
||||||
|
([('7.15', '>=')], 'require-message-auth', KeyInfo(default='yes-for-request-resp')),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
('radius', 'incoming'): APIData(
|
('radius', 'incoming'): APIData(
|
||||||
|
@ -4052,6 +4219,28 @@ PATHS = {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
('routing', 'bfd', 'configuration'): APIData(
|
||||||
|
versioned=[
|
||||||
|
('7.11', '>=', VersionedAPIData(
|
||||||
|
fully_understood=True,
|
||||||
|
fields={
|
||||||
|
'address-list': KeyInfo(),
|
||||||
|
'addresses': KeyInfo(),
|
||||||
|
'comment': KeyInfo(can_disable=True, remove_value=''),
|
||||||
|
'copy-from': KeyInfo(),
|
||||||
|
'disabled': KeyInfo(default=False),
|
||||||
|
'forbid-bfd': KeyInfo(),
|
||||||
|
'interfaces': KeyInfo(),
|
||||||
|
'min-echo-rx': KeyInfo(),
|
||||||
|
'min-rx': KeyInfo(),
|
||||||
|
'min-tx': KeyInfo(),
|
||||||
|
'multiplier': KeyInfo(),
|
||||||
|
'place-before': KeyInfo(),
|
||||||
|
'vrf': KeyInfo(),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
('routing', 'bfd', 'interface'): APIData(
|
('routing', 'bfd', 'interface'): APIData(
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
unknown_mechanism=True,
|
unknown_mechanism=True,
|
||||||
|
@ -4768,6 +4957,18 @@ PATHS = {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
('interface', 'ethernet', 'switch', 'port-isolation'): APIData(
|
||||||
|
versioned=[
|
||||||
|
('6.43', '>=', VersionedAPIData(
|
||||||
|
primary_keys=('name', ),
|
||||||
|
fully_understood=True,
|
||||||
|
fields={
|
||||||
|
'forwarding-override': KeyInfo(),
|
||||||
|
'name': KeyInfo(),
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
('ip', 'dhcp-client', 'option'): APIData(
|
('ip', 'dhcp-client', 'option'): APIData(
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
fixed_entries=True,
|
fixed_entries=True,
|
||||||
|
@ -4858,10 +5059,13 @@ PATHS = {
|
||||||
('routing', 'bgp', 'connection'): APIData(
|
('routing', 'bgp', 'connection'): APIData(
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
|
versioned_fields=[
|
||||||
|
([('7.19', '<')], 'address-families', KeyInfo()),
|
||||||
|
([('7.19', '>=')], 'afi', KeyInfo()),
|
||||||
|
],
|
||||||
fields={
|
fields={
|
||||||
'as': KeyInfo(),
|
'as': KeyInfo(),
|
||||||
'add-path-out': KeyInfo(),
|
'add-path-out': KeyInfo(),
|
||||||
'address-families': KeyInfo(),
|
|
||||||
'cisco-vpls-nlri-len-fmt': KeyInfo(),
|
'cisco-vpls-nlri-len-fmt': KeyInfo(),
|
||||||
'cluster-id': KeyInfo(),
|
'cluster-id': KeyInfo(),
|
||||||
'comment': KeyInfo(),
|
'comment': KeyInfo(),
|
||||||
|
@ -5040,6 +5244,11 @@ PATHS = {
|
||||||
unversioned=VersionedAPIData(
|
unversioned=VersionedAPIData(
|
||||||
fully_understood=True,
|
fully_understood=True,
|
||||||
primary_keys=('name',),
|
primary_keys=('name',),
|
||||||
|
versioned_fields=[
|
||||||
|
([('7.18', '>=')], 'remote-log-format', KeyInfo(default='default')),
|
||||||
|
([('7.18', '>=')], 'remote-protocol', KeyInfo(default='udp')),
|
||||||
|
([('7.18', '>=')], 'cef-event-delimiter', KeyInfo(default='\r\n')),
|
||||||
|
],
|
||||||
fields={
|
fields={
|
||||||
'bsd-syslog': KeyInfo(default=False),
|
'bsd-syslog': KeyInfo(default=False),
|
||||||
'comment': KeyInfo(can_disable=True, remove_value=''),
|
'comment': KeyInfo(can_disable=True, remove_value=''),
|
||||||
|
@ -5142,7 +5351,7 @@ PATHS = {
|
||||||
'protocol': KeyInfo(default='all'),
|
'protocol': KeyInfo(default='all'),
|
||||||
'src-address': KeyInfo(),
|
'src-address': KeyInfo(),
|
||||||
'src-port': KeyInfo(default='any'),
|
'src-port': KeyInfo(default='any'),
|
||||||
# The template field can't really be changed once the item is
|
# The template field ca not really be changed once the item is
|
||||||
# created. This config captures the behavior best as it can
|
# created. This config captures the behavior best as it can
|
||||||
# i.e. template=yes is shown, template=no is hidden.
|
# i.e. template=yes is shown, template=no is hidden.
|
||||||
'template': KeyInfo(can_disable=True, remove_value=False),
|
'template': KeyInfo(can_disable=True, remove_value=False),
|
||||||
|
|
|
@ -77,7 +77,7 @@ def _ros_api_connect(module, username, password, host, port, use_tls, force_no_c
|
||||||
elif not validate_cert_hostname:
|
elif not validate_cert_hostname:
|
||||||
ctx.check_hostname = False
|
ctx.check_hostname = False
|
||||||
else:
|
else:
|
||||||
# Since librouteros doesn't pass server_hostname,
|
# Since librouteros does not pass server_hostname,
|
||||||
# we have to do this ourselves:
|
# we have to do this ourselves:
|
||||||
def wrap_context(*args, **kwargs):
|
def wrap_context(*args, **kwargs):
|
||||||
kwargs.pop('server_hostname', None)
|
kwargs.pop('server_hostname', None)
|
||||||
|
|
|
@ -8,19 +8,17 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = r"""
|
||||||
---
|
|
||||||
module: api
|
module: api
|
||||||
author: "Nikolay Dachev (@NikolayDachev)"
|
author: "Nikolay Dachev (@NikolayDachev)"
|
||||||
short_description: Ansible module for RouterOS API
|
short_description: Ansible module for RouterOS API
|
||||||
description:
|
description:
|
||||||
- Ansible module for RouterOS API with the Python C(librouteros) library.
|
- Ansible module for RouterOS API with the Python C(librouteros) library.
|
||||||
- This module can add, remove, update, query and execute arbitrary command in RouterOS via API.
|
- This module can add, remove, update, query, and execute arbitrary command in RouterOS through the API.
|
||||||
notes:
|
notes:
|
||||||
- O(add), O(remove), O(update), O(cmd), and O(query) are mutually exclusive.
|
- O(add), O(remove), O(update), O(cmd), and O(query) are mutually exclusive.
|
||||||
- Use the M(community.routeros.api_modify) and M(community.routeros.api_find_and_modify) modules
|
- Use the M(community.routeros.api_modify) and M(community.routeros.api_find_and_modify) modules for more specific modifications,
|
||||||
for more specific modifications, and the M(community.routeros.api_info) module for a more controlled
|
and the M(community.routeros.api_info) module for a more controlled way of returning all entries for a path.
|
||||||
way of returning all entries for a path.
|
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- community.routeros.api
|
- community.routeros.api
|
||||||
- community.routeros.attributes
|
- community.routeros.attributes
|
||||||
|
@ -35,11 +33,15 @@ attributes:
|
||||||
platforms: RouterOS
|
platforms: RouterOS
|
||||||
action_group:
|
action_group:
|
||||||
version_added: 2.1.0
|
version_added: 2.1.0
|
||||||
|
idempotent:
|
||||||
|
support: N/A
|
||||||
|
details:
|
||||||
|
- Whether the executed command is idempotent depends on the operation performed.
|
||||||
options:
|
options:
|
||||||
path:
|
path:
|
||||||
description:
|
description:
|
||||||
- Main path for all other arguments.
|
- Main path for all other arguments.
|
||||||
- If other arguments are not set, api will return all items in selected path.
|
- If other arguments are not set, the module will return all items in selected path.
|
||||||
- Example V(ip address). Equivalent of RouterOS CLI C(/ip address print).
|
- Example V(ip address). Equivalent of RouterOS CLI C(/ip address print).
|
||||||
required: true
|
required: true
|
||||||
type: str
|
type: str
|
||||||
|
@ -59,20 +61,21 @@ options:
|
||||||
update:
|
update:
|
||||||
description:
|
description:
|
||||||
- Update config/value in RouterOS by '.id' in selected path.
|
- Update config/value in RouterOS by '.id' in selected path.
|
||||||
- Example V(.id=*03 address=1.1.1.3/32) and path V(ip address) will replace existing ip address with C(.id=*03).
|
- Example V(.id=*03 address=1.1.1.3/32) and path V(ip address) will replace the existing IP address with C(.id=*03).
|
||||||
- Equivalent in RouterOS CLI C(/ip address set address=1.1.1.3/32 numbers=1).
|
- Equivalent in RouterOS CLI C(/ip address set address=1.1.1.3/32 numbers=1).
|
||||||
- Note C(number) in RouterOS CLI is different from C(.id).
|
- Note C(number) in RouterOS CLI is different from C(.id).
|
||||||
type: str
|
type: str
|
||||||
query:
|
query:
|
||||||
description:
|
description:
|
||||||
- Query given path for selected query attributes from RouterOS aip.
|
- Query given path for selected query attributes from RouterOS API.
|
||||||
- WHERE is key word which extend query. WHERE format is key operator value - with spaces.
|
- WHERE is key word which extend query. WHERE format is key operator value - with spaces.
|
||||||
- WHERE valid operators are V(==) or V(eq), V(!=) or V(not), V(>) or V(more), V(<) or V(less).
|
- WHERE valid operators are V(==) or V(eq), V(!=) or V(not), V(>) or V(more), V(<) or V(less).
|
||||||
- Example path V(ip address) and query V(.id address) will return only C(.id) and C(address) for all items in V(ip address) path.
|
- Example path V(ip address) and query V(.id address) will return only C(.id) and C(address) for all items in V(ip address)
|
||||||
- Example path V(ip address) and query V(.id address WHERE address == 1.1.1.3/32).
|
path.
|
||||||
will return only C(.id) and C(address) for items in V(ip address) path, where address is eq to 1.1.1.3/32.
|
- Example path V(ip address) and query V(.id address WHERE address == 1.1.1.3/32). will return only C(.id) and C(address)
|
||||||
- Example path V(interface) and query V(mtu name WHERE mut > 1400) will
|
for items in V(ip address) path, where address is eq to 1.1.1.3/32.
|
||||||
return only interfaces C(mtu,name) where mtu is bigger than 1400.
|
- Example path V(interface) and query V(mtu name WHERE mut > 1400) will return only interfaces C(mtu,name) where mtu
|
||||||
|
is bigger than 1400.
|
||||||
- Equivalent in RouterOS CLI C(/interface print where mtu > 1400).
|
- Equivalent in RouterOS CLI C(/interface print where mtu > 1400).
|
||||||
type: str
|
type: str
|
||||||
extended_query:
|
extended_query:
|
||||||
|
@ -91,7 +94,8 @@ options:
|
||||||
where:
|
where:
|
||||||
description:
|
description:
|
||||||
- Allows to restrict the objects returned.
|
- Allows to restrict the objects returned.
|
||||||
- The conditions here must all match. An O(extended_query.where[].or) condition needs at least one of its conditions to match.
|
- The conditions here must all match. An O(extended_query.where[].or) condition needs at least one of its conditions
|
||||||
|
to match.
|
||||||
type: list
|
type: list
|
||||||
elements: dict
|
elements: dict
|
||||||
suboptions:
|
suboptions:
|
||||||
|
@ -105,7 +109,8 @@ options:
|
||||||
description:
|
description:
|
||||||
- The operator to use for matching.
|
- The operator to use for matching.
|
||||||
- For equality use V(==) or V(eq). For less use V(<) or V(less). For more use V(>) or V(more).
|
- For equality use V(==) or V(eq). For less use V(<) or V(less). For more use V(>) or V(more).
|
||||||
- Use V(in) to check whether the value is part of a list. In that case, O(extended_query.where[].value) must be a list.
|
- Use V(in) to check whether the value is part of a list. In that case, O(extended_query.where[].value) must
|
||||||
|
be a list.
|
||||||
- Either O(extended_query.where[].or) or all of O(extended_query.where[].attribute), O(extended_query.where[].is),
|
- Either O(extended_query.where[].or) or all of O(extended_query.where[].attribute), O(extended_query.where[].is),
|
||||||
and O(extended_query.where[].value) have to be specified.
|
and O(extended_query.where[].value) have to be specified.
|
||||||
type: str
|
type: str
|
||||||
|
@ -133,7 +138,8 @@ options:
|
||||||
description:
|
description:
|
||||||
- The operator to use for matching.
|
- The operator to use for matching.
|
||||||
- For equality use V(==) or V(eq). For less use V(<) or V(less). For more use V(>) or V(more).
|
- For equality use V(==) or V(eq). For less use V(<) or V(less). For more use V(>) or V(more).
|
||||||
- Use V(in) to check whether the value is part of a list. In that case, O(extended_query.where[].or[].value) must be a list.
|
- Use V(in) to check whether the value is part of a list. In that case, O(extended_query.where[].or[].value)
|
||||||
|
must be a list.
|
||||||
type: str
|
type: str
|
||||||
choices: ["==", "!=", ">", "<", "in", "eq", "not", "more", "less"]
|
choices: ["==", "!=", ">", "<", "in", "eq", "not", "more", "less"]
|
||||||
required: true
|
required: true
|
||||||
|
@ -150,14 +156,15 @@ options:
|
||||||
type: str
|
type: str
|
||||||
seealso:
|
seealso:
|
||||||
- ref: ansible_collections.community.routeros.docsite.quoting
|
- ref: ansible_collections.community.routeros.docsite.quoting
|
||||||
description: How to quote and unquote commands and arguments
|
description: How to quote and unquote commands and arguments.
|
||||||
- module: community.routeros.api_facts
|
- module: community.routeros.api_facts
|
||||||
- module: community.routeros.api_find_and_modify
|
- module: community.routeros.api_find_and_modify
|
||||||
- module: community.routeros.api_info
|
- module: community.routeros.api_info
|
||||||
- module: community.routeros.api_modify
|
- module: community.routeros.api_modify
|
||||||
'''
|
"""
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = r"""
|
||||||
|
---
|
||||||
- name: Get example - ip address print
|
- name: Get example - ip address print
|
||||||
community.routeros.api:
|
community.routeros.api:
|
||||||
hostname: "{{ hostname }}"
|
hostname: "{{ hostname }}"
|
||||||
|
@ -216,8 +223,8 @@ EXAMPLES = '''
|
||||||
- attribute: "network"
|
- attribute: "network"
|
||||||
is: "in"
|
is: "in"
|
||||||
value:
|
value:
|
||||||
- "10.20.36.0"
|
- "10.20.36.0"
|
||||||
- "192.168.255.0"
|
- "192.168.255.0"
|
||||||
register: extended_queryout
|
register: extended_queryout
|
||||||
|
|
||||||
- name: Dump "Extended query example" output
|
- name: Dump "Extended query example" output
|
||||||
|
@ -231,9 +238,9 @@ EXAMPLES = '''
|
||||||
username: "{{ username }}"
|
username: "{{ username }}"
|
||||||
path: "ip address"
|
path: "ip address"
|
||||||
update: >-
|
update: >-
|
||||||
.id=*14
|
.id=*14
|
||||||
address=192.168.255.20/24
|
address=192.168.255.20/24
|
||||||
comment={{ 'Update 192.168.255.10/24 to 192.168.255.20/24 on ether2' | community.routeros.quote_argument_value }}
|
comment={{ 'Update 192.168.255.10/24 to 192.168.255.20/24 on ether2' | community.routeros.quote_argument_value }}
|
||||||
|
|
||||||
- name: Remove example - ether2 ip 192.168.255.20/24 with ".id = *14"
|
- name: Remove example - ether2 ip 192.168.255.20/24 with ".id = *14"
|
||||||
community.routeros.api:
|
community.routeros.api:
|
||||||
|
@ -255,18 +262,17 @@ EXAMPLES = '''
|
||||||
- name: Dump "Arbitrary command example" output
|
- name: Dump "Arbitrary command example" output
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg: '{{ arbitraryout }}'
|
msg: '{{ arbitraryout }}'
|
||||||
'''
|
"""
|
||||||
|
|
||||||
RETURN = '''
|
RETURN = r"""
|
||||||
---
|
|
||||||
message:
|
message:
|
||||||
description: All outputs are in list with dictionary elements returned from RouterOS api.
|
description: All outputs are in list with dictionary elements returned from RouterOS API.
|
||||||
sample:
|
sample:
|
||||||
- address: 1.2.3.4
|
- address: 1.2.3.4
|
||||||
- address: 2.3.4.5
|
- address: 2.3.4.5
|
||||||
type: list
|
type: list
|
||||||
returned: always
|
returned: always
|
||||||
'''
|
"""
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
|
|
|
@ -9,29 +9,27 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = r"""
|
||||||
---
|
|
||||||
module: api_facts
|
module: api_facts
|
||||||
author:
|
author:
|
||||||
- "Egor Zaitsev (@heuels)"
|
- "Egor Zaitsev (@heuels)"
|
||||||
- "Nikolay Dachev (@NikolayDachev)"
|
- "Nikolay Dachev (@NikolayDachev)"
|
||||||
- "Felix Fontein (@felixfontein)"
|
- "Felix Fontein (@felixfontein)"
|
||||||
version_added: 2.1.0
|
version_added: 2.1.0
|
||||||
short_description: Collect facts from remote devices running MikroTik RouterOS using the API
|
short_description: Collect facts from remote devices running MikroTik RouterOS using the API
|
||||||
description:
|
description:
|
||||||
- Collects a base set of device facts from a remote device that
|
- Collects a base set of device facts from a remote device that is running RouterOS. This module prepends all of the base
|
||||||
is running RouterOS. This module prepends all of the
|
network fact keys with C(ansible_net_<fact>). The facts module will always collect a base set of facts from the device
|
||||||
base network fact keys with C(ansible_net_<fact>). The facts
|
|
||||||
module will always collect a base set of facts from the device
|
|
||||||
and can enable or disable collection of additional facts.
|
and can enable or disable collection of additional facts.
|
||||||
- As opposed to the M(community.routeros.facts) module, it uses the
|
- As opposed to the M(community.routeros.facts) module, it uses the RouterOS API, similar to the M(community.routeros.api)
|
||||||
RouterOS API, similar to the M(community.routeros.api) module.
|
module.
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- community.routeros.api
|
- community.routeros.api
|
||||||
- community.routeros.attributes
|
- community.routeros.attributes
|
||||||
- community.routeros.attributes.actiongroup_api
|
- community.routeros.attributes.actiongroup_api
|
||||||
- community.routeros.attributes.facts
|
- community.routeros.attributes.facts
|
||||||
- community.routeros.attributes.facts_module
|
- community.routeros.attributes.facts_module
|
||||||
|
- community.routeros.attributes.idempotent_not_modify_state
|
||||||
attributes:
|
attributes:
|
||||||
platform:
|
platform:
|
||||||
support: full
|
support: full
|
||||||
|
@ -39,12 +37,10 @@ attributes:
|
||||||
options:
|
options:
|
||||||
gather_subset:
|
gather_subset:
|
||||||
description:
|
description:
|
||||||
- When supplied, this argument will restrict the facts collected
|
- When supplied, this argument will restrict the facts collected to a given subset. Possible values for this argument
|
||||||
to a given subset. Possible values for this argument include
|
include V(all), V(hardware), V(interfaces), and V(routing).
|
||||||
V(all), V(hardware), V(interfaces), and V(routing).
|
- Can specify a list of values to include a larger subset. Values can also be used with an initial V(!) to specify that
|
||||||
- Can specify a list of values to include a larger subset.
|
a specific subset should not be collected.
|
||||||
Values can also be used with an initial V(!) to specify that a
|
|
||||||
specific subset should not be collected.
|
|
||||||
required: false
|
required: false
|
||||||
default:
|
default:
|
||||||
- all
|
- all
|
||||||
|
@ -56,9 +52,10 @@ seealso:
|
||||||
- module: community.routeros.api_find_and_modify
|
- module: community.routeros.api_find_and_modify
|
||||||
- module: community.routeros.api_info
|
- module: community.routeros.api_info
|
||||||
- module: community.routeros.api_modify
|
- module: community.routeros.api_modify
|
||||||
'''
|
"""
|
||||||
|
|
||||||
EXAMPLES = """
|
EXAMPLES = r"""
|
||||||
|
---
|
||||||
- name: Collect all facts from the device
|
- name: Collect all facts from the device
|
||||||
community.routeros.api_facts:
|
community.routeros.api_facts:
|
||||||
hostname: 192.168.88.1
|
hostname: 192.168.88.1
|
||||||
|
@ -75,7 +72,7 @@ EXAMPLES = """
|
||||||
- "!hardware"
|
- "!hardware"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RETURN = """
|
RETURN = r"""
|
||||||
ansible_facts:
|
ansible_facts:
|
||||||
description: "Dictionary of IP geolocation facts for a host's IP address."
|
description: "Dictionary of IP geolocation facts for a host's IP address."
|
||||||
returned: always
|
returned: always
|
||||||
|
@ -422,8 +419,6 @@ FACT_SUBSETS = dict(
|
||||||
|
|
||||||
VALID_SUBSETS = frozenset(FACT_SUBSETS.keys())
|
VALID_SUBSETS = frozenset(FACT_SUBSETS.keys())
|
||||||
|
|
||||||
warnings = []
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
argument_spec = dict(
|
argument_spec = dict(
|
||||||
|
@ -488,7 +483,7 @@ def main():
|
||||||
key = 'ansible_net_%s' % key
|
key = 'ansible_net_%s' % key
|
||||||
ansible_facts[key] = value
|
ansible_facts[key] = value
|
||||||
|
|
||||||
module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
|
module.exit_json(ansible_facts=ansible_facts)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = r"""
|
||||||
---
|
|
||||||
module: api_find_and_modify
|
module: api_find_and_modify
|
||||||
author:
|
author:
|
||||||
- "Felix Fontein (@felixfontein)"
|
- "Felix Fontein (@felixfontein)"
|
||||||
|
@ -17,13 +16,13 @@ short_description: Find and modify information using the API
|
||||||
version_added: 2.1.0
|
version_added: 2.1.0
|
||||||
description:
|
description:
|
||||||
- Allows to find entries for a path by conditions and modify the values of these entries.
|
- Allows to find entries for a path by conditions and modify the values of these entries.
|
||||||
- Use the M(community.routeros.api_find_and_modify) module to set all entries of a path to specific values,
|
- Use the M(community.routeros.api_find_and_modify) module to set all entries of a path to specific values, or change multiple
|
||||||
or change multiple entries in different ways in one step.
|
entries in different ways in one step.
|
||||||
notes:
|
notes:
|
||||||
- "If you want to change values based on their old values (like change all comments 'foo' to 'bar') and make sure that
|
- "If you want to change values based on their old values (like change all comments 'foo' to 'bar') and make sure that there
|
||||||
there are at least N such values, you can use O(require_matches_min=N) together with O(allow_no_matches=true).
|
are at least N such values, you can use O(require_matches_min=N) together with O(allow_no_matches=true). This will make
|
||||||
This will make the module fail if there are less than N such entries, but not if there is no match. The latter case
|
the module fail if there are less than N such entries, but not if there is no match. The latter case is needed for idempotency
|
||||||
is needed for idempotency of the task: once the values have been changed, there should be no further match."
|
of the task: once the values have been changed, there should be no further match."
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- community.routeros.api
|
- community.routeros.api
|
||||||
- community.routeros.attributes
|
- community.routeros.attributes
|
||||||
|
@ -36,6 +35,8 @@ attributes:
|
||||||
platform:
|
platform:
|
||||||
support: full
|
support: full
|
||||||
platforms: RouterOS
|
platforms: RouterOS
|
||||||
|
idempotent:
|
||||||
|
support: full
|
||||||
options:
|
options:
|
||||||
path:
|
path:
|
||||||
description:
|
description:
|
||||||
|
@ -74,14 +75,30 @@ options:
|
||||||
- Whether to allow that no match is found.
|
- Whether to allow that no match is found.
|
||||||
- If not specified, this value is induced from whether O(require_matches_min) is 0 or larger.
|
- If not specified, this value is induced from whether O(require_matches_min) is 0 or larger.
|
||||||
type: bool
|
type: bool
|
||||||
|
ignore_dynamic:
|
||||||
|
description:
|
||||||
|
- Whether to ignore dynamic entries.
|
||||||
|
- By default, they are considered. If set to V(true), they are not considered.
|
||||||
|
- It is generally recommended to set this to V(true) unless when you really need to modify dynamic entries.
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
version_added: 3.7.0
|
||||||
|
ignore_builtin:
|
||||||
|
description:
|
||||||
|
- Whether to ignore builtin entries.
|
||||||
|
- By default, they are considered. If set to V(true), they are not considered.
|
||||||
|
- It is generally recommended to set this to V(true) unless when you really need to modify builtin entries.
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
version_added: 3.7.0
|
||||||
seealso:
|
seealso:
|
||||||
- module: community.routeros.api
|
- module: community.routeros.api
|
||||||
- module: community.routeros.api_facts
|
- module: community.routeros.api_facts
|
||||||
- module: community.routeros.api_modify
|
- module: community.routeros.api_modify
|
||||||
- module: community.routeros.api_info
|
- module: community.routeros.api_info
|
||||||
'''
|
"""
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = r"""
|
||||||
---
|
---
|
||||||
- name: Rename bridge from 'bridge' to 'my-bridge'
|
- name: Rename bridge from 'bridge' to 'my-bridge'
|
||||||
community.routeros.api_find_and_modify:
|
community.routeros.api_find_and_modify:
|
||||||
|
@ -93,6 +110,10 @@ EXAMPLES = '''
|
||||||
name: bridge
|
name: bridge
|
||||||
values:
|
values:
|
||||||
name: my-bridge
|
name: my-bridge
|
||||||
|
# Always ignore dynamic and builtin entries
|
||||||
|
# (not relevant for this path, but generally recommended)
|
||||||
|
ignore_dynamic: true
|
||||||
|
ignore_builtin: true
|
||||||
|
|
||||||
- name: Change IP address to 192.168.1.1 for interface bridge - assuming there is only one
|
- name: Change IP address to 192.168.1.1 for interface bridge - assuming there is only one
|
||||||
community.routeros.api_find_and_modify:
|
community.routeros.api_find_and_modify:
|
||||||
|
@ -108,55 +129,58 @@ EXAMPLES = '''
|
||||||
# exactly one is configured.
|
# exactly one is configured.
|
||||||
require_matches_min: 1
|
require_matches_min: 1
|
||||||
require_matches_max: 1
|
require_matches_max: 1
|
||||||
'''
|
# Always ignore dynamic and builtin entries
|
||||||
|
# (not relevant for this path, but generally recommended)
|
||||||
|
ignore_dynamic: true
|
||||||
|
ignore_builtin: true
|
||||||
|
"""
|
||||||
|
|
||||||
RETURN = '''
|
RETURN = r"""
|
||||||
---
|
|
||||||
old_data:
|
old_data:
|
||||||
description:
|
description:
|
||||||
- A list of all elements for the current path before a change was made.
|
- A list of all elements for the current path before a change was made.
|
||||||
sample:
|
sample:
|
||||||
- '.id': '*1'
|
- '.id': '*1'
|
||||||
actual-interface: bridge
|
actual-interface: bridge
|
||||||
address: "192.168.88.1/24"
|
address: "192.168.88.1/24"
|
||||||
comment: defconf
|
comment: defconf
|
||||||
disabled: false
|
disabled: false
|
||||||
dynamic: false
|
dynamic: false
|
||||||
interface: bridge
|
interface: bridge
|
||||||
invalid: false
|
invalid: false
|
||||||
network: 192.168.88.0
|
network: 192.168.88.0
|
||||||
type: list
|
type: list
|
||||||
elements: dict
|
elements: dict
|
||||||
returned: success
|
returned: success
|
||||||
new_data:
|
new_data:
|
||||||
description:
|
description:
|
||||||
- A list of all elements for the current path after a change was made.
|
- A list of all elements for the current path after a change was made.
|
||||||
sample:
|
sample:
|
||||||
- '.id': '*1'
|
- '.id': '*1'
|
||||||
actual-interface: bridge
|
actual-interface: bridge
|
||||||
address: "192.168.1.1/24"
|
address: "192.168.1.1/24"
|
||||||
comment: awesome
|
comment: awesome
|
||||||
disabled: false
|
disabled: false
|
||||||
dynamic: false
|
dynamic: false
|
||||||
interface: bridge
|
interface: bridge
|
||||||
invalid: false
|
invalid: false
|
||||||
network: 192.168.1.0
|
network: 192.168.1.0
|
||||||
type: list
|
type: list
|
||||||
elements: dict
|
elements: dict
|
||||||
returned: success
|
returned: success
|
||||||
match_count:
|
match_count:
|
||||||
description:
|
description:
|
||||||
- The number of entries that matched the criteria in O(find).
|
- The number of entries that matched the criteria in O(find).
|
||||||
sample: 1
|
sample: 1
|
||||||
type: int
|
type: int
|
||||||
returned: success
|
returned: success
|
||||||
modify__count:
|
modify__count:
|
||||||
description:
|
description:
|
||||||
- The number of entries that were modified.
|
- The number of entries that were modified.
|
||||||
sample: 1
|
sample: 1
|
||||||
type: int
|
type: int
|
||||||
returned: success
|
returned: success
|
||||||
'''
|
"""
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
|
@ -185,6 +209,17 @@ def compose_api_path(api, path):
|
||||||
return api_path
|
return api_path
|
||||||
|
|
||||||
|
|
||||||
|
def filter_entries(entries, ignore_dynamic=False, ignore_builtin=False):
|
||||||
|
result = []
|
||||||
|
for entry in entries:
|
||||||
|
if ignore_dynamic and entry.get('dynamic', False):
|
||||||
|
continue
|
||||||
|
if ignore_builtin and entry.get('builtin', False):
|
||||||
|
continue
|
||||||
|
result.append(entry)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
DISABLED_MEANS_EMPTY_STRING = ('comment', )
|
DISABLED_MEANS_EMPTY_STRING = ('comment', )
|
||||||
|
|
||||||
|
|
||||||
|
@ -196,6 +231,8 @@ def main():
|
||||||
require_matches_min=dict(type='int', default=0),
|
require_matches_min=dict(type='int', default=0),
|
||||||
require_matches_max=dict(type='int'),
|
require_matches_max=dict(type='int'),
|
||||||
allow_no_matches=dict(type='bool'),
|
allow_no_matches=dict(type='bool'),
|
||||||
|
ignore_dynamic=dict(type='bool', default=False),
|
||||||
|
ignore_builtin=dict(type='bool', default=False),
|
||||||
)
|
)
|
||||||
module_args.update(api_argument_spec())
|
module_args.update(api_argument_spec())
|
||||||
|
|
||||||
|
@ -223,6 +260,9 @@ def main():
|
||||||
if key in values:
|
if key in values:
|
||||||
module.fail_json(msg='`values` must not contain both "{key}" and "!{key}"!'.format(key=key))
|
module.fail_json(msg='`values` must not contain both "{key}" and "!{key}"!'.format(key=key))
|
||||||
|
|
||||||
|
ignore_dynamic = module.params['ignore_dynamic']
|
||||||
|
ignore_builtin = module.params['ignore_builtin']
|
||||||
|
|
||||||
check_has_library(module)
|
check_has_library(module)
|
||||||
api = create_api(module)
|
api = create_api(module)
|
||||||
|
|
||||||
|
@ -230,7 +270,7 @@ def main():
|
||||||
|
|
||||||
api_path = compose_api_path(api, path)
|
api_path = compose_api_path(api, path)
|
||||||
|
|
||||||
old_data = list(api_path)
|
old_data = filter_entries(list(api_path), ignore_dynamic=ignore_dynamic, ignore_builtin=ignore_builtin)
|
||||||
new_data = [entry.copy() for entry in old_data]
|
new_data = [entry.copy() for entry in old_data]
|
||||||
|
|
||||||
# Find matching entries
|
# Find matching entries
|
||||||
|
@ -299,7 +339,7 @@ def main():
|
||||||
error=to_native(e),
|
error=to_native(e),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
new_data = list(api_path)
|
new_data = filter_entries(list(api_path), ignore_dynamic=ignore_dynamic, ignore_builtin=ignore_builtin)
|
||||||
|
|
||||||
# Produce return value
|
# Produce return value
|
||||||
more = {}
|
more = {}
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = r"""
|
||||||
---
|
|
||||||
module: api_info
|
module: api_info
|
||||||
author:
|
author:
|
||||||
- "Felix Fontein (@felixfontein)"
|
- "Felix Fontein (@felixfontein)"
|
||||||
|
@ -18,17 +17,18 @@ version_added: 2.2.0
|
||||||
description:
|
description:
|
||||||
- Allows to retrieve information for a path using the API.
|
- Allows to retrieve information for a path using the API.
|
||||||
- This can be used to backup a path to restore it with the M(community.routeros.api_modify) module.
|
- This can be used to backup a path to restore it with the M(community.routeros.api_modify) module.
|
||||||
- Entries are normalized, dynamic and builtin entries are not returned. Use the O(handle_disabled) and
|
- Entries are normalized, dynamic and builtin entries are not returned. Use the O(handle_disabled) and O(hide_defaults)
|
||||||
O(hide_defaults) options to control normalization, the O(include_dynamic) and O(include_builtin) options to also return
|
options to control normalization, the O(include_dynamic) and O(include_builtin) options to also return dynamic resp. builtin
|
||||||
dynamic resp. builtin entries, and use O(unfiltered) to return all fields including counters.
|
entries, and use O(unfiltered) to return all fields including counters.
|
||||||
- B(Note) that this module is still heavily in development, and only supports B(some) paths.
|
- B(Note) that this module is still heavily in development, and only supports B(some) paths. If you want to support new
|
||||||
If you want to support new paths, or think you found problems with existing paths, please first
|
paths, or think you found problems with existing paths, please first L(create an issue in the community.routeros Issue
|
||||||
L(create an issue in the community.routeros Issue Tracker,https://github.com/ansible-collections/community.routeros/issues/).
|
Tracker,https://github.com/ansible-collections/community.routeros/issues/).
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- community.routeros.api
|
- community.routeros.api
|
||||||
- community.routeros.api.restrict
|
- community.routeros.api.restrict
|
||||||
- community.routeros.attributes
|
- community.routeros.attributes
|
||||||
- community.routeros.attributes.actiongroup_api
|
- community.routeros.attributes.actiongroup_api
|
||||||
|
- community.routeros.attributes.idempotent_not_modify_state
|
||||||
- community.routeros.attributes.info_module
|
- community.routeros.attributes.info_module
|
||||||
attributes:
|
attributes:
|
||||||
platform:
|
platform:
|
||||||
|
@ -43,224 +43,232 @@ options:
|
||||||
type: str
|
type: str
|
||||||
choices:
|
choices:
|
||||||
# BEGIN PATH LIST
|
# BEGIN PATH LIST
|
||||||
- caps-man aaa
|
- caps-man aaa
|
||||||
- caps-man access-list
|
- caps-man access-list
|
||||||
- caps-man channel
|
- caps-man channel
|
||||||
- caps-man configuration
|
- caps-man configuration
|
||||||
- caps-man datapath
|
- caps-man datapath
|
||||||
- caps-man manager
|
- caps-man manager
|
||||||
- caps-man manager interface
|
- caps-man manager interface
|
||||||
- caps-man provisioning
|
- caps-man provisioning
|
||||||
- caps-man security
|
- caps-man security
|
||||||
- certificate settings
|
- certificate settings
|
||||||
- interface bonding
|
- interface 6to4
|
||||||
- interface bridge
|
- interface bonding
|
||||||
- interface bridge mlag
|
- interface bridge
|
||||||
- interface bridge port
|
- interface bridge mlag
|
||||||
- interface bridge port-controller
|
- interface bridge port
|
||||||
- interface bridge port-extender
|
- interface bridge port-controller
|
||||||
- interface bridge settings
|
- interface bridge port-extender
|
||||||
- interface bridge vlan
|
- interface bridge settings
|
||||||
- interface detect-internet
|
- interface bridge vlan
|
||||||
- interface eoip
|
- interface detect-internet
|
||||||
- interface ethernet
|
- interface eoip
|
||||||
- interface ethernet poe
|
- interface ethernet
|
||||||
- interface ethernet switch
|
- interface ethernet poe
|
||||||
- interface ethernet switch port
|
- interface ethernet switch
|
||||||
- interface gre
|
- interface ethernet switch port
|
||||||
- interface gre6
|
- interface ethernet switch port-isolation
|
||||||
- interface l2tp-client
|
- interface gre
|
||||||
- interface l2tp-server server
|
- interface gre6
|
||||||
- interface list
|
- interface l2tp-client
|
||||||
- interface list member
|
- interface l2tp-server server
|
||||||
- interface ovpn-client
|
- interface list
|
||||||
- interface ovpn-server server
|
- interface list member
|
||||||
- interface ppp-client
|
- interface ovpn-client
|
||||||
- interface pppoe-client
|
- interface ovpn-server server
|
||||||
- interface pppoe-server server
|
- interface ppp-client
|
||||||
- interface pptp-server server
|
- interface pppoe-client
|
||||||
- interface sstp-server server
|
- interface pppoe-server server
|
||||||
- interface vlan
|
- interface pptp-server server
|
||||||
- interface vrrp
|
- interface sstp-server server
|
||||||
- interface wifi
|
- interface vlan
|
||||||
- interface wifi aaa
|
- interface vrrp
|
||||||
- interface wifi access-list
|
- interface wifi
|
||||||
- interface wifi cap
|
- interface wifi aaa
|
||||||
- interface wifi capsman
|
- interface wifi access-list
|
||||||
- interface wifi channel
|
- interface wifi cap
|
||||||
- interface wifi configuration
|
- interface wifi capsman
|
||||||
- interface wifi datapath
|
- interface wifi channel
|
||||||
- interface wifi interworking
|
- interface wifi configuration
|
||||||
- interface wifi provisioning
|
- interface wifi datapath
|
||||||
- interface wifi security
|
- interface wifi interworking
|
||||||
- interface wifi steering
|
- interface wifi provisioning
|
||||||
- interface wifiwave2
|
- interface wifi security
|
||||||
- interface wifiwave2 aaa
|
- interface wifi steering
|
||||||
- interface wifiwave2 access-list
|
- interface wifiwave2
|
||||||
- interface wifiwave2 cap
|
- interface wifiwave2 aaa
|
||||||
- interface wifiwave2 capsman
|
- interface wifiwave2 access-list
|
||||||
- interface wifiwave2 channel
|
- interface wifiwave2 cap
|
||||||
- interface wifiwave2 configuration
|
- interface wifiwave2 capsman
|
||||||
- interface wifiwave2 datapath
|
- interface wifiwave2 channel
|
||||||
- interface wifiwave2 interworking
|
- interface wifiwave2 configuration
|
||||||
- interface wifiwave2 provisioning
|
- interface wifiwave2 datapath
|
||||||
- interface wifiwave2 security
|
- interface wifiwave2 interworking
|
||||||
- interface wifiwave2 steering
|
- interface wifiwave2 provisioning
|
||||||
- interface wireguard
|
- interface wifiwave2 security
|
||||||
- interface wireguard peers
|
- interface wifiwave2 steering
|
||||||
- interface wireless
|
- interface wireguard
|
||||||
- interface wireless align
|
- interface wireguard peers
|
||||||
- interface wireless cap
|
- interface wireless
|
||||||
- interface wireless security-profiles
|
- interface wireless access-list
|
||||||
- interface wireless sniffer
|
- interface wireless align
|
||||||
- interface wireless snooper
|
- interface wireless cap
|
||||||
- iot modbus
|
- interface wireless connect-list
|
||||||
- ip accounting
|
- interface wireless security-profiles
|
||||||
- ip accounting web-access
|
- interface wireless sniffer
|
||||||
- ip address
|
- interface wireless snooper
|
||||||
- ip arp
|
- iot modbus
|
||||||
- ip cloud
|
- ip accounting
|
||||||
- ip cloud advanced
|
- ip accounting web-access
|
||||||
- ip dhcp-client
|
- ip address
|
||||||
- ip dhcp-client option
|
- ip arp
|
||||||
- ip dhcp-relay
|
- ip cloud
|
||||||
- ip dhcp-server
|
- ip cloud advanced
|
||||||
- ip dhcp-server config
|
- ip dhcp-client
|
||||||
- ip dhcp-server lease
|
- ip dhcp-client option
|
||||||
- ip dhcp-server matcher
|
- ip dhcp-relay
|
||||||
- ip dhcp-server network
|
- ip dhcp-server
|
||||||
- ip dhcp-server option
|
- ip dhcp-server config
|
||||||
- ip dhcp-server option sets
|
- ip dhcp-server lease
|
||||||
- ip dns
|
- ip dhcp-server matcher
|
||||||
- ip dns adlist
|
- ip dhcp-server network
|
||||||
- ip dns static
|
- ip dhcp-server option
|
||||||
- ip firewall address-list
|
- ip dhcp-server option sets
|
||||||
- ip firewall connection tracking
|
- ip dns
|
||||||
- ip firewall filter
|
- ip dns adlist
|
||||||
- ip firewall layer7-protocol
|
- ip dns forwarders
|
||||||
- ip firewall mangle
|
- ip dns static
|
||||||
- ip firewall nat
|
- ip firewall address-list
|
||||||
- ip firewall raw
|
- ip firewall connection tracking
|
||||||
- ip firewall service-port
|
- ip firewall filter
|
||||||
- ip hotspot service-port
|
- ip firewall layer7-protocol
|
||||||
- ip ipsec identity
|
- ip firewall mangle
|
||||||
- ip ipsec peer
|
- ip firewall nat
|
||||||
- ip ipsec policy
|
- ip firewall raw
|
||||||
- ip ipsec profile
|
- ip firewall service-port
|
||||||
- ip ipsec proposal
|
- ip hotspot service-port
|
||||||
- ip ipsec settings
|
- ip ipsec identity
|
||||||
- ip neighbor discovery-settings
|
- ip ipsec mode-config
|
||||||
- ip pool
|
- ip ipsec peer
|
||||||
- ip proxy
|
- ip ipsec policy
|
||||||
- ip route
|
- ip ipsec profile
|
||||||
- ip route rule
|
- ip ipsec proposal
|
||||||
- ip route vrf
|
- ip ipsec settings
|
||||||
- ip service
|
- ip neighbor discovery-settings
|
||||||
- ip settings
|
- ip pool
|
||||||
- ip smb
|
- ip proxy
|
||||||
- ip socks
|
- ip route
|
||||||
- ip ssh
|
- ip route rule
|
||||||
- ip tftp settings
|
- ip route vrf
|
||||||
- ip traffic-flow
|
- ip service
|
||||||
- ip traffic-flow ipfix
|
- ip settings
|
||||||
- ip traffic-flow target
|
- ip smb
|
||||||
- ip upnp
|
- ip socks
|
||||||
- ip upnp interfaces
|
- ip ssh
|
||||||
- ip vrf
|
- ip tftp settings
|
||||||
- ipv6 address
|
- ip traffic-flow
|
||||||
- ipv6 dhcp-client
|
- ip traffic-flow ipfix
|
||||||
- ipv6 dhcp-server
|
- ip traffic-flow target
|
||||||
- ipv6 dhcp-server option
|
- ip upnp
|
||||||
- ipv6 firewall address-list
|
- ip upnp interfaces
|
||||||
- ipv6 firewall filter
|
- ip vrf
|
||||||
- ipv6 firewall mangle
|
- ipv6 address
|
||||||
- ipv6 firewall nat
|
- ipv6 dhcp-client
|
||||||
- ipv6 firewall raw
|
- ipv6 dhcp-server
|
||||||
- ipv6 nd
|
- ipv6 dhcp-server option
|
||||||
- ipv6 nd prefix
|
- ipv6 firewall address-list
|
||||||
- ipv6 nd prefix default
|
- ipv6 firewall filter
|
||||||
- ipv6 route
|
- ipv6 firewall mangle
|
||||||
- ipv6 settings
|
- ipv6 firewall nat
|
||||||
- mpls
|
- ipv6 firewall raw
|
||||||
- mpls interface
|
- ipv6 nd
|
||||||
- mpls ldp
|
- ipv6 nd prefix
|
||||||
- mpls ldp accept-filter
|
- ipv6 nd prefix default
|
||||||
- mpls ldp advertise-filter
|
- ipv6 route
|
||||||
- mpls ldp interface
|
- ipv6 settings
|
||||||
- port firmware
|
- mpls
|
||||||
- port remote-access
|
- mpls interface
|
||||||
- ppp aaa
|
- mpls ldp
|
||||||
- ppp profile
|
- mpls ldp accept-filter
|
||||||
- ppp secret
|
- mpls ldp advertise-filter
|
||||||
- queue interface
|
- mpls ldp interface
|
||||||
- queue simple
|
- port firmware
|
||||||
- queue tree
|
- port remote-access
|
||||||
- queue type
|
- ppp aaa
|
||||||
- radius
|
- ppp profile
|
||||||
- radius incoming
|
- ppp secret
|
||||||
- routing bgp aggregate
|
- queue interface
|
||||||
- routing bgp connection
|
- queue simple
|
||||||
- routing bgp instance
|
- queue tree
|
||||||
- routing bgp network
|
- queue type
|
||||||
- routing bgp peer
|
- radius
|
||||||
- routing bgp template
|
- radius incoming
|
||||||
- routing filter
|
- routing bfd configuration
|
||||||
- routing filter num-list
|
- routing bgp aggregate
|
||||||
- routing filter rule
|
- routing bgp connection
|
||||||
- routing filter select-rule
|
- routing bgp instance
|
||||||
- routing id
|
- routing bgp network
|
||||||
- routing igmp-proxy
|
- routing bgp peer
|
||||||
- routing igmp-proxy interface
|
- routing bgp template
|
||||||
- routing mme
|
- routing filter
|
||||||
- routing ospf area
|
- routing filter community-list
|
||||||
- routing ospf area range
|
- routing filter num-list
|
||||||
- routing ospf instance
|
- routing filter rule
|
||||||
- routing ospf interface-template
|
- routing filter select-rule
|
||||||
- routing ospf static-neighbor
|
- routing id
|
||||||
- routing pimsm instance
|
- routing igmp-proxy
|
||||||
- routing pimsm interface-template
|
- routing igmp-proxy interface
|
||||||
- routing rip
|
- routing mme
|
||||||
- routing ripng
|
- routing ospf area
|
||||||
- routing rule
|
- routing ospf area range
|
||||||
- routing table
|
- routing ospf instance
|
||||||
- snmp
|
- routing ospf interface-template
|
||||||
- snmp community
|
- routing ospf static-neighbor
|
||||||
- system clock
|
- routing pimsm instance
|
||||||
- system clock manual
|
- routing pimsm interface-template
|
||||||
- system health settings
|
- routing rip
|
||||||
- system identity
|
- routing ripng
|
||||||
- system leds settings
|
- routing rule
|
||||||
- system logging
|
- routing table
|
||||||
- system logging action
|
- snmp
|
||||||
- system note
|
- snmp community
|
||||||
- system ntp client
|
- system clock
|
||||||
- system ntp client servers
|
- system clock manual
|
||||||
- system ntp server
|
- system health settings
|
||||||
- system package update
|
- system identity
|
||||||
- system resource irq rps
|
- system leds settings
|
||||||
- system routerboard settings
|
- system logging
|
||||||
- system scheduler
|
- system logging action
|
||||||
- system script
|
- system note
|
||||||
- system upgrade mirror
|
- system ntp client
|
||||||
- system ups
|
- system ntp client servers
|
||||||
- system watchdog
|
- system ntp server
|
||||||
- tool bandwidth-server
|
- system package update
|
||||||
- tool e-mail
|
- system resource irq rps
|
||||||
- tool graphing
|
- system routerboard settings
|
||||||
- tool graphing interface
|
- system scheduler
|
||||||
- tool graphing resource
|
- system script
|
||||||
- tool mac-server
|
- system upgrade mirror
|
||||||
- tool mac-server mac-winbox
|
- system ups
|
||||||
- tool mac-server ping
|
- system watchdog
|
||||||
- tool netwatch
|
- tool bandwidth-server
|
||||||
- tool romon
|
- tool e-mail
|
||||||
- tool sms
|
- tool graphing
|
||||||
- tool sniffer
|
- tool graphing interface
|
||||||
- tool traffic-generator
|
- tool graphing resource
|
||||||
- user
|
- tool mac-server
|
||||||
- user aaa
|
- tool mac-server mac-winbox
|
||||||
- user group
|
- tool mac-server ping
|
||||||
- user settings
|
- tool netwatch
|
||||||
|
- tool romon
|
||||||
|
- tool sms
|
||||||
|
- tool sniffer
|
||||||
|
- tool traffic-generator
|
||||||
|
- user
|
||||||
|
- user aaa
|
||||||
|
- user group
|
||||||
|
- user settings
|
||||||
# END PATH LIST
|
# END PATH LIST
|
||||||
unfiltered:
|
unfiltered:
|
||||||
description:
|
description:
|
||||||
|
@ -316,9 +324,9 @@ seealso:
|
||||||
- module: community.routeros.api_facts
|
- module: community.routeros.api_facts
|
||||||
- module: community.routeros.api_find_and_modify
|
- module: community.routeros.api_find_and_modify
|
||||||
- module: community.routeros.api_modify
|
- module: community.routeros.api_modify
|
||||||
'''
|
"""
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = r"""
|
||||||
---
|
---
|
||||||
- name: Get IP addresses
|
- name: Get IP addresses
|
||||||
community.routeros.api_info:
|
community.routeros.api_info:
|
||||||
|
@ -343,26 +351,25 @@ EXAMPLES = '''
|
||||||
- name: Print data for IP addresses
|
- name: Print data for IP addresses
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
var: ip_addresses.result
|
var: ip_addresses.result
|
||||||
'''
|
"""
|
||||||
|
|
||||||
RETURN = '''
|
RETURN = r"""
|
||||||
---
|
|
||||||
result:
|
result:
|
||||||
description: A list of all elements for the current path.
|
description: A list of all elements for the current path.
|
||||||
sample:
|
sample:
|
||||||
- '.id': '*1'
|
- '.id': '*1'
|
||||||
actual-interface: bridge
|
actual-interface: bridge
|
||||||
address: "192.168.88.1/24"
|
address: "192.168.88.1/24"
|
||||||
comment: defconf
|
comment: defconf
|
||||||
disabled: false
|
disabled: false
|
||||||
dynamic: false
|
dynamic: false
|
||||||
interface: bridge
|
interface: bridge
|
||||||
invalid: false
|
invalid: false
|
||||||
network: 192.168.88.0
|
network: 192.168.88.0
|
||||||
type: list
|
type: list
|
||||||
elements: dict
|
elements: dict
|
||||||
returned: always
|
returned: always
|
||||||
'''
|
"""
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = r"""
|
||||||
---
|
|
||||||
module: api_modify
|
module: api_modify
|
||||||
author:
|
author:
|
||||||
- "Felix Fontein (@felixfontein)"
|
- "Felix Fontein (@felixfontein)"
|
||||||
|
@ -17,17 +16,17 @@ short_description: Modify data at paths with API
|
||||||
version_added: 2.2.0
|
version_added: 2.2.0
|
||||||
description:
|
description:
|
||||||
- Allows to modify information for a path using the API.
|
- Allows to modify information for a path using the API.
|
||||||
- Use the M(community.routeros.api_find_and_modify) module to modify one or multiple entries in a controlled way
|
- Use the M(community.routeros.api_find_and_modify) module to modify one or multiple entries in a controlled way depending
|
||||||
depending on some search conditions.
|
on some search conditions.
|
||||||
- To make a backup of a path that can be restored with this module, use the M(community.routeros.api_info) module.
|
- To make a backup of a path that can be restored with this module, use the M(community.routeros.api_info) module.
|
||||||
- The module ignores dynamic and builtin entries.
|
- The module ignores dynamic and builtin entries.
|
||||||
- B(Note) that this module is still heavily in development, and only supports B(some) paths.
|
- B(Note) that this module is still heavily in development, and only supports B(some) paths. If you want to support new
|
||||||
If you want to support new paths, or think you found problems with existing paths, please first
|
paths, or think you found problems with existing paths, please first L(create an issue in the community.routeros Issue
|
||||||
L(create an issue in the community.routeros Issue Tracker,https://github.com/ansible-collections/community.routeros/issues/).
|
Tracker,https://github.com/ansible-collections/community.routeros/issues/).
|
||||||
notes:
|
notes:
|
||||||
- If write-only fields are present in the path, the module is B(not idempotent) in a strict sense,
|
- If write-only fields are present in the path, the module is B(not idempotent) in a strict sense, since it is not able
|
||||||
since it is not able to verify the current value of these fields. The behavior the module should
|
to verify the current value of these fields. The behavior the module should assume can be controlled with the O(handle_write_only)
|
||||||
assume can be controlled with the O(handle_write_only) option.
|
option.
|
||||||
requirements:
|
requirements:
|
||||||
- Needs L(ordereddict,https://pypi.org/project/ordereddict) for Python 2.6
|
- Needs L(ordereddict,https://pypi.org/project/ordereddict) for Python 2.6
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
|
@ -43,233 +42,244 @@ attributes:
|
||||||
platform:
|
platform:
|
||||||
support: full
|
support: full
|
||||||
platforms: RouterOS
|
platforms: RouterOS
|
||||||
|
idempotent:
|
||||||
|
support: full
|
||||||
options:
|
options:
|
||||||
path:
|
path:
|
||||||
description:
|
description:
|
||||||
- Path to query.
|
- Path to query.
|
||||||
- An example value is V(ip address). This is equivalent to running modification commands in C(/ip address) in the RouterOS CLI.
|
- An example value is V(ip address). This is equivalent to running modification commands in C(/ip address) in the RouterOS
|
||||||
|
CLI.
|
||||||
required: true
|
required: true
|
||||||
type: str
|
type: str
|
||||||
choices:
|
choices:
|
||||||
# BEGIN PATH LIST
|
# BEGIN PATH LIST
|
||||||
- caps-man aaa
|
- caps-man aaa
|
||||||
- caps-man access-list
|
- caps-man access-list
|
||||||
- caps-man channel
|
- caps-man channel
|
||||||
- caps-man configuration
|
- caps-man configuration
|
||||||
- caps-man datapath
|
- caps-man datapath
|
||||||
- caps-man manager
|
- caps-man manager
|
||||||
- caps-man manager interface
|
- caps-man manager interface
|
||||||
- caps-man provisioning
|
- caps-man provisioning
|
||||||
- caps-man security
|
- caps-man security
|
||||||
- certificate settings
|
- certificate settings
|
||||||
- interface bonding
|
- interface 6to4
|
||||||
- interface bridge
|
- interface bonding
|
||||||
- interface bridge mlag
|
- interface bridge
|
||||||
- interface bridge port
|
- interface bridge mlag
|
||||||
- interface bridge port-controller
|
- interface bridge port
|
||||||
- interface bridge port-extender
|
- interface bridge port-controller
|
||||||
- interface bridge settings
|
- interface bridge port-extender
|
||||||
- interface bridge vlan
|
- interface bridge settings
|
||||||
- interface detect-internet
|
- interface bridge vlan
|
||||||
- interface eoip
|
- interface detect-internet
|
||||||
- interface ethernet
|
- interface eoip
|
||||||
- interface ethernet poe
|
- interface ethernet
|
||||||
- interface ethernet switch
|
- interface ethernet poe
|
||||||
- interface ethernet switch port
|
- interface ethernet switch
|
||||||
- interface gre
|
- interface ethernet switch port
|
||||||
- interface gre6
|
- interface ethernet switch port-isolation
|
||||||
- interface l2tp-client
|
- interface gre
|
||||||
- interface l2tp-server server
|
- interface gre6
|
||||||
- interface list
|
- interface l2tp-client
|
||||||
- interface list member
|
- interface l2tp-server server
|
||||||
- interface ovpn-client
|
- interface list
|
||||||
- interface ovpn-server server
|
- interface list member
|
||||||
- interface ppp-client
|
- interface ovpn-client
|
||||||
- interface pppoe-client
|
- interface ovpn-server server
|
||||||
- interface pppoe-server server
|
- interface ppp-client
|
||||||
- interface pptp-server server
|
- interface pppoe-client
|
||||||
- interface sstp-server server
|
- interface pppoe-server server
|
||||||
- interface vlan
|
- interface pptp-server server
|
||||||
- interface vrrp
|
- interface sstp-server server
|
||||||
- interface wifi
|
- interface vlan
|
||||||
- interface wifi aaa
|
- interface vrrp
|
||||||
- interface wifi access-list
|
- interface wifi
|
||||||
- interface wifi cap
|
- interface wifi aaa
|
||||||
- interface wifi capsman
|
- interface wifi access-list
|
||||||
- interface wifi channel
|
- interface wifi cap
|
||||||
- interface wifi configuration
|
- interface wifi capsman
|
||||||
- interface wifi datapath
|
- interface wifi channel
|
||||||
- interface wifi interworking
|
- interface wifi configuration
|
||||||
- interface wifi provisioning
|
- interface wifi datapath
|
||||||
- interface wifi security
|
- interface wifi interworking
|
||||||
- interface wifi steering
|
- interface wifi provisioning
|
||||||
- interface wifiwave2
|
- interface wifi security
|
||||||
- interface wifiwave2 aaa
|
- interface wifi steering
|
||||||
- interface wifiwave2 access-list
|
- interface wifiwave2
|
||||||
- interface wifiwave2 cap
|
- interface wifiwave2 aaa
|
||||||
- interface wifiwave2 capsman
|
- interface wifiwave2 access-list
|
||||||
- interface wifiwave2 channel
|
- interface wifiwave2 cap
|
||||||
- interface wifiwave2 configuration
|
- interface wifiwave2 capsman
|
||||||
- interface wifiwave2 datapath
|
- interface wifiwave2 channel
|
||||||
- interface wifiwave2 interworking
|
- interface wifiwave2 configuration
|
||||||
- interface wifiwave2 provisioning
|
- interface wifiwave2 datapath
|
||||||
- interface wifiwave2 security
|
- interface wifiwave2 interworking
|
||||||
- interface wifiwave2 steering
|
- interface wifiwave2 provisioning
|
||||||
- interface wireguard
|
- interface wifiwave2 security
|
||||||
- interface wireguard peers
|
- interface wifiwave2 steering
|
||||||
- interface wireless
|
- interface wireguard
|
||||||
- interface wireless align
|
- interface wireguard peers
|
||||||
- interface wireless cap
|
- interface wireless
|
||||||
- interface wireless security-profiles
|
- interface wireless access-list
|
||||||
- interface wireless sniffer
|
- interface wireless align
|
||||||
- interface wireless snooper
|
- interface wireless cap
|
||||||
- iot modbus
|
- interface wireless connect-list
|
||||||
- ip accounting
|
- interface wireless security-profiles
|
||||||
- ip accounting web-access
|
- interface wireless sniffer
|
||||||
- ip address
|
- interface wireless snooper
|
||||||
- ip arp
|
- iot modbus
|
||||||
- ip cloud
|
- ip accounting
|
||||||
- ip cloud advanced
|
- ip accounting web-access
|
||||||
- ip dhcp-client
|
- ip address
|
||||||
- ip dhcp-client option
|
- ip arp
|
||||||
- ip dhcp-relay
|
- ip cloud
|
||||||
- ip dhcp-server
|
- ip cloud advanced
|
||||||
- ip dhcp-server config
|
- ip dhcp-client
|
||||||
- ip dhcp-server lease
|
- ip dhcp-client option
|
||||||
- ip dhcp-server matcher
|
- ip dhcp-relay
|
||||||
- ip dhcp-server network
|
- ip dhcp-server
|
||||||
- ip dhcp-server option
|
- ip dhcp-server config
|
||||||
- ip dhcp-server option sets
|
- ip dhcp-server lease
|
||||||
- ip dns
|
- ip dhcp-server matcher
|
||||||
- ip dns adlist
|
- ip dhcp-server network
|
||||||
- ip dns static
|
- ip dhcp-server option
|
||||||
- ip firewall address-list
|
- ip dhcp-server option sets
|
||||||
- ip firewall connection tracking
|
- ip dns
|
||||||
- ip firewall filter
|
- ip dns adlist
|
||||||
- ip firewall layer7-protocol
|
- ip dns forwarders
|
||||||
- ip firewall mangle
|
- ip dns static
|
||||||
- ip firewall nat
|
- ip firewall address-list
|
||||||
- ip firewall raw
|
- ip firewall connection tracking
|
||||||
- ip firewall service-port
|
- ip firewall filter
|
||||||
- ip hotspot service-port
|
- ip firewall layer7-protocol
|
||||||
- ip ipsec identity
|
- ip firewall mangle
|
||||||
- ip ipsec peer
|
- ip firewall nat
|
||||||
- ip ipsec policy
|
- ip firewall raw
|
||||||
- ip ipsec profile
|
- ip firewall service-port
|
||||||
- ip ipsec proposal
|
- ip hotspot service-port
|
||||||
- ip ipsec settings
|
- ip ipsec identity
|
||||||
- ip neighbor discovery-settings
|
- ip ipsec mode-config
|
||||||
- ip pool
|
- ip ipsec peer
|
||||||
- ip proxy
|
- ip ipsec policy
|
||||||
- ip route
|
- ip ipsec profile
|
||||||
- ip route rule
|
- ip ipsec proposal
|
||||||
- ip route vrf
|
- ip ipsec settings
|
||||||
- ip service
|
- ip neighbor discovery-settings
|
||||||
- ip settings
|
- ip pool
|
||||||
- ip smb
|
- ip proxy
|
||||||
- ip socks
|
- ip route
|
||||||
- ip ssh
|
- ip route rule
|
||||||
- ip tftp settings
|
- ip route vrf
|
||||||
- ip traffic-flow
|
- ip service
|
||||||
- ip traffic-flow ipfix
|
- ip settings
|
||||||
- ip traffic-flow target
|
- ip smb
|
||||||
- ip upnp
|
- ip socks
|
||||||
- ip upnp interfaces
|
- ip ssh
|
||||||
- ip vrf
|
- ip tftp settings
|
||||||
- ipv6 address
|
- ip traffic-flow
|
||||||
- ipv6 dhcp-client
|
- ip traffic-flow ipfix
|
||||||
- ipv6 dhcp-server
|
- ip traffic-flow target
|
||||||
- ipv6 dhcp-server option
|
- ip upnp
|
||||||
- ipv6 firewall address-list
|
- ip upnp interfaces
|
||||||
- ipv6 firewall filter
|
- ip vrf
|
||||||
- ipv6 firewall mangle
|
- ipv6 address
|
||||||
- ipv6 firewall nat
|
- ipv6 dhcp-client
|
||||||
- ipv6 firewall raw
|
- ipv6 dhcp-server
|
||||||
- ipv6 nd
|
- ipv6 dhcp-server option
|
||||||
- ipv6 nd prefix
|
- ipv6 firewall address-list
|
||||||
- ipv6 nd prefix default
|
- ipv6 firewall filter
|
||||||
- ipv6 route
|
- ipv6 firewall mangle
|
||||||
- ipv6 settings
|
- ipv6 firewall nat
|
||||||
- mpls
|
- ipv6 firewall raw
|
||||||
- mpls interface
|
- ipv6 nd
|
||||||
- mpls ldp
|
- ipv6 nd prefix
|
||||||
- mpls ldp accept-filter
|
- ipv6 nd prefix default
|
||||||
- mpls ldp advertise-filter
|
- ipv6 route
|
||||||
- mpls ldp interface
|
- ipv6 settings
|
||||||
- port firmware
|
- mpls
|
||||||
- port remote-access
|
- mpls interface
|
||||||
- ppp aaa
|
- mpls ldp
|
||||||
- ppp profile
|
- mpls ldp accept-filter
|
||||||
- ppp secret
|
- mpls ldp advertise-filter
|
||||||
- queue interface
|
- mpls ldp interface
|
||||||
- queue simple
|
- port firmware
|
||||||
- queue tree
|
- port remote-access
|
||||||
- queue type
|
- ppp aaa
|
||||||
- radius
|
- ppp profile
|
||||||
- radius incoming
|
- ppp secret
|
||||||
- routing bgp aggregate
|
- queue interface
|
||||||
- routing bgp connection
|
- queue simple
|
||||||
- routing bgp instance
|
- queue tree
|
||||||
- routing bgp network
|
- queue type
|
||||||
- routing bgp peer
|
- radius
|
||||||
- routing bgp template
|
- radius incoming
|
||||||
- routing filter
|
- routing bfd configuration
|
||||||
- routing filter num-list
|
- routing bgp aggregate
|
||||||
- routing filter rule
|
- routing bgp connection
|
||||||
- routing filter select-rule
|
- routing bgp instance
|
||||||
- routing id
|
- routing bgp network
|
||||||
- routing igmp-proxy
|
- routing bgp peer
|
||||||
- routing igmp-proxy interface
|
- routing bgp template
|
||||||
- routing mme
|
- routing filter
|
||||||
- routing ospf area
|
- routing filter community-list
|
||||||
- routing ospf area range
|
- routing filter num-list
|
||||||
- routing ospf instance
|
- routing filter rule
|
||||||
- routing ospf interface-template
|
- routing filter select-rule
|
||||||
- routing ospf static-neighbor
|
- routing id
|
||||||
- routing pimsm instance
|
- routing igmp-proxy
|
||||||
- routing pimsm interface-template
|
- routing igmp-proxy interface
|
||||||
- routing rip
|
- routing mme
|
||||||
- routing ripng
|
- routing ospf area
|
||||||
- routing rule
|
- routing ospf area range
|
||||||
- routing table
|
- routing ospf instance
|
||||||
- snmp
|
- routing ospf interface-template
|
||||||
- snmp community
|
- routing ospf static-neighbor
|
||||||
- system clock
|
- routing pimsm instance
|
||||||
- system clock manual
|
- routing pimsm interface-template
|
||||||
- system health settings
|
- routing rip
|
||||||
- system identity
|
- routing ripng
|
||||||
- system leds settings
|
- routing rule
|
||||||
- system logging
|
- routing table
|
||||||
- system logging action
|
- snmp
|
||||||
- system note
|
- snmp community
|
||||||
- system ntp client
|
- system clock
|
||||||
- system ntp client servers
|
- system clock manual
|
||||||
- system ntp server
|
- system health settings
|
||||||
- system package update
|
- system identity
|
||||||
- system resource irq rps
|
- system leds settings
|
||||||
- system routerboard settings
|
- system logging
|
||||||
- system scheduler
|
- system logging action
|
||||||
- system script
|
- system note
|
||||||
- system upgrade mirror
|
- system ntp client
|
||||||
- system ups
|
- system ntp client servers
|
||||||
- system watchdog
|
- system ntp server
|
||||||
- tool bandwidth-server
|
- system package update
|
||||||
- tool e-mail
|
- system resource irq rps
|
||||||
- tool graphing
|
- system routerboard settings
|
||||||
- tool graphing interface
|
- system scheduler
|
||||||
- tool graphing resource
|
- system script
|
||||||
- tool mac-server
|
- system upgrade mirror
|
||||||
- tool mac-server mac-winbox
|
- system ups
|
||||||
- tool mac-server ping
|
- system watchdog
|
||||||
- tool netwatch
|
- tool bandwidth-server
|
||||||
- tool romon
|
- tool e-mail
|
||||||
- tool sms
|
- tool graphing
|
||||||
- tool sniffer
|
- tool graphing interface
|
||||||
- tool traffic-generator
|
- tool graphing resource
|
||||||
- user
|
- tool mac-server
|
||||||
- user aaa
|
- tool mac-server mac-winbox
|
||||||
- user group
|
- tool mac-server ping
|
||||||
- user settings
|
- tool netwatch
|
||||||
|
- tool romon
|
||||||
|
- tool sms
|
||||||
|
- tool sniffer
|
||||||
|
- tool traffic-generator
|
||||||
|
- user
|
||||||
|
- user aaa
|
||||||
|
- user group
|
||||||
|
- user settings
|
||||||
# END PATH LIST
|
# END PATH LIST
|
||||||
data:
|
data:
|
||||||
description:
|
description:
|
||||||
|
@ -297,12 +307,12 @@ options:
|
||||||
default: ignore
|
default: ignore
|
||||||
handle_entries_content:
|
handle_entries_content:
|
||||||
description:
|
description:
|
||||||
- For a single entry in O(data), this describes how to handle fields that are not mentioned
|
- For a single entry in O(data), this describes how to handle fields that are not mentioned in that entry, but appear
|
||||||
in that entry, but appear in the actual config.
|
in the actual config.
|
||||||
- If V(ignore), they are not modified.
|
- If V(ignore), they are not modified.
|
||||||
- If V(remove), they are removed. If at least one cannot be removed, the module will fail.
|
- If V(remove), they are removed. If at least one cannot be removed, the module will fail.
|
||||||
- If V(remove_as_much_as_possible), all that can be removed will be removed. The ones that
|
- If V(remove_as_much_as_possible), all that can be removed will be removed. The ones that cannot be removed will be
|
||||||
cannot be removed will be kept.
|
kept.
|
||||||
- Note that V(remove) and V(remove_as_much_as_possible) do not apply to write-only fields.
|
- Note that V(remove) and V(remove_as_much_as_possible) do not apply to write-only fields.
|
||||||
type: str
|
type: str
|
||||||
choices:
|
choices:
|
||||||
|
@ -314,8 +324,8 @@ options:
|
||||||
description:
|
description:
|
||||||
- How to handle values passed in for read-only fields.
|
- How to handle values passed in for read-only fields.
|
||||||
- If V(ignore), they are not passed to the API.
|
- If V(ignore), they are not passed to the API.
|
||||||
- If V(validate), the values are not passed for creation, and for updating they are compared to the value returned for the object.
|
- If V(validate), the values are not passed for creation, and for updating they are compared to the value returned for
|
||||||
If they differ, the module fails.
|
the object. If they differ, the module fails.
|
||||||
- If V(error), the module will fail if read-only fields are provided.
|
- If V(error), the module will fail if read-only fields are provided.
|
||||||
type: str
|
type: str
|
||||||
choices:
|
choices:
|
||||||
|
@ -328,9 +338,8 @@ options:
|
||||||
description:
|
description:
|
||||||
- How to handle values passed in for write-only fields.
|
- How to handle values passed in for write-only fields.
|
||||||
- If V(create_only), they are passed on creation, and ignored for updating.
|
- If V(create_only), they are passed on creation, and ignored for updating.
|
||||||
- If V(always_update), they are always passed to the API. This means that if such a value is present,
|
- If V(always_update), they are always passed to the API. This means that if such a value is present, the module will
|
||||||
the module will always result in C(changed) since there is no way to validate whether the value
|
always result in C(changed) since there is no way to validate whether the value actually changed.
|
||||||
actually changed.
|
|
||||||
- If V(error), the module will fail if write-only fields are provided.
|
- If V(error), the module will fail if write-only fields are provided.
|
||||||
type: str
|
type: str
|
||||||
choices:
|
choices:
|
||||||
|
@ -342,20 +351,18 @@ options:
|
||||||
restrict:
|
restrict:
|
||||||
description:
|
description:
|
||||||
- Restrict operation to entries matching the following criteria.
|
- Restrict operation to entries matching the following criteria.
|
||||||
- This can be useful together with O(handle_absent_entries=remove) to operate on a subset of
|
- This can be useful together with O(handle_absent_entries=remove) to operate on a subset of the values.
|
||||||
the values.
|
- For example, for O(path=ip firewall filter), you can set O(restrict[].field=chain) and O(restrict[].values=input)
|
||||||
- For example, for O(path=ip firewall filter), you can set O(restrict[].field=chain) and
|
to restrict operation to the input chain, and ignore the forward and output chains.
|
||||||
O(restrict[].values=input) to restrict operation to the input chain, and ignore the
|
|
||||||
forward and output chains.
|
|
||||||
version_added: 2.18.0
|
version_added: 2.18.0
|
||||||
seealso:
|
seealso:
|
||||||
- module: community.routeros.api
|
- module: community.routeros.api
|
||||||
- module: community.routeros.api_facts
|
- module: community.routeros.api_facts
|
||||||
- module: community.routeros.api_find_and_modify
|
- module: community.routeros.api_find_and_modify
|
||||||
- module: community.routeros.api_info
|
- module: community.routeros.api_info
|
||||||
'''
|
"""
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = r"""
|
||||||
---
|
---
|
||||||
- name: Setup DHCP server networks
|
- name: Setup DHCP server networks
|
||||||
# Ensures that we have exactly two DHCP server networks (in the specified order)
|
# Ensures that we have exactly two DHCP server networks (in the specified order)
|
||||||
|
@ -410,43 +417,42 @@ EXAMPLES = '''
|
||||||
data:
|
data:
|
||||||
- action: drop
|
- action: drop
|
||||||
chain: input
|
chain: input
|
||||||
'''
|
"""
|
||||||
|
|
||||||
RETURN = '''
|
RETURN = r"""
|
||||||
---
|
|
||||||
old_data:
|
old_data:
|
||||||
description:
|
description:
|
||||||
- A list of all elements for the current path before a change was made.
|
- A list of all elements for the current path before a change was made.
|
||||||
sample:
|
sample:
|
||||||
- '.id': '*1'
|
- '.id': '*1'
|
||||||
actual-interface: bridge
|
actual-interface: bridge
|
||||||
address: "192.168.88.1/24"
|
address: "192.168.88.1/24"
|
||||||
comment: defconf
|
comment: defconf
|
||||||
disabled: false
|
disabled: false
|
||||||
dynamic: false
|
dynamic: false
|
||||||
interface: bridge
|
interface: bridge
|
||||||
invalid: false
|
invalid: false
|
||||||
network: 192.168.88.0
|
network: 192.168.88.0
|
||||||
type: list
|
type: list
|
||||||
elements: dict
|
elements: dict
|
||||||
returned: always
|
returned: always
|
||||||
new_data:
|
new_data:
|
||||||
description:
|
description:
|
||||||
- A list of all elements for the current path after a change was made.
|
- A list of all elements for the current path after a change was made.
|
||||||
sample:
|
sample:
|
||||||
- '.id': '*1'
|
- '.id': '*1'
|
||||||
actual-interface: bridge
|
actual-interface: bridge
|
||||||
address: "192.168.1.1/24"
|
address: "192.168.1.1/24"
|
||||||
comment: awesome
|
comment: awesome
|
||||||
disabled: false
|
disabled: false
|
||||||
dynamic: false
|
dynamic: false
|
||||||
interface: bridge
|
interface: bridge
|
||||||
invalid: false
|
invalid: false
|
||||||
network: 192.168.1.0
|
network: 192.168.1.0
|
||||||
type: list
|
type: list
|
||||||
elements: dict
|
elements: dict
|
||||||
returned: always
|
returned: always
|
||||||
'''
|
"""
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
|
@ -7,87 +7,77 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = r"""
|
||||||
---
|
|
||||||
module: command
|
module: command
|
||||||
author: "Egor Zaitsev (@heuels)"
|
author: "Egor Zaitsev (@heuels)"
|
||||||
short_description: Run commands on remote devices running MikroTik RouterOS
|
short_description: Run commands on remote devices running MikroTik RouterOS
|
||||||
description:
|
description:
|
||||||
- Sends arbitrary commands to an RouterOS node and returns the results
|
- Sends arbitrary commands to an RouterOS node and returns the results read from the device. This module includes an argument
|
||||||
read from the device. This module includes an
|
that will cause the module to wait for a specific condition before returning or timing out if the condition is not met.
|
||||||
argument that will cause the module to wait for a specific condition
|
- The module always indicates a (changed) status. You can use R(the changed_when task property,override_the_changed_result)
|
||||||
before returning or timing out if the condition is not met.
|
to determine whether a command task actually resulted in a change or not.
|
||||||
- The module always indicates a (changed) status. You can use
|
|
||||||
R(the changed_when task property,override_the_changed_result) to determine
|
|
||||||
whether a command task actually resulted in a change or not.
|
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- community.routeros.attributes
|
- community.routeros.attributes
|
||||||
attributes:
|
attributes:
|
||||||
check_mode:
|
check_mode:
|
||||||
support: none
|
support: none
|
||||||
details:
|
details:
|
||||||
- Before community.routeros 3.0.0, the module claimed to support check mode.
|
- Before community.routeros 3.0.0, the module claimed to support check mode. It simply executed the command in check
|
||||||
It simply executed the command in check mode.
|
mode.
|
||||||
diff_mode:
|
diff_mode:
|
||||||
support: none
|
support: none
|
||||||
platform:
|
platform:
|
||||||
support: full
|
support: full
|
||||||
platforms: RouterOS
|
platforms: RouterOS
|
||||||
|
idempotent:
|
||||||
|
support: N/A
|
||||||
|
details:
|
||||||
|
- Whether the executed command is idempotent depends on the command.
|
||||||
options:
|
options:
|
||||||
commands:
|
commands:
|
||||||
description:
|
description:
|
||||||
- List of commands to send to the remote RouterOS device over the
|
- List of commands to send to the remote RouterOS device over the configured provider. The resulting output from the
|
||||||
configured provider. The resulting output from the command
|
command is returned. If the O(wait_for) argument is provided, the module is not returned until the condition is satisfied
|
||||||
is returned. If the O(wait_for) argument is provided, the
|
or the number of retries has expired.
|
||||||
module is not returned until the condition is satisfied or
|
|
||||||
the number of retries has expired.
|
|
||||||
required: true
|
required: true
|
||||||
type: list
|
type: list
|
||||||
elements: str
|
elements: str
|
||||||
wait_for:
|
wait_for:
|
||||||
description:
|
description:
|
||||||
- List of conditions to evaluate against the output of the
|
- List of conditions to evaluate against the output of the command. The task will wait for each condition to be true
|
||||||
command. The task will wait for each condition to be true
|
before moving forward. If the conditional is not true within the configured number of retries, the task fails. See
|
||||||
before moving forward. If the conditional is not true
|
examples.
|
||||||
within the configured number of retries, the task fails.
|
|
||||||
See examples.
|
|
||||||
type: list
|
type: list
|
||||||
elements: str
|
elements: str
|
||||||
match:
|
match:
|
||||||
description:
|
description:
|
||||||
- The O(match) argument is used in conjunction with the
|
- The O(match) argument is used in conjunction with the O(wait_for) argument to specify the match policy. Valid values
|
||||||
O(wait_for) argument to specify the match policy. Valid
|
are V(all) or V(any). If the value is set to V(all) then all conditionals in the wait_for must be satisfied. If the
|
||||||
values are V(all) or V(any). If the value is set to V(all)
|
value is set to V(any) then only one of the values must be satisfied.
|
||||||
then all conditionals in the wait_for must be satisfied. If
|
|
||||||
the value is set to V(any) then only one of the values must be
|
|
||||||
satisfied.
|
|
||||||
default: all
|
default: all
|
||||||
choices: ['any', 'all']
|
choices: ['any', 'all']
|
||||||
type: str
|
type: str
|
||||||
retries:
|
retries:
|
||||||
description:
|
description:
|
||||||
- Specifies the number of retries a command should by tried
|
- Specifies the number of retries a command should by tried before it is considered failed. The command is run on the
|
||||||
before it is considered failed. The command is run on the
|
target device every retry and evaluated against the O(wait_for) conditions.
|
||||||
target device every retry and evaluated against the
|
|
||||||
O(wait_for) conditions.
|
|
||||||
default: 10
|
default: 10
|
||||||
type: int
|
type: int
|
||||||
interval:
|
interval:
|
||||||
description:
|
description:
|
||||||
- Configures the interval in seconds to wait between retries
|
- Configures the interval in seconds to wait between retries of the command. If the command does not pass the specified
|
||||||
of the command. If the command does not pass the specified
|
conditions, the interval indicates how long to wait before trying the command again.
|
||||||
conditions, the interval indicates how long to wait before
|
|
||||||
trying the command again.
|
|
||||||
default: 1
|
default: 1
|
||||||
type: int
|
type: int
|
||||||
seealso:
|
seealso:
|
||||||
- ref: ansible_collections.community.routeros.docsite.ssh-guide
|
- ref: ansible_collections.community.routeros.docsite.ssh-guide
|
||||||
description: How to connect to RouterOS devices with SSH
|
description: How to connect to RouterOS devices with SSH.
|
||||||
- ref: ansible_collections.community.routeros.docsite.quoting
|
- ref: ansible_collections.community.routeros.docsite.quoting
|
||||||
description: How to quote and unquote commands and arguments
|
description: How to quote and unquote commands and arguments.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
EXAMPLES = """
|
EXAMPLES = r"""
|
||||||
|
---
|
||||||
- name: Run command on remote devices
|
- name: Run command on remote devices
|
||||||
community.routeros.command:
|
community.routeros.command:
|
||||||
commands: /system routerboard print
|
commands: /system routerboard print
|
||||||
|
@ -113,19 +103,19 @@ EXAMPLES = """
|
||||||
- result[1] contains ether1
|
- result[1] contains ether1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RETURN = """
|
RETURN = r"""
|
||||||
stdout:
|
stdout:
|
||||||
description: The set of responses from the commands
|
description: The set of responses from the commands.
|
||||||
returned: always apart from low level errors (such as action plugin)
|
returned: always apart from low level errors (such as action plugin)
|
||||||
type: list
|
type: list
|
||||||
sample: ['...', '...']
|
sample: ['...', '...']
|
||||||
stdout_lines:
|
stdout_lines:
|
||||||
description: The value of stdout split into a list
|
description: The value of stdout split into a list.
|
||||||
returned: always apart from low level errors (such as action plugin)
|
returned: always apart from low level errors (such as action plugin)
|
||||||
type: list
|
type: list
|
||||||
sample: [['...', '...'], ['...'], ['...']]
|
sample: [['...', '...'], ['...'], ['...']]
|
||||||
failed_conditions:
|
failed_conditions:
|
||||||
description: The list of conditionals that have failed
|
description: The list of conditionals that have failed.
|
||||||
returned: failed
|
returned: failed
|
||||||
type: list
|
type: list
|
||||||
sample: ['...', '...']
|
sample: ['...', '...']
|
||||||
|
|
|
@ -7,21 +7,19 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = r"""
|
||||||
---
|
|
||||||
module: facts
|
module: facts
|
||||||
author: "Egor Zaitsev (@heuels)"
|
author: "Egor Zaitsev (@heuels)"
|
||||||
short_description: Collect facts from remote devices running MikroTik RouterOS
|
short_description: Collect facts from remote devices running MikroTik RouterOS
|
||||||
description:
|
description:
|
||||||
- Collects a base set of device facts from a remote device that
|
- Collects a base set of device facts from a remote device that is running RouterOS. This module prepends all of the base
|
||||||
is running RouterOS. This module prepends all of the
|
network fact keys with C(ansible_net_<fact>). The facts module will always collect a base set of facts from the device
|
||||||
base network fact keys with C(ansible_net_<fact>). The facts
|
|
||||||
module will always collect a base set of facts from the device
|
|
||||||
and can enable or disable collection of additional facts.
|
and can enable or disable collection of additional facts.
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- community.routeros.attributes
|
- community.routeros.attributes
|
||||||
- community.routeros.attributes.facts
|
- community.routeros.attributes.facts
|
||||||
- community.routeros.attributes.facts_module
|
- community.routeros.attributes.facts_module
|
||||||
|
- community.routeros.attributes.idempotent_not_modify_state
|
||||||
attributes:
|
attributes:
|
||||||
platform:
|
platform:
|
||||||
support: full
|
support: full
|
||||||
|
@ -29,12 +27,10 @@ attributes:
|
||||||
options:
|
options:
|
||||||
gather_subset:
|
gather_subset:
|
||||||
description:
|
description:
|
||||||
- When supplied, this argument will restrict the facts collected
|
- When supplied, this argument will restrict the facts collected to a given subset. Possible values for this argument
|
||||||
to a given subset. Possible values for this argument include
|
include V(all), V(hardware), V(config), V(interfaces), and V(routing).
|
||||||
V(all), V(hardware), V(config), V(interfaces), and V(routing).
|
- Can specify a list of values to include a larger subset. Values can also be used with an initial V(!) to specify that
|
||||||
- Can specify a list of values to include a larger subset.
|
a specific subset should not be collected.
|
||||||
Values can also be used with an initial V(!) to specify that a
|
|
||||||
specific subset should not be collected.
|
|
||||||
required: false
|
required: false
|
||||||
default:
|
default:
|
||||||
- '!config'
|
- '!config'
|
||||||
|
@ -42,10 +38,11 @@ options:
|
||||||
elements: str
|
elements: str
|
||||||
seealso:
|
seealso:
|
||||||
- ref: ansible_collections.community.routeros.docsite.ssh-guide
|
- ref: ansible_collections.community.routeros.docsite.ssh-guide
|
||||||
description: How to connect to RouterOS devices with SSH
|
description: How to connect to RouterOS devices with SSH.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
EXAMPLES = """
|
EXAMPLES = r"""
|
||||||
|
---
|
||||||
- name: Collect all facts from the device
|
- name: Collect all facts from the device
|
||||||
community.routeros.facts:
|
community.routeros.facts:
|
||||||
gather_subset: all
|
gather_subset: all
|
||||||
|
@ -61,7 +58,7 @@ EXAMPLES = """
|
||||||
- "!hardware"
|
- "!hardware"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RETURN = """
|
RETURN = r"""
|
||||||
ansible_facts:
|
ansible_facts:
|
||||||
description: "Dictionary of IP geolocation facts for a host's IP address."
|
description: "Dictionary of IP geolocation facts for a host's IP address."
|
||||||
returned: always
|
returned: always
|
||||||
|
@ -129,9 +126,9 @@ ansible_facts:
|
||||||
ansible_net_config_nonverbose:
|
ansible_net_config_nonverbose:
|
||||||
description:
|
description:
|
||||||
- The current active config from the device in minimal form.
|
- The current active config from the device in minimal form.
|
||||||
- This value is idempotent in the sense that if the facts module is run twice and the device's config
|
- This value is idempotent in the sense that if the facts module is run twice and the device's config was not changed
|
||||||
was not changed between the runs, the value is identical. This is achieved by running C(/export)
|
between the runs, the value is identical. This is achieved by running C(/export) and stripping the timestamp from
|
||||||
and stripping the timestamp from the comment in the first line.
|
the comment in the first line.
|
||||||
returned: O(gather_subset) contains V(config)
|
returned: O(gather_subset) contains V(config)
|
||||||
type: str
|
type: str
|
||||||
version_added: 1.2.0
|
version_added: 1.2.0
|
||||||
|
@ -592,8 +589,6 @@ FACT_SUBSETS = dict(
|
||||||
|
|
||||||
VALID_SUBSETS = frozenset(FACT_SUBSETS.keys())
|
VALID_SUBSETS = frozenset(FACT_SUBSETS.keys())
|
||||||
|
|
||||||
warnings = list()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""main entry point for module execution
|
"""main entry point for module execution
|
||||||
|
@ -656,7 +651,7 @@ def main():
|
||||||
key = 'ansible_net_%s' % key
|
key = 'ansible_net_%s' % key
|
||||||
ansible_facts[key] = value
|
ansible_facts[key] = value
|
||||||
|
|
||||||
module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
|
module.exit_json(ansible_facts=ansible_facts)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -31,7 +31,9 @@ class TerminalModule(TerminalBase):
|
||||||
|
|
||||||
terminal_stdout_re = [
|
terminal_stdout_re = [
|
||||||
re.compile(br"\x1b<"),
|
re.compile(br"\x1b<"),
|
||||||
re.compile(br"\[[\w\-\.]+\@[\w\s\-\.\/]+\] ?(<SAFE)?> ?$"),
|
re.compile(
|
||||||
|
br"((\[[\w\-\.]+\@)|(\r\<(([\w\-\.]*\@)|)))"
|
||||||
|
br"[\w\s\-\.\/]+\] ?(<SAFE)?> ?$"),
|
||||||
re.compile(br"Please press \"Enter\" to continue!"),
|
re.compile(br"Please press \"Enter\" to continue!"),
|
||||||
re.compile(br"Do you want to see the software license\? \[Y\/n\]: ?"),
|
re.compile(br"Do you want to see the software license\? \[Y\/n\]: ?"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- >-
|
- >-
|
||||||
result.msg == "Unexpected end of string during escaped parameter"
|
"Unexpected end of string during escaped parameter" in result.msg
|
||||||
|
|
||||||
- name: "Test quote_argument filter"
|
- name: "Test quote_argument filter"
|
||||||
assert:
|
assert:
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
collections:
|
collections:
|
||||||
- ansible.netcommon
|
- ansible.netcommon
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- >-
|
- >-
|
||||||
result.msg == "Unexpected end of string during escaped parameter"
|
"Unexpected end of string during escaped parameter" in result.msg
|
||||||
|
|
||||||
- name: "Test quote_argument filter"
|
- name: "Test quote_argument filter"
|
||||||
assert:
|
assert:
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"include_symlinks": false,
|
|
||||||
"prefixes": [
|
|
||||||
"docs/docsite/",
|
|
||||||
"plugins/",
|
|
||||||
"roles/"
|
|
||||||
],
|
|
||||||
"output": "path-line-column-message",
|
|
||||||
"requirements": [
|
|
||||||
"ansible-core",
|
|
||||||
"antsibull-docs"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
"""Check extra collection docs with antsibull-docs."""
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Main entry point."""
|
|
||||||
env = os.environ.copy()
|
|
||||||
suffix = ':{env}'.format(env=env["ANSIBLE_COLLECTIONS_PATH"]) if 'ANSIBLE_COLLECTIONS_PATH' in env else ''
|
|
||||||
env['ANSIBLE_COLLECTIONS_PATH'] = '{root}{suffix}'.format(root=os.path.dirname(os.path.dirname(os.path.dirname(os.getcwd()))), suffix=suffix)
|
|
||||||
p = subprocess.run(
|
|
||||||
['antsibull-docs', 'lint-collection-docs', '--plugin-docs', '--skip-rstcheck', '.'],
|
|
||||||
env=env,
|
|
||||||
check=False,
|
|
||||||
)
|
|
||||||
if p.returncode not in (0, 3):
|
|
||||||
print('{0}:0:0: unexpected return code {1}'.format(sys.argv[0], p.returncode))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"include_symlinks": false,
|
|
||||||
"output": "path-message"
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
SPDX-FileCopyrightText: Ansible Project
|
|
|
@ -1,110 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# Copyright (c) 2022, Felix Fontein <felix@fontein.de>
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
"""Prevent files without a correct license identifier from being added to the source tree."""
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
import os
|
|
||||||
import glob
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def format_license_list(licenses):
|
|
||||||
if not licenses:
|
|
||||||
return '(empty)'
|
|
||||||
return ', '.join(['"%s"' % license for license in licenses])
|
|
||||||
|
|
||||||
|
|
||||||
def find_licenses(filename, relax=False):
|
|
||||||
spdx_license_identifiers = []
|
|
||||||
other_license_identifiers = []
|
|
||||||
has_copyright = False
|
|
||||||
try:
|
|
||||||
with open(filename, 'r', encoding='utf-8') as f:
|
|
||||||
for line in f:
|
|
||||||
line = line.rstrip()
|
|
||||||
if 'Copyright ' in line:
|
|
||||||
has_copyright = True
|
|
||||||
if 'Copyright: ' in line:
|
|
||||||
print('%s: found copyright line with "Copyright:". Please remove the colon.' % (filename, ))
|
|
||||||
if 'SPDX-FileCopyrightText: ' in line:
|
|
||||||
has_copyright = True
|
|
||||||
idx = line.find('SPDX-License-Identifier: ')
|
|
||||||
if idx >= 0:
|
|
||||||
lic_id = line[idx + len('SPDX-License-Identifier: '):]
|
|
||||||
spdx_license_identifiers.extend(lic_id.split(' OR '))
|
|
||||||
if 'GNU General Public License' in line:
|
|
||||||
if 'v3.0+' in line:
|
|
||||||
other_license_identifiers.append('GPL-3.0-or-later')
|
|
||||||
if 'version 3 or later' in line:
|
|
||||||
other_license_identifiers.append('GPL-3.0-or-later')
|
|
||||||
if 'Simplified BSD License' in line:
|
|
||||||
other_license_identifiers.append('BSD-2-Clause')
|
|
||||||
if 'Apache License 2.0' in line:
|
|
||||||
other_license_identifiers.append('Apache-2.0')
|
|
||||||
if 'PSF License' in line or 'Python-2.0' in line:
|
|
||||||
other_license_identifiers.append('PSF-2.0')
|
|
||||||
if 'MIT License' in line:
|
|
||||||
other_license_identifiers.append('MIT')
|
|
||||||
except Exception as exc:
|
|
||||||
print('%s: error while processing file: %s' % (filename, exc))
|
|
||||||
if len(set(spdx_license_identifiers)) < len(spdx_license_identifiers):
|
|
||||||
print('%s: found identical SPDX-License-Identifier values' % (filename, ))
|
|
||||||
if other_license_identifiers and set(other_license_identifiers) != set(spdx_license_identifiers):
|
|
||||||
print('%s: SPDX-License-Identifier yielded the license list %s, while manual guessing yielded the license list %s' % (
|
|
||||||
filename, format_license_list(spdx_license_identifiers), format_license_list(other_license_identifiers)))
|
|
||||||
if not has_copyright and not relax:
|
|
||||||
print('%s: found no copyright notice' % (filename, ))
|
|
||||||
return sorted(spdx_license_identifiers)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Main entry point."""
|
|
||||||
paths = sys.argv[1:] or sys.stdin.read().splitlines()
|
|
||||||
|
|
||||||
# The following paths are allowed to have no license identifier
|
|
||||||
no_comments_allowed = [
|
|
||||||
'changelogs/fragments/*.yml',
|
|
||||||
'changelogs/fragments/*.yaml',
|
|
||||||
]
|
|
||||||
|
|
||||||
# These files are completely ignored
|
|
||||||
ignore_paths = [
|
|
||||||
'.ansible-test-timeout.json',
|
|
||||||
'.reuse/dep5',
|
|
||||||
'LICENSES/*.txt',
|
|
||||||
'COPYING',
|
|
||||||
]
|
|
||||||
|
|
||||||
no_comments_allowed = [fn for pattern in no_comments_allowed for fn in glob.glob(pattern)]
|
|
||||||
ignore_paths = [fn for pattern in ignore_paths for fn in glob.glob(pattern)]
|
|
||||||
|
|
||||||
valid_licenses = [license_file[len('LICENSES/'):-len('.txt')] for license_file in glob.glob('LICENSES/*.txt')]
|
|
||||||
|
|
||||||
for path in paths:
|
|
||||||
if path.startswith('./'):
|
|
||||||
path = path[2:]
|
|
||||||
if path in ignore_paths or path.startswith('tests/output/'):
|
|
||||||
continue
|
|
||||||
if os.stat(path).st_size == 0:
|
|
||||||
continue
|
|
||||||
if not path.endswith('.license') and os.path.exists(path + '.license'):
|
|
||||||
path = path + '.license'
|
|
||||||
valid_licenses_for_path = valid_licenses
|
|
||||||
if path.startswith('plugins/') and not path.startswith(('plugins/modules/', 'plugins/module_utils/')):
|
|
||||||
valid_licenses_for_path = [license for license in valid_licenses if license == 'GPL-3.0-or-later']
|
|
||||||
licenses = find_licenses(path, relax=path in no_comments_allowed)
|
|
||||||
if not licenses:
|
|
||||||
if path not in no_comments_allowed:
|
|
||||||
print('%s: must have at least one license' % (path, ))
|
|
||||||
else:
|
|
||||||
for license in licenses:
|
|
||||||
if license not in valid_licenses_for_path:
|
|
||||||
print('%s: found not allowed license "%s", must be one of %s' % (
|
|
||||||
path, license, format_license_list(valid_licenses_for_path)))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,3 +0,0 @@
|
||||||
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
SPDX-FileCopyrightText: 2022, Felix Fontein <felix@fontein.de>
|
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"include_symlinks": true,
|
|
||||||
"prefixes": [
|
|
||||||
"plugins/"
|
|
||||||
],
|
|
||||||
"output": "path-message"
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
SPDX-FileCopyrightText: Ansible Project
|
|
|
@ -1,58 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
"""Prevent unwanted files from being added to the source tree."""
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
import os
|
|
||||||
import os.path
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Main entry point."""
|
|
||||||
paths = sys.argv[1:] or sys.stdin.read().splitlines()
|
|
||||||
|
|
||||||
allowed_extensions = (
|
|
||||||
'.cs',
|
|
||||||
'.ps1',
|
|
||||||
'.psm1',
|
|
||||||
'.py',
|
|
||||||
)
|
|
||||||
|
|
||||||
skip_paths = set([
|
|
||||||
])
|
|
||||||
|
|
||||||
skip_directories = (
|
|
||||||
)
|
|
||||||
|
|
||||||
yaml_directories = (
|
|
||||||
'plugins/test/',
|
|
||||||
'plugins/filter/',
|
|
||||||
)
|
|
||||||
|
|
||||||
for path in paths:
|
|
||||||
if path in skip_paths:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if any(path.startswith(skip_directory) for skip_directory in skip_directories):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if os.path.islink(path):
|
|
||||||
print('%s: is a symbolic link' % (path, ))
|
|
||||||
elif not os.path.isfile(path):
|
|
||||||
print('%s: is not a regular file' % (path, ))
|
|
||||||
|
|
||||||
ext = os.path.splitext(path)[1]
|
|
||||||
|
|
||||||
if ext in ('.yml', ) and any(path.startswith(yaml_directory) for yaml_directory in yaml_directories):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if ext not in allowed_extensions:
|
|
||||||
print('%s: extension must be one of: %s' % (path, ', '.join(allowed_extensions)))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"include_symlinks": false,
|
|
||||||
"prefixes": [
|
|
||||||
"docs/docsite/rst/api-guide.rst",
|
|
||||||
"plugins/modules/"
|
|
||||||
],
|
|
||||||
"output": "path-line-column-message",
|
|
||||||
"requirements": [
|
|
||||||
"ansible-core"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
SPDX-FileCopyrightText: Ansible Project
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
"""Check whether update-docs.py modifies something."""
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Main entry point."""
|
|
||||||
p = subprocess.run([sys.executable, 'update-docs.py'], check=False)
|
|
||||||
if p.returncode not in (0, 1):
|
|
||||||
print('{0}:0:0: unexpected return code {1}'.format(sys.argv[0], p.returncode))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,9 +1,9 @@
|
||||||
docs/docsite/rst/api-guide.rst rstcheck
|
docs/docsite/rst/api-guide.rst rstcheck
|
||||||
docs/docsite/rst/quoting.rst rstcheck
|
docs/docsite/rst/quoting.rst rstcheck
|
||||||
docs/docsite/rst/ssh-guide.rst rstcheck
|
docs/docsite/rst/ssh-guide.rst rstcheck
|
||||||
update-docs.py compile-2.6
|
tests/update-docs.py compile-2.6
|
||||||
update-docs.py compile-2.7
|
tests/update-docs.py compile-2.7
|
||||||
update-docs.py compile-3.5
|
tests/update-docs.py compile-3.5
|
||||||
update-docs.py future-import-boilerplate
|
tests/update-docs.py future-import-boilerplate
|
||||||
update-docs.py metaclass-boilerplate
|
tests/update-docs.py metaclass-boilerplate
|
||||||
update-docs.py shebang
|
tests/update-docs.py shebang
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
update-docs.py compile-2.6
|
tests/update-docs.py compile-2.6
|
||||||
update-docs.py compile-2.7
|
tests/update-docs.py compile-2.7
|
||||||
update-docs.py compile-3.5
|
tests/update-docs.py compile-3.5
|
||||||
update-docs.py future-import-boilerplate
|
tests/update-docs.py future-import-boilerplate
|
||||||
update-docs.py metaclass-boilerplate
|
tests/update-docs.py metaclass-boilerplate
|
||||||
update-docs.py shebang
|
tests/update-docs.py shebang
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
update-docs.py shebang
|
tests/update-docs.py shebang
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
update-docs.py shebang
|
tests/update-docs.py shebang
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
update-docs.py shebang
|
tests/update-docs.py shebang
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
update-docs.py shebang
|
tests/update-docs.py shebang
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
update-docs.py shebang
|
tests/update-docs.py shebang
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
update-docs.py shebang
|
tests/update-docs.py shebang
|
||||||
tests/unit/compat/mock.py pylint:use-yield-from # suggested construct does not work with Python 2
|
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
update-docs.py shebang
|
tests/update-docs.py shebang
|
||||||
tests/unit/compat/mock.py pylint:use-yield-from # suggested construct does not work with Python 2
|
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
update-docs.py shebang
|
tests/update-docs.py shebang
|
||||||
tests/unit/compat/mock.py pylint:use-yield-from # suggested construct does not work with Python 2
|
|
||||||
|
|
1
tests/sanity/ignore-2.20.txt
Normal file
1
tests/sanity/ignore-2.20.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
tests/update-docs.py shebang
|
|
@ -1,9 +1,9 @@
|
||||||
docs/docsite/rst/api-guide.rst rstcheck
|
docs/docsite/rst/api-guide.rst rstcheck
|
||||||
docs/docsite/rst/quoting.rst rstcheck
|
docs/docsite/rst/quoting.rst rstcheck
|
||||||
docs/docsite/rst/ssh-guide.rst rstcheck
|
docs/docsite/rst/ssh-guide.rst rstcheck
|
||||||
update-docs.py compile-2.6
|
tests/update-docs.py compile-2.6
|
||||||
update-docs.py compile-2.7
|
tests/update-docs.py compile-2.7
|
||||||
update-docs.py compile-3.5
|
tests/update-docs.py compile-3.5
|
||||||
update-docs.py future-import-boilerplate
|
tests/update-docs.py future-import-boilerplate
|
||||||
update-docs.py metaclass-boilerplate
|
tests/update-docs.py metaclass-boilerplate
|
||||||
update-docs.py shebang
|
tests/update-docs.py shebang
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
# Copyright (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
# Make coding more python3-ish
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
#
|
|
||||||
# Compat for python2.7
|
|
||||||
#
|
|
||||||
|
|
||||||
# One unittest needs to import builtins via __import__() so we need to have
|
|
||||||
# the string that represents it
|
|
||||||
try:
|
|
||||||
import __builtin__ # noqa: F401, pylint: disable=unused-import
|
|
||||||
except ImportError:
|
|
||||||
BUILTINS = 'builtins'
|
|
||||||
else:
|
|
||||||
BUILTINS = '__builtin__'
|
|
|
@ -1,109 +0,0 @@
|
||||||
# Copyright (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
# Make coding more python3-ish
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
'''
|
|
||||||
Compat module for Python3.x's unittest.mock module
|
|
||||||
'''
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# Python 2.7
|
|
||||||
|
|
||||||
# Note: Could use the pypi mock library on python3.x as well as python2.x. It
|
|
||||||
# is the same as the python3 stdlib mock library
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Allow wildcard import because we really do want to import all of mock's
|
|
||||||
# symbols into this compat shim
|
|
||||||
# pylint: disable=wildcard-import,unused-wildcard-import
|
|
||||||
from unittest.mock import * # noqa: F401, pylint: disable=unused-import
|
|
||||||
except ImportError:
|
|
||||||
# Python 2
|
|
||||||
# pylint: disable=wildcard-import,unused-wildcard-import
|
|
||||||
try:
|
|
||||||
from mock import * # noqa: F401, pylint: disable=unused-import
|
|
||||||
except ImportError:
|
|
||||||
print('You need the mock library installed on python2.x to run tests')
|
|
||||||
|
|
||||||
|
|
||||||
# Prior to 3.4.4, mock_open cannot handle binary read_data
|
|
||||||
if sys.version_info >= (3,) and sys.version_info < (3, 4, 4):
|
|
||||||
file_spec = None
|
|
||||||
|
|
||||||
def _iterate_read_data(read_data):
|
|
||||||
# Helper for mock_open:
|
|
||||||
# Retrieve lines from read_data via a generator so that separate calls to
|
|
||||||
# readline, read, and readlines are properly interleaved
|
|
||||||
sep = b'\n' if isinstance(read_data, bytes) else '\n'
|
|
||||||
data_as_list = [l + sep for l in read_data.split(sep)]
|
|
||||||
|
|
||||||
if data_as_list[-1] == sep:
|
|
||||||
# If the last line ended in a newline, the list comprehension will have an
|
|
||||||
# extra entry that's just a newline. Remove this.
|
|
||||||
data_as_list = data_as_list[:-1]
|
|
||||||
else:
|
|
||||||
# If there wasn't an extra newline by itself, then the file being
|
|
||||||
# emulated doesn't have a newline to end the last line remove the
|
|
||||||
# newline that our naive format() added
|
|
||||||
data_as_list[-1] = data_as_list[-1][:-1]
|
|
||||||
|
|
||||||
for line in data_as_list:
|
|
||||||
yield line
|
|
||||||
|
|
||||||
def mock_open(mock=None, read_data=''):
|
|
||||||
"""
|
|
||||||
A helper function to create a mock to replace the use of `open`. It works
|
|
||||||
for `open` called directly or used as a context manager.
|
|
||||||
|
|
||||||
The `mock` argument is the mock object to configure. If `None` (the
|
|
||||||
default) then a `MagicMock` will be created for you, with the API limited
|
|
||||||
to methods or attributes available on standard file handles.
|
|
||||||
|
|
||||||
`read_data` is a string for the `read` methoddline`, and `readlines` of the
|
|
||||||
file handle to return. This is an empty string by default.
|
|
||||||
"""
|
|
||||||
def _readlines_side_effect(*args, **kwargs):
|
|
||||||
if handle.readlines.return_value is not None:
|
|
||||||
return handle.readlines.return_value
|
|
||||||
return list(_data)
|
|
||||||
|
|
||||||
def _read_side_effect(*args, **kwargs):
|
|
||||||
if handle.read.return_value is not None:
|
|
||||||
return handle.read.return_value
|
|
||||||
return type(read_data)().join(_data)
|
|
||||||
|
|
||||||
def _readline_side_effect():
|
|
||||||
if handle.readline.return_value is not None:
|
|
||||||
while True:
|
|
||||||
yield handle.readline.return_value
|
|
||||||
for line in _data:
|
|
||||||
yield line
|
|
||||||
|
|
||||||
global file_spec
|
|
||||||
if file_spec is None:
|
|
||||||
import _io
|
|
||||||
file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO))))
|
|
||||||
|
|
||||||
if mock is None:
|
|
||||||
mock = MagicMock(name='open', spec=open)
|
|
||||||
|
|
||||||
handle = MagicMock(spec=file_spec)
|
|
||||||
handle.__enter__.return_value = handle
|
|
||||||
|
|
||||||
_data = _iterate_read_data(read_data)
|
|
||||||
|
|
||||||
handle.write.return_value = None
|
|
||||||
handle.read.return_value = None
|
|
||||||
handle.readline.return_value = None
|
|
||||||
handle.readlines.return_value = None
|
|
||||||
|
|
||||||
handle.read.side_effect = _read_side_effect
|
|
||||||
handle.readline.side_effect = _readline_side_effect()
|
|
||||||
handle.readlines.side_effect = _readlines_side_effect
|
|
||||||
|
|
||||||
mock.return_value = handle
|
|
||||||
return mock
|
|
|
@ -1,25 +0,0 @@
|
||||||
# Copyright (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
# Make coding more python3-ish
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
'''
|
|
||||||
Compat module for Python2.7's unittest module
|
|
||||||
'''
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# Allow wildcard import because we really do want to import all of
|
|
||||||
# unittests's symbols into this compat shim
|
|
||||||
# pylint: disable=wildcard-import,unused-wildcard-import
|
|
||||||
if sys.version_info < (2, 7):
|
|
||||||
try:
|
|
||||||
# Need unittest2 on python2.6
|
|
||||||
from unittest2 import * # noqa: F401, pylint: disable=unused-import
|
|
||||||
except ImportError:
|
|
||||||
print('You need unittest2 installed on python2.6.x to run tests')
|
|
||||||
else:
|
|
||||||
from unittest import * # noqa: F401, pylint: disable=unused-import
|
|
|
@ -9,7 +9,7 @@ __metaclass__ = type
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
||||||
|
|
||||||
|
|
||||||
fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
|
fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.compat.mock import patch, MagicMock
|
from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import patch, MagicMock
|
||||||
|
from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import set_module_args, AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.fake_api import FakeLibRouterosError, Key, Or, fake_ros_api
|
from ansible_collections.community.routeros.tests.unit.plugins.modules.fake_api import FakeLibRouterosError, Key, Or, fake_ros_api
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.utils import set_module_args, AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
|
||||||
from ansible_collections.community.routeros.plugins.modules import api
|
from ansible_collections.community.routeros.plugins.modules import api
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,8 +35,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
|
|
||||||
def test_module_fail_when_required_args_missing(self):
|
def test_module_fail_when_required_args_missing(self):
|
||||||
with self.assertRaises(AnsibleFailJson) as exc:
|
with self.assertRaises(AnsibleFailJson) as exc:
|
||||||
set_module_args({})
|
with set_module_args({}):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -43,8 +44,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
@patch('ansible_collections.community.routeros.plugins.modules.api.ROS_api_module.api_add_path', new=fake_ros_api.path)
|
@patch('ansible_collections.community.routeros.plugins.modules.api.ROS_api_module.api_add_path', new=fake_ros_api.path)
|
||||||
def test_api_path(self):
|
def test_api_path(self):
|
||||||
with self.assertRaises(AnsibleExitJson) as exc:
|
with self.assertRaises(AnsibleExitJson) as exc:
|
||||||
set_module_args(self.config_module_args.copy())
|
with set_module_args(self.config_module_args.copy()):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -54,8 +55,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleExitJson) as exc:
|
with self.assertRaises(AnsibleExitJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['add'] = "name=unit_test_brige"
|
module_args['add'] = "name=unit_test_brige"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -65,8 +66,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleFailJson) as exc:
|
with self.assertRaises(AnsibleFailJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['add'] = "name=unit_test_brige_exist"
|
module_args['add'] = "name=unit_test_brige_exist"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -77,8 +78,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleExitJson) as exc:
|
with self.assertRaises(AnsibleExitJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['remove'] = "*A1"
|
module_args['remove'] = "*A1"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -88,8 +89,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleFailJson) as exc:
|
with self.assertRaises(AnsibleFailJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['remove'] = "*A2"
|
module_args['remove'] = "*A2"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -100,8 +101,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleExitJson) as exc:
|
with self.assertRaises(AnsibleExitJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['cmd'] = "add name=unit_test_brige_arbitrary"
|
module_args['cmd'] = "add name=unit_test_brige_arbitrary"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -111,8 +112,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleFailJson) as exc:
|
with self.assertRaises(AnsibleFailJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['cmd'] = "add NONE_EXIST=unit_test_brige_arbitrary"
|
module_args['cmd'] = "add NONE_EXIST=unit_test_brige_arbitrary"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -123,8 +124,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleExitJson) as exc:
|
with self.assertRaises(AnsibleExitJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['update'] = ".id=*A1 name=unit_test_brige"
|
module_args['update'] = ".id=*A1 name=unit_test_brige"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -134,8 +135,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleFailJson) as exc:
|
with self.assertRaises(AnsibleFailJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['update'] = ".id=*A2 name=unit_test_brige"
|
module_args['update'] = ".id=*A2 name=unit_test_brige"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -146,8 +147,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleExitJson) as exc:
|
with self.assertRaises(AnsibleExitJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['query'] = ".id name"
|
module_args['query'] = ".id name"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -162,8 +163,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleExitJson) as exc:
|
with self.assertRaises(AnsibleExitJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['query'] = ".id other"
|
module_args['query'] = ".id other"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -174,8 +175,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleExitJson) as exc:
|
with self.assertRaises(AnsibleExitJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['query'] = ".id name WHERE name == dummy_bridge_A2"
|
module_args['query'] = ".id name WHERE name == dummy_bridge_A2"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -188,8 +189,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleExitJson) as exc:
|
with self.assertRaises(AnsibleExitJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['query'] = ".id name WHERE name != dummy_bridge_A2"
|
module_args['query'] = ".id name WHERE name != dummy_bridge_A2"
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -204,8 +205,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
module_args['extended_query'] = {
|
module_args['extended_query'] = {
|
||||||
'attributes': ['.id', 'name'],
|
'attributes': ['.id', 'name'],
|
||||||
}
|
}
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -222,8 +223,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
module_args['extended_query'] = {
|
module_args['extended_query'] = {
|
||||||
'attributes': ['.id', 'other'],
|
'attributes': ['.id', 'other'],
|
||||||
}
|
}
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -243,8 +244,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -266,8 +267,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -298,8 +299,8 @@ class TestRouterosApiModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.compat.mock import patch, MagicMock
|
from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import patch, MagicMock
|
||||||
|
from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import set_module_args, AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.fake_api import FakeLibRouterosError, Key, fake_ros_api
|
from ansible_collections.community.routeros.tests.unit.plugins.modules.fake_api import FakeLibRouterosError, Key, fake_ros_api
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.utils import set_module_args, AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
|
||||||
from ansible_collections.community.routeros.plugins.modules import api_facts
|
from ansible_collections.community.routeros.plugins.modules import api_facts
|
||||||
|
|
||||||
|
|
||||||
|
@ -437,8 +438,8 @@ class TestRouterosApiFactsModule(ModuleTestCase):
|
||||||
|
|
||||||
def test_module_fail_when_required_args_missing(self):
|
def test_module_fail_when_required_args_missing(self):
|
||||||
with self.assertRaises(AnsibleFailJson) as exc:
|
with self.assertRaises(AnsibleFailJson) as exc:
|
||||||
set_module_args({})
|
with set_module_args({}):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -447,8 +448,8 @@ class TestRouterosApiFactsModule(ModuleTestCase):
|
||||||
with self.assertRaises(AnsibleFailJson) as exc:
|
with self.assertRaises(AnsibleFailJson) as exc:
|
||||||
module_args = self.config_module_args.copy()
|
module_args = self.config_module_args.copy()
|
||||||
module_args['gather_subset'] = ['!foobar']
|
module_args['gather_subset'] = ['!foobar']
|
||||||
set_module_args(module_args)
|
with set_module_args(module_args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -456,8 +457,8 @@ class TestRouterosApiFactsModule(ModuleTestCase):
|
||||||
|
|
||||||
def test_full_run(self):
|
def test_full_run(self):
|
||||||
with self.assertRaises(AnsibleExitJson) as exc:
|
with self.assertRaises(AnsibleExitJson) as exc:
|
||||||
set_module_args(self.config_module_args.copy())
|
with set_module_args(self.config_module_args.copy()):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
|
|
@ -6,11 +6,12 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.compat.mock import patch, MagicMock
|
from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import patch, MagicMock
|
||||||
|
from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import set_module_args, AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.fake_api import (
|
from ansible_collections.community.routeros.tests.unit.plugins.modules.fake_api import (
|
||||||
FakeLibRouterosError, fake_ros_api, massage_expected_result_data, create_fake_path,
|
FakeLibRouterosError, fake_ros_api, massage_expected_result_data, create_fake_path,
|
||||||
)
|
)
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.utils import set_module_args, AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
|
||||||
from ansible_collections.community.routeros.plugins.modules import api_find_and_modify
|
from ansible_collections.community.routeros.plugins.modules import api_find_and_modify
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,6 +94,52 @@ START_IP_FIREWALL_FILTER = [
|
||||||
|
|
||||||
START_IP_FIREWALL_FILTER_OLD_DATA = massage_expected_result_data(START_IP_FIREWALL_FILTER, ('ip', 'firewall', 'filter'), keep_all=True)
|
START_IP_FIREWALL_FILTER_OLD_DATA = massage_expected_result_data(START_IP_FIREWALL_FILTER, ('ip', 'firewall', 'filter'), keep_all=True)
|
||||||
|
|
||||||
|
START_IP_SERVICE = [
|
||||||
|
# I removed all entryes not for 'api' and 'api-ssl'
|
||||||
|
{
|
||||||
|
"certificate": None,
|
||||||
|
"tls-version": None,
|
||||||
|
".id": "*7",
|
||||||
|
"address": "",
|
||||||
|
"disabled": True,
|
||||||
|
"dynamic": False,
|
||||||
|
"invalid": True,
|
||||||
|
"name": "api",
|
||||||
|
"port": 8728,
|
||||||
|
"proto": "tcp",
|
||||||
|
"vrf": "main"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
".id": "*9",
|
||||||
|
"address": "192.168.1.0/24",
|
||||||
|
"certificate": "mycert",
|
||||||
|
"dynamic": False,
|
||||||
|
"invalid": False,
|
||||||
|
"name": "api-ssl",
|
||||||
|
"port": 8729,
|
||||||
|
"proto": "tcp",
|
||||||
|
"tls-version": "only-1.2",
|
||||||
|
"vrf": "main"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": None,
|
||||||
|
"certificate": None,
|
||||||
|
"max-sessions": None,
|
||||||
|
"tls-version": None,
|
||||||
|
".id": "*13",
|
||||||
|
"connection": True,
|
||||||
|
"dynamic": True,
|
||||||
|
"invalid": False,
|
||||||
|
"local": "192.168.1.1",
|
||||||
|
"name": "api-ssl",
|
||||||
|
"port": 8729,
|
||||||
|
"proto": "tcp",
|
||||||
|
"remote": "192.168.1.2:12346"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
START_IP_SERVICE_OLD_DATA = massage_expected_result_data(START_IP_SERVICE, ('ip', 'service'), keep_all=True)
|
||||||
|
|
||||||
|
|
||||||
class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
|
|
||||||
|
@ -117,8 +164,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
|
|
||||||
def test_module_fail_when_required_args_missing(self):
|
def test_module_fail_when_required_args_missing(self):
|
||||||
with self.assertRaises(AnsibleFailJson) as exc:
|
with self.assertRaises(AnsibleFailJson) as exc:
|
||||||
set_module_args({})
|
with set_module_args({}):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -136,8 +183,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'comment': 'bar',
|
'comment': 'bar',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -155,8 +202,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'comment': 'bar',
|
'comment': 'bar',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -173,8 +220,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'!comment': None,
|
'!comment': None,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -190,8 +237,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'!comment': 'gone',
|
'!comment': 'gone',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -212,8 +259,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
'require_matches_min': 10,
|
'require_matches_min': 10,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -234,8 +281,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
'require_matches_min': 10,
|
'require_matches_min': 10,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -256,8 +303,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
'require_matches_max': 1,
|
'require_matches_max': 1,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -277,8 +324,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'name': 'bam',
|
'name': 'bam',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -303,8 +350,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'require_matches_min': 2,
|
'require_matches_min': 2,
|
||||||
'allow_no_matches': True,
|
'allow_no_matches': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -325,8 +372,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'values': {
|
'values': {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -349,8 +396,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'comment': None,
|
'comment': None,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -374,8 +421,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
'_ansible_diff': True,
|
'_ansible_diff': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -450,8 +497,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'comment': None,
|
'comment': None,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -502,8 +549,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'comment': '',
|
'comment': '',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -553,8 +600,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'!comment': None,
|
'!comment': None,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -606,8 +653,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'!connection-state': None,
|
'!connection-state': None,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -620,6 +667,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'comment': 'defconf',
|
'comment': 'defconf',
|
||||||
'protocol': 'icmp',
|
'protocol': 'icmp',
|
||||||
'disabled': False,
|
'disabled': False,
|
||||||
|
'log': False,
|
||||||
|
'log-prefix': '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'.id': '*3',
|
'.id': '*3',
|
||||||
|
@ -627,6 +676,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'chain': 'input',
|
'chain': 'input',
|
||||||
'comment': 'defconf',
|
'comment': 'defconf',
|
||||||
'disabled': False,
|
'disabled': False,
|
||||||
|
'log': False,
|
||||||
|
'log-prefix': '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'.id': '*4',
|
'.id': '*4',
|
||||||
|
@ -634,6 +685,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'chain': 'input',
|
'chain': 'input',
|
||||||
'comment': 'defconf',
|
'comment': 'defconf',
|
||||||
'disabled': False,
|
'disabled': False,
|
||||||
|
'log': False,
|
||||||
|
'log-prefix': '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'.id': '*7',
|
'.id': '*7',
|
||||||
|
@ -642,6 +695,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'comment': 'defconf',
|
'comment': 'defconf',
|
||||||
'disabled': False,
|
'disabled': False,
|
||||||
'in-interface': 'wan',
|
'in-interface': 'wan',
|
||||||
|
'log': False,
|
||||||
|
'log-prefix': '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'.id': '*8',
|
'.id': '*8',
|
||||||
|
@ -650,6 +705,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'comment': 'defconf',
|
'comment': 'defconf',
|
||||||
'connection-state': 'established',
|
'connection-state': 'established',
|
||||||
'disabled': False,
|
'disabled': False,
|
||||||
|
'log': False,
|
||||||
|
'log-prefix': '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'.id': '*9',
|
'.id': '*9',
|
||||||
|
@ -658,6 +715,8 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'comment': 'defconf',
|
'comment': 'defconf',
|
||||||
'connection-state': 'related',
|
'connection-state': 'related',
|
||||||
'disabled': False,
|
'disabled': False,
|
||||||
|
'log': False,
|
||||||
|
'log-prefix': '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'.id': '*A',
|
'.id': '*A',
|
||||||
|
@ -666,7 +725,35 @@ class TestRouterosApiFindAndModifyModule(ModuleTestCase):
|
||||||
'comment': 'defconf',
|
'comment': 'defconf',
|
||||||
'connection-status': 'invalid',
|
'connection-status': 'invalid',
|
||||||
'disabled': False,
|
'disabled': False,
|
||||||
|
'log': False,
|
||||||
|
'log-prefix': '',
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
self.assertEqual(result['match_count'], 3)
|
self.assertEqual(result['match_count'], 3)
|
||||||
self.assertEqual(result['modify_count'], 2)
|
self.assertEqual(result['modify_count'], 2)
|
||||||
|
|
||||||
|
@patch('ansible_collections.community.routeros.plugins.modules.api_find_and_modify.compose_api_path',
|
||||||
|
new=create_fake_path(('ip', 'service'), START_IP_SERVICE))
|
||||||
|
def test_change_ignore_dynamic(self):
|
||||||
|
with self.assertRaises(AnsibleExitJson) as exc:
|
||||||
|
args = self.config_module_args.copy()
|
||||||
|
args.update({
|
||||||
|
'path': 'ip service',
|
||||||
|
'find': {
|
||||||
|
'name': 'api-ssl',
|
||||||
|
},
|
||||||
|
'values': {
|
||||||
|
'address': '192.168.1.0/24',
|
||||||
|
},
|
||||||
|
'ignore_dynamic': True,
|
||||||
|
'_ansible_diff': True,
|
||||||
|
})
|
||||||
|
with set_module_args(args):
|
||||||
|
self.module.main()
|
||||||
|
|
||||||
|
result = exc.exception.args[0]
|
||||||
|
self.assertEqual(result['changed'], False)
|
||||||
|
self.assertEqual(result['old_data'], [entry for entry in START_IP_SERVICE_OLD_DATA if entry["dynamic"] is False])
|
||||||
|
self.assertEqual(result['new_data'], [entry for entry in START_IP_SERVICE_OLD_DATA if entry["dynamic"] is False])
|
||||||
|
self.assertEqual(result['match_count'], 1)
|
||||||
|
self.assertEqual(result['modify_count'], 0)
|
||||||
|
|
|
@ -6,11 +6,12 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.compat.mock import patch, MagicMock
|
from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import patch, MagicMock
|
||||||
|
from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import set_module_args, AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.fake_api import (
|
from ansible_collections.community.routeros.tests.unit.plugins.modules.fake_api import (
|
||||||
FAKE_ROS_VERSION, FakeLibRouterosError, Key, fake_ros_api,
|
FAKE_ROS_VERSION, FakeLibRouterosError, Key, fake_ros_api,
|
||||||
)
|
)
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.utils import set_module_args, AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
|
||||||
from ansible_collections.community.routeros.plugins.modules import api_info
|
from ansible_collections.community.routeros.plugins.modules import api_info
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,8 +42,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
|
|
||||||
def test_module_fail_when_required_args_missing(self):
|
def test_module_fail_when_required_args_missing(self):
|
||||||
with self.assertRaises(AnsibleFailJson) as exc:
|
with self.assertRaises(AnsibleFailJson) as exc:
|
||||||
set_module_args({})
|
with set_module_args({}):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -53,8 +54,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
args.update({
|
args.update({
|
||||||
'path': 'something invalid'
|
'path': 'something invalid'
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -68,8 +69,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
args.update({
|
args.update({
|
||||||
'path': 'ip dns static'
|
'path': 'ip dns static'
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -93,8 +94,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
args.update({
|
args.update({
|
||||||
'path': 'caps-man aaa',
|
'path': 'caps-man aaa',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -122,8 +123,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'path': 'caps-man aaa',
|
'path': 'caps-man aaa',
|
||||||
'hide_defaults': False,
|
'hide_defaults': False,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -155,8 +156,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'path': 'caps-man aaa',
|
'path': 'caps-man aaa',
|
||||||
'unfiltered': True,
|
'unfiltered': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -189,8 +190,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'path': 'ip firewall filter',
|
'path': 'ip firewall filter',
|
||||||
'handle_disabled': 'exclamation',
|
'handle_disabled': 'exclamation',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -278,8 +279,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'path': 'ip firewall filter',
|
'path': 'ip firewall filter',
|
||||||
'handle_disabled': 'null-value',
|
'handle_disabled': 'null-value',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -367,8 +368,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'path': 'ip firewall filter',
|
'path': 'ip firewall filter',
|
||||||
'handle_disabled': 'omit',
|
'handle_disabled': 'omit',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -402,8 +403,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'handle_disabled': 'omit',
|
'handle_disabled': 'omit',
|
||||||
'include_dynamic': True,
|
'include_dynamic': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -460,8 +461,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'path': 'interface list',
|
'path': 'interface list',
|
||||||
'handle_disabled': 'omit',
|
'handle_disabled': 'omit',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -513,8 +514,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'handle_disabled': 'omit',
|
'handle_disabled': 'omit',
|
||||||
'include_builtin': True,
|
'include_builtin': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -605,8 +606,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'path': 'ip dhcp-server lease',
|
'path': 'ip dhcp-server lease',
|
||||||
'handle_disabled': 'omit',
|
'handle_disabled': 'omit',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -688,8 +689,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
args.update({
|
args.update({
|
||||||
'path': 'interface gre',
|
'path': 'interface gre',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -776,8 +777,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'handle_disabled': 'omit',
|
'handle_disabled': 'omit',
|
||||||
'hide_defaults': False,
|
'hide_defaults': False,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -847,8 +848,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'handle_disabled': 'omit',
|
'handle_disabled': 'omit',
|
||||||
'restrict': [],
|
'restrict': [],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -899,8 +900,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
'values': ['forward'],
|
'values': ['forward'],
|
||||||
}],
|
}],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -970,8 +971,8 @@ class TestRouterosApiInfoModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
|
|
@ -6,11 +6,12 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.compat.mock import patch, MagicMock
|
from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import patch, MagicMock
|
||||||
|
from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import set_module_args, AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.fake_api import (
|
from ansible_collections.community.routeros.tests.unit.plugins.modules.fake_api import (
|
||||||
FAKE_ROS_VERSION, FakeLibRouterosError, fake_ros_api, massage_expected_result_data, create_fake_path,
|
FAKE_ROS_VERSION, FakeLibRouterosError, fake_ros_api, massage_expected_result_data, create_fake_path,
|
||||||
)
|
)
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.utils import set_module_args, AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
|
||||||
from ansible_collections.community.routeros.plugins.modules import api_modify
|
from ansible_collections.community.routeros.plugins.modules import api_modify
|
||||||
|
|
||||||
|
|
||||||
|
@ -318,8 +319,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
|
|
||||||
def test_module_fail_when_required_args_missing(self):
|
def test_module_fail_when_required_args_missing(self):
|
||||||
with self.assertRaises(AnsibleFailJson) as exc:
|
with self.assertRaises(AnsibleFailJson) as exc:
|
||||||
set_module_args({})
|
with set_module_args({}):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -331,8 +332,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'path': 'something invalid',
|
'path': 'something invalid',
|
||||||
'data': [],
|
'data': [],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -348,8 +349,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'foo': 'bar',
|
'foo': 'bar',
|
||||||
}],
|
}],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -366,8 +367,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'!comment': None,
|
'!comment': None,
|
||||||
}],
|
}],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -383,8 +384,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'!disabled': None,
|
'!disabled': None,
|
||||||
}],
|
}],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -400,8 +401,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'!comment': 'foo',
|
'!comment': 'foo',
|
||||||
}],
|
}],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -416,8 +417,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'name': None,
|
'name': None,
|
||||||
}],
|
}],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -432,8 +433,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'interface': 'eth0',
|
'interface': 'eth0',
|
||||||
}],
|
}],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -448,8 +449,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'address': '192.168.88.1',
|
'address': '192.168.88.1',
|
||||||
}],
|
}],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -466,8 +467,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'address': '192.168.88.1',
|
'address': '192.168.88.1',
|
||||||
}],
|
}],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['failed'], True)
|
self.assertEqual(result['failed'], True)
|
||||||
|
@ -498,8 +499,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -533,8 +534,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_absent_entries': 'remove',
|
'handle_absent_entries': 'remove',
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -556,8 +557,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -591,8 +592,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -656,8 +657,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -722,8 +723,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
],
|
],
|
||||||
'_ansible_check_mode': True,
|
'_ansible_check_mode': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -785,8 +786,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_absent_entries': 'remove',
|
'handle_absent_entries': 'remove',
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -844,8 +845,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
'_ansible_check_mode': True,
|
'_ansible_check_mode': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -903,8 +904,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_absent_entries': 'remove',
|
'handle_absent_entries': 'remove',
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -963,8 +964,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
'_ansible_check_mode': True,
|
'_ansible_check_mode': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1017,8 +1018,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_absent_entries': 'remove',
|
'handle_absent_entries': 'remove',
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1077,8 +1078,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
'_ansible_check_mode': True,
|
'_ansible_check_mode': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1128,8 +1129,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_absent_entries': 'remove',
|
'handle_absent_entries': 'remove',
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1164,8 +1165,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
'_ansible_check_mode': True,
|
'_ansible_check_mode': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1212,8 +1213,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
'ensure_order': True,
|
'ensure_order': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1285,8 +1286,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'ensure_order': True,
|
'ensure_order': True,
|
||||||
'_ansible_check_mode': True,
|
'_ansible_check_mode': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1340,8 +1341,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -1363,8 +1364,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
],
|
],
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -1386,8 +1387,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1426,8 +1427,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
],
|
],
|
||||||
'_ansible_check_mode': True,
|
'_ansible_check_mode': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1466,8 +1467,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
],
|
],
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1507,8 +1508,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
'_ansible_check_mode': True,
|
'_ansible_check_mode': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1551,8 +1552,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -1587,8 +1588,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_absent_entries': 'remove',
|
'handle_absent_entries': 'remove',
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -1621,8 +1622,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_absent_entries': 'remove',
|
'handle_absent_entries': 'remove',
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1676,8 +1677,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
'_ansible_check_mode': True,
|
'_ansible_check_mode': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1729,8 +1730,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
'ensure_order': True,
|
'ensure_order': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1785,8 +1786,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'ensure_order': True,
|
'ensure_order': True,
|
||||||
'_ansible_check_mode': True,
|
'_ansible_check_mode': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1847,8 +1848,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
'ensure_order': True,
|
'ensure_order': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -1879,8 +1880,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
'ensure_order': True,
|
'ensure_order': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -1911,8 +1912,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_entries_content': 'remove',
|
'handle_entries_content': 'remove',
|
||||||
'ensure_order': True,
|
'ensure_order': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], True)
|
self.assertEqual(result['changed'], True)
|
||||||
|
@ -1969,8 +1970,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_absent_entries': 'remove',
|
'handle_absent_entries': 'remove',
|
||||||
'ensure_order': True,
|
'ensure_order': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
@ -2005,8 +2006,8 @@ class TestRouterosApiModifyModule(ModuleTestCase):
|
||||||
'handle_absent_entries': 'remove',
|
'handle_absent_entries': 'remove',
|
||||||
'ensure_order': True,
|
'ensure_order': True,
|
||||||
})
|
})
|
||||||
set_module_args(args)
|
with set_module_args(args):
|
||||||
self.module.main()
|
self.module.main()
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
result = exc.exception.args[0]
|
||||||
self.assertEqual(result['changed'], False)
|
self.assertEqual(result['changed'], False)
|
||||||
|
|
|
@ -8,9 +8,10 @@ __metaclass__ = type
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.compat.mock import patch
|
from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import patch
|
||||||
|
from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import set_module_args
|
||||||
|
|
||||||
from ansible_collections.community.routeros.plugins.modules import command
|
from ansible_collections.community.routeros.plugins.modules import command
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.utils import set_module_args
|
|
||||||
from .routeros_module import TestRouterosModule, load_fixture
|
from .routeros_module import TestRouterosModule, load_fixture
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,54 +48,54 @@ class TestRouterosCommandModule(TestRouterosModule):
|
||||||
self.run_commands.side_effect = load_from_file
|
self.run_commands.side_effect = load_from_file
|
||||||
|
|
||||||
def test_command_simple(self):
|
def test_command_simple(self):
|
||||||
set_module_args(dict(commands=['/system resource print']))
|
with set_module_args(dict(commands=['/system resource print'])):
|
||||||
result = self.execute_module(changed=True)
|
result = self.execute_module(changed=True)
|
||||||
self.assertEqual(len(result['stdout']), 1)
|
self.assertEqual(len(result['stdout']), 1)
|
||||||
self.assertTrue('platform: "MikroTik"' in result['stdout'][0])
|
self.assertTrue('platform: "MikroTik"' in result['stdout'][0])
|
||||||
|
|
||||||
def test_command_multiple(self):
|
def test_command_multiple(self):
|
||||||
set_module_args(dict(commands=['/system resource print', '/system resource print']))
|
with set_module_args(dict(commands=['/system resource print', '/system resource print'])):
|
||||||
result = self.execute_module(changed=True)
|
result = self.execute_module(changed=True)
|
||||||
self.assertEqual(len(result['stdout']), 2)
|
self.assertEqual(len(result['stdout']), 2)
|
||||||
self.assertTrue('platform: "MikroTik"' in result['stdout'][0])
|
self.assertTrue('platform: "MikroTik"' in result['stdout'][0])
|
||||||
|
|
||||||
def test_command_wait_for(self):
|
def test_command_wait_for(self):
|
||||||
wait_for = 'result[0] contains "MikroTik"'
|
wait_for = 'result[0] contains "MikroTik"'
|
||||||
set_module_args(dict(commands=['/system resource print'], wait_for=wait_for))
|
with set_module_args(dict(commands=['/system resource print'], wait_for=wait_for)):
|
||||||
self.execute_module(changed=True)
|
self.execute_module(changed=True)
|
||||||
|
|
||||||
def test_command_wait_for_fails(self):
|
def test_command_wait_for_fails(self):
|
||||||
wait_for = 'result[0] contains "test string"'
|
wait_for = 'result[0] contains "test string"'
|
||||||
set_module_args(dict(commands=['/system resource print'], wait_for=wait_for))
|
with set_module_args(dict(commands=['/system resource print'], wait_for=wait_for)):
|
||||||
self.execute_module(failed=True)
|
self.execute_module(failed=True)
|
||||||
self.assertEqual(self.run_commands.call_count, 10)
|
self.assertEqual(self.run_commands.call_count, 10)
|
||||||
|
|
||||||
def test_command_retries(self):
|
def test_command_retries(self):
|
||||||
wait_for = 'result[0] contains "test string"'
|
wait_for = 'result[0] contains "test string"'
|
||||||
set_module_args(dict(commands=['/system resource print'], wait_for=wait_for, retries=2))
|
with set_module_args(dict(commands=['/system resource print'], wait_for=wait_for, retries=2)):
|
||||||
self.execute_module(failed=True)
|
self.execute_module(failed=True)
|
||||||
self.assertEqual(self.run_commands.call_count, 2)
|
self.assertEqual(self.run_commands.call_count, 2)
|
||||||
|
|
||||||
def test_command_match_any(self):
|
def test_command_match_any(self):
|
||||||
wait_for = ['result[0] contains "MikroTik"',
|
wait_for = ['result[0] contains "MikroTik"',
|
||||||
'result[0] contains "test string"']
|
'result[0] contains "test string"']
|
||||||
set_module_args(dict(commands=['/system resource print'], wait_for=wait_for, match='any'))
|
with set_module_args(dict(commands=['/system resource print'], wait_for=wait_for, match='any')):
|
||||||
self.execute_module(changed=True)
|
self.execute_module(changed=True)
|
||||||
|
|
||||||
def test_command_match_all(self):
|
def test_command_match_all(self):
|
||||||
wait_for = ['result[0] contains "MikroTik"',
|
wait_for = ['result[0] contains "MikroTik"',
|
||||||
'result[0] contains "RB1100"']
|
'result[0] contains "RB1100"']
|
||||||
set_module_args(dict(commands=['/system resource print'], wait_for=wait_for, match='all'))
|
with set_module_args(dict(commands=['/system resource print'], wait_for=wait_for, match='all')):
|
||||||
self.execute_module(changed=True)
|
self.execute_module(changed=True)
|
||||||
|
|
||||||
def test_command_match_all_failure(self):
|
def test_command_match_all_failure(self):
|
||||||
wait_for = ['result[0] contains "MikroTik"',
|
wait_for = ['result[0] contains "MikroTik"',
|
||||||
'result[0] contains "test string"']
|
'result[0] contains "test string"']
|
||||||
commands = ['/system resource print', '/system resource print']
|
commands = ['/system resource print', '/system resource print']
|
||||||
set_module_args(dict(commands=commands, wait_for=wait_for, match='all'))
|
with set_module_args(dict(commands=commands, wait_for=wait_for, match='all')):
|
||||||
self.execute_module(failed=True)
|
self.execute_module(failed=True)
|
||||||
|
|
||||||
def test_command_wait_for_2(self):
|
def test_command_wait_for_2(self):
|
||||||
wait_for = 'result[0] contains "wireless"'
|
wait_for = 'result[0] contains "wireless"'
|
||||||
set_module_args(dict(commands=['/system package print'], wait_for=wait_for))
|
with set_module_args(dict(commands=['/system package print'], wait_for=wait_for)):
|
||||||
self.execute_module(changed=True)
|
self.execute_module(changed=True)
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.compat.mock import patch
|
from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import patch
|
||||||
|
from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import set_module_args
|
||||||
|
|
||||||
from ansible_collections.community.routeros.plugins.modules import facts
|
from ansible_collections.community.routeros.plugins.modules import facts
|
||||||
from ansible_collections.community.routeros.tests.unit.plugins.modules.utils import set_module_args
|
|
||||||
from .routeros_module import TestRouterosModule, load_fixture
|
from .routeros_module import TestRouterosModule, load_fixture
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,8 +40,8 @@ class TestRouterosFactsModule(TestRouterosModule):
|
||||||
self.run_commands.side_effect = load_from_file
|
self.run_commands.side_effect = load_from_file
|
||||||
|
|
||||||
def test_facts_default(self):
|
def test_facts_default(self):
|
||||||
set_module_args(dict(gather_subset='default'))
|
with set_module_args(dict(gather_subset='default')):
|
||||||
result = self.execute_module()
|
result = self.execute_module()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
result['ansible_facts']['ansible_net_hostname'], 'MikroTik'
|
result['ansible_facts']['ansible_net_hostname'], 'MikroTik'
|
||||||
)
|
)
|
||||||
|
@ -61,8 +62,8 @@ class TestRouterosFactsModule(TestRouterosModule):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_facts_hardware(self):
|
def test_facts_hardware(self):
|
||||||
set_module_args(dict(gather_subset='hardware'))
|
with set_module_args(dict(gather_subset='hardware')):
|
||||||
result = self.execute_module()
|
result = self.execute_module()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
result['ansible_facts']['ansible_net_spacefree_mb'], 64921.6
|
result['ansible_facts']['ansible_net_spacefree_mb'], 64921.6
|
||||||
)
|
)
|
||||||
|
@ -77,8 +78,8 @@ class TestRouterosFactsModule(TestRouterosModule):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_facts_config(self):
|
def test_facts_config(self):
|
||||||
set_module_args(dict(gather_subset='config'))
|
with set_module_args(dict(gather_subset='config')):
|
||||||
result = self.execute_module()
|
result = self.execute_module()
|
||||||
self.assertIsInstance(
|
self.assertIsInstance(
|
||||||
result['ansible_facts']['ansible_net_config'], str
|
result['ansible_facts']['ansible_net_config'], str
|
||||||
)
|
)
|
||||||
|
@ -88,8 +89,8 @@ class TestRouterosFactsModule(TestRouterosModule):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_facts_interfaces(self):
|
def test_facts_interfaces(self):
|
||||||
set_module_args(dict(gather_subset='interfaces'))
|
with set_module_args(dict(gather_subset='interfaces')):
|
||||||
result = self.execute_module()
|
result = self.execute_module()
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
result['ansible_facts']['ansible_net_all_ipv4_addresses'][0], ['10.37.129.3', '10.37.0.0', '192.168.88.1']
|
result['ansible_facts']['ansible_net_all_ipv4_addresses'][0], ['10.37.129.3', '10.37.0.0', '192.168.88.1']
|
||||||
)
|
)
|
||||||
|
@ -118,8 +119,8 @@ class TestRouterosFactsModule(TestRouterosModule):
|
||||||
self.assertEqual(result, None)
|
self.assertEqual(result, None)
|
||||||
|
|
||||||
def test_facts_routing(self):
|
def test_facts_routing(self):
|
||||||
set_module_args(dict(gather_subset='routing'))
|
with set_module_args(dict(gather_subset='routing')):
|
||||||
result = self.execute_module()
|
result = self.execute_module()
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['name'], ['iBGP_BRAS.TYRMA']
|
result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['name'], ['iBGP_BRAS.TYRMA']
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
import json
|
|
||||||
|
|
||||||
from ansible_collections.community.routeros.tests.unit.compat import unittest
|
|
||||||
from ansible_collections.community.routeros.tests.unit.compat.mock import patch
|
|
||||||
from ansible.module_utils import basic
|
|
||||||
from ansible.module_utils.common.text.converters import to_bytes
|
|
||||||
|
|
||||||
|
|
||||||
def set_module_args(args):
|
|
||||||
if '_ansible_remote_tmp' not in args:
|
|
||||||
args['_ansible_remote_tmp'] = '/tmp'
|
|
||||||
if '_ansible_keep_remote_files' not in args:
|
|
||||||
args['_ansible_keep_remote_files'] = False
|
|
||||||
|
|
||||||
args = json.dumps({'ANSIBLE_MODULE_ARGS': args})
|
|
||||||
basic._ANSIBLE_ARGS = to_bytes(args)
|
|
||||||
|
|
||||||
|
|
||||||
class AnsibleExitJson(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class AnsibleFailJson(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def exit_json(*args, **kwargs):
|
|
||||||
if 'changed' not in kwargs:
|
|
||||||
kwargs['changed'] = False
|
|
||||||
raise AnsibleExitJson(kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def fail_json(*args, **kwargs):
|
|
||||||
kwargs['failed'] = True
|
|
||||||
raise AnsibleFailJson(kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class ModuleTestCase(unittest.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.mock_module = patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json)
|
|
||||||
self.mock_module.start()
|
|
||||||
self.mock_sleep = patch('time.sleep')
|
|
||||||
self.mock_sleep.start()
|
|
||||||
set_module_args({})
|
|
||||||
self.addCleanup(self.mock_module.stop)
|
|
||||||
self.addCleanup(self.mock_sleep.stop)
|
|
|
@ -4,4 +4,4 @@
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
collections:
|
collections:
|
||||||
- ansible.netcommon
|
- community.internal_test_tools
|
||||||
|
|
29
update-docs.py → tests/update-docs.py
Executable file → Normal file
29
update-docs.py → tests/update-docs.py
Executable file → Normal file
|
@ -11,9 +11,6 @@ Updates DOCUMENTATION of modules using module_utils._api_data with the correct l
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Ensure that we can import things from ansible_collections
|
|
||||||
sys.path.append('../../..')
|
|
||||||
|
|
||||||
from ansible_collections.community.routeros.plugins.module_utils._api_data import (
|
from ansible_collections.community.routeros.plugins.module_utils._api_data import (
|
||||||
PATHS,
|
PATHS,
|
||||||
join_path,
|
join_path,
|
||||||
|
@ -26,24 +23,34 @@ MODULES = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def update_file(file, begin_line, end_line, choice_line, path_choices):
|
def update_file(file: str, begin_line: str, end_line: str, choice_line: str, path_choices: list[str]) -> bool:
|
||||||
with open(file, 'r', encoding='utf-8') as f:
|
with open(file, 'r', encoding='utf-8') as f:
|
||||||
lines = f.read().splitlines()
|
lines = f.read().splitlines()
|
||||||
begin_index = lines.index(begin_line)
|
begin_index = lines.index(begin_line)
|
||||||
end_index = lines.index(end_line, begin_index + 1)
|
end_index = lines.index(end_line, begin_index + 1)
|
||||||
new_lines = lines[:begin_index + 1] + [choice_line.format(choice=choice) for choice in path_choices] + lines[end_index:]
|
new_lines = lines[:begin_index + 1] + [choice_line.format(choice=choice) for choice in path_choices] + lines[end_index:]
|
||||||
if lines != new_lines:
|
if lines == new_lines:
|
||||||
print(f'{file} has been updated')
|
return False
|
||||||
with open(file, 'w', encoding='utf-8') as f:
|
print(f'{file} has been updated')
|
||||||
f.write('\n'.join(new_lines) + '\n')
|
with open(file, 'w', encoding='utf-8') as f:
|
||||||
|
f.write('\n'.join(new_lines) + '\n')
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main(args: list[str]) -> int:
|
||||||
path_choices = sorted([join_path(path) for path, path_info in PATHS.items() if path_info.fully_understood])
|
path_choices = sorted([join_path(path) for path, path_info in PATHS.items() if path_info.fully_understood])
|
||||||
|
|
||||||
|
changes = False
|
||||||
for file in MODULES:
|
for file in MODULES:
|
||||||
update_file(file, ' # BEGIN PATH LIST', ' # END PATH LIST', ' - {choice}', path_choices)
|
changes |= update_file(file, ' # BEGIN PATH LIST', ' # END PATH LIST', ' - {choice}', path_choices)
|
||||||
|
|
||||||
|
lint = "--lint" in args
|
||||||
|
if not lint or not changes:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
print("Run 'nox -Re update-docs'!")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
sys.exit(main(sys.argv[1:]))
|
Loading…
Add table
Add a link
Reference in a new issue