Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d44f85ecf1 | ||
|
|
e9b054c718 | ||
|
|
3b833e025f | ||
|
|
b5806110c9 | ||
|
|
021737539b | ||
|
|
0aa0497403 | ||
|
|
3fd554eee9 | ||
|
|
b494779b5b | ||
|
|
96439acf91 | ||
|
|
ff17600709 | ||
|
|
929a7e319b | ||
|
|
552ee76b4e | ||
|
|
68b1c26de5 | ||
|
|
8a3ccd056c | ||
|
|
4b14f84dd2 | ||
|
|
792ee3498b | ||
|
|
7a25b61ce3 | ||
|
|
ffb0ea4027 | ||
|
|
2cb3576c8e | ||
|
|
39632ed5ef | ||
|
|
c6123d17d8 | ||
|
|
85d097ab18 | ||
|
|
ee17554213 | ||
|
|
ed131defc0 | ||
|
|
ef3a7fbd46 | ||
|
|
d0cf9ec991 | ||
|
|
c264bdee39 | ||
|
|
aafccc0c4a | ||
|
|
0551d7058d | ||
|
|
f9d8451a8f | ||
|
|
2e29d65b99 | ||
|
|
360c6eef4a | ||
|
|
22bcf2d50b | ||
|
|
f69d904725 | ||
|
|
1fa9b0df4b |
14
README.md
14
README.md
@@ -3,12 +3,11 @@
|
||||
## 개요
|
||||
|
||||
현재 모든 고객사가 모두 각기 다른 Kubernetes 버전 , 다른 CNI , 다른 CRI 로 구성이 되어 있음.<br>
|
||||
올해 Kubernetes 버전 1.18 및 Docker 로 구축을 한 환경이 존재함.<br>
|
||||
작년(2023년) Kubernetes 버전 1.18 및 Docker 로 구축을 한 환경이 존재함.<br>
|
||||
(최신 버전의 Kubernetes는 1.28 / Docker는 공식적으로 Kubernetes에서 지원에서 제외 되었다)<br>
|
||||
사실상 이해하기 어려운 구성의 환경들이 있는 관계로 최소한의 버전과 환경 통일을 위해 제작 되었음.<br>
|
||||
|
||||
최신 버전인 v1.28 로 구성하고 싶었지만 v1.27 과 v1.28 을 지원하는 kubespray 2.23 버전에서 버그 존재<br>
|
||||
정상적으로 클러스터 구성을 못하는 문제가 있어서 v1.26 까지 지원하는 kubespray 2.22 버전으로 구성하였습니다.
|
||||
최신 버전의 kubespray 2.24 기준으로 제작되었으며, kubernetes 버전 v1.28.6 을 지원하고 있음<br>
|
||||
|
||||
## 준비물
|
||||
|
||||
@@ -36,9 +35,9 @@
|
||||
|
||||
```yaml
|
||||
[all]
|
||||
hostname1 ansible_host=10.10.43.231 ip=10.10.43.231 etcd_member_name=hostname1 ansible_port=22 node_role=master
|
||||
hostname2 ansible_host=10.10.43.232 ip=10.10.43.232 ansible_port=22 node_role=node
|
||||
hostname3 ansible_host=10.10.43.233 ip=10.10.43.233 ansible_port=22 node_role=node
|
||||
hostname1 ansible_host=10.10.43.231 ip=10.10.43.231 etcd_member_name=hostname1 ansible_port=22
|
||||
hostname2 ansible_host=10.10.43.232 ip=10.10.43.232 ansible_port=22
|
||||
hostname3 ansible_host=10.10.43.233 ip=10.10.43.233 ansible_port=22
|
||||
|
||||
[kube_control_plane]
|
||||
hostname1
|
||||
@@ -61,7 +60,6 @@ calico_rr
|
||||
hostname1,2,3 , etcd_member_name 에 각각 사용할 서버들의 hostname을 입력<br>
|
||||
ansible_host , ip 두 부분에 각 서버의 IP를 입력<br>
|
||||
ansible_port 에 각 서버가 사용중인 ssh 포트 입력<br>
|
||||
node_role 부분은 변경하지 않음, node_role=master 인 서버 즉 첫번째 입력을 하는 서버가 master 노드임<br>
|
||||
|
||||
7. `./installer.sh` 커맨드로 `install.sh` 실행 후 1번 메뉴 실행
|
||||
|
||||
@@ -88,4 +86,4 @@ httpd 를 마스터 노드에 설치 및 설정 ➝ local repo 생성
|
||||
local registry 생성 (master node에 container)
|
||||
kubernetes 클러스터 생성
|
||||
|
||||
10. 따란-! Kubernetes v1.26.5 구성 완료---!!
|
||||
10. 따란-! Kubernetes v1.28.6 구성 완료---!!
|
||||
|
||||
8
collection/ansible.netcommon-6.0.0.info/GALAXY.yml
Normal file
8
collection/ansible.netcommon-6.0.0.info/GALAXY.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
download_url: https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/ansible-netcommon-6.0.0.tar.gz
|
||||
format_version: 1.0.0
|
||||
name: netcommon
|
||||
namespace: ansible
|
||||
server: https://galaxy.ansible.com/api/
|
||||
signatures: []
|
||||
version: 6.0.0
|
||||
version_url: /api/v3/plugin/ansible/content/published/collections/index/ansible/netcommon/versions/6.0.0/
|
||||
8
collection/ansible.posix-1.5.4.info/GALAXY.yml
Normal file
8
collection/ansible.posix-1.5.4.info/GALAXY.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
download_url: https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/ansible-posix-1.5.4.tar.gz
|
||||
format_version: 1.0.0
|
||||
name: posix
|
||||
namespace: ansible
|
||||
server: https://galaxy.ansible.com/api/
|
||||
signatures: []
|
||||
version: 1.5.4
|
||||
version_url: /api/v3/plugin/ansible/content/published/collections/index/ansible/posix/versions/1.5.4/
|
||||
8
collection/ansible.utils-3.1.0.info/GALAXY.yml
Normal file
8
collection/ansible.utils-3.1.0.info/GALAXY.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
download_url: https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/ansible-utils-3.1.0.tar.gz
|
||||
format_version: 1.0.0
|
||||
name: utils
|
||||
namespace: ansible
|
||||
server: https://galaxy.ansible.com/api/
|
||||
signatures: []
|
||||
version: 3.1.0
|
||||
version_url: /api/v3/plugin/ansible/content/published/collections/index/ansible/utils/versions/3.1.0/
|
||||
7
collection/ansible/netcommon/.ansible-lint
Normal file
7
collection/ansible/netcommon/.ansible-lint
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
profile: production
|
||||
exclude_paths:
|
||||
- changelogs/changelog.yaml
|
||||
skip_list:
|
||||
# ansible-lint does not like the `import-3.11` ignore in tests/sanity/ignore-*.txt
|
||||
- sanity[cannot-ignore]
|
||||
45
collection/ansible/netcommon/.flake8
Normal file
45
collection/ansible/netcommon/.flake8
Normal file
@@ -0,0 +1,45 @@
|
||||
[flake8]
|
||||
|
||||
builtins = _
|
||||
|
||||
# Print the total number of errors:
|
||||
count = true
|
||||
|
||||
# Don't even try to analyze these:
|
||||
extend-exclude =
|
||||
# vendored files
|
||||
compat
|
||||
# project env vars
|
||||
.env,
|
||||
# GitHub configs
|
||||
.github,
|
||||
.mypy_cache
|
||||
# Cache files of pytest
|
||||
.pytest_cache,
|
||||
tests/output/
|
||||
.tox
|
||||
# Occasional virtualenv dirs
|
||||
.venv
|
||||
venv
|
||||
# VS Code
|
||||
.vscode,
|
||||
|
||||
# IMPORTANT: avoid using ignore option, always use extend-ignore instead
|
||||
# Completely and unconditionally ignore the following errors:
|
||||
extend-ignore =
|
||||
# E123, E125 skipped as they are invalid PEP-8.
|
||||
E123,
|
||||
E125,
|
||||
# annoy black by allowing white space before : https://github.com/psf/black/issues/315
|
||||
E203,
|
||||
# ansible requires import after doc strings
|
||||
E402,
|
||||
# given the ansible_collections this is nearly impossible
|
||||
E501,
|
||||
W503,
|
||||
|
||||
# Accessibility/large fonts and PEP8 unfriendly:
|
||||
max-line-length = 100
|
||||
|
||||
# Count the number of occurrences of each error/warning code and print a report:
|
||||
statistics = true
|
||||
3
collection/ansible/netcommon/.github/release-drafter.yml
vendored
Normal file
3
collection/ansible/netcommon/.github/release-drafter.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
# see https://github.com/ansible-community/devtools
|
||||
_extends: ansible-community/devtools
|
||||
15
collection/ansible/netcommon/.github/workflows/ack.yml
vendored
Normal file
15
collection/ansible/netcommon/.github/workflows/ack.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
# See https://github.com/ansible-community/devtools/blob/main/.github/workflows/ack.yml
|
||||
name: ack
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on: # yamllint disable-line rule:truthy
|
||||
pull_request_target:
|
||||
types: [opened, labeled, unlabeled, synchronize]
|
||||
|
||||
jobs:
|
||||
ack:
|
||||
uses: ansible/devtools/.github/workflows/ack.yml@main
|
||||
14
collection/ansible/netcommon/.github/workflows/codecoverage.yml
vendored
Normal file
14
collection/ansible/netcommon/.github/workflows/codecoverage.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: code_coverage
|
||||
|
||||
on: # yamllint disable-line rule:truthy
|
||||
push:
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
codecoverage:
|
||||
uses: ansible-network/github_actions/.github/workflows/coverage_network_devices.yml@main
|
||||
with:
|
||||
collection_pre_install: >-
|
||||
git+https://github.com/ansible-collections/ansible.utils.git
|
||||
14
collection/ansible/netcommon/.github/workflows/lint.yml
vendored
Normal file
14
collection/ansible/netcommon/.github/workflows/lint.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: ansible-lint
|
||||
on: # yamllint disable-line rule:truthy
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
jobs:
|
||||
build:
|
||||
name: Ansible Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run ansible-lint
|
||||
uses: ansible/ansible-lint@main
|
||||
27
collection/ansible/netcommon/.github/workflows/push.yml
vendored
Normal file
27
collection/ansible/netcommon/.github/workflows/push.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
# push workflow is shared and expected to perform actions after a merge happens
|
||||
# on a maintenance branch (default or release). For example updating the
|
||||
# draft release-notes.
|
||||
# based on great work from
|
||||
# https://github.com/T-Systems-MMS/ansible-collection-icinga-director
|
||||
name: push
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on: # yamllint disable-line rule:truthy
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
NAMESPACE: ansible
|
||||
COLLECTION_NAME: netcommon
|
||||
ANSIBLE_COLLECTIONS_PATHS: ./
|
||||
|
||||
jobs:
|
||||
update_release_draft:
|
||||
uses: ansible/devtools/.github/workflows/push_network.yml@main
|
||||
with:
|
||||
repo: ansible-collections/ansible.netcommon
|
||||
secrets:
|
||||
BOT_PAT: ${{ secrets.BOT_PAT }}
|
||||
14
collection/ansible/netcommon/.github/workflows/release.yml
vendored
Normal file
14
collection/ansible/netcommon/.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: release
|
||||
on: # yamllint disable-line rule:truthy
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
release:
|
||||
uses: ansible/devtools/.github/workflows/release_collection.yml@main
|
||||
with:
|
||||
environment: release
|
||||
secrets:
|
||||
ah_token: ${{ secrets.AH_TOKEN }}
|
||||
ansible_galaxy_api_key: ${{ secrets.ANSIBLE_GALAXY_API_KEY }}
|
||||
44
collection/ansible/netcommon/.github/workflows/tests.yml
vendored
Normal file
44
collection/ansible/netcommon/.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
name: CI
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on: # yamllint disable-line rule:truthy
|
||||
pull_request:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
changelog:
|
||||
uses: ansible-network/github_actions/.github/workflows/changelog.yml@main
|
||||
if: github.event_name == 'pull_request'
|
||||
sanity:
|
||||
uses: ansible-network/github_actions/.github/workflows/sanity.yml@main
|
||||
unit-galaxy:
|
||||
uses: ansible-network/github_actions/.github/workflows/unit_galaxy.yml@main
|
||||
unit-source:
|
||||
uses: ansible-network/github_actions/.github/workflows/unit_source.yml@main
|
||||
with:
|
||||
collection_pre_install: >-
|
||||
git+https://github.com/ansible-collections/ansible.utils.git
|
||||
all_green:
|
||||
if: ${{ always() }}
|
||||
needs:
|
||||
- changelog
|
||||
- sanity
|
||||
- unit-galaxy
|
||||
- unit-source
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: >-
|
||||
python -c "assert 'failure' not in
|
||||
set([
|
||||
'${{ needs.changelog.result }}',
|
||||
'${{ needs.sanity.result }}',
|
||||
'${{ needs.unit-galaxy.result }}',
|
||||
'${{ needs.unit-source.result }}'
|
||||
])"
|
||||
14
collection/ansible/netcommon/.github/workflows/token_refresh.yml
vendored
Normal file
14
collection/ansible/netcommon/.github/workflows/token_refresh.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: refresh_automation_hub_token
|
||||
on: # yamllint disable-line rule:truthy
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
refresh:
|
||||
uses: ansible/devtools/.github/workflows/ah_token_refresh.yml@main
|
||||
with:
|
||||
environment: release
|
||||
secrets:
|
||||
ah_token: ${{ secrets.AH_TOKEN }}
|
||||
113
collection/ansible/netcommon/.gitignore
vendored
Normal file
113
collection/ansible/netcommon/.gitignore
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
/tests/output/
|
||||
/changelogs/.plugin-cache.yaml
|
||||
|
||||
# In case a collection directory is present, ignore it
|
||||
/collections/
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
|
||||
# vs code configuration
|
||||
.vscode/
|
||||
6
collection/ansible/netcommon/.isort.cfg
Normal file
6
collection/ansible/netcommon/.isort.cfg
Normal file
@@ -0,0 +1,6 @@
|
||||
[settings]
|
||||
known_first_party=ansible_collections.ansible.netcommon
|
||||
line_length=100
|
||||
lines_after_imports=2
|
||||
lines_between_types=1
|
||||
profile=black
|
||||
34
collection/ansible/netcommon/.pre-commit-config.yaml
Normal file
34
collection/ansible/netcommon/.pre-commit-config.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
repos:
|
||||
- repo: https://github.com/ansible-network/collection_prep
|
||||
rev: 1.1.1
|
||||
hooks:
|
||||
- id: update-docs
|
||||
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.5.0
|
||||
hooks:
|
||||
- id: check-merge-conflict
|
||||
- id: debug-statements
|
||||
- id: end-of-file-fixer
|
||||
- id: no-commit-to-branch
|
||||
- id: trailing-whitespace
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: "v3.1.0"
|
||||
hooks:
|
||||
- id: prettier
|
||||
additional_dependencies:
|
||||
- prettier
|
||||
- prettier-plugin-toml
|
||||
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.12.0
|
||||
hooks:
|
||||
- id: isort
|
||||
args: ["--filter-files"]
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.11.0
|
||||
hooks:
|
||||
- id: black
|
||||
17
collection/ansible/netcommon/.prettierignore
Normal file
17
collection/ansible/netcommon/.prettierignore
Normal file
@@ -0,0 +1,17 @@
|
||||
# Stuff we don't want priettier to ever to look into
|
||||
.*/
|
||||
coverage/
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# A linked collection directory created by pytest-ansible-units
|
||||
collections/
|
||||
|
||||
README.md
|
||||
15
collection/ansible/netcommon/.yamllint
Normal file
15
collection/ansible/netcommon/.yamllint
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
extends: default
|
||||
|
||||
ignore: |
|
||||
\.tox
|
||||
changelogs/*
|
||||
|
||||
rules:
|
||||
braces:
|
||||
max-spaces-inside: 1
|
||||
level: error
|
||||
brackets:
|
||||
max-spaces-inside: 1
|
||||
level: error
|
||||
line-length: disable
|
||||
610
collection/ansible/netcommon/CHANGELOG.rst
Normal file
610
collection/ansible/netcommon/CHANGELOG.rst
Normal file
@@ -0,0 +1,610 @@
|
||||
==========================================
|
||||
Ansible Netcommon Collection Release Notes
|
||||
==========================================
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
|
||||
v6.0.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Starting from this release, the minimum `ansible-core` version this collection requires is `2.14.0`. That last known version compatible with ansible-core<2.14 is `v5.3.0`.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Bumping `requires_ansible` to `>=2.14.0`, since previous ansible-core versions are EoL now.
|
||||
|
||||
v5.3.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add new module cli_backup that exclusively handles configuration backup.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix attribute types from string to str in filter plugins.
|
||||
|
||||
v5.2.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add a new cliconf plugin ``default`` that can be used when no cliconf plugin is found for a given network_os. This plugin only supports ``get()``. (https://github.com/ansible-collections/ansible.netcommon/pull/569)
|
||||
- httpapi - Add additional option ``ca_path``, ``client_cert``, ``client_key``, and ``http_agent`` that are available in open_url but not to httpapi. (https://github.com/ansible-collections/ansible.netcommon/issues/528)
|
||||
- telnet - add crlf option to send CRLF instead of just LF (https://github.com/ansible-collections/ansible.netcommon/pull/440).
|
||||
|
||||
Deprecated Features
|
||||
-------------------
|
||||
|
||||
- libssh - the ssh_*_args options are now marked that they will be removed after 2026-01-01.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Ensure that all connection plugin options that should be strings are actually strings (https://github.com/ansible-collections/ansible.netcommon/pull/549).
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Cliconf
|
||||
~~~~~~~
|
||||
|
||||
- default - General purpose cliconf plugin for new platforms
|
||||
|
||||
v5.1.3
|
||||
======
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Vendor telnetlib from cpython (https://github.com/ansible-collections/ansible.netcommon/pull/546)
|
||||
|
||||
v5.1.2
|
||||
======
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Ensure that all connection plugin options that should be strings are actually strings (https://github.com/ansible-collections/ansible.netcommon/pull/549).
|
||||
|
||||
v5.1.1
|
||||
======
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- network_resource - do not append network_os to module names when building supported resources list. This fix is only valid for cases where FACTS_RESOURCE_SUBSETS is undefined.
|
||||
|
||||
v5.1.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- libssh - add ``config_file`` option to specify an alternate SSH config file to use.
|
||||
- parse_cli - add support for multiple matches inside a block by adding new dictionary key to result
|
||||
- telnet - add ``stdout`` and ``stdout_lines`` to module output.
|
||||
- telnet - add support for regexes to ``login_prompt`` and ``password_prompt``.
|
||||
- telnet - apply ``timeout`` to command prompts.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- httpapi - ``send()`` method no longer applied leftover kwargs to ``open_url()``. Fix applies those arguments as intended (https://github.com/ansible-collections/ansible.netcommon/pull/524).
|
||||
- network_cli - network cli connection avoids traceback when using invalid user
|
||||
- network_cli - when receiving longer responses with libssh, parts of the response were sometimes repeated. The response is now returned as it is received (https://github.com/ansible-collections/community.routeros/issues/132).
|
||||
- network_resource - fix a potential UnboundLocalError if the module fails to import a Resource Module. (https://github.com/ansible-collections/ansible.netcommon/pull/513)
|
||||
- restconf - creation of new resources is no longer erroneously forced to use POST. (https://github.com/ansible-collections/ansible.netcommon/issues/502)
|
||||
|
||||
v5.0.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- httpapi - Add option netcommon_httpapi_ciphers to allow overriding default SSL/TLS ciphers. (https://github.com/ansible-collections/ansible.netcommon/pull/494)
|
||||
|
||||
Breaking Changes / Porting Guide
|
||||
--------------------------------
|
||||
|
||||
- NetworkConnectionBase now inherits from PersistentConnectionBase in ansible.utils. As a result, the minimum ansible.utils version has increased to 2.7.0.
|
||||
- NetworkTemplate is no longer importable from ansible_collections.ansible.netcommon.plugins.module_utils.network.common and should now be found at its proper location ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template
|
||||
- ResourceModule is no longer importable from ansible_collections.ansible.netcommon.plugins.module_utils.network.common and should now be found at its proper location ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module
|
||||
- VALID_MASKS, is_masklen, is_netmask, to_bits, to_ipv6_network, to_masklen, to_netmask, and to_subnet are no longer importable from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils and should now be found at their proper location ansible.module_utils.common.network
|
||||
|
||||
Removed Features (previously deprecated)
|
||||
----------------------------------------
|
||||
|
||||
- cli_parse - This plugin was moved to ansible.utils in version 1.0.0, and the redirect to that collection has now been removed.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Cast AnsibleUnsafeText to str in convert_doc_to_ansible_module_kwargs() to keep CSafeLoader happy. This fixes issues with content scaffolding tools.
|
||||
|
||||
v4.1.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add implementation for content_templates_parser.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- restconf_get - fix direction of XML deserialization when ``output == 'xml'``
|
||||
|
||||
v4.0.0
|
||||
======
|
||||
|
||||
Removed Features (previously deprecated)
|
||||
----------------------------------------
|
||||
|
||||
- napalm - Removed unused connection plugin.
|
||||
- net_banner - Use <network_os>_banner instead.
|
||||
- net_interface - Use <network_os>_interfaces instead.
|
||||
- net_l2_interface - Use <network_os>_l2_interfaces instead.
|
||||
- net_l3_interface - Use <network_os>_l3_interfaces instead.
|
||||
- net_linkagg - Use <network_os>_lag_interfaces instead.
|
||||
- net_lldp - Use <network_os>_lldp_global instead.
|
||||
- net_lldp_interface - Use <network_os>_lldp_interfaces instead.
|
||||
- net_logging - Use <network_os>_logging_global instead.
|
||||
- net_static_route - Use <network_os>_static_routes instead.
|
||||
- net_system - Use <network_os>_system instead.
|
||||
- net_user - Use <network_os>_user instead.
|
||||
- net_vlan - Use <network_os>_vlans instead.
|
||||
- net_vrf - Use <network_os>_vrf instead.
|
||||
|
||||
v3.1.3
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
The v3.1.2 is unavailable on Ansible Automation Hub because a technical issue. Please download and use v3.1.3 from Automation Hub.
|
||||
|
||||
v3.1.2
|
||||
======
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- libssh - check for minimum ansible-pylibssh version before using password_prompt option. (https://github.com/ansible-collections/ansible.netcommon/pull/467)
|
||||
|
||||
v3.1.1
|
||||
======
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix a small number of potential use-before-assignment issues.
|
||||
- Fix to set connection plugin options correctly.
|
||||
- libssh - Removed the wording "Tech preview". From version 3.0.0 the default if installed.
|
||||
- libssh - add ssh_args, ssh_common_args, and ssh_extra_args options. These options are exclusively for collecting proxy information from as an alternative to the proxy_command option.
|
||||
|
||||
v3.1.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add grpc connection plugin support.
|
||||
- Adds a new option `terminal_errors` in network_cli, that determines how terminal setting failures are handled.
|
||||
- libssh - Added `password_prompt` option to override default "password:" prompt used by pylibssh
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Connection
|
||||
~~~~~~~~~~
|
||||
|
||||
- grpc - Provides a persistent connection using the gRPC protocol
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- grpc_config - Fetch configuration/state data from gRPC enabled target hosts.
|
||||
- grpc_get - Fetch configuration/state data from gRPC enabled target hosts.
|
||||
|
||||
v3.0.1
|
||||
======
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- httpapi - Fix for improperly set hostname in url
|
||||
- libssh - Fix for improperly set hostname in connect
|
||||
- restconf - When non-JSON data is encountered, return the bytes found instead of nothing.
|
||||
|
||||
v3.0.0
|
||||
======
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- cli_parse - this module has been moved to the ansible.utils collection. ``ansible.netcommon.cli_parse`` will continue to work to reference the module in its new location, but this redirect will be removed in a future release
|
||||
- network_cli - Change default value of `ssh_type` option from `paramiko` to `auto`. This value will use libssh if the ansible-pylibssh module is installed, otherwise will fallback to paramiko.
|
||||
|
||||
Breaking Changes / Porting Guide
|
||||
--------------------------------
|
||||
|
||||
- httpapi - Change default value of ``import_modules`` option from ``no`` to ``yes``
|
||||
- netconf - Change default value of ``import_modules`` option from ``no`` to ``yes``
|
||||
- network_cli - Change default value of ``import_modules`` option from ``no`` to ``yes``
|
||||
|
||||
Known Issues
|
||||
------------
|
||||
|
||||
- eos - When using eos modules on Ansible 2.9, tasks will occasionally fail with ``import_modules`` enabled. This can be avoided by setting ``import_modules: no``
|
||||
|
||||
v2.6.1
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Rereleased 2.6.0 with updated utils dependancy.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix validate-module sanity test.
|
||||
|
||||
v2.6.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Redirected ipaddr filters to ansible.utils (https://github.com/ansible-collections/ansible.netcommon/pull/359).
|
||||
- httpapi - new parameter retries in send() method limits the number of times a request is retried when a HTTP error that can be worked around is encountered. The default is to retry indefinitely to maintain old behavior, but this default may change in a later breaking release.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix issue with cli_parse native_parser plugin when input is empty (https://github.com/ansible-collections/ansible.netcommon/issues/347).
|
||||
- No activity on the transport's channel was triggering a socket.timeout() after 30 secs, even if persistent_command_timeout is set to a higher value. This patch fixes it.
|
||||
|
||||
v2.5.1
|
||||
======
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fixed plugins inheriting from netcommon's base plugins (for example httpapi/restconf or netconf/default) so that they can be properly loaded (https://github.com/ansible-collections/ansible.netcommon/issues/356).
|
||||
|
||||
v2.5.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Copied the cliconf, httpapi, netconf, and terminal base plugins and NetworkConnectionBase into netcommon. These base plugins may now be imported from netcommmon instead of ansible if a collection depends on netcommon versions newer than this version, allowing features and bugfixes to flow to those collections without upgrading ansible.
|
||||
- Make ansible_network_os as optional param for httpapi connection plugin.
|
||||
- Support removal of non-config lines from running config while taking backup.
|
||||
- `network_cli` - added new option 'become_errors' to determine how privilege escalation failures are handled.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- network_cli - Provide clearer error message when a prompt regex fails to compile
|
||||
- network_cli - fix issue when multiple terminal_initial_(prompt|answer) values are given (https://github.com/ansible-collections/ansible.netcommon/issues/331).
|
||||
|
||||
v2.4.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add network_resource plugin to manage and provide single entry point for all resource modules for higher oder roles.
|
||||
|
||||
Deprecated Features
|
||||
-------------------
|
||||
|
||||
- network_cli - The paramiko_ssh setting ``look_for_keys`` was set automatically based on the values of the ``password`` and ``private_key_file`` options passed to network_cli. This option can now be set explicitly, and the automatic setting of ``look_for_keys`` will be removed after 2024-01-01 (https://github.com/ansible-collections/ansible.netcommon/pull/271).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- network_cli - Add ability to set options inherited from paramiko/libssh in ansible >= 2.11 (https://github.com/ansible-collections/ansible.netcommon/pull/271).
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- network_resource - Manage resource modules
|
||||
|
||||
v2.3.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add vlan_expander filter
|
||||
- Persistent connection options (persistent_command_timeout, persistent_log_messages, etc.) have been unified across all persistent connections. New persistent connections may also now get these options by extending the connection_persistent documentation fragment.
|
||||
|
||||
v2.2.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add variable to control ProxyCommand with libssh connection.
|
||||
- NetworkTemplate and ResouceModule base classes have been moved under module_utils.network.common.rm_base. Stubs have been kept for backwards compatibility. These will be removed after 2023-01-01. Please update imports for existing modules that subclass them. The `cli_rm_builder <https://github.com/ansible-network/cli_rm_builder>`_ has been updated to use the new imports.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- libssh - Fix fromatting of authenticity error message when not prompting for input (https://github.com/ansible-collections/ansible.netcommon/issues/283)
|
||||
- netconf - Fix connection with ncclient versions < 0.6.10
|
||||
- network_cli - Fix for execution failing when ansible_ssh_password is used to specify password (https://github.com/ansible-collections/ansible.netcommon/issues/288)
|
||||
|
||||
v2.1.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add support for ProxyCommand with netconf connection.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Variables in play_context will now be updated for netconf connections on each task run.
|
||||
- fix SCP/SFTP when using network_cli with libssh
|
||||
|
||||
v2.0.2
|
||||
======
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix cli_parse issue with parsers in utils collection (https://github.com/ansible-collections/ansible.netcommon/pull/270)
|
||||
- Support single_user_mode with Ansible 2.9.
|
||||
|
||||
v2.0.1
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Several module_utils files were intended to be licensed BSD, but missing a license preamble in the files. The preamble has been added, and all authors for the files have given their assent to the intended license https://github.com/ansible-collections/ansible.netcommon/pull/122
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Allow setting `host_key_checking` through a play/task var for `network_cli`.
|
||||
- Ensure passed-in terminal_initial_prompt and terminal_initial_answer values are cast to bytes before using
|
||||
- Update valid documentation for net_ping module.
|
||||
- ncclient - catch and handle exception to prevent stack trace when running in FIPS mode
|
||||
- net_put - Remove temp file created when file already exist on destination when mode is 'text'.
|
||||
|
||||
v2.0.0
|
||||
======
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Remove deprecated connection arguments from netconf_config
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add SCP support when using ssh_type libssh
|
||||
- Add `single_user_mode` option for command output caching.
|
||||
- Move cli_config idempotent warning message with the task response under `warnings` key if `changed` is `True`
|
||||
- Reduce CPU usage and network module run time when using `ansible_network_import_modules`
|
||||
- Support any() and all() filters in Jinja2.
|
||||
|
||||
Breaking Changes / Porting Guide
|
||||
--------------------------------
|
||||
|
||||
- Removed vendored ipaddress package from collection. If you use ansible_collections.ansible.netcommon.plugins.module_utils.compat.ipaddress in your collection, you will need to change this to import ipaddress instead. If your content using ipaddress supports Python 2.7, you will additionally need to make sure that the user has the ipaddress package installed. Please refer to https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_best_practices.html#importing-and-using-shared-code to see how to safely import external packages that may be missing from the user's system A backport of ipaddress for Python 2.7 is available at https://pypi.org/project/ipaddress/
|
||||
|
||||
Deprecated Features
|
||||
-------------------
|
||||
|
||||
- Deprecate cli_parse module and textfsm, ttp, xml, json parser plugins as they are moved to ansible.utils collection (https://github.com/ansible-collections/ansible.netcommon/pull/182 https://github.com/ansible-collections/ansible.utils/pull/28)
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Expose connection class object to rm_template (https://github.com/ansible-collections/ansible.netcommon/pull/180)
|
||||
- network_cli - When using ssh_type libssh, handle closed connection gracefully instead of throwing an exception
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Cache
|
||||
~~~~~
|
||||
|
||||
- memory - RAM backed, non persistent cache.
|
||||
|
||||
v1.5.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add 'purged' to ACTION_STATES.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Add netconf_config integration tests for nxos (https://github.com/ansible-collections/ansible.netcommon/pull/185)
|
||||
- Fix GetReply object has no attribute strip() (https://github.com/ansible-collections/cisco.iosxr/issues/97)
|
||||
- Fix config diff logic if parent configuration is present more than once in the candidate config and update docs (https://github.com/ansible-collections/ansible.netcommon/pull/189)
|
||||
- Fix missing changed from net_get (https://github.com/ansible-collections/ansible.netcommon/issues/198)
|
||||
- Fix netconf_config module integration test issuea (https://github.com/ansible-collections/ansible.netcommon/pull/177)
|
||||
- Fix restconf_config incorrectly spoofs HTTP 409 codes (https://github.com/ansible-collections/ansible.netcommon/issues/191)
|
||||
- Split checks for prompt and errors in network_cli so that detected errors are not lost if the prompt is in a later chunk.
|
||||
|
||||
v1.4.1
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Change how black config is specified to avoid issues with Automation Hub release process
|
||||
|
||||
v1.4.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- 'prefix' added to NetworkTemplate class, inorder to handle the negate operation for vyos config commands.
|
||||
- Add support for json format input format for netconf modules using ``xmltodict``
|
||||
- Update docs for netconf_get and netconf_config examples using display=native
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Added support for private key based authentication with libssh transport (https://github.com/ansible-collections/ansible.netcommon/issues/168)
|
||||
- Fixed ipaddr filter plugins in ansible.netcommon collections is not working with latest Ansible (https://github.com/ansible-collections/ansible.netcommon/issues/157)
|
||||
- Fixed netconf_rpc task fails due to encoding issue in the response (https://github.com/ansible-collections/ansible.netcommon/issues/151)
|
||||
- Fixed ssh_type none issue while using net_put and net_get module (https://github.com/ansible-collections/ansible.netcommon/issues/153)
|
||||
- Fixed unit tests under python3.5
|
||||
- ipaddr filter - query "address/prefix" (also: "gateway", "gw", "host/prefix", "hostnet", and "router") now handles addresses with /32 prefix or /255.255.255.255 netmask
|
||||
- network_cli - Update underlying ssh connection's play_context in update_play_context, so that the username or password can be updated
|
||||
|
||||
v1.3.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Confirmed commit fails with TypeError in IOS XR netconf plugin (https://github.com/ansible-collections/cisco.iosxr/issues/74)
|
||||
- The netconf_config module now allows root tag with namespace prefix.
|
||||
- cli_config: Add new return value diff which is returned when the cliconf plugin supports onbox diff
|
||||
- cli_config: Clarify when commands is returned when the module is run
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- cli_parse - Ensure only native types are returned to the control node from the parser.
|
||||
- netconf - Changed log level for message of using default netconf plugin to match the level used when a platform-specific netconf plugin is found
|
||||
|
||||
v1.2.1
|
||||
======
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fixed "Object of type Capabilities is not JSON serializable" when using default netconf plugin.
|
||||
|
||||
v1.2.0
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Added description to collection galaxy.yml file.
|
||||
- NetworkConfig objects now have an optional `comment_tokens` parameter which takes a list of strings which will override the DEFAULT_COMMENT_TOKENS list.
|
||||
- New cli_parse module for parsing structured text using a variety of parsers. The initial implemetation of cli_parse can be used with json, native, ntc_templates, pyats, textfsm, ttp, and xml.
|
||||
- The httpapi connection plugin now works with `wait_for_connection`. This will periodically request the root page of the server described by the plugin's options until the request succeeds. This can only test that the server is reachable, the correctness or usability of the API is not guaranteed.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- cli_config fixes issue when rollback_id = 0 evalutes to False
|
||||
- sort_list will sort a list of dicts using the sorted method with key as an argument.
|
||||
|
||||
v1.1.2
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Rereleased 1.1.1 with updated changelog.
|
||||
|
||||
v1.1.1
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Rereleased 1.1.0 with regenerated documentation.
|
||||
|
||||
v1.1.0
|
||||
======
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Add libssh connection plugin and refactor network_cli (https://github.com/ansible-collections/ansible.netcommon/pull/30)
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add content option validation for netconf_config module (https://github.com/ansible-collections/ansible.netcommon/pull/66)
|
||||
- Documentation of module arguments updated to match expected types where missing.
|
||||
- Resource Modules: changed flag is set to true in check_mode for all ACTION_STATES (https://github.com/ansible-collections/ansible.netcommon/pull/82)
|
||||
|
||||
Removed Features (previously deprecated)
|
||||
----------------------------------------
|
||||
|
||||
- module_utils.network.common.utils.ComplexDict has been removed
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Replace deprecated `getiterator` call with `iter`
|
||||
- ipaddr - "host" query supports /31 subnets properly
|
||||
- ipaddr filter - Fixed issue where the first IPv6 address in a subnet was not being considered a valid address.
|
||||
- ipaddr filter now returns empty list instead of False on empty list input
|
||||
- net_put - Restore missing function removed when action plugin stopped inheriting NetworkActionBase
|
||||
- nthhost filter now returns str instead of IPAddress object
|
||||
- slaac filter now returns str instead of IPAddress object
|
||||
|
||||
v1.0.0
|
||||
======
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Become
|
||||
~~~~~~
|
||||
|
||||
- enable - Switch to elevated permissions on a network device
|
||||
|
||||
Connection
|
||||
~~~~~~~~~~
|
||||
|
||||
- httpapi - Use httpapi to run command on network appliances
|
||||
- netconf - Provides a persistent connection using the netconf protocol
|
||||
- network_cli - Use network_cli to run command on network appliances
|
||||
- persistent - Use a persistent unix socket for connection
|
||||
|
||||
Httpapi
|
||||
~~~~~~~
|
||||
|
||||
- restconf - HttpApi Plugin for devices supporting Restconf API
|
||||
|
||||
Netconf
|
||||
~~~~~~~
|
||||
|
||||
- default - Use default netconf plugin to run standard netconf commands as per RFC
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- cli_command - Run a cli command on cli-based network devices
|
||||
- cli_config - Push text based configuration to network devices over network_cli
|
||||
- net_get - Copy a file from a network device to Ansible Controller
|
||||
- net_ping - Tests reachability using ping from a network device
|
||||
- net_put - Copy a file from Ansible Controller to a network device
|
||||
- netconf_config - netconf device configuration
|
||||
- netconf_get - Fetch configuration/state data from NETCONF enabled network devices.
|
||||
- netconf_rpc - Execute operations on NETCONF enabled network devices.
|
||||
- restconf_config - Handles create, update, read and delete of configuration data on RESTCONF enabled devices.
|
||||
- restconf_get - Fetch configuration/state data from RESTCONF enabled devices.
|
||||
- telnet - Executes a low-down and dirty telnet command
|
||||
2826
collection/ansible/netcommon/FILES.json
Normal file
2826
collection/ansible/netcommon/FILES.json
Normal file
File diff suppressed because it is too large
Load Diff
674
collection/ansible/netcommon/LICENSE
Normal file
674
collection/ansible/netcommon/LICENSE
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
7
collection/ansible/netcommon/LICENSES/BSD-2-Clause.txt
Normal file
7
collection/ansible/netcommon/LICENSES/BSD-2-Clause.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
1
collection/ansible/netcommon/LICENSES/GPL-3.0-or-later.txt
Symbolic link
1
collection/ansible/netcommon/LICENSES/GPL-3.0-or-later.txt
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE
|
||||
48
collection/ansible/netcommon/LICENSES/PSF-2.0.txt
Normal file
48
collection/ansible/netcommon/LICENSES/PSF-2.0.txt
Normal file
@@ -0,0 +1,48 @@
|
||||
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
||||
--------------------------------------------
|
||||
|
||||
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
||||
("PSF"), and the Individual or Organization ("Licensee") accessing and
|
||||
otherwise using this software ("Python") in source or binary form and
|
||||
its associated documentation.
|
||||
|
||||
2. Subject to the terms and conditions of this License Agreement, PSF hereby
|
||||
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
|
||||
analyze, test, perform and/or display publicly, prepare derivative works,
|
||||
distribute, and otherwise use Python alone or in any derivative version,
|
||||
provided, however, that PSF's License Agreement and PSF's notice of copyright,
|
||||
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Python Software Foundation;
|
||||
All Rights Reserved" are retained in Python alone or in any derivative version
|
||||
prepared by Licensee.
|
||||
|
||||
3. In the event Licensee prepares a derivative work that is based on
|
||||
or incorporates Python or any part thereof, and wants to make
|
||||
the derivative work available to others as provided herein, then
|
||||
Licensee hereby agrees to include in any such work a brief summary of
|
||||
the changes made to Python.
|
||||
|
||||
4. PSF is making Python available to Licensee on an "AS IS"
|
||||
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
|
||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
6. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
7. Nothing in this License Agreement shall be deemed to create any
|
||||
relationship of agency, partnership, or joint venture between PSF and
|
||||
Licensee. This License Agreement does not grant permission to use PSF
|
||||
trademarks or trade name in a trademark sense to endorse or promote
|
||||
products or services of Licensee, or any third party.
|
||||
|
||||
8. By copying, installing or otherwise using Python, Licensee
|
||||
agrees to be bound by the terms and conditions of this License
|
||||
Agreement.
|
||||
38
collection/ansible/netcommon/MANIFEST.json
Normal file
38
collection/ansible/netcommon/MANIFEST.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"collection_info": {
|
||||
"namespace": "ansible",
|
||||
"name": "netcommon",
|
||||
"version": "6.0.0",
|
||||
"authors": [
|
||||
"Ansible Network Community (ansible-network)"
|
||||
],
|
||||
"readme": "README.md",
|
||||
"tags": [
|
||||
"networking",
|
||||
"security",
|
||||
"cloud",
|
||||
"network_cli",
|
||||
"netconf",
|
||||
"httpapi",
|
||||
"grpc"
|
||||
],
|
||||
"description": "Ansible Collection with common content to help automate the management of network, security, and cloud devices.",
|
||||
"license": [],
|
||||
"license_file": "LICENSE",
|
||||
"dependencies": {
|
||||
"ansible.utils": ">=3.0.0"
|
||||
},
|
||||
"repository": "https://github.com/ansible-collections/ansible.netcommon",
|
||||
"documentation": null,
|
||||
"homepage": null,
|
||||
"issues": "https://github.com/ansible-collections/ansible.netcommon/issues"
|
||||
},
|
||||
"file_manifest_file": {
|
||||
"name": "FILES.json",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "b0c86e07b3c71fcba92378a549243c5ddc0d647e848127a364bf517d6bc1a9d1",
|
||||
"format": 1
|
||||
},
|
||||
"format": 1
|
||||
}
|
||||
152
collection/ansible/netcommon/README.md
Normal file
152
collection/ansible/netcommon/README.md
Normal file
@@ -0,0 +1,152 @@
|
||||
|
||||
|
||||
# Ansible Network Collection for Common Code (netcommon)
|
||||
[](https://ansible.softwarefactory-project.io/zuul/builds?project=ansible-collections%2Fansible.netcommon) <!--[](https://codecov.io/gh/ansible-collections/ansible.netcommon)-->
|
||||
[](https://codecov.io/gh/ansible-collections/ansible.netcommon)
|
||||
[](https://github.com/ansible-collections/ansible.netcommon/actions/workflows/tests.yml)
|
||||
|
||||
The Ansible ``ansible.netcommon`` collection includes common content to help automate the management of network, security, and cloud devices.
|
||||
This includes connection plugins, such as ``network_cli``, ``httpapi``, and ``netconf``.
|
||||
|
||||
<!--start requires_ansible-->
|
||||
## Ansible version compatibility
|
||||
|
||||
This collection has been tested against following Ansible versions: **>=2.14.0**.
|
||||
|
||||
For collections that support Ansible 2.9, please ensure you update your `network_os` to use the
|
||||
fully qualified collection name (for example, `cisco.ios.ios`).
|
||||
Plugins and modules within a collection may be tested with only specific Ansible versions.
|
||||
A collection may contain metadata that identifies these versions.
|
||||
PEP440 is the schema used to describe the versions of Ansible.
|
||||
<!--end requires_ansible-->
|
||||
|
||||
## Included content
|
||||
|
||||
<!--start collection content-->
|
||||
### Become plugins
|
||||
Name | Description
|
||||
--- | ---
|
||||
[ansible.netcommon.enable](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.enable_become.rst)|Switch to elevated permissions on a network device
|
||||
|
||||
### Cliconf plugins
|
||||
Name | Description
|
||||
--- | ---
|
||||
[ansible.netcommon.default](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.default_cliconf.rst)|General purpose cliconf plugin for new platforms
|
||||
|
||||
### Connection plugins
|
||||
Name | Description
|
||||
--- | ---
|
||||
[ansible.netcommon.grpc](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.grpc_connection.rst)|Provides a persistent connection using the gRPC protocol
|
||||
[ansible.netcommon.httpapi](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.httpapi_connection.rst)|Use httpapi to run command on network appliances
|
||||
[ansible.netcommon.libssh](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.libssh_connection.rst)|Run tasks using libssh for ssh connection
|
||||
[ansible.netcommon.netconf](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.netconf_connection.rst)|Provides a persistent connection using the netconf protocol
|
||||
[ansible.netcommon.network_cli](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.network_cli_connection.rst)|Use network_cli to run command on network appliances
|
||||
[ansible.netcommon.persistent](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.persistent_connection.rst)|Use a persistent unix socket for connection
|
||||
|
||||
### Filter plugins
|
||||
Name | Description
|
||||
--- | ---
|
||||
[ansible.netcommon.comp_type5](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.comp_type5_filter.rst)|The comp_type5 filter plugin.
|
||||
[ansible.netcommon.hash_salt](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.hash_salt_filter.rst)|The hash_salt filter plugin.
|
||||
[ansible.netcommon.parse_cli](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.parse_cli_filter.rst)|parse_cli filter plugin.
|
||||
[ansible.netcommon.parse_cli_textfsm](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.parse_cli_textfsm_filter.rst)|parse_cli_textfsm filter plugin.
|
||||
[ansible.netcommon.parse_xml](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.parse_xml_filter.rst)|The parse_xml filter plugin.
|
||||
[ansible.netcommon.pop_ace](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.pop_ace_filter.rst)|Remove ace entries from a acl source of truth.
|
||||
[ansible.netcommon.type5_pw](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.type5_pw_filter.rst)|The type5_pw filter plugin.
|
||||
[ansible.netcommon.vlan_expander](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.vlan_expander_filter.rst)|The vlan_expander filter plugin.
|
||||
[ansible.netcommon.vlan_parser](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.vlan_parser_filter.rst)|The vlan_parser filter plugin.
|
||||
|
||||
### Httpapi plugins
|
||||
Name | Description
|
||||
--- | ---
|
||||
[ansible.netcommon.restconf](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.restconf_httpapi.rst)|HttpApi Plugin for devices supporting Restconf API
|
||||
|
||||
### Netconf plugins
|
||||
Name | Description
|
||||
--- | ---
|
||||
[ansible.netcommon.default](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.default_netconf.rst)|Use default netconf plugin to run standard netconf commands as per RFC
|
||||
|
||||
### Modules
|
||||
Name | Description
|
||||
--- | ---
|
||||
[ansible.netcommon.cli_backup](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.cli_backup_module.rst)|Back up device configuration from network devices over network_cli
|
||||
[ansible.netcommon.cli_command](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.cli_command_module.rst)|Run a cli command on cli-based network devices
|
||||
[ansible.netcommon.cli_config](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.cli_config_module.rst)|Push text based configuration to network devices over network_cli
|
||||
[ansible.netcommon.grpc_config](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.grpc_config_module.rst)|Fetch configuration/state data from gRPC enabled target hosts.
|
||||
[ansible.netcommon.grpc_get](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.grpc_get_module.rst)|Fetch configuration/state data from gRPC enabled target hosts.
|
||||
[ansible.netcommon.net_get](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.net_get_module.rst)|Copy a file from a network device to Ansible Controller
|
||||
[ansible.netcommon.net_ping](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.net_ping_module.rst)|Tests reachability using ping from a network device
|
||||
[ansible.netcommon.net_put](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.net_put_module.rst)|Copy a file from Ansible Controller to a network device
|
||||
[ansible.netcommon.netconf_config](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.netconf_config_module.rst)|netconf device configuration
|
||||
[ansible.netcommon.netconf_get](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.netconf_get_module.rst)|Fetch configuration/state data from NETCONF enabled network devices.
|
||||
[ansible.netcommon.netconf_rpc](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.netconf_rpc_module.rst)|Execute operations on NETCONF enabled network devices.
|
||||
[ansible.netcommon.network_resource](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.network_resource_module.rst)|Manage resource modules
|
||||
[ansible.netcommon.restconf_config](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.restconf_config_module.rst)|Handles create, update, read and delete of configuration data on RESTCONF enabled devices.
|
||||
[ansible.netcommon.restconf_get](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.restconf_get_module.rst)|Fetch configuration/state data from RESTCONF enabled devices.
|
||||
[ansible.netcommon.telnet](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.telnet_module.rst)|Executes a low-down and dirty telnet command
|
||||
|
||||
<!--end collection content-->
|
||||
|
||||
|
||||
## Installing this collection
|
||||
|
||||
You can install the ``ansible.netcommon`` collection with the Ansible Galaxy CLI:
|
||||
|
||||
ansible-galaxy collection install ansible.netcommon
|
||||
|
||||
You can also include it in a `requirements.yml` file and install it with `ansible-galaxy collection install -r requirements.yml`, using the format:
|
||||
|
||||
```yaml
|
||||
---
|
||||
collections:
|
||||
- name: ansible.netcommon
|
||||
```
|
||||
## Using this collection
|
||||
|
||||
The most common use case for this collection is to include it as a dependency in a network device-specific collection. Use the Fully Qualified Collection Name (FQCN) when referring to content in this collection (for example, `ansible.netcommon.network_cli`).
|
||||
|
||||
See the [Vyos collection](https://github.com/ansible-collections/vyos) for an example of this.
|
||||
|
||||
### See Also:
|
||||
|
||||
* [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details.
|
||||
|
||||
## Contributing to this collection
|
||||
|
||||
We welcome community contributions to this collection. If you find problems, please open an issue or create a PR against the [ansible.netcommon collection repository](https://github.com/ansible-collections/ansible.netcommon). See [Contributing to Ansible-maintained collections](https://docs.ansible.com/ansible/devel/community/contributing_maintained_collections.html#contributing-maintained-collections) for complete details.
|
||||
|
||||
You can also join us on:
|
||||
|
||||
- IRC - ``#ansible-network`` [irc.libera.chat](https://libera.chat/) channel
|
||||
- Slack - https://ansiblenetwork.slack.com
|
||||
|
||||
See the [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html) for details on contributing to Ansible.
|
||||
|
||||
### Code of Conduct
|
||||
This collection follows the Ansible project's
|
||||
[Code of Conduct](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html).
|
||||
Please read and familiarize yourself with this document.
|
||||
|
||||
|
||||
## Release notes
|
||||
<!--Add a link to a changelog.md file or an external docsite to cover this information. -->
|
||||
Release notes are available [here](https://github.com/ansible-collections/ansible.netcommon/blob/main/CHANGELOG.rst)
|
||||
|
||||
## Roadmap
|
||||
|
||||
<!-- Optional. Include the roadmap for this collection, and the proposed release/versioning strategy so users can anticipate the upgrade/update cycle. -->
|
||||
|
||||
## More information
|
||||
|
||||
- [Developing network resource modules](https://docs.ansible.com/ansible/latest/network/dev_guide/developing_resource_modules_network.html#developing-resource-modules)
|
||||
- [Ansible network resources](https://docs.ansible.com/ansible/latest/network/getting_started/network_resources.html)
|
||||
- [Ansible Collection overview](https://github.com/ansible-collections/overview)
|
||||
- [Ansible User guide](https://docs.ansible.com/ansible/latest/user_guide/index.html)
|
||||
- [Ansible Developer guide](https://docs.ansible.com/ansible/latest/dev_guide/index.html)
|
||||
- [Ansible Community code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html)
|
||||
|
||||
## Licensing
|
||||
|
||||
GNU General Public License v3.0 or later.
|
||||
|
||||
See [LICENSE](https://www.gnu.org/licenses/gpl-3.0.txt) to see the full text.
|
||||
36
collection/ansible/netcommon/bindep.txt
Normal file
36
collection/ansible/netcommon/bindep.txt
Normal file
@@ -0,0 +1,36 @@
|
||||
# This is a cross-platform list tracking distribution packages needed by tests;
|
||||
# see https://docs.openstack.org/infra/bindep/ for additional information.
|
||||
|
||||
gcc-c++ [doc test platform:rpm]
|
||||
libyaml-devel [test platform:rpm]
|
||||
libyaml-dev [test platform:dpkg]
|
||||
python3-devel [test platform:rpm]
|
||||
python3 [test platform:rpm]
|
||||
|
||||
# ansible-pylibssh
|
||||
gcc [compile platform:rpm]
|
||||
libssh-dev [compile platform:dpkg]
|
||||
libssh-devel [compile platform:rpm]
|
||||
python3-Cython [compile platform:fedora-35 platform:rhel-9]
|
||||
# 3.9 Cython doesn't seem to be available on our centos-8 images
|
||||
# But I'm not sure why we would need it anyway?
|
||||
# python39-Cython [compile platform:centos-8 platform:rhel-8]
|
||||
|
||||
# ncclient
|
||||
python3-six [platform:centos-9 platform:rhel-9]
|
||||
python39-six [platform:centos-8 platform:rhel-8]
|
||||
python3-lxml [platform:centos-9 platform:rhel-9]
|
||||
python39-lxml [platform:centos-8 platform:rhel-8]
|
||||
|
||||
# paramiko
|
||||
findutils [compile platform:centos-8 platform:rhel-8]
|
||||
gcc [compile platform:centos-8 platform:rhel-8]
|
||||
make [compile platform:centos-8 platform:rhel-8]
|
||||
python3-devel [compile platform:centos-9 platform:rhel-9]
|
||||
python39-devel [compile platform:centos-8 platform:rhel-8]
|
||||
python3-cffi [platform:centos-9 platform:rhel-9]
|
||||
python39-cffi [platform:centos-8 platform:rhel-8]
|
||||
python3-cryptography [platform:centos-9 platform:rhel-9]
|
||||
python39-cryptography [platform:centos-8 platform:rhel-8]
|
||||
python3-pycparser [platform:centos-9 platform:rhel-9]
|
||||
python39-pycparser [platform:centos-8 platform:rhel-8]
|
||||
1
collection/ansible/netcommon/changelogs/CHANGELOG.rst
Normal file
1
collection/ansible/netcommon/changelogs/CHANGELOG.rst
Normal file
@@ -0,0 +1 @@
|
||||
The changelog has moved `here <https://github.com/ansible-collections/ansible.netcommon/blob/main/CHANGELOG.rst>`_
|
||||
733
collection/ansible/netcommon/changelogs/changelog.yaml
Normal file
733
collection/ansible/netcommon/changelogs/changelog.yaml
Normal file
@@ -0,0 +1,733 @@
|
||||
ancestor: null
|
||||
releases:
|
||||
1.0.0:
|
||||
modules:
|
||||
- description: Run a cli command on cli-based network devices
|
||||
name: cli_command
|
||||
namespace: ""
|
||||
- description: Push text based configuration to network devices over network_cli
|
||||
name: cli_config
|
||||
namespace: ""
|
||||
- description: Copy a file from a network device to Ansible Controller
|
||||
name: net_get
|
||||
namespace: ""
|
||||
- description: Tests reachability using ping from a network device
|
||||
name: net_ping
|
||||
namespace: ""
|
||||
- description: Copy a file from Ansible Controller to a network device
|
||||
name: net_put
|
||||
namespace: ""
|
||||
- description: netconf device configuration
|
||||
name: netconf_config
|
||||
namespace: ""
|
||||
- description: Fetch configuration/state data from NETCONF enabled network devices.
|
||||
name: netconf_get
|
||||
namespace: ""
|
||||
- description: Execute operations on NETCONF enabled network devices.
|
||||
name: netconf_rpc
|
||||
namespace: ""
|
||||
- description:
|
||||
Handles create, update, read and delete of configuration data on
|
||||
RESTCONF enabled devices.
|
||||
name: restconf_config
|
||||
namespace: ""
|
||||
- description: Fetch configuration/state data from RESTCONF enabled devices.
|
||||
name: restconf_get
|
||||
namespace: ""
|
||||
- description: Executes a low-down and dirty telnet command
|
||||
name: telnet
|
||||
namespace: ""
|
||||
plugins:
|
||||
become:
|
||||
- description: Switch to elevated permissions on a network device
|
||||
name: enable
|
||||
namespace: null
|
||||
connection:
|
||||
- description: Use httpapi to run command on network appliances
|
||||
name: httpapi
|
||||
namespace: null
|
||||
- description: Provides a persistent connection using the netconf protocol
|
||||
name: netconf
|
||||
namespace: null
|
||||
- description: Use network_cli to run command on network appliances
|
||||
name: network_cli
|
||||
namespace: null
|
||||
- description: Use a persistent unix socket for connection
|
||||
name: persistent
|
||||
namespace: null
|
||||
httpapi:
|
||||
- description: HttpApi Plugin for devices supporting Restconf API
|
||||
name: restconf
|
||||
namespace: null
|
||||
netconf:
|
||||
- description:
|
||||
Use default netconf plugin to run standard netconf commands as
|
||||
per RFC
|
||||
name: default
|
||||
namespace: null
|
||||
release_date: "2020-06-23"
|
||||
1.1.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Replace deprecated `getiterator` call with `iter`
|
||||
- ipaddr - "host" query supports /31 subnets properly
|
||||
- ipaddr filter - Fixed issue where the first IPv6 address in a subnet was not
|
||||
being considered a valid address.
|
||||
- ipaddr filter now returns empty list instead of False on empty list input
|
||||
- net_put - Restore missing function removed when action plugin stopped inheriting
|
||||
NetworkActionBase
|
||||
- nthhost filter now returns str instead of IPAddress object
|
||||
- slaac filter now returns str instead of IPAddress object
|
||||
major_changes:
|
||||
- Add libssh connection plugin and refactor network_cli (https://github.com/ansible-collections/ansible.netcommon/pull/30)
|
||||
minor_changes:
|
||||
- Add content option validation for netconf_config module (https://github.com/ansible-collections/ansible.netcommon/pull/66)
|
||||
- Documentation of module arguments updated to match expected types where missing.
|
||||
- "Resource Modules: changed flag is set to true in check_mode for all ACTION_STATES
|
||||
(https://github.com/ansible-collections/ansible.netcommon/pull/82)"
|
||||
removed_features:
|
||||
- module_utils.network.common.utils.ComplexDict has been removed
|
||||
fragments:
|
||||
- 103-net-put-handle-src.yaml
|
||||
- 30-add-libssh-connection-support.yaml
|
||||
- 34-ipaddr-empty-list.yaml
|
||||
- 66-netconf-config-vaildation.yml
|
||||
- 72-ipv6-first-address-fix.yaml
|
||||
- 74-remove-getiterator.yaml
|
||||
- 75-unit-tests.yaml
|
||||
- 78-sanity-cleanup.yaml
|
||||
- 82-changed_true_action_states_check_mode_yes.yml
|
||||
- 95-ipaddr.yaml
|
||||
release_date: "2020-07-30"
|
||||
1.1.1:
|
||||
changes:
|
||||
release_summary: Rereleased 1.1.0 with regenerated documentation.
|
||||
fragments:
|
||||
- 1.1.1.yaml
|
||||
release_date: "2020-07-31"
|
||||
1.1.2:
|
||||
changes:
|
||||
release_summary: Rereleased 1.1.1 with updated changelog.
|
||||
fragments:
|
||||
- 1.1.2.yaml
|
||||
release_date: "2020-08-06"
|
||||
1.2.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- cli_config fixes issue when rollback_id = 0 evalutes to False
|
||||
- sort_list will sort a list of dicts using the sorted method with key as an
|
||||
argument.
|
||||
minor_changes:
|
||||
- Added description to collection galaxy.yml file.
|
||||
- NetworkConfig objects now have an optional `comment_tokens` parameter which
|
||||
takes a list of strings which will override the DEFAULT_COMMENT_TOKENS list.
|
||||
- New cli_parse module for parsing structured text using a variety of parsers.
|
||||
The initial implemetation of cli_parse can be used with json, native, ntc_templates,
|
||||
pyats, textfsm, ttp, and xml.
|
||||
- The httpapi connection plugin now works with `wait_for_connection`. This will
|
||||
periodically request the root page of the server described by the plugin's
|
||||
options until the request succeeds. This can only test that the server is
|
||||
reachable, the correctness or usability of the API is not guaranteed.
|
||||
fragments:
|
||||
- 105-wait_for_conn-httpapi.yaml
|
||||
- 109-cli_parse_module_addition.yaml
|
||||
- 110-NetworkConfig-comments.yaml
|
||||
- 114-sort_list_listofdicts.yaml
|
||||
- 118-cli_config.yaml
|
||||
- 127-galaxy-fragment.yaml
|
||||
release_date: "2020-08-25"
|
||||
1.2.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Fixed "Object of type Capabilities is not JSON serializable" when using default
|
||||
netconf plugin.
|
||||
fragments:
|
||||
- netconf-capabilites-fix.yaml
|
||||
release_date: "2020-09-04"
|
||||
1.3.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- cli_parse - Ensure only native types are returned to the control node from
|
||||
the parser.
|
||||
- netconf - Changed log level for message of using default netconf plugin to
|
||||
match the level used when a platform-specific netconf plugin is found
|
||||
minor_changes:
|
||||
- Confirmed commit fails with TypeError in IOS XR netconf plugin (https://github.com/ansible-collections/cisco.iosxr/issues/74)
|
||||
- The netconf_config module now allows root tag with namespace prefix.
|
||||
- "cli_config: Add new return value diff which is returned when the cliconf
|
||||
plugin supports onbox diff"
|
||||
- "cli_config: Clarify when commands is returned when the module is run"
|
||||
fragments:
|
||||
- 134-cli-config-diff.yaml
|
||||
- allow_root_tag_with_prefix.yaml
|
||||
- cli_parse_fix.yaml
|
||||
- iosxr_netconf_config_commit_testcase.yaml
|
||||
- netconf-default.yaml
|
||||
release_date: "2020-09-29"
|
||||
1.4.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Added support for private key based authentication with libssh transport (https://github.com/ansible-collections/ansible.netcommon/issues/168)
|
||||
- Fixed ipaddr filter plugins in ansible.netcommon collections is not working
|
||||
with latest Ansible (https://github.com/ansible-collections/ansible.netcommon/issues/157)
|
||||
- Fixed netconf_rpc task fails due to encoding issue in the response (https://github.com/ansible-collections/ansible.netcommon/issues/151)
|
||||
- Fixed ssh_type none issue while using net_put and net_get module (https://github.com/ansible-collections/ansible.netcommon/issues/153)
|
||||
- Fixed unit tests under python3.5
|
||||
- 'ipaddr filter - query "address/prefix" (also: "gateway", "gw", "host/prefix",
|
||||
"hostnet", and "router") now handles addresses with /32 prefix or /255.255.255.255
|
||||
netmask'
|
||||
- network_cli - Update underlying ssh connection's play_context in update_play_context,
|
||||
so that the username or password can be updated
|
||||
minor_changes:
|
||||
- "'prefix' added to NetworkTemplate class, inorder to handle the negate operation
|
||||
for vyos config commands."
|
||||
- Add support for json format input format for netconf modules using ``xmltodict``
|
||||
- Update docs for netconf_get and netconf_config examples using display=native
|
||||
fragments:
|
||||
- 135-network-cli-change-password.yaml
|
||||
- 144-test-fixes.yaml
|
||||
- 151-netconf_rpc_fix.yaml
|
||||
- 153-part1-fix_ssh_type_none_issue.yaml
|
||||
- 157-ipaddr-fix.yaml
|
||||
- 168-libssh-privatekey-support.yaml
|
||||
- ipaddr-host-prefix-32.yaml
|
||||
- negate-command-vyos.yaml
|
||||
- netconf_get_config_doc_updates.yaml
|
||||
- netconf_xmltodict_support.yaml
|
||||
release_date: "2020-10-29"
|
||||
1.4.1:
|
||||
changes:
|
||||
release_summary:
|
||||
Change how black config is specified to avoid issues with Automation
|
||||
Hub release process
|
||||
fragments:
|
||||
- revert_pyproject.yaml
|
||||
release_date: "2020-10-29"
|
||||
1.5.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Add netconf_config integration tests for nxos (https://github.com/ansible-collections/ansible.netcommon/pull/185)
|
||||
- Fix GetReply object has no attribute strip() (https://github.com/ansible-collections/cisco.iosxr/issues/97)
|
||||
- Fix config diff logic if parent configuration is present more than once in
|
||||
the candidate config and update docs (https://github.com/ansible-collections/ansible.netcommon/pull/189)
|
||||
- Fix missing changed from net_get (https://github.com/ansible-collections/ansible.netcommon/issues/198)
|
||||
- Fix netconf_config module integration test issuea (https://github.com/ansible-collections/ansible.netcommon/pull/177)
|
||||
- Fix restconf_config incorrectly spoofs HTTP 409 codes (https://github.com/ansible-collections/ansible.netcommon/issues/191)
|
||||
- Split checks for prompt and errors in network_cli so that detected errors
|
||||
are not lost if the prompt is in a later chunk.
|
||||
minor_changes:
|
||||
- Add 'purged' to ACTION_STATES.
|
||||
fragments:
|
||||
- 177_netconf_config_test_issue.yaml
|
||||
- 189_config_diff_fix.yaml
|
||||
- 191_restconf_config_fix.yaml
|
||||
- 198_net_get_missing_changed.yaml
|
||||
- 97_getReplyobject_has_no_attribute_strip_issue.yaml
|
||||
- add_purged_action_state.yaml
|
||||
- error-independently.yaml
|
||||
- netconf_nxos_tests.yaml
|
||||
release_date: "2021-01-27"
|
||||
2.0.0:
|
||||
changes:
|
||||
breaking_changes:
|
||||
- Removed vendored ipaddress package from collection. If you use ansible_collections.ansible.netcommon.plugins.module_utils.compat.ipaddress
|
||||
in your collection, you will need to change this to import ipaddress instead.
|
||||
If your content using ipaddress supports Python 2.7, you will additionally
|
||||
need to make sure that the user has the ipaddress package installed. Please
|
||||
refer to https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_best_practices.html#importing-and-using-shared-code
|
||||
to see how to safely import external packages that may be missing from the
|
||||
user's system A backport of ipaddress for Python 2.7 is available at https://pypi.org/project/ipaddress/
|
||||
bugfixes:
|
||||
- Expose connection class object to rm_template (https://github.com/ansible-collections/ansible.netcommon/pull/180)
|
||||
- network_cli - When using ssh_type libssh, handle closed connection gracefully
|
||||
instead of throwing an exception
|
||||
deprecated_features:
|
||||
- Deprecate cli_parse module and textfsm, ttp, xml, json parser plugins as they
|
||||
are moved to ansible.utils collection (https://github.com/ansible-collections/ansible.netcommon/pull/182
|
||||
https://github.com/ansible-collections/ansible.utils/pull/28)
|
||||
major_changes:
|
||||
- Remove deprecated connection arguments from netconf_config
|
||||
minor_changes:
|
||||
- Add SCP support when using ssh_type libssh
|
||||
- Add `single_user_mode` option for command output caching.
|
||||
- Move cli_config idempotent warning message with the task response under `warnings`
|
||||
key if `changed` is `True`
|
||||
- Reduce CPU usage and network module run time when using `ansible_network_import_modules`
|
||||
- Support any() and all() filters in Jinja2.
|
||||
fragments:
|
||||
- 180_RMbase_engine.yaml
|
||||
- 182-cli_parse_deprecate.yaml
|
||||
- 212-update-documentation.yaml
|
||||
- 213-docs-updates.yaml
|
||||
- 217-pylibssh-conn-closed.yaml
|
||||
- 226-libssh-scp.yaml
|
||||
- 93-remove-ipaddress.yaml
|
||||
- ansible_network_direct_execution.yaml
|
||||
- config_module_warning_msg.yaml
|
||||
- remove-netconf_config-args.yaml
|
||||
- support_caching.yaml
|
||||
- support_custom_filters.yaml
|
||||
- update_requires_ansible.yaml
|
||||
- yamllint.yaml
|
||||
plugins:
|
||||
cache:
|
||||
- description: RAM backed, non persistent cache.
|
||||
name: memory
|
||||
namespace: null
|
||||
release_date: "2021-03-01"
|
||||
2.0.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Allow setting `host_key_checking` through a play/task var for `network_cli`.
|
||||
- Ensure passed-in terminal_initial_prompt and terminal_initial_answer values
|
||||
are cast to bytes before using
|
||||
- Update valid documentation for net_ping module.
|
||||
- ncclient - catch and handle exception to prevent stack trace when running
|
||||
in FIPS mode
|
||||
- net_put - Remove temp file created when file already exist on destination
|
||||
when mode is 'text'.
|
||||
minor_changes:
|
||||
- Several module_utils files were intended to be licensed BSD, but missing a
|
||||
license preamble in the files. The preamble has been added, and all authors
|
||||
for the files have given their assent to the intended license https://github.com/ansible-collections/ansible.netcommon/pull/122
|
||||
fragments:
|
||||
- 100-bugfix-net-ping-docs.yaml
|
||||
- 122-add-license.yaml
|
||||
- 220-initial-prompt-bytes.yaml
|
||||
- 227-remove_tests_sanity_requirements.yml
|
||||
- 231-unit-tests.yaml
|
||||
- 235-fix-net-put-issue.yaml
|
||||
- 240-document-libssh-requirement.yaml
|
||||
- fips-ncclient-import-error.yaml
|
||||
- new_action_state.yaml
|
||||
- no_log_fix.yaml
|
||||
- set_host_key_checking.yaml
|
||||
release_date: "2021-03-30"
|
||||
2.0.2:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Fix cli_parse issue with parsers in utils collection (https://github.com/ansible-collections/ansible.netcommon/pull/270)
|
||||
- Support single_user_mode with Ansible 2.9.
|
||||
fragments:
|
||||
- 254-add_ignore_txt.yml
|
||||
- cli_parse_fix.yaml
|
||||
- single_user_mode.yaml
|
||||
release_date: "2021-04-28"
|
||||
2.1.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Variables in play_context will now be updated for netconf connections on each
|
||||
task run.
|
||||
- fix SCP/SFTP when using network_cli with libssh
|
||||
minor_changes:
|
||||
- Add support for ProxyCommand with netconf connection.
|
||||
fragments:
|
||||
- 259-netconf-play-context.yaml
|
||||
- drop-base-cache.yaml
|
||||
- libssh-get-put.yaml
|
||||
- support_proxycommand_netconf.yaml
|
||||
release_date: "2021-05-17"
|
||||
2.2.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- libssh - Fix fromatting of authenticity error message when not prompting for
|
||||
input (https://github.com/ansible-collections/ansible.netcommon/issues/283)
|
||||
- netconf - Fix connection with ncclient versions < 0.6.10
|
||||
- network_cli - Fix for execution failing when ansible_ssh_password is used
|
||||
to specify password (https://github.com/ansible-collections/ansible.netcommon/issues/288)
|
||||
minor_changes:
|
||||
- Add variable to control ProxyCommand with libssh connection.
|
||||
- "NetworkTemplate and ResouceModule base classes have been moved under module_utils.network.common.rm_base.
|
||||
Stubs have been kept for backwards compatibility. These will be removed after
|
||||
2023-01-01. Please update imports for existing modules that subclass them.
|
||||
The `cli_rm_builder <https://github.com/ansible-network/cli_rm_builder>`_
|
||||
has been updated to use the new imports.
|
||||
|
||||
"
|
||||
fragments:
|
||||
- 257-libssh-proxy-var.yaml
|
||||
- 288-netcli-password.yaml
|
||||
- libssh-auth-msg.yaml
|
||||
- ncclient-sock-arg.yaml
|
||||
- update_rmbase.yaml
|
||||
release_date: "2021-06-23"
|
||||
2.3.0:
|
||||
changes:
|
||||
minor_changes:
|
||||
- Add vlan_expander filter
|
||||
- Persistent connection options (persistent_command_timeout, persistent_log_messages,
|
||||
etc.) have been unified across all persistent connections. New persistent
|
||||
connections may also now get these options by extending the connection_persistent
|
||||
documentation fragment.
|
||||
fragments:
|
||||
- 280-vlan_expander.yaml
|
||||
- 295-connection-tests.yaml
|
||||
- 308-unify-persistent.yaml
|
||||
- fix_integration_test_iosxr_7.0.2.yaml
|
||||
release_date: "2021-07-27"
|
||||
2.4.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- network_cli - Add ability to set options inherited from paramiko/libssh in
|
||||
ansible >= 2.11 (https://github.com/ansible-collections/ansible.netcommon/pull/271).
|
||||
deprecated_features:
|
||||
- network_cli - The paramiko_ssh setting ``look_for_keys`` was set automatically
|
||||
based on the values of the ``password`` and ``private_key_file`` options passed
|
||||
to network_cli. This option can now be set explicitly, and the automatic setting
|
||||
of ``look_for_keys`` will be removed after 2024-01-01 (https://github.com/ansible-collections/ansible.netcommon/pull/271).
|
||||
minor_changes:
|
||||
- Add network_resource plugin to manage and provide single entry point for all
|
||||
resource modules for higher oder roles.
|
||||
fragments:
|
||||
- 271-net-cli-options.yaml
|
||||
- 318-netcli-tests.yaml
|
||||
- backup-without-copy.yaml
|
||||
- disable-look_for_keys-warning.yaml
|
||||
- network_resource-version_added.yaml
|
||||
- network_resource_plugin.yaml
|
||||
modules:
|
||||
- description: Manage resource modules
|
||||
name: network_resource
|
||||
namespace: ""
|
||||
release_date: "2021-08-27"
|
||||
2.5.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- network_cli - Provide clearer error message when a prompt regex fails to compile
|
||||
- network_cli - fix issue when multiple terminal_initial_(prompt|answer) values
|
||||
are given (https://github.com/ansible-collections/ansible.netcommon/issues/331).
|
||||
minor_changes:
|
||||
- Copied the cliconf, httpapi, netconf, and terminal base plugins and NetworkConnectionBase
|
||||
into netcommon. These base plugins may now be imported from netcommmon instead
|
||||
of ansible if a collection depends on netcommon versions newer than this version,
|
||||
allowing features and bugfixes to flow to those collections without upgrading
|
||||
ansible.
|
||||
- Make ansible_network_os as optional param for httpapi connection plugin.
|
||||
- Support removal of non-config lines from running config while taking backup.
|
||||
- "`network_cli` - added new option 'become_errors' to determine how privilege
|
||||
escalation failures are handled."
|
||||
fragments:
|
||||
- 0-copy_ignore_txt.yml
|
||||
- 334-base-plugins.yaml
|
||||
- httpapi_make_ansible_network_os_optional_param.yaml
|
||||
- initial_prompt-bytes-fix.yaml
|
||||
- non_config.yaml
|
||||
- on_become_errors.yaml
|
||||
- prompt-regex.yaml
|
||||
release_date: "2021-12-07"
|
||||
2.5.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Fixed plugins inheriting from netcommon's base plugins (for example httpapi/restconf
|
||||
or netconf/default) so that they can be properly loaded (https://github.com/ansible-collections/ansible.netcommon/issues/356).
|
||||
fragments:
|
||||
- 358-pluginloader.yaml
|
||||
- pre-commit.yaml
|
||||
release_date: "2022-02-09"
|
||||
2.6.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Fix issue with cli_parse native_parser plugin when input is empty (https://github.com/ansible-collections/ansible.netcommon/issues/347).
|
||||
- No activity on the transport's channel was triggering a socket.timeout() after
|
||||
30 secs, even if persistent_command_timeout is set to a higher value. This
|
||||
patch fixes it.
|
||||
minor_changes:
|
||||
- Redirected ipaddr filters to ansible.utils (https://github.com/ansible-collections/ansible.netcommon/pull/359).
|
||||
- httpapi - new parameter retries in send() method limits the number of times
|
||||
a request is retried when a HTTP error that can be worked around is encountered.
|
||||
The default is to retry indefinitely to maintain old behavior, but this default
|
||||
may change in a later breaking release.
|
||||
fragments:
|
||||
- 364-pre-commit-ci.yaml
|
||||
- add_remove_prompt.yaml
|
||||
- bugfix_cli_parse_native_parser.yaml
|
||||
- deprecate_ipaddr_filters.yaml
|
||||
- httpapi-retries.yaml
|
||||
- shell_timeout.yaml
|
||||
release_date: "2022-03-01"
|
||||
2.6.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Fix validate-module sanity test.
|
||||
release_summary: Rereleased 2.6.0 with updated utils dependancy.
|
||||
fragments:
|
||||
- 2.6.0.yaml
|
||||
- fix_sanity.yaml
|
||||
release_date: "2022-03-10"
|
||||
3.0.0:
|
||||
changes:
|
||||
breaking_changes:
|
||||
- httpapi - Change default value of ``import_modules`` option from ``no`` to
|
||||
``yes``
|
||||
- netconf - Change default value of ``import_modules`` option from ``no`` to
|
||||
``yes``
|
||||
- network_cli - Change default value of ``import_modules`` option from ``no``
|
||||
to ``yes``
|
||||
known_issues:
|
||||
- "eos - When using eos modules on Ansible 2.9, tasks will occasionally fail
|
||||
with ``import_modules`` enabled. This can be avoided by setting ``import_modules:
|
||||
no``"
|
||||
major_changes:
|
||||
- cli_parse - this module has been moved to the ansible.utils collection. ``ansible.netcommon.cli_parse``
|
||||
will continue to work to reference the module in its new location, but this
|
||||
redirect will be removed in a future release
|
||||
- "network_cli - Change default value of `ssh_type` option from `paramiko` to
|
||||
`auto`. This value will use libssh if the ansible-pylibssh module is installed,
|
||||
otherwise will fallback to paramiko.
|
||||
|
||||
"
|
||||
fragments:
|
||||
- 364-pre-commit-ci.yaml
|
||||
- 384-cli_parse-move.yaml
|
||||
- 387-change-defaults.yaml
|
||||
- 390-sanity.yaml
|
||||
- 394-change-defaults.yaml
|
||||
- pre-commit-add-docs.yaml
|
||||
- update-linter-config.yaml
|
||||
release_date: "2022-04-26"
|
||||
3.0.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- httpapi - Fix for improperly set hostname in url
|
||||
- libssh - Fix for improperly set hostname in connect
|
||||
- restconf - When non-JSON data is encountered, return the bytes found instead
|
||||
of nothing.
|
||||
fragments:
|
||||
- 412-unit-updates.yaml
|
||||
- 419-prettier.yaml
|
||||
- 428.yaml
|
||||
- 432.yaml
|
||||
- fix-changelog-location.yaml
|
||||
- import_modules-logging.yaml
|
||||
- libssh-tests.yaml
|
||||
- remote_addr.yaml
|
||||
- restconf-not-json.yaml
|
||||
- update-pre-commit.yaml
|
||||
release_date: "2022-05-31"
|
||||
3.1.0:
|
||||
changes:
|
||||
minor_changes:
|
||||
- Add grpc connection plugin support.
|
||||
- Adds a new option `terminal_errors` in network_cli, that determines how terminal
|
||||
setting failures are handled.
|
||||
- libssh - Added `password_prompt` option to override default "password:" prompt
|
||||
used by pylibssh
|
||||
fragments:
|
||||
- add-grpc-connection-plugin.yaml
|
||||
- libssh-password-prompt.yaml
|
||||
- terminal_errors.yaml
|
||||
modules:
|
||||
- description: Fetch configuration/state data from gRPC enabled target hosts.
|
||||
name: grpc_config
|
||||
namespace: ""
|
||||
- description: Fetch configuration/state data from gRPC enabled target hosts.
|
||||
name: grpc_get
|
||||
namespace: ""
|
||||
plugins:
|
||||
connection:
|
||||
- description: Provides a persistent connection using the gRPC protocol
|
||||
name: grpc
|
||||
namespace: null
|
||||
release_date: "2022-08-02"
|
||||
3.1.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Fix a small number of potential use-before-assignment issues.
|
||||
- Fix to set connection plugin options correctly.
|
||||
- libssh - Removed the wording "Tech preview". From version 3.0.0 the default
|
||||
if installed.
|
||||
- libssh - add ssh_args, ssh_common_args, and ssh_extra_args options. These
|
||||
options are exclusively for collecting proxy information from as an alternative
|
||||
to the proxy_command option.
|
||||
fragments:
|
||||
- 441-pre-commit.yaml
|
||||
- 448-set_options.yaml
|
||||
- 451-libssh-remove-tech-preview.yaml
|
||||
- 454-legacy_cleanup.yaml
|
||||
- pylint.yaml
|
||||
release_date: "2022-09-06"
|
||||
3.1.2:
|
||||
changes:
|
||||
bugfixes:
|
||||
- libssh - check for minimum ansible-pylibssh version before using password_prompt
|
||||
option. (https://github.com/ansible-collections/ansible.netcommon/pull/467)
|
||||
fragments:
|
||||
- 2.15-ignores.yaml
|
||||
- libssh_check.yaml
|
||||
release_date: "2022-09-30"
|
||||
3.1.3:
|
||||
changes:
|
||||
release_summary:
|
||||
The v3.1.2 is unavailable on Ansible Automation Hub because
|
||||
a technical issue. Please download and use v3.1.3 from Automation Hub.
|
||||
fragments:
|
||||
- prepare_312.yaml
|
||||
release_date: "2022-10-04"
|
||||
4.0.0:
|
||||
changes:
|
||||
removed_features:
|
||||
- napalm - Removed unused connection plugin.
|
||||
- net_banner - Use <network_os>_banner instead.
|
||||
- net_interface - Use <network_os>_interfaces instead.
|
||||
- net_l2_interface - Use <network_os>_l2_interfaces instead.
|
||||
- net_l3_interface - Use <network_os>_l3_interfaces instead.
|
||||
- net_linkagg - Use <network_os>_lag_interfaces instead.
|
||||
- net_lldp - Use <network_os>_lldp_global instead.
|
||||
- net_lldp_interface - Use <network_os>_lldp_interfaces instead.
|
||||
- net_logging - Use <network_os>_logging_global instead.
|
||||
- net_static_route - Use <network_os>_static_routes instead.
|
||||
- net_system - Use <network_os>_system instead.
|
||||
- net_user - Use <network_os>_user instead.
|
||||
- net_vlan - Use <network_os>_vlans instead.
|
||||
- net_vrf - Use <network_os>_vrf instead.
|
||||
fragments:
|
||||
- 2H22_removal.yaml
|
||||
- license.yaml
|
||||
release_date: "2022-10-13"
|
||||
4.1.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- restconf_get - fix direction of XML deserialization when ``output == 'xml'``
|
||||
minor_changes:
|
||||
- Add implementation for content_templates_parser.
|
||||
fragments:
|
||||
- add_content_template_parser.yaml
|
||||
- fix_wrong_xml_direction.yaml
|
||||
release_date: "2022-11-02"
|
||||
5.0.0:
|
||||
changes:
|
||||
breaking_changes:
|
||||
- NetworkConnectionBase now inherits from PersistentConnectionBase in ansible.utils.
|
||||
As a result, the minimum ansible.utils version has increased to 2.7.0.
|
||||
- NetworkTemplate is no longer importable from ansible_collections.ansible.netcommon.plugins.module_utils.network.common
|
||||
and should now be found at its proper location ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template
|
||||
- ResourceModule is no longer importable from ansible_collections.ansible.netcommon.plugins.module_utils.network.common
|
||||
and should now be found at its proper location ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module
|
||||
- VALID_MASKS, is_masklen, is_netmask, to_bits, to_ipv6_network, to_masklen,
|
||||
to_netmask, and to_subnet are no longer importable from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils
|
||||
and should now be found at their proper location ansible.module_utils.common.network
|
||||
bugfixes:
|
||||
- Cast AnsibleUnsafeText to str in convert_doc_to_ansible_module_kwargs() to
|
||||
keep CSafeLoader happy. This fixes issues with content scaffolding tools.
|
||||
minor_changes:
|
||||
- httpapi - Add option netcommon_httpapi_ciphers to allow overriding default
|
||||
SSL/TLS ciphers. (https://github.com/ansible-collections/ansible.netcommon/pull/494)
|
||||
removed_features:
|
||||
- cli_parse - This plugin was moved to ansible.utils in version 1.0.0, and the
|
||||
redirect to that collection has now been removed.
|
||||
fragments:
|
||||
- 23H1_breaking.yaml
|
||||
- flake8.yaml
|
||||
- netcommon_httpapi_ciphers.yaml
|
||||
- persistentbase.yaml
|
||||
- telnet.yaml
|
||||
release_date: "2023-02-27"
|
||||
5.1.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- httpapi - ``send()`` method no longer applied leftover kwargs to ``open_url()``.
|
||||
Fix applies those arguments as intended (https://github.com/ansible-collections/ansible.netcommon/pull/524).
|
||||
- network_cli - network cli connection avoids traceback when using invalid user
|
||||
- network_cli - when receiving longer responses with libssh, parts of the response
|
||||
were sometimes repeated. The response is now returned as it is received (https://github.com/ansible-collections/community.routeros/issues/132).
|
||||
- network_resource - fix a potential UnboundLocalError if the module fails to
|
||||
import a Resource Module. (https://github.com/ansible-collections/ansible.netcommon/pull/513)
|
||||
- restconf - creation of new resources is no longer erroneously forced to use
|
||||
POST. (https://github.com/ansible-collections/ansible.netcommon/issues/502)
|
||||
minor_changes:
|
||||
- libssh - add ``config_file`` option to specify an alternate SSH config file
|
||||
to use.
|
||||
- parse_cli - add support for multiple matches inside a block by adding new
|
||||
dictionary key to result
|
||||
- telnet - add ``stdout`` and ``stdout_lines`` to module output.
|
||||
- telnet - add support for regexes to ``login_prompt`` and ``password_prompt``.
|
||||
- telnet - apply ``timeout`` to command prompts.
|
||||
fragments:
|
||||
- 530-parse_cli.yaml
|
||||
- httpapi-kwargs.yaml
|
||||
- libssh-repeated-text.yaml
|
||||
- libssh_config_file.yaml
|
||||
- lint.yaml
|
||||
- network_cli_bad_user.yaml
|
||||
- restconf_put.yaml
|
||||
- telnet-refactoring.yml
|
||||
- ule-docs.yaml
|
||||
release_date: "2023-04-03"
|
||||
5.1.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- network_resource - do not append network_os to module names when building
|
||||
supported resources list. This fix is only valid for cases where FACTS_RESOURCE_SUBSETS
|
||||
is undefined.
|
||||
fragments:
|
||||
- resource_manager.yaml
|
||||
release_date: "2023-05-09"
|
||||
5.1.2:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Ensure that all connection plugin options that should be strings are actually
|
||||
strings (https://github.com/ansible-collections/ansible.netcommon/pull/549).
|
||||
fragments:
|
||||
- 549-connection-strings.yml
|
||||
- 550-ansible-lint.yml
|
||||
- gha_release.yaml
|
||||
- line-length.yaml
|
||||
release_date: "2023-07-05"
|
||||
5.1.3:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Vendor telnetlib from cpython (https://github.com/ansible-collections/ansible.netcommon/pull/546)
|
||||
fragments:
|
||||
- telnet.yaml
|
||||
release_date: "2023-07-24"
|
||||
5.2.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Ensure that all connection plugin options that should be strings are actually
|
||||
strings (https://github.com/ansible-collections/ansible.netcommon/pull/549).
|
||||
deprecated_features:
|
||||
- libssh - the ssh_*_args options are now marked that they will be removed after
|
||||
2026-01-01.
|
||||
minor_changes:
|
||||
- Add a new cliconf plugin ``default`` that can be used when no cliconf plugin
|
||||
is found for a given network_os. This plugin only supports ``get()``. (https://github.com/ansible-collections/ansible.netcommon/pull/569)
|
||||
- httpapi - Add additional option ``ca_path``, ``client_cert``, ``client_key``,
|
||||
and ``http_agent`` that are available in open_url but not to httpapi. (https://github.com/ansible-collections/ansible.netcommon/issues/528)
|
||||
- telnet - add crlf option to send CRLF instead of just LF (https://github.com/ansible-collections/ansible.netcommon/pull/440).
|
||||
fragments:
|
||||
- 440-telnet-add-crlf-option.yml
|
||||
- 558-load_provider.yml
|
||||
- default-cliconf.yaml
|
||||
- httpapi_options.yaml
|
||||
- ssh_args.yaml
|
||||
- vlan_extender.yaml
|
||||
plugins:
|
||||
cliconf:
|
||||
- description: General purpose cliconf plugin for new platforms
|
||||
name: default
|
||||
namespace: null
|
||||
release_date: "2023-09-07"
|
||||
5.3.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Fix attribute types from string to str in filter plugins.
|
||||
minor_changes:
|
||||
- Add new module cli_backup that exclusively handles configuration backup.
|
||||
fragments:
|
||||
- cli_backup.yaml
|
||||
- fix_attribute_type.yaml
|
||||
- sanity_ignores.yaml
|
||||
- trivial_lint.yaml
|
||||
release_date: "2023-10-17"
|
||||
6.0.0:
|
||||
changes:
|
||||
major_changes:
|
||||
- Bumping `requires_ansible` to `>=2.14.0`, since previous ansible-core versions
|
||||
are EoL now.
|
||||
release_summary:
|
||||
Starting from this release, the minimum `ansible-core` version
|
||||
this collection requires is `2.14.0`. That last known version compatible with
|
||||
ansible-core<2.14 is `v5.3.0`.
|
||||
fragments:
|
||||
- major_600.yml
|
||||
release_date: "2023-11-30"
|
||||
32
collection/ansible/netcommon/changelogs/config.yaml
Normal file
32
collection/ansible/netcommon/changelogs/config.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
changelog_filename_template: ../CHANGELOG.rst
|
||||
changelog_filename_version_depth: 0
|
||||
changes_file: changelog.yaml
|
||||
changes_format: combined
|
||||
keep_fragments: false
|
||||
mention_ancestor: true
|
||||
new_plugins_after_name: removed_features
|
||||
notesdir: fragments
|
||||
prelude_section_name: release_summary
|
||||
prelude_section_title: Release Summary
|
||||
flatmap: true
|
||||
sections:
|
||||
- - major_changes
|
||||
- Major Changes
|
||||
- - minor_changes
|
||||
- Minor Changes
|
||||
- - breaking_changes
|
||||
- Breaking Changes / Porting Guide
|
||||
- - deprecated_features
|
||||
- Deprecated Features
|
||||
- - removed_features
|
||||
- Removed Features (previously deprecated)
|
||||
- - security_fixes
|
||||
- Security Fixes
|
||||
- - bugfixes
|
||||
- Bugfixes
|
||||
- - known_issues
|
||||
- Known Issues
|
||||
- - doc_changes
|
||||
- Documentation Changes
|
||||
title: Ansible Netcommon Collection
|
||||
trivial_section_name: trivial
|
||||
12
collection/ansible/netcommon/codecov.yml
Normal file
12
collection/ansible/netcommon/codecov.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
codecov:
|
||||
require_ci_to_pass: true
|
||||
comment: false
|
||||
coverage:
|
||||
status:
|
||||
patch: false
|
||||
project:
|
||||
default:
|
||||
threshold: 0.3%
|
||||
fixes:
|
||||
- "source/::"
|
||||
@@ -0,0 +1,149 @@
|
||||
.. _ansible.netcommon.cli_backup_module:
|
||||
|
||||
|
||||
****************************
|
||||
ansible.netcommon.cli_backup
|
||||
****************************
|
||||
|
||||
**Back up device configuration from network devices over network_cli**
|
||||
|
||||
|
||||
Version added: 4.2.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This module provides platform agnostic way of backing up text based configuration from network devices over network_cli connection plugin.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>defaults</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The <em>defaults</em> argument will influence how the running-config is collected from the device. When the value is set to true, the command used to collect the running-config is append with the all keyword. When the value is set to false, the command is issued without the all keyword.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>dir_path</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">path</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option provides the path ending with directory name in which the backup configuration file will be stored. If the directory does not exist it will be first created and the filename is either the value of <code>filename</code> or default filename as described in <code>filename</code> options description. If the path value is not given in that case a <em>backup</em> directory will be created in the current working directory and backup configuration will be copied in <code>filename</code> within <em>backup</em> directory.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>filename</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The filename to be used to store the backup configuration. If the filename is not given it will be generated based on the hostname, current time and date in format defined by <hostname>_config.<current-date>@<current-time></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- This module is supported on ``ansible_network_os`` network platforms. See the :ref:`Network Platform Options <platform_options>` for details.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: configurable backup path
|
||||
ansible.netcommon.cli_backup:
|
||||
filename: backup.cfg
|
||||
dir_path: /home/user
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>backup_path</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>The full path to the backup file</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">/playbooks/ansible/backup/hostname_config.2016-07-16@22:28:34</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Kate Case (@Qalthos)
|
||||
@@ -0,0 +1,268 @@
|
||||
.. _ansible.netcommon.cli_command_module:
|
||||
|
||||
|
||||
*****************************
|
||||
ansible.netcommon.cli_command
|
||||
*****************************
|
||||
|
||||
**Run a cli command on cli-based network devices**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- Sends a command to a network device and returns the result read from the device.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>answer</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The answer to reply with if <em>prompt</em> is matched. The value can be a single answer or a list of answer for multiple prompts. In case the command execution results in multiple prompts the sequence of the prompt and excepted answer should be in same order.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>check_all</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>By default if any one of the prompts mentioned in <code>prompt</code> option is matched it won't check for other prompts. This boolean flag, that when set to <em>True</em> will check for all the prompts mentioned in <code>prompt</code> option in the given order. If the option is set to <em>True</em> all the prompts should be received from remote host if not it will result in timeout.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>command</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The command to send to the remote network device. The resulting output from the command is returned, unless <em>sendonly</em> is set.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>newline</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>no</li>
|
||||
<li><div style="color: blue"><b>yes</b> ←</div></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The boolean value, that when set to false will send <em>answer</em> to the device without a trailing newline.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>prompt</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>A single regex pattern or a sequence of patterns to evaluate the expected prompt from <em>command</em>.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>sendonly</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The boolean value, that when set to true will send <em>command</em> to the device but not wait for a result.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- This module is supported on ``ansible_network_os`` network platforms. See the :ref:`Network Platform Options <platform_options>` for details.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: run show version on remote devices
|
||||
ansible.netcommon.cli_command:
|
||||
command: show version
|
||||
|
||||
- name: run command with json formatted output
|
||||
ansible.netcommon.cli_command:
|
||||
command: show version | json
|
||||
|
||||
- name: run command expecting user confirmation
|
||||
ansible.netcommon.cli_command:
|
||||
command: commit replace
|
||||
prompt: This commit will replace or remove the entire running configuration
|
||||
answer: "yes"
|
||||
|
||||
- name: run command expecting user confirmation
|
||||
ansible.netcommon.cli_command:
|
||||
command: show interface summary
|
||||
prompt: Press any key to continue
|
||||
answer: y
|
||||
newline: false
|
||||
|
||||
- name: run config mode command and handle prompt/answer
|
||||
ansible.netcommon.cli_command:
|
||||
command: "{{ item }}"
|
||||
prompt:
|
||||
- Exit with uncommitted changes
|
||||
answer: y
|
||||
loop:
|
||||
- configure
|
||||
- set system syslog file test any any
|
||||
- exit
|
||||
|
||||
- name: multiple prompt, multiple answer (mandatory check for all prompts)
|
||||
ansible.netcommon.cli_command:
|
||||
command: copy sftp sftp://user@host//user/test.img
|
||||
check_all: true
|
||||
prompt:
|
||||
- Confirm download operation
|
||||
- Password
|
||||
- Do you want to change that to the standby image
|
||||
answer:
|
||||
- y
|
||||
- <password>
|
||||
- y
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>json</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>when the device response is valid JSON</td>
|
||||
<td>
|
||||
<div>A dictionary representing a JSON-formatted response</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">{
|
||||
"architecture": "i386",
|
||||
"bootupTimestamp": 1532649700.56,
|
||||
"modelName": "vEOS",
|
||||
"version": "4.15.9M"
|
||||
[...]
|
||||
}</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stdout</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>when sendonly is false</td>
|
||||
<td>
|
||||
<div>The response from the command</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">Version: VyOS 1.1.7[...]</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Nathaniel Case (@Qalthos)
|
||||
@@ -0,0 +1,418 @@
|
||||
.. _ansible.netcommon.cli_config_module:
|
||||
|
||||
|
||||
****************************
|
||||
ansible.netcommon.cli_config
|
||||
****************************
|
||||
|
||||
**Push text based configuration to network devices over network_cli**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This module provides platform agnostic way of pushing text based configuration to network devices over network_cli connection plugin.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="2">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>backup</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>This argument will cause the module to create a full backup of the current running config from the remote device before any changes are made. If the <code>backup_options</code> value is not given, the backup file is written to the <code>backup</code> folder in the playbook root directory or role root directory, if playbook is part of an ansible role. If the directory does not exist, it is created.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>backup_options</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This is a dict object containing configurable options related to backup file path. The value of this option is read only when <code>backup</code> is set to <em>yes</em>, if <code>backup</code> is set to <em>no</em> this option will be silently ignored.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="elbow-placeholder"></td>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>dir_path</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">path</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option provides the path ending with directory name in which the backup configuration file will be stored. If the directory does not exist it will be first created and the filename is either the value of <code>filename</code> or default filename as described in <code>filename</code> options description. If the path value is not given in that case a <em>backup</em> directory will be created in the current working directory and backup configuration will be copied in <code>filename</code> within <em>backup</em> directory.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="elbow-placeholder"></td>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>filename</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The filename to be used to store the backup configuration. If the filename is not given it will be generated based on the hostname, current time and date in format defined by <hostname>_config.<current-date>@<current-time></div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>commit</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>no</li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The <code>commit</code> argument instructs the module to push the configuration to the device. This is mapped to module check mode.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>commit_comment</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The <code>commit_comment</code> argument specifies a text string to be used when committing the configuration. If the <code>commit</code> argument is set to False, this argument is silently ignored. This argument is only valid for the platforms that support commit operation with comment.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>config</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The config to be pushed to the network device. This argument is mutually exclusive with <code>rollback</code> and either one of the option should be given as input. To ensure idempotency and correct diff the configuration lines should be similar to how they appear if present in the running configuration on device including the indentation.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>defaults</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The <em>defaults</em> argument will influence how the running-config is collected from the device. When the value is set to true, the command used to collect the running-config is append with the all keyword. When the value is set to false, the command is issued without the all keyword.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>diff_ignore_lines</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Use this argument to specify one or more lines that should be ignored during the diff. This is used for lines in the configuration that are automatically updated by the system. This argument takes a list of regular expressions or exact line matches. Note that this parameter will be ignored if the platform has onbox diff support.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>diff_match</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>line</li>
|
||||
<li>strict</li>
|
||||
<li>exact</li>
|
||||
<li>none</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Instructs the module on the way to perform the matching of the set of commands against the current device config. If <code>diff_match</code> is set to <em>line</em>, commands are matched line by line. If <code>diff_match</code> is set to <em>strict</em>, command lines are matched with respect to position. If <code>diff_match</code> is set to <em>exact</em>, command lines must be an equal match. Finally, if <code>diff_match</code> is set to <em>none</em>, the module will not attempt to compare the source configuration with the running configuration on the remote device. Note that this parameter will be ignored if the platform has onbox diff support.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>diff_replace</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>line</li>
|
||||
<li>block</li>
|
||||
<li>config</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Instructs the module on the way to perform the configuration on the device. If the <code>diff_replace</code> argument is set to <em>line</em> then the modified lines are pushed to the device in configuration mode. If the argument is set to <em>block</em> then the entire command block is pushed to the device in configuration mode if any line is not correct. Note that this parameter will be ignored if the platform has onbox diff support.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>multiline_delimiter</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This argument is used when pushing a multiline configuration element to the device. It specifies the character to use as the delimiting character. This only applies to the configuration action.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>replace</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>If the <code>replace</code> argument is set to <code>yes</code>, it will replace the entire running-config of the device with the <code>config</code> argument value. For devices that support replacing running configuration from file on device like NXOS/JUNOS, the <code>replace</code> argument takes path to the file on the device that will be used for replacing the entire running-config. The value of <code>config</code> option should be <em>None</em> for such devices. Nexus 9K devices only support replace. Use <em>net_put</em> or <em>nxos_file_copy</em> in case of NXOS module to copy the flat file to remote device and then use set the fullpath to this argument.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>rollback</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The <code>rollback</code> argument instructs the module to rollback the current configuration to the identifier specified in the argument. If the specified rollback identifier does not exist on the remote device, the module will fail. To rollback to the most recent commit, set the <code>rollback</code> argument to 0. This option is mutually exclusive with <code>config</code>.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- The commands will be returned only for platforms that do not support onbox diff. The ``--diff`` option with the playbook will return the difference in configuration for devices that has support for onbox diff
|
||||
- To ensure idempotency and correct diff the configuration lines in the relevant module options should be similar to how they appear if present in the running configuration on device including the indentation.
|
||||
- This module is supported on ``ansible_network_os`` network platforms. See the :ref:`Network Platform Options <platform_options>` for details.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: configure device with config
|
||||
ansible.netcommon.cli_config:
|
||||
config: "{{ lookup('template', 'basic/config.j2') }}"
|
||||
|
||||
- name: multiline config
|
||||
ansible.netcommon.cli_config:
|
||||
config: |
|
||||
hostname foo
|
||||
feature nxapi
|
||||
|
||||
- name: configure device with config with defaults enabled
|
||||
ansible.netcommon.cli_config:
|
||||
config: "{{ lookup('template', 'basic/config.j2') }}"
|
||||
defaults: "yes"
|
||||
|
||||
- name: Use diff_match
|
||||
ansible.netcommon.cli_config:
|
||||
config: "{{ lookup('file', 'interface_config') }}"
|
||||
diff_match: none
|
||||
|
||||
- name: nxos replace config
|
||||
ansible.netcommon.cli_config:
|
||||
replace: bootflash:nxoscfg
|
||||
|
||||
- name: junos replace config
|
||||
ansible.netcommon.cli_config:
|
||||
replace: /var/home/ansible/junos01.cfg
|
||||
|
||||
- name: commit with comment
|
||||
ansible.netcommon.cli_config:
|
||||
config: set system host-name foo
|
||||
commit_comment: this is a test
|
||||
|
||||
- name: configurable backup path
|
||||
ansible.netcommon.cli_config:
|
||||
config: "{{ lookup('template', 'basic/config.j2') }}"
|
||||
backup: "yes"
|
||||
backup_options:
|
||||
filename: backup.cfg
|
||||
dir_path: /home/user
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>backup_path</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>when backup is yes</td>
|
||||
<td>
|
||||
<div>The full path to the backup file</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">/playbooks/ansible/backup/hostname_config.2016-07-16@22:28:34</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>commands</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>When <em>supports_generated_diff=True</em> and <em>supports_onbox_diff=False</em> in the platform's cliconf plugin</td>
|
||||
<td>
|
||||
<div>The set of commands that will be pushed to the remote device</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">['interface Loopback999', 'no shutdown']</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>diff</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>When <em>supports_onbox_diff=True</em> in the platform's cliconf plugin</td>
|
||||
<td>
|
||||
<div>The diff generated on the device when the commands were applied</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">--- system:/running-config
|
||||
+++ session:/ansible_1599745461-session-config
|
||||
@@ -4,7 +4,7 @@
|
||||
!
|
||||
transceiver qsfp default-mode 4x10G
|
||||
!
|
||||
-hostname veos
|
||||
+hostname veos3
|
||||
!
|
||||
spanning-tree mode mstp</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Trishna Guha (@trishnaguha)
|
||||
@@ -0,0 +1,152 @@
|
||||
.. _ansible.netcommon.comp_type5_filter:
|
||||
|
||||
|
||||
****************************
|
||||
ansible.netcommon.comp_type5
|
||||
****************************
|
||||
|
||||
**The comp_type5 filter plugin.**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- The filter confirms configuration idempotency on use of type5_pw.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>encrypted_password</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The encrypted text.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>return_original</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>no</li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Return the original text.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>unencrypted_password</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The unencrypted text.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- The filter confirms configuration idempotency on use of type5_pw.
|
||||
- Can be used to validate password post hashing username cisco secret 5 {{ ansible_ssh_pass | ansible.netcommon.comp_type5(encrypted, True) }}
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Using comp_type5
|
||||
|
||||
# playbook
|
||||
|
||||
- name: Set the facts
|
||||
ansible.builtin.set_fact:
|
||||
unencrypted_password: "cisco@123"
|
||||
encrypted_password: "$1$avs$uSTOEMh65ADDBREAKqzvpb9yBMpzd/"
|
||||
|
||||
- name: Invoke comp_type5
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ unencrypted_password | ansible.netcommon.comp_type5(encrypted_password, False) }}"
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Set the facts]
|
||||
# ok: [35.155.113.92] => changed=false
|
||||
# ansible_facts:
|
||||
# encrypted_password: $1$avs$uSTOEMh65ADDBREAKqzvpb9yBMpzd/
|
||||
# unencrypted_password: cisco@123
|
||||
|
||||
# TASK [Invoke comp_type5]
|
||||
# ok: [35.155.113.92] =>
|
||||
# msg: true
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ken Celenza (@itdependsnetworks)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,43 @@
|
||||
.. _ansible.netcommon.default_cliconf:
|
||||
|
||||
|
||||
*************************
|
||||
ansible.netcommon.default
|
||||
*************************
|
||||
|
||||
**General purpose cliconf plugin for new platforms**
|
||||
|
||||
|
||||
Version added: 5.2.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This plugin attemts to provide low level abstraction apis for sending and receiving CLI commands from arbitrary network devices.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,76 @@
|
||||
.. _ansible.netcommon.default_netconf:
|
||||
|
||||
|
||||
*************************
|
||||
ansible.netcommon.default
|
||||
*************************
|
||||
|
||||
**Use default netconf plugin to run standard netconf commands as per RFC**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This default plugin provides low level abstraction apis for sending and receiving netconf commands as per Netconf RFC specification.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>ncclient_device_handler</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"default"</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the ncclient device handler name for network os that support default netconf implementation as per Netconf RFC specification. To identify the ncclient device handler name refer ncclient library documentation.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,90 @@
|
||||
.. _ansible.netcommon.enable_become:
|
||||
|
||||
|
||||
************************
|
||||
ansible.netcommon.enable
|
||||
************************
|
||||
|
||||
**Switch to elevated permissions on a network device**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This become plugins allows elevated permissions on a remote network device.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>become_pass</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[enable_become_plugin]<br>password = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_BECOME_PASS</div>
|
||||
<div>env:ANSIBLE_ENABLE_PASS</div>
|
||||
<div>var: ansible_become_password</div>
|
||||
<div>var: ansible_become_pass</div>
|
||||
<div>var: ansible_enable_pass</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>password</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- enable is really implemented in the network connection handler and as such can only be used with network connections.
|
||||
- This plugin ignores the 'become_exe' and 'become_user' settings as it uses an API and not an executable.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,285 @@
|
||||
.. _ansible.netcommon.grpc_config_module:
|
||||
|
||||
|
||||
*****************************
|
||||
ansible.netcommon.grpc_config
|
||||
*****************************
|
||||
|
||||
**Fetch configuration/state data from gRPC enabled target hosts.**
|
||||
|
||||
|
||||
Version added: 3.1.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- gRPC is a high performance, open-source universal RPC framework.
|
||||
- This module allows the user to append configs to an existing configuration in a gRPC enabled devices.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The below requirements are needed on the host that executes this module.
|
||||
|
||||
- grpcio
|
||||
- protobuf
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="2">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>backup</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>This argument will cause the module to create a full backup of the current <code>running-config</code> from the remote device before any changes are made. If the <code>backup_options</code> value is not given, the backup file is written to the <code>backup</code> folder in the playbook root directory or role root directory, if playbook is part of an ansible role. If the directory does not exist, it is created.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>backup_options</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This is a dict object containing configurable options related to backup file path. The value of this option is read only when <code>backup</code> is set to <em>yes</em>, if <code>backup</code> is set to <em>no</em> this option will be silently ignored.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="elbow-placeholder"></td>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>dir_path</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">path</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option provides the path ending with directory name in which the backup configuration file will be stored. If the directory does not exist it will be first created and the filename is either the value of <code>filename</code> or default filename as described in <code>filename</code> options description. If the path value is not given in that case a <em>backup</em> directory will be created in the current working directory and backup configuration will be copied in <code>filename</code> within <em>backup</em> directory.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="elbow-placeholder"></td>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>filename</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The filename to be used to store the backup configuration. If the filename is not given it will be generated based on the hostname, current time and date in format defined by <hostname>_config.<current-date>@<current-time></div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>config</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option specifies the string which acts as a filter to restrict the portions of the data to be retrieved from the target host device. If this option is not specified the entire configuration or state data is returned in response provided it is supported by target host.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>state</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>action to be performed</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- This module requires the gRPC system service be enabled on the target host being managed.
|
||||
- This module supports the use of connection=connection=ansible.netcommon.grpc
|
||||
- This module requires the value of 'ansible_network_os' or 'grpc_type' configuration option (refer ansible.netcommon.grpc connection plugin documentation) be defined as an inventory variable.
|
||||
- Tested against iosxrv 9k version 6.1.2.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: Merge static route config
|
||||
ansible.netcommon.grpc_config:
|
||||
config:
|
||||
Cisco-IOS-XR-ip-static-cfg:router-static:
|
||||
default-vrf:
|
||||
address-family:
|
||||
vrfipv4:
|
||||
vrf-unicast:
|
||||
vrf-prefixes:
|
||||
vrf-prefix:
|
||||
- prefix: "1.2.3.6"
|
||||
prefix-length: 32
|
||||
vrf-route:
|
||||
vrf-next-hop-table:
|
||||
vrf-next-hop-next-hop-address:
|
||||
- next-hop-address: "10.0.2.2"
|
||||
state: merged
|
||||
|
||||
- name: Merge bgp config
|
||||
ansible.netcommon.grpc_config:
|
||||
config: "{{ lookup('file', 'bgp.json') }}"
|
||||
state: merged
|
||||
|
||||
- name: Find diff
|
||||
diff: true
|
||||
ansible.netcommon.grpc_config:
|
||||
config: "{{ lookup('file', 'bgp_start.yml') }}"
|
||||
state: merged
|
||||
|
||||
- name: Backup running config
|
||||
ansible.netcommon.grpc_config:
|
||||
backup: true
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>backup_path</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>when backup is yes</td>
|
||||
<td>
|
||||
<div>The full path to the backup file</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">/playbooks/ansible/backup/config.2022-07-16@22:28:34</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>diff</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>when diff is enabled</td>
|
||||
<td>
|
||||
<div>If --diff option in enabled while running, the before and after configuration change are returned as part of before and after key.</div>
|
||||
<br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stdout</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>error mesage, when failure happens. empty , when the operation is successful</td>
|
||||
<td>
|
||||
<div>The raw string containing response object received from the gRPC server.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">...</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stdout_lines</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always apart from low-level errors (such as action plugin)</td>
|
||||
<td>
|
||||
<div>The value of stdout split into a list</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">['...', '...']</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Gomathi Selvi S (@GomathiselviS)
|
||||
@@ -0,0 +1,371 @@
|
||||
.. _ansible.netcommon.grpc_connection:
|
||||
|
||||
|
||||
**********************
|
||||
ansible.netcommon.grpc
|
||||
**********************
|
||||
|
||||
**Provides a persistent connection using the gRPC protocol**
|
||||
|
||||
|
||||
Version added: 3.1.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This connection plugin provides a connection to remote devices over gRPC and is typically used with devices for sending and receiving RPC calls over gRPC framework.
|
||||
- Note this connection plugin requires the grpcio python library to be installed on the local Ansible controller.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The below requirements are needed on the local Ansible controller node that executes this connection.
|
||||
|
||||
- grpcio
|
||||
- protobuf
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>certificate_chain_file</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[grpc_connection]<br>certificate_chain_file = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_CERTIFICATE_CHAIN_FILE</div>
|
||||
<div>var: ansible_certificate_chain_file</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The PEM encoded certificate chain file used to create a SSL-enabled channel. If the value is None, no certificate chain is used.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>grpc_type</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[grpc_connection]<br>type = no</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_GRPC_CONNECTION_TYPE</div>
|
||||
<div>var: ansible_grpc_connection_type</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option indicates the grpc type and it can be used in place of network_os. (example cisco.iosxr.iosxr)</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>host</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"inventory_hostname"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_host</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the remote device FQDN or IP address to establish the gRPC connection to.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>import_modules</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[ansible_network]<br>import_modules = yes</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_NETWORK_IMPORT_MODULES</div>
|
||||
<div>var: ansible_network_import_modules</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Reduce CPU usage and network module execution time by enabling direct execution. Instead of the module being packaged and executed by the shell, it will be directly executed by the Ansible control node using the same python interpreter as the Ansible process. Note- Incompatible with <code>asynchronous mode</code>. Note- Python 3 and Ansible 2.9.16 or greater required. Note- With Ansible 2.9.x fully qualified modules names are required in tasks.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>network_os</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_network_os</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures the device platform network operating system. This value is used to load a device specific grpc plugin to communicate with the remote device.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>password</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_password</div>
|
||||
<div>var: ansible_ssh_pass</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures the user password used to authenticate to the remote device when first establishing the gRPC connection.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_command_timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">30</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>command_timeout = 30</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_COMMAND_TIMEOUT</div>
|
||||
<div>var: ansible_command_timeout</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures, in seconds, the amount of time to wait for a command to return from the remote device. If this timer is exceeded before the command returns, the connection plugin will raise an exception and close.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_connect_timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">30</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>connect_timeout = 30</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_CONNECT_TIMEOUT</div>
|
||||
<div>var: ansible_connect_timeout</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures, in seconds, the amount of time to wait when trying to initially establish a persistent connection. If this value expires before the connection to the remote device is completed, the connection will fail.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_log_messages</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>log_messages = no</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_LOG_MESSAGES</div>
|
||||
<div>var: ansible_persistent_log_messages</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This flag will enable logging the command executed and response received from target device in the ansible log file. For this option to work 'log_path' ansible configuration option is required to be set to a file path with write access.</div>
|
||||
<div>Be sure to fully understand the security implications of enabling this option as it could create a security vulnerability by logging sensitive information in log file.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>port</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>remote_port = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_REMOTE_PORT</div>
|
||||
<div>var: ansible_port</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the port on the remote device that listens for connections when establishing the gRPC connection. If None only the <code>host</code> part will be used.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>private_key_file</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[grpc_connection]<br>private_key_file = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PRIVATE_KEY_FILE</div>
|
||||
<div>var: ansible_private_key_file</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The PEM encoded private key file used to authenticate to the remote device when first establishing the grpc connection.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>remote_user</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>remote_user = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_REMOTE_USER</div>
|
||||
<div>var: ansible_user</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The username used to authenticate to the remote device when the gRPC connection is first established. If the remote_user is not specified, the connection will use the username of the logged in user.</div>
|
||||
<div>Can be configured from the CLI via the <code>--user</code> or <code>-u</code> options.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>root_certificates_file</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[grpc_connection]<br>root_certificates_file = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_ROOT_CERTIFICATES_FILE</div>
|
||||
<div>var: ansible_root_certificates_file</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The PEM encoded root certificate file used to create a SSL-enabled channel, if the value is None it reads the root certificates from a default location chosen by gRPC at runtime.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>ssl_target_name_override</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[grpc_connection]<br>ssl_target_name_override = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_GPRC_SSL_TARGET_NAME_OVERRIDE</div>
|
||||
<div>var: ansible_grpc_ssl_target_name_override</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The option overrides SSL target name used for SSL host name checking. The name used for SSL host name checking will be the target parameter (assuming that the secure channel is an SSL channel). If this parameter is specified and the underlying is not an SSL channel, it will just be ignored.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,241 @@
|
||||
.. _ansible.netcommon.grpc_get_module:
|
||||
|
||||
|
||||
**************************
|
||||
ansible.netcommon.grpc_get
|
||||
**************************
|
||||
|
||||
**Fetch configuration/state data from gRPC enabled target hosts.**
|
||||
|
||||
|
||||
Version added: 3.1.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- gRPC is a high performance, open-source universal RPC framework.
|
||||
- This module allows the user to fetch configuration and state data from gRPC enabled devices.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The below requirements are needed on the host that executes this module.
|
||||
|
||||
- grpcio
|
||||
- protobuf
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>command</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The option specifies the command to be executed on the target host and return the response in result. This option is supported if the gRPC target host supports executing CLI command over the gRPC connection.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>data_type</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The type of data that should be fetched from the target host. The value depends on the capability of the gRPC server running on target host. The values can be <em>config</em>, <em>oper</em> etc. based on what is supported by the gRPC server. By default it will return both configuration and operational state data in response.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>display</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Encoding scheme to use when serializing output from the device. The encoding scheme value depends on the capability of the gRPC server running on the target host. The values can be <em>json</em>, <em>text</em> etc.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>section</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option specifies the string which acts as a filter to restrict the portions of the data to be retrieved from the target host device. If this option is not specified the entire configuration or state data is returned in response provided it is supported by target host.</div>
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: filter</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- This module requires the gRPC system service be enabled on the target host being managed.
|
||||
- This module supports the use of connection=ansible.netcommon.grpc.
|
||||
- This module requires the value of 'ansible_network_os or grpc_type' configuration option (refer ansible.netcommon.grpc connection plugin documentation) be defined as an inventory variable.
|
||||
- Tested against iosxrv 9k version 6.1.2.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: Get bgp configuration data
|
||||
grpc_get:
|
||||
section:
|
||||
Cisco-IOS-XR-ip-static-cfg:router-static:
|
||||
- null
|
||||
- name: run cli command
|
||||
grpc_get:
|
||||
command: "show version"
|
||||
display: text
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>output</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>when the device response is valid JSON</td>
|
||||
<td>
|
||||
<div>A dictionary representing a JSON-formatted response, if the response is a valid json string</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">[{
|
||||
"Cisco-IOS-XR-ip-static-cfg:router-static": {
|
||||
"default-vrf": {
|
||||
"address-family": {
|
||||
"vrfipv4": {
|
||||
"vrf-unicast": {
|
||||
"vrf-prefixes": {
|
||||
"vrf-prefix": [
|
||||
{
|
||||
"prefix": "0.0.0.0",
|
||||
"prefix-length": 0,
|
||||
"vrf-route": {
|
||||
"vrf-next-hop-table": {
|
||||
"vrf-next-hop-interface-name-next-hop-address": [
|
||||
{
|
||||
"interface-name": "MgmtEth0/RP0/CPU0/0",
|
||||
"next-hop-address": "10.0.2.2"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stdout</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always apart from low-level errors (such as action plugin)</td>
|
||||
<td>
|
||||
<div>The raw string containing configuration or state data received from the gRPC server.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">...</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stdout_lines</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always apart from low-level errors (such as action plugin)</td>
|
||||
<td>
|
||||
<div>The value of stdout split into a list</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">['...', '...']</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ganesh Nalawade (@ganeshrn)
|
||||
- Gomathi Selvi S (@GomathiselviS)
|
||||
@@ -0,0 +1,113 @@
|
||||
.. _ansible.netcommon.hash_salt_filter:
|
||||
|
||||
|
||||
***************************
|
||||
ansible.netcommon.hash_salt
|
||||
***************************
|
||||
|
||||
**The hash_salt filter plugin.**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- The filter plugin produces the salt from a hashed password.
|
||||
- Using the parameters below - ``password | ansible.netcommon.hash_salt(template.yml``)
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>password</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This source data on which hash_salt invokes.</div>
|
||||
<div>For example <code>password | ansible.netcommon.hash_salt</code>, in this case <code>password</code> represents the hashed password.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- The filter plugin produces the salt from a hashed password.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Using hash_salt
|
||||
|
||||
# playbook
|
||||
|
||||
- name: Set the facts
|
||||
ansible.builtin.set_fact:
|
||||
password: "$1$avs$uSTOEMh65ADDBREAKqzvpb9yBMpzd/"
|
||||
|
||||
- name: Invoke hash_salt
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ password | ansible.netcommon.hash_salt() }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Set the facts]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# password: $1$avs$uSTOEMh65ADDBREAKqzvpb9yBMpzd/
|
||||
|
||||
# TASK [Invoke hash_salt]
|
||||
# ok: [host] =>
|
||||
# msg: avs
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ken Celenza (@itdependsnetworks)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,498 @@
|
||||
.. _ansible.netcommon.httpapi_connection:
|
||||
|
||||
|
||||
*************************
|
||||
ansible.netcommon.httpapi
|
||||
*************************
|
||||
|
||||
**Use httpapi to run command on network appliances**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This connection plugin provides a connection to remote devices over a HTTP(S)-based api.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>become</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[privilege_escalation]<br>become = no</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_BECOME</div>
|
||||
<div>var: ansible_become</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The become option will instruct the CLI session to attempt privilege escalation on platforms that support it. Normally this means transitioning from user mode to <code>enable</code> mode in the CLI session. If become is set to True and the remote device does not support privilege escalation or the privilege has already been elevated, then this option is silently ignored.</div>
|
||||
<div>Can be configured from the CLI via the <code>--become</code> or <code>-b</code> options.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>become_method</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"sudo"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[privilege_escalation]<br>become_method = sudo</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_BECOME_METHOD</div>
|
||||
<div>var: ansible_become_method</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option allows the become method to be specified in for handling privilege escalation. Typically the become_method value is set to <code>enable</code> but could be defined as other values.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>ca_path</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">path</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 5.2.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_httpapi_ca_path</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Path to CA cert bundle to use.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>ciphers</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=string</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 5.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_httpapi_ciphers</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>SSL/TLS Ciphers to use for requests</div>
|
||||
<div>When a list is provided, all ciphers are joined in order with <code>:</code></div>
|
||||
<div>See the <a href='https://www.openssl.org/docs/manmaster/man1/openssl-ciphers.html#CIPHER-LIST-FORMAT'>OpenSSL Cipher List Format</a> for more details.</div>
|
||||
<div>The available ciphers is dependent on the Python and OpenSSL/LibreSSL versions.</div>
|
||||
<div>This option will have no effect on ansible-core<2.14 but a warning will be emitted.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>client_cert</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 5.2.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_httpapi_client_cert</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>PEM formatted certificate chain file to be used for SSL client authentication. This file can also include the key as well, and if the key is included, <em>client_key</em> is not required</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>client_key</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 5.2.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_httpapi_client_key</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>PEM formatted file that contains the private key to be used for SSL client authentication. If <em>client_cert</em> contains both the certificate and key, this option is not required.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>host</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"inventory_hostname"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: inventory_hostname</div>
|
||||
<div>var: ansible_host</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the remote device FQDN or IP address to establish the HTTP(S) connection to.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>http_agent</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 5.2.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_httpapi_http_agent</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>User-Agent to use in the request.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>import_modules</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[ansible_network]<br>import_modules = yes</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_NETWORK_IMPORT_MODULES</div>
|
||||
<div>var: ansible_network_import_modules</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Reduce CPU usage and network module execution time by enabling direct execution. Instead of the module being packaged and executed by the shell, it will be directly executed by the Ansible control node using the same python interpreter as the Ansible process. Note- Incompatible with <code>asynchronous mode</code>. Note- Python 3 and Ansible 2.9.16 or greater required. Note- With Ansible 2.9.x fully qualified modules names are required in tasks.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>network_os</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_network_os</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures the device platform network operating system. This value is used to load the correct httpapi plugin to communicate with the remote device</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>password</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_password</div>
|
||||
<div>var: ansible_httpapi_pass</div>
|
||||
<div>var: ansible_httpapi_password</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures the user password used to authenticate to the remote device when needed for the device API.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_command_timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">30</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>command_timeout = 30</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_COMMAND_TIMEOUT</div>
|
||||
<div>var: ansible_command_timeout</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures, in seconds, the amount of time to wait for a command to return from the remote device. If this timer is exceeded before the command returns, the connection plugin will raise an exception and close.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_connect_timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">30</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>connect_timeout = 30</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_CONNECT_TIMEOUT</div>
|
||||
<div>var: ansible_connect_timeout</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures, in seconds, the amount of time to wait when trying to initially establish a persistent connection. If this value expires before the connection to the remote device is completed, the connection will fail.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_log_messages</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>log_messages = no</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_LOG_MESSAGES</div>
|
||||
<div>var: ansible_persistent_log_messages</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This flag will enable logging the command executed and response received from target device in the ansible log file. For this option to work 'log_path' ansible configuration option is required to be set to a file path with write access.</div>
|
||||
<div>Be sure to fully understand the security implications of enabling this option as it could create a security vulnerability by logging sensitive information in log file.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>platform_type</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>env:ANSIBLE_PLATFORM_TYPE</div>
|
||||
<div>var: ansible_platform_type</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Set type of platform.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>port</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>remote_port = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_REMOTE_PORT</div>
|
||||
<div>var: ansible_httpapi_port</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the port on the remote device that listens for connections when establishing the HTTP(S) connection.</div>
|
||||
<div>When unspecified, will pick 80 or 443 based on the value of use_ssl.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>remote_user</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>remote_user = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_REMOTE_USER</div>
|
||||
<div>var: ansible_user</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The username used to authenticate to the remote device when the API connection is first established. If the remote_user is not specified, the connection will use the username of the logged in user.</div>
|
||||
<div>Can be configured from the CLI via the <code>--user</code> or <code>-u</code> options.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>session_key</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_httpapi_session_key</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures the session key to be used to authenticate to the remote device when needed for the device API.</div>
|
||||
<div>This should contain a dictionary representing the key name and value for the token.</div>
|
||||
<div>When specified, <em>password</em> is ignored.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>use_proxy</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_httpapi_use_proxy</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Whether to use https_proxy for requests.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>use_ssl</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_httpapi_use_ssl</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Whether to connect using SSL (HTTPS) or not (HTTP).</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>validate_certs</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_httpapi_validate_certs</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Whether to validate SSL certificates</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,390 @@
|
||||
.. _ansible.netcommon.libssh_connection:
|
||||
|
||||
|
||||
************************
|
||||
ansible.netcommon.libssh
|
||||
************************
|
||||
|
||||
**Run tasks using libssh for ssh connection**
|
||||
|
||||
|
||||
Version added: 1.1.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- Use the ansible-pylibssh python bindings to connect to targets
|
||||
- The python bindings use libssh C library (https://www.libssh.org/) to connect to targets
|
||||
- This plugin borrows a lot of settings from the ssh plugin as they both cover the same protocol.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>config_file</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">path</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 5.1.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[libssh_connection]<br>config_file = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_LIBSSH_CONFIG_FILE</div>
|
||||
<div>var: ansible_libssh_config_file</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Alternate SSH config file location</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>host_key_auto_add</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[libssh_connection]<br>host_key_auto_add = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_LIBSSH_HOST_KEY_AUTO_ADD</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>TODO: write it</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>host_key_checking</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>host_key_checking = yes</p>
|
||||
<p>[libssh_connection]<br>host_key_checking = yes</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_HOST_KEY_CHECKING</div>
|
||||
<div>env:ANSIBLE_SSH_HOST_KEY_CHECKING</div>
|
||||
<div>env:ANSIBLE_LIBSSH_HOST_KEY_CHECKING</div>
|
||||
<div>var: ansible_host_key_checking</div>
|
||||
<div>var: ansible_ssh_host_key_checking</div>
|
||||
<div>var: ansible_libssh_host_key_checking</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Set this to "False" if you want to avoid host key checking by the underlying tools Ansible uses to connect to the host</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>look_for_keys</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[libssh_connection]<br>look_for_keys = yes</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_LIBSSH_LOOK_FOR_KEYS</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>TODO: write it</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>password</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_password</div>
|
||||
<div>var: ansible_ssh_pass</div>
|
||||
<div>var: ansible_ssh_password</div>
|
||||
<div>var: ansible_libssh_pass</div>
|
||||
<div>var: ansible_libssh_password</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Secret used to either login the ssh server or as a passphrase for ssh keys that require it</div>
|
||||
<div>Can be set from the CLI via the <code>--ask-pass</code> option.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>password_prompt</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.1.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_libssh_password_prompt</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Text to match when using keyboard-interactive authentication to determine if the prompt is for the password.</div>
|
||||
<div>Requires ansible-pylibssh version >= 1.0.0</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>proxy_command</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">""</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[libssh_connection]<br>proxy_command = </p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_LIBSSH_PROXY_COMMAND</div>
|
||||
<div>var: ansible_paramiko_proxy_command</div>
|
||||
<div>var: ansible_libssh_proxy_command</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Proxy information for running the connection via a jumphost.</div>
|
||||
<div>Also this plugin will scan 'ssh_args', 'ssh_extra_args' and 'ssh_common_args' from the 'ssh' plugin settings for proxy information if set.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>pty</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[libssh_connection]<br>pty = yes</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_LIBSSH_PTY</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>TODO: write it</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>remote_addr</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"inventory_hostname"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: inventory_hostname</div>
|
||||
<div>var: ansible_host</div>
|
||||
<div>var: ansible_ssh_host</div>
|
||||
<div>var: ansible_libssh_host</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Address of the remote target</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>remote_user</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>remote_user = VALUE</p>
|
||||
<p>[libssh_connection]<br>remote_user = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_REMOTE_USER</div>
|
||||
<div>env:ANSIBLE_LIBSSH_REMOTE_USER</div>
|
||||
<div>var: ansible_user</div>
|
||||
<div>var: ansible_ssh_user</div>
|
||||
<div>var: ansible_libssh_user</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>User to login/authenticate as</div>
|
||||
<div>Can be set from the CLI via the <code>--user</code> or <code>-u</code> options.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>ssh_args</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.2.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[ssh_connection]<br>ssh_args = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_SSH_ARGS</div>
|
||||
<div>var: ansible_ssh_args</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Arguments to pass to all ssh CLI tools.</div>
|
||||
<div>ProxyCommand is the only supported argument.</div>
|
||||
<div>This option is deprecated in favor of <em>proxy_command</em> and will be removed in a release after 2026-01-01.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>ssh_common_args</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.2.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[ssh_connection]<br>ssh_common_args = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_SSH_COMMON_ARGS</div>
|
||||
<div>var: ansible_ssh_common_args</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Common extra arguments for all ssh CLI tools.</div>
|
||||
<div>ProxyCommand is the only supported argument.</div>
|
||||
<div>This option is deprecated in favor of <em>proxy_command</em> and will be removed in a release after 2026-01-01.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>ssh_extra_args</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.2.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[ssh_connection]<br>ssh_extra_args = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_SSH_EXTRA_ARGS</div>
|
||||
<div>var: ansible_ssh_extra_args</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Extra arguments exclusive to the 'ssh' CLI tool.</div>
|
||||
<div>ProxyCommand is the only supported argument.</div>
|
||||
<div>This option is deprecated in favor of <em>proxy_command</em> and will be removed in a release after 2026-01-01.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>use_persistent_connections</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>use_persistent_connections = no</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_USE_PERSISTENT_CONNECTIONS</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Toggles the use of persistence for connections</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,132 @@
|
||||
.. _ansible.netcommon.net_get_module:
|
||||
|
||||
|
||||
*************************
|
||||
ansible.netcommon.net_get
|
||||
*************************
|
||||
|
||||
**Copy a file from a network device to Ansible Controller**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This module provides functionality to copy file from network device to ansible controller.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The below requirements are needed on the host that executes this module.
|
||||
|
||||
- scp if using protocol=scp with paramiko
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>dest</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">["Same filename as specified in I(src). The path will be playbook root or role root directory if playbook is part of a role."]</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the destination file. The path to the destination file can either be the full path on the Ansible control host or a relative path from the playbook or role root directory.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>protocol</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>scp</b> ←</div></li>
|
||||
<li>sftp</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Protocol used to transfer file.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>src</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the source file. The path to the source file can either be the full path on the network device or a relative path as per path supported by destination network device.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- Some devices need specific configurations to be enabled before scp can work These configuration should be pre-configured before using this module e.g ios - ``ip scp server enable``.
|
||||
- User privilege to do scp on network device should be pre-configured e.g. ios - need user privilege 15 by default for allowing scp.
|
||||
- Default destination of source file.
|
||||
- This module is supported on ``ansible_network_os`` network platforms. See the :ref:`Network Platform Options <platform_options>` for details.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: copy file from the network device to Ansible controller
|
||||
ansible.netcommon.net_get:
|
||||
src: running_cfg_ios1.txt
|
||||
|
||||
- name: copy file from ios to common location at /tmp
|
||||
ansible.netcommon.net_get:
|
||||
src: running_cfg_sw1.txt
|
||||
dest: /tmp/ios1.txt
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Deepak Agrawal (@dagrawal)
|
||||
@@ -0,0 +1,273 @@
|
||||
.. _ansible.netcommon.net_ping_module:
|
||||
|
||||
|
||||
**************************
|
||||
ansible.netcommon.net_ping
|
||||
**************************
|
||||
|
||||
**Tests reachability using ping from a network device**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- Tests reachability using ping from network device to a remote destination.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>count</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">5</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Number of packets to send.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>dest</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The IP Address or hostname (resolvable by switch) of the remote node.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>source</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The source IP Address.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>state</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>absent</li>
|
||||
<li><div style="color: blue"><b>present</b> ←</div></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Determines if the expected result is success or fail.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>vrf</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"default"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The VRF to use for forwarding.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- For targets running Python, use the :ref:`ansible.builtin.shell <ansible.builtin.shell_module>` module along with ping command instead.
|
||||
- This module is supported on ``ansible_network_os`` network platforms. See the :ref:`Network Platform Options <platform_options>` for details.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: Test reachability to 10.10.10.10 using default vrf
|
||||
ansible.netcommon.net_ping:
|
||||
dest: 10.10.10.10
|
||||
|
||||
- name: Test reachability to 10.20.20.20 using prod vrf
|
||||
ansible.netcommon.net_ping:
|
||||
dest: 10.20.20.20
|
||||
vrf: prod
|
||||
|
||||
- name: Test unreachability to 10.30.30.30 using default vrf
|
||||
ansible.netcommon.net_ping:
|
||||
dest: 10.30.30.30
|
||||
state: absent
|
||||
|
||||
- name: Test reachability to 10.40.40.40 using prod vrf and setting count and source
|
||||
ansible.netcommon.net_ping:
|
||||
dest: 10.40.40.40
|
||||
source: loopback0
|
||||
vrf: prod
|
||||
count: 20
|
||||
|
||||
- Note:
|
||||
- For targets running Python, use the M(ansible.builtin.shell) module along with ping command instead.
|
||||
- Example:
|
||||
name: ping
|
||||
shell: ping -c 1 <remote-ip>
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>commands</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>Show the command sent.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">['ping vrf prod 10.40.40.40 count 20 source loopback0']</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>packet_loss</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>Percentage of packets lost.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">0%</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>packets_rx</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>Packets successfully received.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">20</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>packets_tx</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>Packets successfully transmitted.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">20</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>rtt</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>Show RTT stats.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">{'avg': 2, 'max': 8, 'min': 1}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Jacob McGill (@jmcgill298)
|
||||
@@ -0,0 +1,152 @@
|
||||
.. _ansible.netcommon.net_put_module:
|
||||
|
||||
|
||||
*************************
|
||||
ansible.netcommon.net_put
|
||||
*************************
|
||||
|
||||
**Copy a file from Ansible Controller to a network device**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This module provides functionality to copy file from Ansible controller to network devices.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The below requirements are needed on the host that executes this module.
|
||||
|
||||
- scp if using protocol=scp with paramiko
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>dest</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">["Filename from src and at default directory of user shell on network_os."]</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the destination file. The path to destination file can either be the full path or relative path as supported by network_os.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>mode</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>binary</b> ←</div></li>
|
||||
<li>text</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Set the file transfer mode. If mode is set to <em>text</em> then <em>src</em> file will go through Jinja2 template engine to replace any vars if present in the src file. If mode is set to <em>binary</em> then file will be copied as it is to destination device.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>protocol</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>scp</b> ←</div></li>
|
||||
<li>sftp</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Protocol used to transfer file.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>src</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the source file. The path to the source file can either be the full path on the Ansible control host or a relative path from the playbook or role root directory.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- Some devices need specific configurations to be enabled before scp can work These configuration should be pre-configured before using this module e.g ios - ``ip scp server enable``.
|
||||
- User privilege to do scp on network device should be pre-configured e.g. ios - need user privilege 15 by default for allowing scp.
|
||||
- Default destination of source file.
|
||||
- This module is supported on ``ansible_network_os`` network platforms. See the :ref:`Network Platform Options <platform_options>` for details.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: copy file from ansible controller to a network device
|
||||
ansible.netcommon.net_put:
|
||||
src: running_cfg_ios1.txt
|
||||
|
||||
- name: copy file at root dir of flash in slot 3 of sw1(ios)
|
||||
ansible.netcommon.net_put:
|
||||
src: running_cfg_sw1.txt
|
||||
protocol: sftp
|
||||
dest: flash3:/running_cfg_sw1.txt
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Deepak Agrawal (@dagrawal)
|
||||
@@ -0,0 +1,636 @@
|
||||
.. _ansible.netcommon.netconf_config_module:
|
||||
|
||||
|
||||
********************************
|
||||
ansible.netcommon.netconf_config
|
||||
********************************
|
||||
|
||||
**netconf device configuration**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- Netconf is a network management protocol developed and standardized by the IETF. It is documented in RFC 6241.
|
||||
- This module allows the user to send a configuration XML file to a netconf device, and detects if there was a configuration change.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The below requirements are needed on the host that executes this module.
|
||||
|
||||
- ncclient
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="2">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>backup</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>This argument will cause the module to create a full backup of the current <code>running-config</code> from the remote device before any changes are made. If the <code>backup_options</code> value is not given, the backup file is written to the <code>backup</code> folder in the playbook root directory or role root directory, if playbook is part of an ansible role. If the directory does not exist, it is created.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>backup_options</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This is a dict object containing configurable options related to backup file path. The value of this option is read only when <code>backup</code> is set to <em>yes</em>, if <code>backup</code> is set to <em>no</em> this option will be silently ignored.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="elbow-placeholder"></td>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>dir_path</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">path</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option provides the path ending with directory name in which the backup configuration file will be stored. If the directory does not exist it will be first created and the filename is either the value of <code>filename</code> or default filename as described in <code>filename</code> options description. If the path value is not given in that case a <em>backup</em> directory will be created in the current working directory and backup configuration will be copied in <code>filename</code> within <em>backup</em> directory.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="elbow-placeholder"></td>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>filename</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The filename to be used to store the backup configuration. If the filename is not given it will be generated based on the hostname, current time and date in format defined by <hostname>_config.<current-date>@<current-time></div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>commit</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>no</li>
|
||||
<li><div style="color: blue"><b>yes</b> ←</div></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>This boolean flag controls if the configuration changes should be committed or not after editing the candidate datastore. This option is supported only if remote Netconf server supports :candidate capability. If the value is set to <em>False</em> commit won't be issued after edit-config operation and user needs to handle commit or discard-changes explicitly.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>confirm</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">0</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This argument will configure a timeout value for the commit to be confirmed before it is automatically rolled back. If the <code>confirm_commit</code> argument is set to False, this argument is silently ignored. If the value of this argument is set to 0, the commit is confirmed immediately. The remote host MUST support :candidate and :confirmed-commit capability for this option to .</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>confirm_commit</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>This argument will execute commit operation on remote device. It can be used to confirm a previous commit.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>content</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">raw</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The configuration data as defined by the device's data models, the value can be either in xml string format or text format or python dictionary representation of JSON format.</div>
|
||||
<div>In case of json string format it will be converted to the corresponding xml string using xmltodict library before pushing onto the remote host.</div>
|
||||
<div>In case the value of this option isn <em>text</em> format the format should be supported by remote Netconf server.</div>
|
||||
<div>If the value of <code>content</code> option is in <em>xml</em> format in that case the xml value should have <em>config</em> as root tag.</div>
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: xml</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>default_operation</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>merge</li>
|
||||
<li>replace</li>
|
||||
<li>none</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The default operation for <edit-config> rpc, valid values are <em>merge</em>, <em>replace</em> and <em>none</em>. If the default value is merge, the configuration data in the <code>content</code> option is merged at the corresponding level in the <code>target</code> datastore. If the value is replace the data in the <code>content</code> option completely replaces the configuration in the <code>target</code> datastore. If the value is none the <code>target</code> datastore is unaffected by the configuration in the config option, unless and until the incoming configuration data uses the <code>operation</code> operation to request a different operation.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>delete</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>It instructs the module to delete the configuration from value mentioned in <code>target</code> datastore.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>error_option</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>stop-on-error</b> ←</div></li>
|
||||
<li>continue-on-error</li>
|
||||
<li>rollback-on-error</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option controls the netconf server action after an error occurs while editing the configuration.</div>
|
||||
<div>If <em>error_option=stop-on-error</em>, abort the config edit on first error.</div>
|
||||
<div>If <em>error_option=continue-on-error</em>, continue to process configuration data on error. The error is recorded and negative response is generated if any errors occur.</div>
|
||||
<div>If <em>error_option=rollback-on-error</em>, rollback to the original configuration if any error occurs. This requires the remote Netconf server to support the <em>error_option=rollback-on-error</em> capability.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>format</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>xml</li>
|
||||
<li>text</li>
|
||||
<li>json</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The format of the configuration provided as value of <code>content</code>.</div>
|
||||
<div>In case of json string format it will be converted to the corresponding xml string using xmltodict library before pushing onto the remote host.</div>
|
||||
<div>In case of <em>text</em> format of the configuration should be supported by remote Netconf server.</div>
|
||||
<div>If the value of <code>format</code> options is not given it tries to guess the data format of <code>content</code> option as one of <em>xml</em> or <em>json</em> or <em>text</em>.</div>
|
||||
<div>If the data format is not identified it is set to <em>xml</em> by default.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>get_filter</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">raw</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This argument specifies the XML string which acts as a filter to restrict the portions of the data retrieved from the remote device when comparing the before and after state of the device following calls to edit_config. When not specified, the entire configuration or state data is returned for comparison depending on the value of <code>source</code> option. The <code>get_filter</code> value can be either XML string or XPath or JSON string or native python dictionary, if the filter is in XPath format the NETCONF server running on remote host should support xpath capability else it will result in an error.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>lock</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>never</li>
|
||||
<li><div style="color: blue"><b>always</b> ←</div></li>
|
||||
<li>if-supported</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Instructs the module to explicitly lock the datastore specified as <code>target</code>. By setting the option value <em>always</em> is will explicitly lock the datastore mentioned in <code>target</code> option. It the value is <em>never</em> it will not lock the <code>target</code> datastore. The value <em>if-supported</em> lock the <code>target</code> datastore only if it is supported by the remote Netconf server.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>save</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The <code>save</code> argument instructs the module to save the configuration in <code>target</code> datastore to the startup-config if changed and if :startup capability is supported by Netconf server.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>source_datastore</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Name of the configuration datastore to use as the source to copy the configuration to the datastore mentioned by <code>target</code> option. The values can be either <em>running</em>, <em>candidate</em>, <em>startup</em> or a remote URL</div>
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: source</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>target</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>auto</b> ←</div></li>
|
||||
<li>candidate</li>
|
||||
<li>running</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Name of the configuration datastore to be edited. - auto, uses candidate and fallback to running - candidate, edit <candidate/> datastore and then commit - running, edit <running/> datastore directly</div>
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: datastore</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>validate</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>This boolean flag if set validates the content of datastore given in <code>target</code> option. For this option to work remote Netconf server should support :validate capability.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- This module requires the netconf system service be enabled on the remote device being managed.
|
||||
- This module supports devices with and without the candidate and confirmed-commit capabilities. It will always use the safer feature.
|
||||
- This module supports the use of connection=netconf
|
||||
- This module is supported on ``ansible_network_os`` network platforms. See the :ref:`Network Platform Options <platform_options>` for details.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: use lookup filter to provide xml configuration
|
||||
ansible.netcommon.netconf_config:
|
||||
content: "{{ lookup('file', './config.xml') }}"
|
||||
|
||||
- name: set ntp server in the device
|
||||
ansible.netcommon.netconf_config:
|
||||
content: |
|
||||
<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
|
||||
<system xmlns="urn:ietf:params:xml:ns:yang:ietf-system">
|
||||
<ntp>
|
||||
<enabled>true</enabled>
|
||||
<server>
|
||||
<name>ntp1</name>
|
||||
<udp><address>127.0.0.1</address></udp>
|
||||
</server>
|
||||
</ntp>
|
||||
</system>
|
||||
</config>
|
||||
|
||||
- name: wipe ntp configuration
|
||||
ansible.netcommon.netconf_config:
|
||||
content: |
|
||||
<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
|
||||
<system xmlns="urn:ietf:params:xml:ns:yang:ietf-system">
|
||||
<ntp>
|
||||
<enabled>false</enabled>
|
||||
<server operation="remove">
|
||||
<name>ntp1</name>
|
||||
</server>
|
||||
</ntp>
|
||||
</system>
|
||||
</config>
|
||||
|
||||
- name: configure interface while providing different private key file path (for connection=netconf)
|
||||
ansible.netcommon.netconf_config:
|
||||
backup: true
|
||||
register: backup_junos_location
|
||||
vars:
|
||||
ansible_private_key_file: /home/admin/.ssh/newprivatekeyfile
|
||||
|
||||
- name: configurable backup path
|
||||
ansible.netcommon.netconf_config:
|
||||
backup: true
|
||||
backup_options:
|
||||
filename: backup.cfg
|
||||
dir_path: /home/user
|
||||
|
||||
- name: "configure using direct native format configuration (cisco iosxr)"
|
||||
ansible.netcommon.netconf_config:
|
||||
format: json
|
||||
content:
|
||||
{
|
||||
"config":
|
||||
{
|
||||
"interface-configurations":
|
||||
{
|
||||
"@xmlns": "http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg",
|
||||
"interface-configuration":
|
||||
{
|
||||
"active": "act",
|
||||
"description": "test for ansible Loopback999",
|
||||
"interface-name": "Loopback999",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
get_filter:
|
||||
{
|
||||
"interface-configurations":
|
||||
{
|
||||
"@xmlns": "http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg",
|
||||
"interface-configuration": null,
|
||||
},
|
||||
}
|
||||
|
||||
- name: "configure using json string format configuration (cisco iosxr)"
|
||||
ansible.netcommon.netconf_config:
|
||||
format: json
|
||||
content: |
|
||||
{
|
||||
"config": {
|
||||
"interface-configurations": {
|
||||
"@xmlns": "http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg",
|
||||
"interface-configuration": {
|
||||
"active": "act",
|
||||
"description": "test for ansible Loopback999",
|
||||
"interface-name": "Loopback999"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
get_filter: |
|
||||
{
|
||||
"interface-configurations": {
|
||||
"@xmlns": "http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg",
|
||||
"interface-configuration": null
|
||||
}
|
||||
}
|
||||
|
||||
# Make a round-trip interface description change, diff the before and after
|
||||
# this demonstrates the use of the native display format and several utilities
|
||||
# from the ansible.utils collection
|
||||
|
||||
- name: Define the openconfig interface filter
|
||||
set_fact:
|
||||
filter:
|
||||
interfaces:
|
||||
"@xmlns": "http://openconfig.net/yang/interfaces"
|
||||
interface:
|
||||
name: Ethernet2
|
||||
|
||||
- name: Get the pre-change config using the filter
|
||||
ansible.netcommon.netconf_get:
|
||||
source: running
|
||||
filter: "{{ filter }}"
|
||||
display: native
|
||||
register: pre
|
||||
|
||||
- name: Update the description
|
||||
ansible.utils.update_fact:
|
||||
updates:
|
||||
- path: pre.output.data.interfaces.interface.config.description
|
||||
value: "Configured by ansible {{ 100 | random }}"
|
||||
register: updated
|
||||
|
||||
- name: Apply the new configuration
|
||||
ansible.netcommon.netconf_config:
|
||||
content:
|
||||
config:
|
||||
interfaces: "{{ updated.pre.output.data.interfaces }}"
|
||||
|
||||
- name: Get the post-change config using the filter
|
||||
ansible.netcommon.netconf_get:
|
||||
source: running
|
||||
filter: "{{ filter }}"
|
||||
display: native
|
||||
register: post
|
||||
|
||||
- name: Show the differences between the pre and post configurations
|
||||
ansible.utils.fact_diff:
|
||||
before: "{{ pre.output.data|ansible.utils.to_paths }}"
|
||||
after: "{{ post.output.data|ansible.utils.to_paths }}"
|
||||
# TASK [Show the differences between the pre and post configurations] ********
|
||||
# --- before
|
||||
# +++ after
|
||||
# @@ -1,11 +1,11 @@
|
||||
# {
|
||||
# - "@time-modified": "2020-10-23T12:27:17.462332477Z",
|
||||
# + "@time-modified": "2020-10-23T12:27:21.744541708Z",
|
||||
# "@xmlns": "urn:ietf:params:xml:ns:netconf:base:1.0",
|
||||
# "interfaces.interface.aggregation.config['fallback-timeout']['#text']": "90",
|
||||
# "interfaces.interface.aggregation.config['fallback-timeout']['@xmlns']": "http://arista.com/yang/openconfig/interfaces/augments",
|
||||
# "interfaces.interface.aggregation.config['min-links']": "0",
|
||||
# "interfaces.interface.aggregation['@xmlns']": "http://openconfig.net/yang/interfaces/aggregate",
|
||||
# - "interfaces.interface.config.description": "Configured by ansible 56",
|
||||
# + "interfaces.interface.config.description": "Configured by ansible 67",
|
||||
# "interfaces.interface.config.enabled": "true",
|
||||
# "interfaces.interface.config.mtu": "0",
|
||||
# "interfaces.interface.config.name": "Ethernet2",
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>backup_path</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>when backup is yes</td>
|
||||
<td>
|
||||
<div>The full path to the backup file</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">/playbooks/ansible/backup/config.2016-07-16@22:28:34</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>diff</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>when diff is enabled</td>
|
||||
<td>
|
||||
<div>If --diff option in enabled while running, the before and after configuration change are returned as part of before and after key.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">{'after': '<rpc-reply> <data> <configuration> <version>17.3R1.10</version>...<--snip-->', 'before': '<rpc-reply> <data> <configuration> <version>17.3R1.10</version>...<--snip-->'}</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>server_capabilities</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>success</td>
|
||||
<td>
|
||||
<div>list of capabilities of the server</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">['urn:ietf:params:netconf:base:1.1', 'urn:ietf:params:netconf:capability:confirmed-commit:1.0', 'urn:ietf:params:netconf:capability:candidate:1.0']</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Leandro Lisboa Penz (@lpenz)
|
||||
- Ganesh Nalawade (@ganeshrn)
|
||||
@@ -0,0 +1,382 @@
|
||||
.. _ansible.netcommon.netconf_connection:
|
||||
|
||||
|
||||
*************************
|
||||
ansible.netcommon.netconf
|
||||
*************************
|
||||
|
||||
**Provides a persistent connection using the netconf protocol**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This connection plugin provides a connection to remote devices over the SSH NETCONF subsystem. This connection plugin is typically used by network devices for sending and receiving RPC calls over NETCONF.
|
||||
- Note this connection plugin requires ncclient to be installed on the local Ansible controller.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The below requirements are needed on the local Ansible controller node that executes this connection.
|
||||
|
||||
- ncclient
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>host</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"inventory_hostname"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: inventory_hostname</div>
|
||||
<div>var: ansible_host</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the remote device FQDN or IP address to establish the SSH connection to.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>host_key_checking</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>host_key_checking = yes</p>
|
||||
<p>[paramiko_connection]<br>host_key_checking = yes</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_HOST_KEY_CHECKING</div>
|
||||
<div>env:ANSIBLE_SSH_HOST_KEY_CHECKING</div>
|
||||
<div>env:ANSIBLE_NETCONF_HOST_KEY_CHECKING</div>
|
||||
<div>var: ansible_host_key_checking</div>
|
||||
<div>var: ansible_ssh_host_key_checking</div>
|
||||
<div>var: ansible_netconf_host_key_checking</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Set this to "False" if you want to avoid host key checking by the underlying tools Ansible uses to connect to the host</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>import_modules</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[ansible_network]<br>import_modules = yes</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_NETWORK_IMPORT_MODULES</div>
|
||||
<div>var: ansible_network_import_modules</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Reduce CPU usage and network module execution time by enabling direct execution. Instead of the module being packaged and executed by the shell, it will be directly executed by the Ansible control node using the same python interpreter as the Ansible process. Note- Incompatible with <code>asynchronous mode</code>. Note- Python 3 and Ansible 2.9.16 or greater required. Note- With Ansible 2.9.x fully qualified modules names are required in tasks.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>look_for_keys</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[paramiko_connection]<br>look_for_keys = yes</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PARAMIKO_LOOK_FOR_KEYS</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Enables looking for ssh keys in the usual locations for ssh keys (e.g. :file:`~/.ssh/id_*`).</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>netconf_ssh_config</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[netconf_connection]<br>ssh_config = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_NETCONF_SSH_CONFIG</div>
|
||||
<div>var: ansible_netconf_ssh_config</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This variable is used to enable bastion/jump host with netconf connection. If set to True the bastion/jump host ssh settings should be present in ~/.ssh/config file, alternatively it can be set to custom ssh configuration file path to read the bastion/jump host settings.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>network_os</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_network_os</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures the device platform network operating system. This value is used to load a device specific netconf plugin. If this option is not configured (or set to <code>auto</code>), then Ansible will attempt to guess the correct network_os to use. If it can not guess a network_os correctly it will use <code>default</code>.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>password</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_password</div>
|
||||
<div>var: ansible_ssh_pass</div>
|
||||
<div>var: ansible_ssh_password</div>
|
||||
<div>var: ansible_netconf_password</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures the user password used to authenticate to the remote device when first establishing the SSH connection.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_command_timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">30</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>command_timeout = 30</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_COMMAND_TIMEOUT</div>
|
||||
<div>var: ansible_command_timeout</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures, in seconds, the amount of time to wait for a command to return from the remote device. If this timer is exceeded before the command returns, the connection plugin will raise an exception and close.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_connect_timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">30</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>connect_timeout = 30</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_CONNECT_TIMEOUT</div>
|
||||
<div>var: ansible_connect_timeout</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures, in seconds, the amount of time to wait when trying to initially establish a persistent connection. If this value expires before the connection to the remote device is completed, the connection will fail.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_log_messages</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>log_messages = no</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_LOG_MESSAGES</div>
|
||||
<div>var: ansible_persistent_log_messages</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This flag will enable logging the command executed and response received from target device in the ansible log file. For this option to work 'log_path' ansible configuration option is required to be set to a file path with write access.</div>
|
||||
<div>Be sure to fully understand the security implications of enabling this option as it could create a security vulnerability by logging sensitive information in log file.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>port</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">830</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>remote_port = 830</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_REMOTE_PORT</div>
|
||||
<div>var: ansible_port</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the port on the remote device that listens for connections when establishing the SSH connection.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>private_key_file</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>private_key_file = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PRIVATE_KEY_FILE</div>
|
||||
<div>var: ansible_private_key_file</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The private SSH key or certificate file used to authenticate to the remote device when first establishing the SSH connection.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>proxy_command</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">""</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[paramiko_connection]<br>proxy_command = </p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_NETCONF_PROXY_COMMAND</div>
|
||||
<div>var: ansible_paramiko_proxy_command</div>
|
||||
<div>var: ansible_netconf_proxy_command</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Proxy information for running the connection via a jumphost.</div>
|
||||
<div>This requires ncclient >= 0.6.10 to be installed on the controller.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>remote_user</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>remote_user = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_REMOTE_USER</div>
|
||||
<div>var: ansible_user</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The username used to authenticate to the remote device when the SSH connection is first established. If the remote_user is not specified, the connection will use the username of the logged in user.</div>
|
||||
<div>Can be configured from the CLI via the <code>--user</code> or <code>-u</code> options.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,378 @@
|
||||
.. _ansible.netcommon.netconf_get_module:
|
||||
|
||||
|
||||
*****************************
|
||||
ansible.netcommon.netconf_get
|
||||
*****************************
|
||||
|
||||
**Fetch configuration/state data from NETCONF enabled network devices.**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- NETCONF is a network management protocol developed and standardized by the IETF. It is documented in RFC 6241.
|
||||
- This module allows the user to fetch configuration and state data from NETCONF enabled network devices.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The below requirements are needed on the host that executes this module.
|
||||
|
||||
- ncclient (>=v0.5.2)
|
||||
- jxmlease (for display=json)
|
||||
- xmltodict (for display=native)
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>display</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>json</li>
|
||||
<li>pretty</li>
|
||||
<li>xml</li>
|
||||
<li>native</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Encoding scheme to use when serializing output from the device. The option <em>json</em> will serialize the output as JSON data. If the option value is <em>json</em> it requires jxmlease to be installed on control node. The option <em>pretty</em> is similar to received XML response but is using human readable format (spaces, new lines). The option value <em>xml</em> is similar to received XML response but removes all XML namespaces.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>filter</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">raw</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This argument specifies the string which acts as a filter to restrict the portions of the data to be are retrieved from the remote device. If this option is not specified entire configuration or state data is returned in result depending on the value of <code>source</code> option. The <code>filter</code> value can be either XML string or XPath or JSON string or native python dictionary, if the filter is in XPath format the NETCONF server running on remote host should support xpath capability else it will result in an error. If the filter is in JSON format the xmltodict library should be installed on the control node for JSON to XML conversion.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>lock</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>never</b> ←</div></li>
|
||||
<li>always</li>
|
||||
<li>if-supported</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Instructs the module to explicitly lock the datastore specified as <code>source</code>. If no <em>source</em> is defined, the <em>running</em> datastore will be locked. By setting the option value <em>always</em> is will explicitly lock the datastore mentioned in <code>source</code> option. By setting the option value <em>never</em> it will not lock the <code>source</code> datastore. The value <em>if-supported</em> allows better interworking with NETCONF servers, which do not support the (un)lock operation for all supported datastores.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>source</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>running</li>
|
||||
<li>candidate</li>
|
||||
<li>startup</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>This argument specifies the datastore from which configuration data should be fetched. Valid values are <em>running</em>, <em>candidate</em> and <em>startup</em>. If the <code>source</code> value is not set both configuration and state information are returned in response from running datastore.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- This module requires the NETCONF system service be enabled on the remote device being managed.
|
||||
- This module supports the use of connection=netconf
|
||||
- This module is supported on ``ansible_network_os`` network platforms. See the :ref:`Network Platform Options <platform_options>` for details.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: Get running configuration and state data
|
||||
ansible.netcommon.netconf_get:
|
||||
|
||||
- name: Get configuration and state data from startup datastore
|
||||
ansible.netcommon.netconf_get:
|
||||
source: startup
|
||||
|
||||
- name: Get system configuration data from running datastore state (junos)
|
||||
ansible.netcommon.netconf_get:
|
||||
source: running
|
||||
filter: <configuration><system></system></configuration>
|
||||
|
||||
- name: Get configuration and state data in JSON format
|
||||
ansible.netcommon.netconf_get:
|
||||
display: json
|
||||
|
||||
- name: get schema list using subtree w/ namespaces
|
||||
ansible.netcommon.netconf_get:
|
||||
display: json
|
||||
filter: <netconf-state xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"><schemas><schema/></schemas></netconf-state>
|
||||
lock: never
|
||||
|
||||
- name: get schema list using xpath
|
||||
ansible.netcommon.netconf_get:
|
||||
display: xml
|
||||
filter: /netconf-state/schemas/schema
|
||||
|
||||
- name: get interface configuration with filter (iosxr)
|
||||
ansible.netcommon.netconf_get:
|
||||
display: pretty
|
||||
filter: <interface-configurations xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg"></interface-configurations>
|
||||
lock: if-supported
|
||||
|
||||
- name: Get system configuration data from running datastore state (junos)
|
||||
ansible.netcommon.netconf_get:
|
||||
source: running
|
||||
filter: <configuration><system></system></configuration>
|
||||
lock: if-supported
|
||||
|
||||
- name: Get complete configuration data from running datastore (SROS)
|
||||
ansible.netcommon.netconf_get:
|
||||
source: running
|
||||
filter: <configure xmlns="urn:nokia.com:sros:ns:yang:sr:conf"/>
|
||||
|
||||
- name: Get complete state data (SROS)
|
||||
ansible.netcommon.netconf_get:
|
||||
filter: <state xmlns="urn:nokia.com:sros:ns:yang:sr:state"/>
|
||||
|
||||
- name: "get configuration with json filter string and native output (using xmltodict)"
|
||||
netconf_get:
|
||||
filter: |
|
||||
{
|
||||
"interface-configurations": {
|
||||
"@xmlns": "http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg",
|
||||
"interface-configuration": null
|
||||
}
|
||||
}
|
||||
display: native
|
||||
|
||||
- name: Define the Cisco IOSXR interface filter
|
||||
set_fact:
|
||||
filter:
|
||||
interface-configurations:
|
||||
"@xmlns": "http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg"
|
||||
interface-configuration: null
|
||||
|
||||
- name: "get configuration with native filter type using set_facts"
|
||||
ansible.netcommon.netconf_get:
|
||||
filter: "{{ filter }}"
|
||||
display: native
|
||||
register: result
|
||||
|
||||
- name: "get configuration with direct native filter type"
|
||||
ansible.netcommon.netconf_get:
|
||||
filter:
|
||||
{
|
||||
"interface-configurations":
|
||||
{
|
||||
"@xmlns": "http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg",
|
||||
"interface-configuration": null,
|
||||
},
|
||||
}
|
||||
display: native
|
||||
register: result
|
||||
|
||||
# Make a round-trip interface description change, diff the before and after
|
||||
# this demonstrates the use of the native display format and several utilities
|
||||
# from the ansible.utils collection
|
||||
|
||||
- name: Define the openconfig interface filter
|
||||
set_fact:
|
||||
filter:
|
||||
interfaces:
|
||||
"@xmlns": "http://openconfig.net/yang/interfaces"
|
||||
interface:
|
||||
name: Ethernet2
|
||||
|
||||
- name: Get the pre-change config using the filter
|
||||
ansible.netcommon.netconf_get:
|
||||
source: running
|
||||
filter: "{{ filter }}"
|
||||
display: native
|
||||
register: pre
|
||||
|
||||
- name: Update the description
|
||||
ansible.utils.update_fact:
|
||||
updates:
|
||||
- path: pre.output.data.interfaces.interface.config.description
|
||||
value: "Configured by ansible {{ 100 | random }}"
|
||||
register: updated
|
||||
|
||||
- name: Apply the new configuration
|
||||
ansible.netcommon.netconf_config:
|
||||
content:
|
||||
config:
|
||||
interfaces: "{{ updated.pre.output.data.interfaces }}"
|
||||
|
||||
- name: Get the post-change config using the filter
|
||||
ansible.netcommon.netconf_get:
|
||||
source: running
|
||||
filter: "{{ filter }}"
|
||||
display: native
|
||||
register: post
|
||||
|
||||
- name: Show the differences between the pre and post configurations
|
||||
ansible.utils.fact_diff:
|
||||
before: "{{ pre.output.data|ansible.utils.to_paths }}"
|
||||
after: "{{ post.output.data|ansible.utils.to_paths }}"
|
||||
# TASK [Show the differences between the pre and post configurations] ********
|
||||
# --- before
|
||||
# +++ after
|
||||
# @@ -1,11 +1,11 @@
|
||||
# {
|
||||
# - "@time-modified": "2020-10-23T12:27:17.462332477Z",
|
||||
# + "@time-modified": "2020-10-23T12:27:21.744541708Z",
|
||||
# "@xmlns": "urn:ietf:params:xml:ns:netconf:base:1.0",
|
||||
# "interfaces.interface.aggregation.config['fallback-timeout']['#text']": "90",
|
||||
# "interfaces.interface.aggregation.config['fallback-timeout']['@xmlns']": "http://arista.com/yang/openconfig/interfaces/augments",
|
||||
# "interfaces.interface.aggregation.config['min-links']": "0",
|
||||
# "interfaces.interface.aggregation['@xmlns']": "http://openconfig.net/yang/interfaces/aggregate",
|
||||
# - "interfaces.interface.config.description": "Configured by ansible 56",
|
||||
# + "interfaces.interface.config.description": "Configured by ansible 67",
|
||||
# "interfaces.interface.config.enabled": "true",
|
||||
# "interfaces.interface.config.mtu": "0",
|
||||
# "interfaces.interface.config.name": "Ethernet2",
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="2">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>output</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">complex</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>If the display format is selected as <em>json</em> it is returned as dict type and the conversion is done using jxmlease python library. If the display format is selected as <em>native</em> it is returned as dict type and the conversion is done using xmltodict python library. If the display format is xml or pretty it is returned as a string apart from low-level errors (such as action plugin).</td>
|
||||
<td>
|
||||
<div>Based on the value of display option will return either the set of transformed XML to JSON format from the RPC response with type dict or pretty XML string response (human-readable) or response with namespace removed from XML string.</div>
|
||||
<br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="elbow-placeholder"> </td>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>formatted_output</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td></td>
|
||||
<td>
|
||||
<div>Contains formatted response received from remote host as per the value in display format.</div>
|
||||
<br/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stdout</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always apart from low-level errors (such as action plugin)</td>
|
||||
<td>
|
||||
<div>The raw XML string containing configuration or state data received from the underlying ncclient library.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">...</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stdout_lines</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always apart from low-level errors (such as action plugin)</td>
|
||||
<td>
|
||||
<div>The value of stdout split into a list</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">['...', '...']</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ganesh Nalawade (@ganeshrn)
|
||||
- Sven Wisotzky (@wisotzky)
|
||||
@@ -0,0 +1,276 @@
|
||||
.. _ansible.netcommon.netconf_rpc_module:
|
||||
|
||||
|
||||
*****************************
|
||||
ansible.netcommon.netconf_rpc
|
||||
*****************************
|
||||
|
||||
**Execute operations on NETCONF enabled network devices.**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- NETCONF is a network management protocol developed and standardized by the IETF. It is documented in RFC 6241.
|
||||
- This module allows the user to execute NETCONF RPC requests as defined by IETF RFC standards as well as proprietary requests.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The below requirements are needed on the host that executes this module.
|
||||
|
||||
- ncclient (>=v0.5.2)
|
||||
- jxmlease
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>content</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This argument specifies the optional request content (all RPC attributes). The <em>content</em> value can either be provided as XML formatted string or as dictionary.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>display</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>json</li>
|
||||
<li>pretty</li>
|
||||
<li>xml</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Encoding scheme to use when serializing output from the device. The option <em>json</em> will serialize the output as JSON data. If the option value is <em>json</em> it requires jxmlease to be installed on control node. The option <em>pretty</em> is similar to received XML response but is using human readable format (spaces, new lines). The option value <em>xml</em> is similar to received XML response but removes all XML namespaces.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>rpc</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This argument specifies the request (name of the operation) to be executed on the remote NETCONF enabled device.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>xmlns</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>NETCONF operations not defined in rfc6241 typically require the appropriate XML namespace to be set. In the case the <em>request</em> option is not already provided in XML format, the namespace can be defined by the <em>xmlns</em> option.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- This module requires the NETCONF system service be enabled on the remote device being managed.
|
||||
- This module supports the use of connection=netconf
|
||||
- To execute ``get-config``, ``get`` or ``edit-config`` requests it is recommended to use the Ansible *netconf_get* and *netconf_config* modules.
|
||||
- This module is supported on ``ansible_network_os`` network platforms. See the :ref:`Network Platform Options <platform_options>` for details.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: lock candidate
|
||||
ansible.netcommon.netconf_rpc:
|
||||
rpc: lock
|
||||
content:
|
||||
target:
|
||||
candidate:
|
||||
|
||||
- name: unlock candidate
|
||||
ansible.netcommon.netconf_rpc:
|
||||
rpc: unlock
|
||||
xmlns: urn:ietf:params:xml:ns:netconf:base:1.0
|
||||
content: "{'target': {'candidate': None}}"
|
||||
|
||||
- name: discard changes
|
||||
ansible.netcommon.netconf_rpc:
|
||||
rpc: discard-changes
|
||||
|
||||
- name: get-schema
|
||||
ansible.netcommon.netconf_rpc:
|
||||
rpc: get-schema
|
||||
xmlns: urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring
|
||||
content:
|
||||
identifier: ietf-netconf
|
||||
version: '2011-06-01'
|
||||
|
||||
- name: copy running to startup
|
||||
ansible.netcommon.netconf_rpc:
|
||||
rpc: copy-config
|
||||
content:
|
||||
source:
|
||||
running:
|
||||
target:
|
||||
startup:
|
||||
|
||||
- name: get schema list with JSON output
|
||||
ansible.netcommon.netconf_rpc:
|
||||
rpc: get
|
||||
content: |
|
||||
<filter>
|
||||
<netconf-state xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
|
||||
<schemas/>
|
||||
</netconf-state>
|
||||
</filter>
|
||||
display: json
|
||||
|
||||
- name: get schema using XML request
|
||||
ansible.netcommon.netconf_rpc:
|
||||
rpc: get-schema
|
||||
xmlns: urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring
|
||||
content: |
|
||||
<identifier>ietf-netconf-monitoring</identifier>
|
||||
<version>2010-10-04</version>
|
||||
display: json
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="2">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>output</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">complex</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>when the display format is selected as JSON it is returned as dict type, if the display format is xml or pretty pretty it is returned as a string apart from low-level errors (such as action plugin).</td>
|
||||
<td>
|
||||
<div>Based on the value of display option will return either the set of transformed XML to JSON format from the RPC response with type dict or pretty XML string response (human-readable) or response with namespace removed from XML string.</div>
|
||||
<br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="elbow-placeholder"> </td>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>formatted_output</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td></td>
|
||||
<td>
|
||||
<div>Contains formatted response received from remote host as per the value in display format.</div>
|
||||
<br/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stdout</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always apart from low-level errors (such as action plugin)</td>
|
||||
<td>
|
||||
<div>The raw XML string containing configuration or state data received from the underlying ncclient library.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">...</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stdout_lines</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always apart from low-level errors (such as action plugin)</td>
|
||||
<td>
|
||||
<div>The value of stdout split into a list</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">['...', '...']</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ganesh Nalawade (@ganeshrn)
|
||||
- Sven Wisotzky (@wisotzky)
|
||||
@@ -0,0 +1,640 @@
|
||||
.. _ansible.netcommon.network_cli_connection:
|
||||
|
||||
|
||||
*****************************
|
||||
ansible.netcommon.network_cli
|
||||
*****************************
|
||||
|
||||
**Use network_cli to run command on network appliances**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This connection plugin provides a connection to remote devices over the SSH and implements a CLI shell. This connection plugin is typically used by network devices for sending and receiving CLi commands to network devices.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The below requirements are needed on the local Ansible controller node that executes this connection.
|
||||
|
||||
- ansible-pylibssh if using *ssh_type=libssh*
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>become</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[privilege_escalation]<br>become = no</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_BECOME</div>
|
||||
<div>var: ansible_become</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The become option will instruct the CLI session to attempt privilege escalation on platforms that support it. Normally this means transitioning from user mode to <code>enable</code> mode in the CLI session. If become is set to True and the remote device does not support privilege escalation or the privilege has already been elevated, then this option is silently ignored.</div>
|
||||
<div>Can be configured from the CLI via the <code>--become</code> or <code>-b</code> options.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>become_errors</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>ignore</li>
|
||||
<li>warn</li>
|
||||
<li><div style="color: blue"><b>fail</b> ←</div></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_network_become_errors</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option determines how privilege escalation failures are handled when <em>become</em> is enabled.</div>
|
||||
<div>When set to <code>ignore</code>, the errors are silently ignored. When set to <code>warn</code>, a warning message is displayed. The default option <code>fail</code>, triggers a failure and halts execution.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>become_method</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"sudo"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[privilege_escalation]<br>become_method = sudo</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_BECOME_METHOD</div>
|
||||
<div>var: ansible_become_method</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option allows the become method to be specified in for handling privilege escalation. Typically the become_method value is set to <code>enable</code> but could be defined as other values.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>host</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"inventory_hostname"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: inventory_hostname</div>
|
||||
<div>var: ansible_host</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the remote device FQDN or IP address to establish the SSH connection to.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>host_key_auto_add</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[paramiko_connection]<br>host_key_auto_add = no</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_HOST_KEY_AUTO_ADD</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>By default, Ansible will prompt the user before adding SSH keys to the known hosts file. Since persistent connections such as network_cli run in background processes, the user will never be prompted. By enabling this option, unknown host keys will automatically be added to the known hosts file.</div>
|
||||
<div>Be sure to fully understand the security implications of enabling this option on production systems as it could create a security vulnerability.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>host_key_checking</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>host_key_checking = yes</p>
|
||||
<p>[persistent_connection]<br>host_key_checking = yes</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_HOST_KEY_CHECKING</div>
|
||||
<div>env:ANSIBLE_SSH_HOST_KEY_CHECKING</div>
|
||||
<div>var: ansible_host_key_checking</div>
|
||||
<div>var: ansible_ssh_host_key_checking</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Set this to "False" if you want to avoid host key checking by the underlying tools Ansible uses to connect to the host</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>import_modules</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[ansible_network]<br>import_modules = yes</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_NETWORK_IMPORT_MODULES</div>
|
||||
<div>var: ansible_network_import_modules</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Reduce CPU usage and network module execution time by enabling direct execution. Instead of the module being packaged and executed by the shell, it will be directly executed by the Ansible control node using the same python interpreter as the Ansible process. Note- Incompatible with <code>asynchronous mode</code>. Note- Python 3 and Ansible 2.9.16 or greater required. Note- With Ansible 2.9.x fully qualified modules names are required in tasks.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>network_cli_retries</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">3</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>network_cli_retries = 3</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_NETWORK_CLI_RETRIES</div>
|
||||
<div>var: ansible_network_cli_retries</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Number of attempts to connect to remote host. The delay time between the retires increases after every attempt by power of 2 in seconds till either the maximum attempts are exhausted or any of the <code>persistent_command_timeout</code> or <code>persistent_connect_timeout</code> timers are triggered.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>network_os</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_network_os</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures the device platform network operating system. This value is used to load the correct terminal and cliconf plugins to communicate with the remote device.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>password</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_password</div>
|
||||
<div>var: ansible_ssh_pass</div>
|
||||
<div>var: ansible_ssh_password</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures the user password used to authenticate to the remote device when first establishing the SSH connection.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_buffer_read_timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">float</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">0.1</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>buffer_read_timeout = 0.1</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_BUFFER_READ_TIMEOUT</div>
|
||||
<div>var: ansible_buffer_read_timeout</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures, in seconds, the amount of time to wait for the data to be read from Paramiko channel after the command prompt is matched. This timeout value ensures that command prompt matched is correct and there is no more data left to be received from remote host.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_command_timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">30</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>command_timeout = 30</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_COMMAND_TIMEOUT</div>
|
||||
<div>var: ansible_command_timeout</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures, in seconds, the amount of time to wait for a command to return from the remote device. If this timer is exceeded before the command returns, the connection plugin will raise an exception and close.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_connect_timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">30</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>connect_timeout = 30</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_CONNECT_TIMEOUT</div>
|
||||
<div>var: ansible_connect_timeout</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures, in seconds, the amount of time to wait when trying to initially establish a persistent connection. If this value expires before the connection to the remote device is completed, the connection will fail.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_log_messages</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>log_messages = no</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_LOG_MESSAGES</div>
|
||||
<div>var: ansible_persistent_log_messages</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This flag will enable logging the command executed and response received from target device in the ansible log file. For this option to work 'log_path' ansible configuration option is required to be set to a file path with write access.</div>
|
||||
<div>Be sure to fully understand the security implications of enabling this option as it could create a security vulnerability by logging sensitive information in log file.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>port</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">22</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>remote_port = 22</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_REMOTE_PORT</div>
|
||||
<div>var: ansible_port</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the port on the remote device that listens for connections when establishing the SSH connection.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>private_key_file</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>private_key_file = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PRIVATE_KEY_FILE</div>
|
||||
<div>var: ansible_private_key_file</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The private SSH key or certificate file used to authenticate to the remote device when first establishing the SSH connection.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>remote_user</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[defaults]<br>remote_user = VALUE</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_REMOTE_USER</div>
|
||||
<div>var: ansible_user</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The username used to authenticate to the remote device when the SSH connection is first established. If the remote_user is not specified, the connection will use the username of the logged in user.</div>
|
||||
<div>Can be configured from the CLI via the <code>--user</code> or <code>-u</code> options.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>single_user_mode</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>env:ANSIBLE_NETWORK_SINGLE_USER_MODE</div>
|
||||
<div>var: ansible_network_single_user_mode</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option enables caching of data fetched from the target for re-use. The cache is invalidated when the target device enters configuration mode.</div>
|
||||
<div>Applicable only for platforms where this has been implemented.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>ssh_type</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>libssh</li>
|
||||
<li>paramiko</li>
|
||||
<li><div style="color: blue"><b>auto</b> ←</div></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>ssh_type = auto</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_NETWORK_CLI_SSH_TYPE</div>
|
||||
<div>var: ansible_network_cli_ssh_type</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The python package that will be used by the <code>network_cli</code> connection plugin to create a SSH connection to remote host.</div>
|
||||
<div><em>libssh</em> will use the ansible-pylibssh package, which needs to be installed in order to work.</div>
|
||||
<div><em>paramiko</em> will instead use the paramiko package to manage the SSH connection.</div>
|
||||
<div><em>auto</em> will use ansible-pylibssh if that package is installed, otherwise will fallback to paramiko.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>terminal_errors</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.1.0</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>ignore</li>
|
||||
<li>warn</li>
|
||||
<li><div style="color: blue"><b>fail</b> ←</div></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_network_terminal_errors</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option determines how failures while setting terminal parameters are handled.</div>
|
||||
<div>When set to <code>ignore</code>, the errors are silently ignored. When set to <code>warn</code>, a warning message is displayed. The default option <code>fail</code>, triggers a failure and halts execution.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>terminal_inital_prompt_newline</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_terminal_initial_prompt_newline</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This boolean flag, that when set to <em>True</em> will send newline in the response if any of values in <em>terminal_initial_prompt</em> is matched.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>terminal_initial_answer</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_terminal_initial_answer</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The answer to reply with if the <code>terminal_initial_prompt</code> is matched. The value can be a single answer or a list of answers for multiple terminal_initial_prompt. In case the login menu has multiple prompts the sequence of the prompt and excepted answer should be in same order and the value of <em>terminal_prompt_checkall</em> should be set to <em>True</em> if all the values in <code>terminal_initial_prompt</code> are expected to be matched and set to <em>False</em> if any one login prompt is to be matched.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>terminal_initial_prompt</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_terminal_initial_prompt</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>A single regex pattern or a sequence of patterns to evaluate the expected prompt at the time of initial login to the remote host.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>terminal_initial_prompt_checkall</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_terminal_initial_prompt_checkall</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>By default the value is set to <em>False</em> and any one of the prompts mentioned in <code>terminal_initial_prompt</code> option is matched it won't check for other prompts. When set to <em>True</em> it will check for all the prompts mentioned in <code>terminal_initial_prompt</code> option in the given order and all the prompts should be received from remote host if not it will result in timeout.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>terminal_stderr_re</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_terminal_stderr_re</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option provides the regex pattern and optional flags to match the error string from the received response chunk. This option accepts <code>pattern</code> and <code>flags</code> keys. The value of <code>pattern</code> is a python regex pattern to match the response and the value of <code>flags</code> is the value accepted by <em>flags</em> argument of <em>re.compile</em> python method to control the way regex is matched with the response, for example <em>'re.I'</em>.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>terminal_stdout_re</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_terminal_stdout_re</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>A single regex pattern or a sequence of patterns along with optional flags to match the command prompt from the received response chunk. This option accepts <code>pattern</code> and <code>flags</code> keys. The value of <code>pattern</code> is a python regex pattern to match the response and the value of <code>flags</code> is the value accepted by <em>flags</em> argument of <em>re.compile</em> python method to control the way regex is matched with the response, for example <em>'re.I'</em>.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,267 @@
|
||||
.. _ansible.netcommon.network_resource_module:
|
||||
|
||||
|
||||
**********************************
|
||||
ansible.netcommon.network_resource
|
||||
**********************************
|
||||
|
||||
**Manage resource modules**
|
||||
|
||||
|
||||
Version added: 2.4.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- Get list of available resource modules for given os name
|
||||
- Retrieve given resource module configuration facts
|
||||
- Push given resource module configuration
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>config</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">raw</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The resource module configuration. For details on the type and structure of this option refer the individual resource module platform documentation.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>name</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The name of the resource module to manage.</div>
|
||||
<div>The resource module should be supported for given <em>os_name</em>, if not supported it will result in error.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>os_name</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The name of the os to manage the resource modules.</div>
|
||||
<div>The name should be fully qualified collection name format, that is <em><namespace>.<collection-name>.<plugin-name></em>.</div>
|
||||
<div>If value of this option is not set the os value will be read from <em>ansible_network_os</em> variable.</div>
|
||||
<div>If value of both <em>os_name</em> and <em>ansible_network_os</em> is not set it will result in error.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>running_config</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option is used only with state <em>parsed</em>.</div>
|
||||
<div>The value of this option should be the output received from the host device by executing the cli command to get the resource configuration on host.</div>
|
||||
<div>The state <em>parsed</em> reads the configuration from <code>running_config</code> option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the <em>parsed</em> key within the result.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>state</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">-</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The state the configuration should be left in.</div>
|
||||
<div>For supported values refer the individual resource module platform documentation.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- Refer the individual module documentation for the valid inputs of *state* and *config* modules.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: get list of resource modules for given network_os
|
||||
ansible.netcommon.network_resource:
|
||||
register: result
|
||||
|
||||
- name: fetch acl config for
|
||||
ansible.netcommon.network_resource:
|
||||
os_name: cisco.ios.ios
|
||||
name: acls
|
||||
state: gathered
|
||||
|
||||
- name: manage acl config for cisco.ios.ios network os.
|
||||
ansible.netcommon.network_resource:
|
||||
name: acls
|
||||
config:
|
||||
- afi: ipv4
|
||||
acls:
|
||||
- name: test_acl
|
||||
acl_type: extended
|
||||
aces:
|
||||
- grant: deny
|
||||
protocol_options:
|
||||
tcp:
|
||||
fin: true
|
||||
source:
|
||||
address: 192.0.2.0
|
||||
wildcard_bits: 0.0.0.255
|
||||
destination:
|
||||
address: 192.0.3.0
|
||||
wildcard_bits: 0.0.0.255
|
||||
port_protocol:
|
||||
eq: www
|
||||
option:
|
||||
traceroute: true
|
||||
ttl:
|
||||
eq: 10
|
||||
state: merged
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>after</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>when changed and when <em>state</em> and/or <em>config</em> option is set</td>
|
||||
<td>
|
||||
<div>The configuration as structured data after module completion.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">The configuration returned will always be in the same format of the parameters above.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>before</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>When <em>state</em> and/or <em>config</em> option is set</td>
|
||||
<td>
|
||||
<div>The configuration as structured data prior to module invocation.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">The configuration returned will always be in the same format of the parameters above.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>commands</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>When <em>state</em> and/or <em>config</em> option is set</td>
|
||||
<td>
|
||||
<div>The set of commands pushed to the remote device</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">['ip access-list extended 110']</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>modules</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>When only <em>os_name</em> or <em>ansible_network_os</em> is set</td>
|
||||
<td>
|
||||
<div>List of resource modules supported for given OS.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">['acl_interfaces', 'acls', 'bgp_global']</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ganesh B. Nalawade (@ganeshrn)
|
||||
@@ -0,0 +1,191 @@
|
||||
.. _ansible.netcommon.parse_cli_filter:
|
||||
|
||||
|
||||
***************************
|
||||
ansible.netcommon.parse_cli
|
||||
***************************
|
||||
|
||||
**parse_cli filter plugin.**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- The filter plugins converts the output of a network device CLI command into structured JSON output.
|
||||
- Using the parameters below - ``xml_data | ansible.netcommon.parse_cli(template.yml``)
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>output</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">raw</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This source data on which parse_cli invokes.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>tmpl</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The spec file should be valid formatted YAML. It defines how to parse the CLI output and return JSON data.</div>
|
||||
<div>For example <code>cli_data | ansible.netcommon.parse_cli(template.yml</code>), in this case <code>cli_data</code> represents cli output.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- The parse_cli filter will load the spec file and pass the command output through it, returning JSON output. The YAML spec file defines how to parse the CLI output
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Using parse_cli
|
||||
|
||||
# outputConfig
|
||||
|
||||
# ip dhcp pool Data
|
||||
# import all
|
||||
# network 192.168.1.0 255.255.255.0
|
||||
# update dns
|
||||
# default-router 192.168.1.1
|
||||
# dns-server 192.168.1.1 8.8.8.8
|
||||
# option 42 ip 192.168.1.1
|
||||
# domain-name test.local
|
||||
# lease 8
|
||||
|
||||
# pconnection.yml
|
||||
|
||||
# ---
|
||||
# vars:
|
||||
# dhcp_pool:
|
||||
# name: "{{ item.name }}"
|
||||
# network: "{{ item.network_ip }}"
|
||||
# subnet: "{{ item.network_subnet }}"
|
||||
# dns_servers: "{{ item.dns_servers_1 }}{{ item.dns_servers_2 }}"
|
||||
# domain_name: "{{ item.domain_name_0 }}{{ item.domain_name_1 }}{{ item.domain_name_2 }}{{ item.domain_name_3 }}"
|
||||
# options: "{{ item.options_1 }}{{ item.options_2 }}"
|
||||
# lease_days: "{{ item.lease_days }}"
|
||||
# lease_hours: "{{ item.lease_hours }}"
|
||||
# lease_minutes: "{{ item.lease_minutes }}"
|
||||
|
||||
# keys:
|
||||
# dhcp_pools:
|
||||
# value: "{{ dhcp_pool }}"
|
||||
# items: "^ip dhcp pool (
|
||||
# ?P<name>[^\\n]+)\\s+(?:import (?P<import_all>all)\\s*)?(?:network (?P<network_ip>[\\d.]+)
|
||||
# (?P<network_subnet>[\\d.]+)?\\s*)?(?:update dns\\s*)?(?:host (?P<host_ip>[\\d.]+)
|
||||
# (?P<host_subnet>[\\d.]+)\\s*)?(?:domain-name (?P<domain_name_0>[\\w._-]+)\\s+)?
|
||||
# (?:default-router (?P<default_router>[\\d.]+)\\s*)?(?:dns-server
|
||||
# (?P<dns_servers_1>(?:[\\d.]+ ?)+ ?)+\\s*)?(?:domain-name (?P<domain_name_1>[\\w._-]+)\\s+)?
|
||||
# (?P<options_1>(?:option [^\\n]+\\n*\\s*)*)?(?:domain-name (?P<domain_name_2>[\\w._-]+)\\s+)?(?P<options_2>(?:option [^\\n]+\\n*\\s*)*)?
|
||||
# (?:dns-server (?P<dns_servers_2>(?:[\\d.]+ ?)+ ?)+\\s*)?(?:domain-name
|
||||
# (?P<domain_name_3>[\\w._-]+)\\s*)?(lease (?P<lease_days>\\d+)(?: (?P<lease_hours>\\d+))?(?: (?P<lease_minutes>\\d+))?\\s*)?(?:update arp)?"
|
||||
|
||||
# playbook
|
||||
|
||||
- name: Add config data
|
||||
ansible.builtin.set_fact:
|
||||
opconfig: "{{lookup('ansible.builtin.file', 'outputConfig') }}"
|
||||
|
||||
- name: Parse Data
|
||||
ansible.builtin.set_fact:
|
||||
output: "{{ opconfig | parse_cli('pconnection.yml') }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Add config data]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# xml: |-
|
||||
# ip dhcp pool Data
|
||||
# import all
|
||||
# network 192.168.1.0 255.255.255.0
|
||||
# update dns
|
||||
# default-router 192.168.1.1
|
||||
# dns-server 192.168.1.1 8.8.8.8
|
||||
# option 42 ip 192.168.1.1
|
||||
# domain-name test.local
|
||||
# lease 8
|
||||
|
||||
# TASK [Parse Data]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# output:
|
||||
# dhcp_pools:
|
||||
# - dns_servers: 192.168.1.1 8.8.8.8
|
||||
# domain_name: test.local
|
||||
# lease_days: 8
|
||||
# lease_hours: null
|
||||
# lease_minutes: null
|
||||
# name: Data
|
||||
# network: 192.168.1.0
|
||||
# options: |-
|
||||
# option 42 ip 192.168.1.1
|
||||
# subnet: 255.255.255.0
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Peter Sprygada (@privateip)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,148 @@
|
||||
.. _ansible.netcommon.parse_cli_textfsm_filter:
|
||||
|
||||
|
||||
***********************************
|
||||
ansible.netcommon.parse_cli_textfsm
|
||||
***********************************
|
||||
|
||||
**parse_cli_textfsm filter plugin.**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- The network filters also support parsing the output of a CLI command using the TextFSM library. To parse the CLI output with TextFSM use this filter.
|
||||
- Using the parameters below - ``data | ansible.netcommon.parse_cli_textfsm(template.yml``)
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>template</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The template to compare it with.</div>
|
||||
<div>For example <code>data | ansible.netcommon.parse_cli_textfsm(template.yml</code>), in this case <code>data</code> represents this option.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>value</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">raw</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This source data on which parse_cli_textfsm invokes.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- Use of the TextFSM filter requires the TextFSM library to be installed.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Using parse_cli_textfsm
|
||||
|
||||
- name: "Fetch command output"
|
||||
cisco.ios.ios_command:
|
||||
commands:
|
||||
- show lldp neighbors
|
||||
register: lldp_output
|
||||
|
||||
- name: "Invoke parse_cli_textfsm"
|
||||
ansible.builtin.set_fact:
|
||||
device_neighbors: "{{ lldp_output.stdout[0] | parse_cli_textfsm('~/ntc-templates/templates/cisco_ios_show_lldp_neighbors.textfsm') }}"
|
||||
|
||||
- name: "Debug"
|
||||
ansible.builtindebug:
|
||||
msg: "{{ device_neighbors }}"
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Fetch command output]
|
||||
# ok: [rtr-2]
|
||||
|
||||
# TASK [Invoke parse_cli_textfsm]
|
||||
# ok: [rtr-1]
|
||||
|
||||
# TASK [Debug]
|
||||
# ok: [rtr-1] => {
|
||||
# "msg": [
|
||||
# {
|
||||
# "CAPABILITIES": "R",
|
||||
# "LOCAL_INTERFACE": "Gi0/0",
|
||||
# "NEIGHBOR": "rtr-3",
|
||||
# "NEIGHBOR_INTERFACE": "Gi0/0"
|
||||
# },
|
||||
# {
|
||||
# "CAPABILITIES": "R",
|
||||
# "LOCAL_INTERFACE": "Gi0/1",
|
||||
# "NEIGHBOR": "rtr-1",
|
||||
# "NEIGHBOR_INTERFACE": "Gi0/1"
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Peter Sprygada (@privateip)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,223 @@
|
||||
.. _ansible.netcommon.parse_xml_filter:
|
||||
|
||||
|
||||
***************************
|
||||
ansible.netcommon.parse_xml
|
||||
***************************
|
||||
|
||||
**The parse_xml filter plugin.**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This filter will load the spec file and pass the command output through it, returning JSON output.
|
||||
- The YAML spec file defines how to parse the CLI output.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>output</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">raw</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This source xml on which parse_xml invokes.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>tmpl</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The spec file should be valid formatted YAML. It defines how to parse the XML output and return JSON data.</div>
|
||||
<div>For example <code>xml_data | ansible.netcommon.parse_xml(template.yml</code>), in this case <code>xml_data</code> represents xml data option.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- To convert the XML output of a network device command into structured JSON output.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Using parse_xml
|
||||
|
||||
# example_output.xml
|
||||
|
||||
# <?xml version="1.0" encoding="UTF-8"?>
|
||||
# <rpc-reply message-id="urn:uuid:0cadb4e8-5bba-47f4-986e-72906227007f">
|
||||
# <data>
|
||||
# <ntp>
|
||||
# <nodes>
|
||||
# <node>
|
||||
# <node>0/0/CPU0</node>
|
||||
# <associations>
|
||||
# <is-ntp-enabled>true</is-ntp-enabled>
|
||||
# <sys-leap>ntp-leap-no-warning</sys-leap>
|
||||
# <peer-summary-info>
|
||||
# <peer-info-common>
|
||||
# <host-mode>ntp-mode-client</host-mode>
|
||||
# <is-configured>true</is-configured>
|
||||
# <address>10.1.1.1</address>
|
||||
# <reachability>0</reachability>
|
||||
# </peer-info-common>
|
||||
# <time-since>-1</time-since>
|
||||
# </peer-summary-info>
|
||||
# <peer-summary-info>
|
||||
# <peer-info-common>
|
||||
# <host-mode>ntp-mode-client</host-mode>
|
||||
# <is-configured>true</is-configured>
|
||||
# <address>172.16.252.29</address>
|
||||
# <reachability>255</reachability>
|
||||
# </peer-info-common>
|
||||
# <time-since>991</time-since>
|
||||
# </peer-summary-info>
|
||||
# </associations>
|
||||
# </node>
|
||||
# </nodes>
|
||||
# </ntp>
|
||||
# </data>
|
||||
# </rpc-reply>
|
||||
|
||||
# parse_xml.yml
|
||||
|
||||
# ---
|
||||
# vars:
|
||||
# ntp_peers:
|
||||
# address: "{{ item.address }}"
|
||||
# reachability: "{{ item.reachability}}"
|
||||
# keys:
|
||||
# result:
|
||||
# value: "{{ ntp_peers }}"
|
||||
# top: data/ntp/nodes/node/associations
|
||||
# items:
|
||||
# address: peer-summary-info/peer-info-common/address
|
||||
# reachability: peer-summary-info/peer-info-common/reachability
|
||||
|
||||
|
||||
- name: Facts setup
|
||||
ansible.builtin.set_fact:
|
||||
xml: "{{ lookup('file', 'example_output.xml') }}"
|
||||
|
||||
- name: Parse xml invocation
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ xml | ansible.netcommon.parse_xml('parse_xml.yml') }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [set xml Data]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# xml: |-
|
||||
# <?xml version="1.0" encoding="UTF-8"?>
|
||||
# <rpc-reply message-id="urn:uuid:0cadb4e8-5bba-47f4-986e-72906227007f">
|
||||
# <data>
|
||||
# <ntp>
|
||||
# <nodes>
|
||||
# <node>
|
||||
# <node>0/0/CPU0</node>
|
||||
# <associations>
|
||||
# <is-ntp-enabled>true</is-ntp-enabled>
|
||||
# <sys-leap>ntp-leap-no-warning</sys-leap>
|
||||
# <peer-summary-info>
|
||||
# <peer-info-common>
|
||||
# <host-mode>ntp-mode-client</host-mode>
|
||||
# <is-configured>true</is-configured>
|
||||
# <address>10.1.1.1</address>
|
||||
# <reachability>0</reachability>
|
||||
# </peer-info-common>
|
||||
# <time-since>-1</time-since>
|
||||
# </peer-summary-info>
|
||||
# <peer-summary-info>
|
||||
# <peer-info-common>
|
||||
# <host-mode>ntp-mode-client</host-mode>
|
||||
# <is-configured>true</is-configured>
|
||||
# <address>172.16.252.29</address>
|
||||
# <reachability>255</reachability>
|
||||
# </peer-info-common>
|
||||
# <time-since>991</time-since>
|
||||
# </peer-summary-info>
|
||||
# </associations>
|
||||
# </node>
|
||||
# </nodes>
|
||||
# </ntp>
|
||||
# </data>
|
||||
# </rpc-reply>
|
||||
|
||||
# TASK [Parse Data]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# output:
|
||||
# result:
|
||||
# - address:
|
||||
# - 10.1.1.1
|
||||
# - 172.16.252.29
|
||||
# reachability:
|
||||
# - '0'
|
||||
# - '255'
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ganesh Nalawade (@ganeshrn)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,151 @@
|
||||
.. _ansible.netcommon.persistent_connection:
|
||||
|
||||
|
||||
****************************
|
||||
ansible.netcommon.persistent
|
||||
****************************
|
||||
|
||||
**Use a persistent unix socket for connection**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This is a helper plugin to allow making other connections persistent.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>import_modules</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"yes"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[ansible_network]<br>import_modules = yes</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_NETWORK_IMPORT_MODULES</div>
|
||||
<div>var: ansible_network_import_modules</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Reduce CPU usage and network module execution time by enabling direct execution. Instead of the module being packaged and executed by the shell, it will be directly executed by the Ansible control node using the same python interpreter as the Ansible process. Note- Incompatible with <code>asynchronous mode</code>. Note- Python 3 and Ansible 2.9.16 or greater required. Note- With Ansible 2.9.x fully qualified modules names are required in tasks.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_command_timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">30</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>command_timeout = 30</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_COMMAND_TIMEOUT</div>
|
||||
<div>var: ansible_command_timeout</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures, in seconds, the amount of time to wait for a command to return from the remote device. If this timer is exceeded before the command returns, the connection plugin will raise an exception and close.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_connect_timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">30</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>connect_timeout = 30</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_CONNECT_TIMEOUT</div>
|
||||
<div>var: ansible_connect_timeout</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Configures, in seconds, the amount of time to wait when trying to initially establish a persistent connection. If this value expires before the connection to the remote device is completed, the connection will fail.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>persistent_log_messages</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"no"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div> ini entries:
|
||||
<p>[persistent_connection]<br>log_messages = no</p>
|
||||
</div>
|
||||
<div>env:ANSIBLE_PERSISTENT_LOG_MESSAGES</div>
|
||||
<div>var: ansible_persistent_log_messages</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>This flag will enable logging the command executed and response received from target device in the ansible log file. For this option to work 'log_path' ansible configuration option is required to be set to a file path with write access.</div>
|
||||
<div>Be sure to fully understand the security implications of enabling this option as it could create a security vulnerability by logging sensitive information in log file.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,226 @@
|
||||
.. _ansible.netcommon.restconf_config_module:
|
||||
|
||||
|
||||
*********************************
|
||||
ansible.netcommon.restconf_config
|
||||
*********************************
|
||||
|
||||
**Handles create, update, read and delete of configuration data on RESTCONF enabled devices.**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- RESTCONF is a standard mechanisms to allow web applications to configure and manage data. RESTCONF is a IETF standard and documented on RFC 8040.
|
||||
- This module allows the user to configure data on RESTCONF enabled devices.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>content</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The configuration data in format as specififed in <code>format</code> option. Required unless <code>method</code> is <em>delete</em>.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>format</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>json</b> ←</div></li>
|
||||
<li>xml</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The format of the configuration provided as value of <code>content</code>. Accepted values are <em>xml</em> and <em>json</em> and the given configuration format should be supported by remote RESTCONF server.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>method</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>post</b> ←</div></li>
|
||||
<li>put</li>
|
||||
<li>patch</li>
|
||||
<li>delete</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The RESTCONF method to manage the configuration change on device. The value <em>post</em> is used to create a data resource or invoke an operation resource, <em>put</em> is used to replace the target data resource, <em>patch</em> is used to modify the target resource, and <em>delete</em> is used to delete the target resource.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>path</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>URI being used to execute API calls.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- This module requires the RESTCONF system service be enabled on the remote device being managed.
|
||||
- This module is supported with *ansible_connection* value of *ansible.netcommon.httpapi* and *ansible_network_os* value of *ansible.netcommon.restconf*.
|
||||
- This module is tested against Cisco IOSXE 16.12.02 version.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: create l3vpn services
|
||||
ansible.netcommon.restconf_config:
|
||||
path: /config/ietf-l3vpn-svc:l3vpn-svc/vpn-services
|
||||
content: |
|
||||
{
|
||||
"vpn-service":[
|
||||
{
|
||||
"vpn-id": "red_vpn2",
|
||||
"customer-name": "blue",
|
||||
"vpn-service-topology": "ietf-l3vpn-svc:any-to-any"
|
||||
},
|
||||
{
|
||||
"vpn-id": "blue_vpn1",
|
||||
"customer-name": "red",
|
||||
"vpn-service-topology": "ietf-l3vpn-svc:any-to-any"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>candidate</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>When the method is not delete</td>
|
||||
<td>
|
||||
<div>The configuration sent to the device.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">{
|
||||
"vpn-service": [
|
||||
{
|
||||
"customer-name": "red",
|
||||
"vpn-id": "blue_vpn1",
|
||||
"vpn-service-topology": "ietf-l3vpn-svc:any-to-any"
|
||||
}
|
||||
]
|
||||
}</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>running</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>When the method is not delete</td>
|
||||
<td>
|
||||
<div>The current running configuration on the device.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">{
|
||||
"vpn-service": [
|
||||
{
|
||||
"vpn-id": "red_vpn2",
|
||||
"customer-name": "blue",
|
||||
"vpn-service-topology": "ietf-l3vpn-svc:any-to-any"
|
||||
},
|
||||
{
|
||||
"vpn-id": "blue_vpn1",
|
||||
"customer-name": "red",
|
||||
"vpn-service-topology": "ietf-l3vpn-svc:any-to-any"
|
||||
}
|
||||
]
|
||||
}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ganesh Nalawade (@ganeshrn)
|
||||
@@ -0,0 +1,167 @@
|
||||
.. _ansible.netcommon.restconf_get_module:
|
||||
|
||||
|
||||
******************************
|
||||
ansible.netcommon.restconf_get
|
||||
******************************
|
||||
|
||||
**Fetch configuration/state data from RESTCONF enabled devices.**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- RESTCONF is a standard mechanisms to allow web applications to access the configuration data and state data developed and standardized by the IETF. It is documented in RFC 8040.
|
||||
- This module allows the user to fetch configuration and state data from RESTCONF enabled devices.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>content</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>config</li>
|
||||
<li>nonconfig</li>
|
||||
<li>all</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The <code>content</code> is a query parameter that controls how descendant nodes of the requested data nodes in <code>path</code> will be processed in the reply. If value is <em>config</em> return only configuration descendant data nodes of value in <code>path</code>. If value is <em>nonconfig</em> return only non-configuration descendant data nodes of value in <code>path</code>. If value is <em>all</em> return all descendant data nodes of value in <code>path</code></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>output</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>json</b> ←</div></li>
|
||||
<li>xml</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>The output of response received.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>path</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>URI being used to execute API calls.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- This module requires the RESTCONF system service be enabled on the remote device being managed.
|
||||
- This module is supported with *ansible_connection* value of *ansible.netcommon.httpapi* and *ansible_network_os* value of *ansible.netcommon.restconf*.
|
||||
- This module is tested against Cisco IOSXE 16.12.02 version.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: get l3vpn services
|
||||
ansible.netcommon.restconf_get:
|
||||
path: /config/ietf-l3vpn-svc:l3vpn-svc/vpn-services
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>response</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">dictionary</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>when the device response is valid JSON</td>
|
||||
<td>
|
||||
<div>A dictionary representing a JSON-formatted response</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">{
|
||||
"vpn-services": {
|
||||
"vpn-service": [
|
||||
{
|
||||
"customer-name": "red",
|
||||
"vpn-id": "blue_vpn1",
|
||||
"vpn-service-topology": "ietf-l3vpn-svc:any-to-any"
|
||||
}
|
||||
]
|
||||
}
|
||||
}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ganesh Nalawade (@ganeshrn)
|
||||
@@ -0,0 +1,77 @@
|
||||
.. _ansible.netcommon.restconf_httpapi:
|
||||
|
||||
|
||||
**************************
|
||||
ansible.netcommon.restconf
|
||||
**************************
|
||||
|
||||
**HttpApi Plugin for devices supporting Restconf API**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- This HttpApi plugin provides methods to connect to Restconf API endpoints.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>root_path</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"/restconf"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_httpapi_restconf_root</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Specifies the location of the Restconf root.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,319 @@
|
||||
.. _ansible.netcommon.telnet_module:
|
||||
|
||||
|
||||
************************
|
||||
ansible.netcommon.telnet
|
||||
************************
|
||||
|
||||
**Executes a low-down and dirty telnet command**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- Executes a low-down and dirty telnet command, not going through the module subsystem.
|
||||
- This is mostly to be used for enabling ssh on devices that only have telnet enabled by default.
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>command</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=string</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>List of commands to be executed in the telnet session.</div>
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: commands</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>crlf</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Sends a CRLF (Carrage Return) instead of just a LF (Line Feed).</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>host</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"remote_addr"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The host/target on which to execute the command</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>login_prompt</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"login: "</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Login or username prompt to expect</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>password</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The password for login</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>password_prompt</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"Password: "</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Login or username prompt to expect</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>pause</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">1</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Seconds to pause between each command issued</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>port</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">23</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Remote port to use</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>prompts</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">["$"]</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>List of prompts expected before sending next command</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>send_newline</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Sends a newline character upon successful connection to start the terminal session.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>timeout</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">120</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>timeout for remote operations</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>user</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">"remote_user"</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>The user for login</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- The ``environment`` keyword does not work with this task
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: send configuration commands to IOS
|
||||
ansible.netcommon.telnet:
|
||||
user: cisco
|
||||
password: cisco
|
||||
login_prompt: "Username: "
|
||||
prompts:
|
||||
- "[>#]"
|
||||
command:
|
||||
- terminal length 0
|
||||
- configure terminal
|
||||
- hostname ios01
|
||||
|
||||
- name: run show commands
|
||||
ansible.netcommon.telnet:
|
||||
user: cisco
|
||||
password: cisco
|
||||
login_prompt: "Username: "
|
||||
prompts:
|
||||
- "[>#]"
|
||||
command:
|
||||
- terminal length 0
|
||||
- show version
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>output</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>output of each command is an element in this list</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">['success', 'success', '', 'warning .. something']</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ansible Core Team
|
||||
@@ -0,0 +1,127 @@
|
||||
.. _ansible.netcommon.type5_pw_filter:
|
||||
|
||||
|
||||
**************************
|
||||
ansible.netcommon.type5_pw
|
||||
**************************
|
||||
|
||||
**The type5_pw filter plugin.**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- Filter plugin to produce cisco type5 hashed password.
|
||||
- Using the parameters below - ``xml_data | ansible.netcommon.type5_pw(template.yml``)
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>password</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The password to be hashed.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>salt</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Mention the salt to hash the password.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- The filter plugin generates cisco type5 hashed password.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Using type5_pw
|
||||
|
||||
- name: Set some facts
|
||||
ansible.builtin.set_fact:
|
||||
password: "cisco@123"
|
||||
|
||||
- name: Filter type5_pw invocation
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ password | ansible.netcommon.type5_pw(salt='avs') }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Set some facts]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# password: cisco@123
|
||||
|
||||
# TASK [Filter type5_pw invocation]
|
||||
# ok: [host] =>
|
||||
# msg: $1$avs$uSTOEMh65qzvpb9yBMpzd/
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Ken Celenza (@itdependsnetworks)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,119 @@
|
||||
.. _ansible.netcommon.vlan_expander_filter:
|
||||
|
||||
|
||||
*******************************
|
||||
ansible.netcommon.vlan_expander
|
||||
*******************************
|
||||
|
||||
**The vlan_expander filter plugin.**
|
||||
|
||||
|
||||
Version added: 2.3.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- Expand shorthand list of VLANs to list all VLANs. Inverse of vlan_parser
|
||||
- Using the parameters below - ``vlans_data | ansible.netcommon.vlan_expander``
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>data</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option represents a string containing the range of vlans.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- The filter plugin extends vlans when data provided in range or comma separated.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Using vlan_expander
|
||||
|
||||
- name: Setting host facts for vlan_expander filter plugin
|
||||
ansible.builtin.set_fact:
|
||||
vlan_ranges: "1,10-12,15,20-22"
|
||||
|
||||
- name: Invoke vlan_expander filter plugin
|
||||
ansible.builtin.set_fact:
|
||||
extended_vlans: "{{ vlan_ranges | ansible.netcommon.vlan_expander }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Setting host facts for vlan_expander filter plugin]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# vlan_ranges: 1,10-12,15,20-22
|
||||
|
||||
# TASK [Invoke vlan_expander filter plugin]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# extended_vlans:
|
||||
# - 1
|
||||
# - 10
|
||||
# - 11
|
||||
# - 12
|
||||
# - 15
|
||||
# - 20
|
||||
# - 21
|
||||
# - 22
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Akira Yokochi (@akira6592)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
@@ -0,0 +1,181 @@
|
||||
.. _ansible.netcommon.vlan_parser_filter:
|
||||
|
||||
|
||||
*****************************
|
||||
ansible.netcommon.vlan_parser
|
||||
*****************************
|
||||
|
||||
**The vlan_parser filter plugin.**
|
||||
|
||||
|
||||
Version added: 1.0.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- The filter plugin converts a list of vlans to IOS like vlan configuration.
|
||||
- Converts list to a list of range of numbers into multiple lists.
|
||||
- ``vlans_data | ansible.netcommon.vlan_parser(first_line_len = 20, other_line_len=20``)
|
||||
|
||||
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th>Configuration</th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>data</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>This option represents a list containing vlans.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>first_line_len</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">48</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The first line of the list can be first_line_len characters long.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>other_line_len</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">integer</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">44</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The subsequent list lines can be other_line_len characters.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
.. note::
|
||||
- The filter plugin extends vlans when data provided in range or comma separated.
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Using vlan_parser
|
||||
|
||||
- name: Setting host facts for vlan_parser filter plugin
|
||||
ansible.builtin.set_fact:
|
||||
vlans:
|
||||
[
|
||||
100,
|
||||
1688,
|
||||
3002,
|
||||
3003,
|
||||
3004,
|
||||
3005,
|
||||
3102,
|
||||
3103,
|
||||
3104,
|
||||
3105,
|
||||
3802,
|
||||
3900,
|
||||
3998,
|
||||
3999,
|
||||
]
|
||||
|
||||
- name: Invoke vlan_parser filter plugin
|
||||
ansible.builtin.set_fact:
|
||||
vlans_ranges: "{{ vlans | ansible.netcommon.vlan_parser(first_line_len = 20, other_line_len=20) }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Setting host facts for vlan_parser filter plugin]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# vlans:
|
||||
# - 100
|
||||
# - 1688
|
||||
# - 3002
|
||||
# - 3003
|
||||
# - 3004
|
||||
# - 3005
|
||||
# - 3102
|
||||
# - 3103
|
||||
# - 3104
|
||||
# - 3105
|
||||
# - 3802
|
||||
# - 3900
|
||||
# - 3998
|
||||
# - 3999
|
||||
|
||||
# TASK [Invoke vlan_parser filter plugin]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# msg:
|
||||
# - 100,1688,3002-3005
|
||||
# - 3102-3105,3802,3900
|
||||
# - 3998,3999
|
||||
|
||||
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Steve Dodd (@idahood)
|
||||
|
||||
|
||||
.. hint::
|
||||
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||
94
collection/ansible/netcommon/meta/runtime.yml
Normal file
94
collection/ansible/netcommon/meta/runtime.yml
Normal file
@@ -0,0 +1,94 @@
|
||||
---
|
||||
requires_ansible: ">=2.14.0"
|
||||
plugin_routing:
|
||||
action:
|
||||
grpc_config:
|
||||
redirect: ansible.netcommon.grpc
|
||||
grpc_get:
|
||||
redirect: ansible.netcommon.grpc
|
||||
filter:
|
||||
cidr_merge:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.cidr_merge' module instead.
|
||||
redirect: ansible.utils.cidr_merge
|
||||
ipaddr:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.ipaddr' module instead.
|
||||
redirect: ansible.utils.ipaddr
|
||||
ipmath:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.ipmath' module instead.
|
||||
redirect: ansible.utils.ipmath
|
||||
ipwrap:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.ipwrap' module instead.
|
||||
redirect: ansible.utils.ipwrap
|
||||
ip4_hex:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.ip4_hex' module instead.
|
||||
redirect: ansible.utils.ipv4_hex
|
||||
ipv4:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.ipv4' module instead.
|
||||
redirect: ansible.utils.ipv4
|
||||
ipv6:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.ipv6' module instead.
|
||||
redirect: ansible.utils.ipv6
|
||||
ipsubnet:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.ipsubnet' module instead.
|
||||
redirect: ansible.utils.ipsubnet
|
||||
next_nth_usable:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.next_nth_usable' module instead.
|
||||
redirect: ansible.utils.next_nth_usable
|
||||
network_in_network:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.network_in_network' module instead.
|
||||
redirect: ansible.utils.network_in_network
|
||||
network_in_usable:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.network_in_usable' module instead.
|
||||
redirect: ansible.utils.network_in_usable
|
||||
reduce_on_network:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.reduce_on_network' module instead.
|
||||
redirect: ansible.utils.reduce_on_network
|
||||
nthhost:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.nthhost' module instead.
|
||||
redirect: ansible.utils.nthhost
|
||||
previous_nth_usable:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.previous_nth_usable' module instead.
|
||||
redirect: ansible.utils.previous_nth_usable
|
||||
slaac:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.slaac' module instead.
|
||||
redirect: ansible.utils.slaac
|
||||
hwaddr:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.hwaddr' module instead.
|
||||
redirect: ansible.utils.hwaddr
|
||||
macaddr:
|
||||
deprecation:
|
||||
removal_date: "2024-01-01"
|
||||
warning_text: Use 'ansible.utils.macaddr' module instead.
|
||||
redirect: ansible.utils.macaddr
|
||||
31
collection/ansible/netcommon/plugins/action/cli_backup.py
Normal file
31
collection/ansible/netcommon/plugins/action/cli_backup.py
Normal file
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# Copyright 2018 Red Hat Inc.
|
||||
# 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
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.action.network import (
|
||||
ActionModule as ActionNetworkModule,
|
||||
)
|
||||
|
||||
|
||||
class ActionModule(ActionNetworkModule):
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
if self._play_context.connection.split(".")[-1] != "network_cli":
|
||||
return {
|
||||
"failed": True,
|
||||
"msg": "Connection type %s is not valid for this module"
|
||||
% self._play_context.connection,
|
||||
}
|
||||
result = super(ActionModule, self).run(task_vars=task_vars)
|
||||
self._handle_backup_option(
|
||||
result,
|
||||
task_vars,
|
||||
self._task.args,
|
||||
)
|
||||
|
||||
return result
|
||||
24
collection/ansible/netcommon/plugins/action/cli_command.py
Normal file
24
collection/ansible/netcommon/plugins/action/cli_command.py
Normal file
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright 2018 Red Hat Inc.
|
||||
# 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
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.action.network import (
|
||||
ActionModule as ActionNetworkModule,
|
||||
)
|
||||
|
||||
|
||||
class ActionModule(ActionNetworkModule):
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
if self._play_context.connection.split(".")[-1] != "network_cli":
|
||||
return {
|
||||
"failed": True,
|
||||
"msg": "Connection type %s is not valid for this module"
|
||||
% self._play_context.connection,
|
||||
}
|
||||
return super(ActionModule, self).run(task_vars=task_vars)
|
||||
28
collection/ansible/netcommon/plugins/action/cli_config.py
Normal file
28
collection/ansible/netcommon/plugins/action/cli_config.py
Normal file
@@ -0,0 +1,28 @@
|
||||
#
|
||||
# Copyright 2018 Red Hat Inc.
|
||||
# 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
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.action.network import (
|
||||
ActionModule as ActionNetworkModule,
|
||||
)
|
||||
|
||||
|
||||
class ActionModule(ActionNetworkModule):
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
del tmp # tmp no longer has any effect
|
||||
|
||||
self._config_module = True
|
||||
if self._play_context.connection.split(".")[-1] != "network_cli":
|
||||
return {
|
||||
"failed": True,
|
||||
"msg": "Connection type %s is not valid for cli_config module"
|
||||
% self._play_context.connection,
|
||||
}
|
||||
|
||||
return super(ActionModule, self).run(task_vars=task_vars)
|
||||
35
collection/ansible/netcommon/plugins/action/grpc.py
Normal file
35
collection/ansible/netcommon/plugins/action/grpc.py
Normal file
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright 2022 Red Hat Inc.
|
||||
# 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
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.action.network import (
|
||||
ActionModule as ActionNetworkModule,
|
||||
)
|
||||
|
||||
|
||||
class ActionModule(ActionNetworkModule):
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
del tmp # tmp no longer has any effect
|
||||
|
||||
self._config_module = True
|
||||
warnings = []
|
||||
if self._play_context.connection.split(".")[-1] != "grpc":
|
||||
return {
|
||||
"failed": True,
|
||||
"msg": "Connection type %s is not valid for grpc module. "
|
||||
"Valid connection type is grpc" % self._play_context.connection,
|
||||
}
|
||||
|
||||
result = super(ActionModule, self).run(task_vars=task_vars)
|
||||
if warnings:
|
||||
if "warnings" in result:
|
||||
result["warnings"].extend(warnings)
|
||||
else:
|
||||
result["warnings"] = warnings
|
||||
return result
|
||||
182
collection/ansible/netcommon/plugins/action/net_get.py
Normal file
182
collection/ansible/netcommon/plugins/action/net_get.py
Normal file
@@ -0,0 +1,182 @@
|
||||
# (c) 2018, Ansible Inc,
|
||||
# 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 hashlib
|
||||
import os
|
||||
import re
|
||||
import uuid
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.connection import Connection, ConnectionError
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlsplit
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
class ActionModule(ActionBase):
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
changed = False
|
||||
socket_path = None
|
||||
self._get_network_os(task_vars)
|
||||
persistent_connection = self._play_context.connection.split(".")[-1]
|
||||
|
||||
result = super(ActionModule, self).run(task_vars=task_vars)
|
||||
|
||||
if persistent_connection != "network_cli":
|
||||
# It is supported only with network_cli
|
||||
result["failed"] = True
|
||||
result["msg"] = (
|
||||
"connection type %s is not valid for net_get module,"
|
||||
" please use fully qualified name of network_cli connection type"
|
||||
% self._play_context.connection
|
||||
)
|
||||
return result
|
||||
|
||||
try:
|
||||
src = self._task.args["src"]
|
||||
except KeyError as exc:
|
||||
return {
|
||||
"failed": True,
|
||||
"msg": "missing required argument: %s" % exc,
|
||||
}
|
||||
|
||||
# Get destination file if specified
|
||||
dest = self._task.args.get("dest")
|
||||
|
||||
if dest is None:
|
||||
dest = self._get_default_dest(src)
|
||||
else:
|
||||
dest = self._handle_dest_path(dest)
|
||||
|
||||
# Get proto
|
||||
proto = self._task.args.get("protocol")
|
||||
if proto is None:
|
||||
proto = "scp"
|
||||
|
||||
if socket_path is None:
|
||||
socket_path = self._connection.socket_path
|
||||
|
||||
conn = Connection(socket_path)
|
||||
sock_timeout = conn.get_option("persistent_command_timeout")
|
||||
|
||||
try:
|
||||
changed = self._handle_existing_file(conn, src, dest, proto, sock_timeout)
|
||||
if changed is False:
|
||||
result["changed"] = changed
|
||||
result["destination"] = dest
|
||||
return result
|
||||
except Exception as exc:
|
||||
result["msg"] = "Warning: %s idempotency check failed. Check dest" % exc
|
||||
|
||||
try:
|
||||
conn.get_file(source=src, destination=dest, proto=proto, timeout=sock_timeout)
|
||||
except Exception as exc:
|
||||
result["failed"] = True
|
||||
result["msg"] = "Exception received: %s" % exc
|
||||
|
||||
result["changed"] = changed
|
||||
result["destination"] = dest
|
||||
return result
|
||||
|
||||
def _handle_dest_path(self, dest):
|
||||
working_path = self._get_working_path()
|
||||
|
||||
if os.path.isabs(dest) or urlsplit("dest").scheme:
|
||||
dst = dest
|
||||
else:
|
||||
dst = self._loader.path_dwim_relative(working_path, "", dest)
|
||||
|
||||
return dst
|
||||
|
||||
def _get_src_filename_from_path(self, src_path):
|
||||
filename_list = re.split("/|:", src_path)
|
||||
return filename_list[-1]
|
||||
|
||||
def _get_default_dest(self, src_path):
|
||||
dest_path = self._get_working_path()
|
||||
src_fname = self._get_src_filename_from_path(src_path)
|
||||
filename = "%s/%s" % (dest_path, src_fname)
|
||||
return filename
|
||||
|
||||
def _handle_existing_file(self, conn, source, dest, proto, timeout):
|
||||
"""
|
||||
Determines whether the source and destination file match.
|
||||
|
||||
:return: False if source and dest both exist and have matching sha1 sums, True otherwise.
|
||||
"""
|
||||
if not os.path.exists(dest):
|
||||
return True
|
||||
|
||||
cwd = self._loader.get_basedir()
|
||||
filename = str(uuid.uuid4())
|
||||
tmp_dest_file = os.path.join(cwd, filename)
|
||||
try:
|
||||
conn.get_file(
|
||||
source=source,
|
||||
destination=tmp_dest_file,
|
||||
proto=proto,
|
||||
timeout=timeout,
|
||||
)
|
||||
except ConnectionError as exc:
|
||||
error = to_text(exc)
|
||||
if error.endswith("No such file or directory"):
|
||||
if os.path.exists(tmp_dest_file):
|
||||
os.remove(tmp_dest_file)
|
||||
return True
|
||||
|
||||
try:
|
||||
with open(tmp_dest_file, "r") as f:
|
||||
new_content = f.read()
|
||||
with open(dest, "r") as f:
|
||||
old_content = f.read()
|
||||
except (IOError, OSError):
|
||||
os.remove(tmp_dest_file)
|
||||
raise
|
||||
|
||||
sha1 = hashlib.sha1()
|
||||
old_content_b = to_bytes(old_content, errors="surrogate_or_strict")
|
||||
sha1.update(old_content_b)
|
||||
checksum_old = sha1.digest()
|
||||
|
||||
sha1 = hashlib.sha1()
|
||||
new_content_b = to_bytes(new_content, errors="surrogate_or_strict")
|
||||
sha1.update(new_content_b)
|
||||
checksum_new = sha1.digest()
|
||||
os.remove(tmp_dest_file)
|
||||
if checksum_old == checksum_new:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _get_working_path(self):
|
||||
cwd = self._loader.get_basedir()
|
||||
if self._task._role is not None:
|
||||
cwd = self._task._role._role_path
|
||||
return cwd
|
||||
|
||||
def _get_network_os(self, task_vars):
|
||||
if "network_os" in self._task.args and self._task.args["network_os"]:
|
||||
display.vvvv("Getting network OS from task argument")
|
||||
network_os = self._task.args["network_os"]
|
||||
elif self._play_context.network_os:
|
||||
display.vvvv("Getting network OS from inventory")
|
||||
network_os = self._play_context.network_os
|
||||
elif (
|
||||
"network_os" in task_vars.get("ansible_facts", {})
|
||||
and task_vars["ansible_facts"]["network_os"]
|
||||
):
|
||||
display.vvvv("Getting network OS from fact")
|
||||
network_os = task_vars["ansible_facts"]["network_os"]
|
||||
else:
|
||||
raise AnsibleError("ansible_network_os must be specified on this host")
|
||||
|
||||
return network_os
|
||||
87
collection/ansible/netcommon/plugins/action/net_ping.py
Normal file
87
collection/ansible/netcommon/plugins/action/net_ping.py
Normal file
@@ -0,0 +1,87 @@
|
||||
# (c) 2017, Ansible by Red Hat, inc
|
||||
# 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 copy
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
class ActionModule(ActionBase):
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
del tmp # tmp no longer has any effect
|
||||
|
||||
result = {}
|
||||
play_context = copy.deepcopy(self._play_context)
|
||||
play_context.network_os = self._get_network_os(task_vars)
|
||||
new_task = self._task.copy()
|
||||
|
||||
module = self._get_implementation_module(play_context.network_os, self._task.action)
|
||||
if not module:
|
||||
if self._task.args["fail_on_missing_module"]:
|
||||
result["failed"] = True
|
||||
else:
|
||||
result["failed"] = False
|
||||
|
||||
result["msg"] = "Could not find implementation module %s for %s" % (
|
||||
self._task.action,
|
||||
play_context.network_os,
|
||||
)
|
||||
return result
|
||||
|
||||
new_task.action = module
|
||||
|
||||
action = self._shared_loader_obj.action_loader.get(
|
||||
play_context.network_os,
|
||||
task=new_task,
|
||||
connection=self._connection,
|
||||
play_context=play_context,
|
||||
loader=self._loader,
|
||||
templar=self._templar,
|
||||
shared_loader_obj=self._shared_loader_obj,
|
||||
)
|
||||
display.vvvv("Running implementation module %s" % module)
|
||||
return action.run(task_vars=task_vars)
|
||||
|
||||
def _get_network_os(self, task_vars):
|
||||
if "network_os" in self._task.args and self._task.args["network_os"]:
|
||||
display.vvvv("Getting network OS from task argument")
|
||||
network_os = self._task.args["network_os"]
|
||||
elif self._play_context.network_os:
|
||||
display.vvvv("Getting network OS from inventory")
|
||||
network_os = self._play_context.network_os
|
||||
elif (
|
||||
"network_os" in task_vars.get("ansible_facts", {})
|
||||
and task_vars["ansible_facts"]["network_os"]
|
||||
):
|
||||
display.vvvv("Getting network OS from fact")
|
||||
network_os = task_vars["ansible_facts"]["network_os"]
|
||||
else:
|
||||
raise AnsibleError(
|
||||
"ansible_network_os must be specified on this host to use platform agnostic modules"
|
||||
)
|
||||
|
||||
return network_os
|
||||
|
||||
def _get_implementation_module(self, network_os, platform_agnostic_module):
|
||||
module_name = network_os.split(".")[-1] + "_" + platform_agnostic_module.partition("_")[2]
|
||||
if "." in network_os:
|
||||
fqcn_module = ".".join(network_os.split(".")[0:-1])
|
||||
implementation_module = fqcn_module + "." + module_name
|
||||
else:
|
||||
implementation_module = module_name
|
||||
|
||||
if implementation_module not in self._shared_loader_obj.module_loader:
|
||||
implementation_module = None
|
||||
|
||||
return implementation_module
|
||||
255
collection/ansible/netcommon/plugins/action/net_put.py
Normal file
255
collection/ansible/netcommon/plugins/action/net_put.py
Normal file
@@ -0,0 +1,255 @@
|
||||
# (c) 2018, Ansible Inc,
|
||||
# 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 hashlib
|
||||
import os
|
||||
import uuid
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.connection import Connection, ConnectionError
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlsplit
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
class ActionModule(ActionBase):
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
changed = False
|
||||
socket_path = None
|
||||
network_os = self._get_network_os(task_vars).split(".")[-1]
|
||||
persistent_connection = self._play_context.connection.split(".")[-1]
|
||||
|
||||
result = super(ActionModule, self).run(task_vars=task_vars)
|
||||
|
||||
if persistent_connection != "network_cli":
|
||||
# It is supported only with network_cli
|
||||
result["failed"] = True
|
||||
result["msg"] = (
|
||||
"connection type %s is not valid for net_put module,"
|
||||
" please use fully qualified name of network_cli connection type"
|
||||
% self._play_context.connection
|
||||
)
|
||||
return result
|
||||
|
||||
try:
|
||||
src = self._task.args["src"]
|
||||
except KeyError as exc:
|
||||
return {
|
||||
"failed": True,
|
||||
"msg": "missing required argument: %s" % exc,
|
||||
}
|
||||
|
||||
src_file_path_name = src
|
||||
|
||||
# Get destination file if specified
|
||||
dest = self._task.args.get("dest")
|
||||
|
||||
# Get proto
|
||||
proto = self._task.args.get("protocol")
|
||||
if proto is None:
|
||||
proto = "scp"
|
||||
|
||||
# Get mode if set
|
||||
mode = self._task.args.get("mode")
|
||||
if mode is None:
|
||||
mode = "binary"
|
||||
|
||||
if mode == "text":
|
||||
try:
|
||||
self._handle_src_option(convert_data=False)
|
||||
except AnsibleError as exc:
|
||||
return dict(failed=True, msg=to_text(exc))
|
||||
|
||||
# Now src has resolved file write to disk in current diectory for scp
|
||||
src = self._task.args.get("src")
|
||||
filename = str(uuid.uuid4())
|
||||
cwd = self._loader.get_basedir()
|
||||
output_file = os.path.join(cwd, filename)
|
||||
try:
|
||||
with open(output_file, "wb") as f:
|
||||
f.write(to_bytes(src, encoding="utf-8"))
|
||||
except Exception:
|
||||
os.remove(output_file)
|
||||
raise
|
||||
else:
|
||||
try:
|
||||
output_file = self._get_binary_src_file(src)
|
||||
except ValueError as exc:
|
||||
return dict(failed=True, msg=to_text(exc))
|
||||
|
||||
if socket_path is None:
|
||||
socket_path = self._connection.socket_path
|
||||
|
||||
conn = Connection(socket_path)
|
||||
sock_timeout = conn.get_option("persistent_command_timeout")
|
||||
|
||||
if dest is None:
|
||||
dest = src_file_path_name
|
||||
try:
|
||||
changed = self._handle_existing_file(conn, output_file, dest, proto, sock_timeout)
|
||||
if changed is False:
|
||||
result["changed"] = changed
|
||||
result["destination"] = dest
|
||||
if mode == "text":
|
||||
# Cleanup tmp file expanded wih ansible vars
|
||||
os.remove(output_file)
|
||||
return result
|
||||
except Exception as exc:
|
||||
result["msg"] = "Warning: %s idempotency check failed. Check dest" % exc
|
||||
|
||||
try:
|
||||
conn.copy_file(
|
||||
source=output_file,
|
||||
destination=dest,
|
||||
proto=proto,
|
||||
timeout=sock_timeout,
|
||||
)
|
||||
except Exception as exc:
|
||||
if to_text(exc) == "No response from server":
|
||||
if network_os == "iosxr":
|
||||
# IOSXR sometimes closes socket prematurely after completion
|
||||
# of file transfer
|
||||
result["msg"] = "Warning: iosxr scp server pre close issue. Please check dest"
|
||||
else:
|
||||
result["failed"] = True
|
||||
result["msg"] = "Exception received: %s" % exc
|
||||
|
||||
if mode == "text":
|
||||
# Cleanup tmp file expanded wih ansible vars
|
||||
os.remove(output_file)
|
||||
|
||||
result["changed"] = changed
|
||||
result["destination"] = dest
|
||||
return result
|
||||
|
||||
def _handle_existing_file(self, conn, source, dest, proto, timeout):
|
||||
"""
|
||||
Determines whether the source and destination file match.
|
||||
|
||||
:return: False if source and dest both exist and have matching sha1 sums, True otherwise.
|
||||
"""
|
||||
cwd = self._loader.get_basedir()
|
||||
filename = str(uuid.uuid4())
|
||||
tmp_source_file = os.path.join(cwd, filename)
|
||||
try:
|
||||
conn.get_file(
|
||||
source=dest,
|
||||
destination=tmp_source_file,
|
||||
proto=proto,
|
||||
timeout=timeout,
|
||||
)
|
||||
except ConnectionError as exc:
|
||||
error = to_text(exc)
|
||||
if error.endswith("No such file or directory"):
|
||||
if os.path.exists(tmp_source_file):
|
||||
os.remove(tmp_source_file)
|
||||
return True
|
||||
try:
|
||||
with open(source, "r") as f:
|
||||
new_content = f.read()
|
||||
with open(tmp_source_file, "r") as f:
|
||||
old_content = f.read()
|
||||
except (IOError, OSError):
|
||||
os.remove(tmp_source_file)
|
||||
raise
|
||||
|
||||
sha1 = hashlib.sha1()
|
||||
old_content_b = to_bytes(old_content, errors="surrogate_or_strict")
|
||||
sha1.update(old_content_b)
|
||||
checksum_old = sha1.digest()
|
||||
|
||||
sha1 = hashlib.sha1()
|
||||
new_content_b = to_bytes(new_content, errors="surrogate_or_strict")
|
||||
sha1.update(new_content_b)
|
||||
checksum_new = sha1.digest()
|
||||
os.remove(tmp_source_file)
|
||||
if checksum_old == checksum_new:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _get_binary_src_file(self, src):
|
||||
working_path = self._get_working_path()
|
||||
|
||||
if os.path.isabs(src) or urlsplit("src").scheme:
|
||||
source = src
|
||||
else:
|
||||
source = self._loader.path_dwim_relative(working_path, "templates", src)
|
||||
if not source:
|
||||
source = self._loader.path_dwim_relative(working_path, src)
|
||||
|
||||
if not os.path.exists(source):
|
||||
raise ValueError("path specified in src not found")
|
||||
|
||||
return source
|
||||
|
||||
def _get_working_path(self):
|
||||
cwd = self._loader.get_basedir()
|
||||
if self._task._role is not None:
|
||||
cwd = self._task._role._role_path
|
||||
return cwd
|
||||
|
||||
def _handle_src_option(self, convert_data=True):
|
||||
src = self._task.args.get("src")
|
||||
working_path = self._get_working_path()
|
||||
|
||||
if os.path.isabs(src) or urlsplit("src").scheme:
|
||||
source = src
|
||||
else:
|
||||
source = self._loader.path_dwim_relative(working_path, "templates", src)
|
||||
if not source:
|
||||
source = self._loader.path_dwim_relative(working_path, src)
|
||||
|
||||
if not os.path.exists(source):
|
||||
raise AnsibleError("path specified in src not found")
|
||||
|
||||
try:
|
||||
with open(source, "r") as f:
|
||||
template_data = to_text(f.read())
|
||||
except IOError as e:
|
||||
raise AnsibleError(
|
||||
"unable to load src file {0}, I/O error({1}): {2}".format(
|
||||
source, e.errno, e.strerror
|
||||
)
|
||||
)
|
||||
|
||||
# Create a template search path in the following order:
|
||||
# [working_path, self_role_path, dependent_role_paths, dirname(source)]
|
||||
searchpath = [working_path]
|
||||
if self._task._role is not None:
|
||||
searchpath.append(self._task._role._role_path)
|
||||
if hasattr(self._task, "_block:"):
|
||||
dep_chain = self._task._block.get_dep_chain()
|
||||
if dep_chain is not None:
|
||||
for role in dep_chain:
|
||||
searchpath.append(role._role_path)
|
||||
searchpath.append(os.path.dirname(source))
|
||||
self._templar.environment.loader.searchpath = searchpath
|
||||
self._task.args["src"] = self._templar.template(template_data)
|
||||
|
||||
def _get_network_os(self, task_vars):
|
||||
if "network_os" in self._task.args and self._task.args["network_os"]:
|
||||
display.vvvv("Getting network OS from task argument")
|
||||
network_os = self._task.args["network_os"]
|
||||
elif self._play_context.network_os:
|
||||
display.vvvv("Getting network OS from inventory")
|
||||
network_os = self._play_context.network_os
|
||||
elif (
|
||||
"network_os" in task_vars.get("ansible_facts", {})
|
||||
and task_vars["ansible_facts"]["network_os"]
|
||||
):
|
||||
display.vvvv("Getting network OS from fact")
|
||||
network_os = task_vars["ansible_facts"]["network_os"]
|
||||
else:
|
||||
raise AnsibleError("ansible_network_os must be specified on this host")
|
||||
|
||||
return network_os
|
||||
112
collection/ansible/netcommon/plugins/action/netconf.py
Normal file
112
collection/ansible/netcommon/plugins/action/netconf.py
Normal file
@@ -0,0 +1,112 @@
|
||||
#
|
||||
# Copyright 2018 Red Hat Inc.
|
||||
# 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 copy
|
||||
import sys
|
||||
|
||||
from ansible.utils.display import Display
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.action.network import (
|
||||
ActionModule as ActionNetworkModule,
|
||||
)
|
||||
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
class ActionModule(ActionNetworkModule):
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
del tmp # tmp no longer has any effect
|
||||
|
||||
module_name = self._task.action.split(".")[-1]
|
||||
self._config_module = True if module_name == "netconf_config" else False
|
||||
persistent_connection = self._play_context.connection.split(".")[-1]
|
||||
warnings = []
|
||||
|
||||
if persistent_connection not in ["netconf", "local"] and module_name == "netconf_config":
|
||||
return {
|
||||
"failed": True,
|
||||
"msg": "Connection type %s is not valid for netconf_config module. "
|
||||
"Valid connection type is netconf or local (deprecated)"
|
||||
% self._play_context.connection,
|
||||
}
|
||||
elif persistent_connection not in ["netconf"] and module_name != "netconf_config":
|
||||
return {
|
||||
"failed": True,
|
||||
"msg": "Connection type %s is not valid for %s module. "
|
||||
"Valid connection type is netconf." % (self._play_context.connection, module_name),
|
||||
}
|
||||
|
||||
if self._play_context.connection == "local" and module_name == "netconf_config":
|
||||
args = self._task.args
|
||||
pc = copy.deepcopy(self._play_context)
|
||||
pc.connection = "ansible.netcommon.netconf"
|
||||
pc.port = int(args.get("port") or self._play_context.port or 830)
|
||||
|
||||
pc.remote_user = args.get("username") or self._play_context.connection_user
|
||||
pc.password = args.get("password") or self._play_context.password
|
||||
pc.private_key_file = args.get("ssh_keyfile") or self._play_context.private_key_file
|
||||
|
||||
connection = self._shared_loader_obj.connection_loader.get(
|
||||
"ansible.netcommon.persistent",
|
||||
pc,
|
||||
sys.stdin,
|
||||
task_uuid=self._task._uuid,
|
||||
)
|
||||
|
||||
# TODO: Remove below code after ansible minimal is cut out
|
||||
if connection is None:
|
||||
pc.connection = "netconf"
|
||||
connection = self._shared_loader_obj.connection_loader.get(
|
||||
"persistent", pc, sys.stdin, task_uuid=self._task._uuid
|
||||
)
|
||||
|
||||
display.vvv(
|
||||
"using connection plugin %s (was local)" % pc.connection,
|
||||
pc.remote_addr,
|
||||
)
|
||||
|
||||
timeout = args.get("timeout")
|
||||
command_timeout = (
|
||||
int(timeout) if timeout else connection.get_option("persistent_command_timeout")
|
||||
)
|
||||
connection.set_options(
|
||||
direct={
|
||||
"persistent_command_timeout": command_timeout,
|
||||
"look_for_keys": args.get("look_for_keys"),
|
||||
"hostkey_verify": args.get("hostkey_verify"),
|
||||
"allow_agent": args.get("allow_agent"),
|
||||
}
|
||||
)
|
||||
|
||||
socket_path = connection.run()
|
||||
display.vvvv("socket_path: %s" % socket_path, pc.remote_addr)
|
||||
if not socket_path:
|
||||
return {
|
||||
"failed": True,
|
||||
"msg": "unable to open shell. Please see: "
|
||||
+ "https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell",
|
||||
}
|
||||
|
||||
task_vars["ansible_socket"] = socket_path
|
||||
warnings.append(
|
||||
[
|
||||
"connection local support for this module is deprecated and will be removed in version 2.14, use connection %s"
|
||||
% pc.connection
|
||||
]
|
||||
)
|
||||
|
||||
result = super(ActionModule, self).run(task_vars=task_vars)
|
||||
if warnings:
|
||||
if "warnings" in result:
|
||||
result["warnings"].extend(warnings)
|
||||
else:
|
||||
result["warnings"] = warnings
|
||||
return result
|
||||
363
collection/ansible/netcommon/plugins/action/network.py
Normal file
363
collection/ansible/netcommon/plugins/action/network.py
Normal file
@@ -0,0 +1,363 @@
|
||||
#
|
||||
# (c) 2018 Red Hat Inc.
|
||||
# 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 os
|
||||
import re
|
||||
import time
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.six import PY3
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlsplit
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.utils.display import Display
|
||||
from ansible.utils.hashing import checksum, checksum_s
|
||||
|
||||
|
||||
display = Display()
|
||||
|
||||
DEXEC_PREFIX = "ANSIBLE_NETWORK_IMPORT_MODULES:"
|
||||
|
||||
|
||||
class ActionModule(_ActionModule):
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
config_module = hasattr(self, "_config_module") and self._config_module
|
||||
if config_module and self._task.args.get("src"):
|
||||
try:
|
||||
self._handle_src_option()
|
||||
except AnsibleError as exc:
|
||||
return dict(failed=True, msg=to_text(exc))
|
||||
|
||||
host = task_vars["ansible_host"]
|
||||
dexec_eligible = self._check_dexec_eligibility(host)
|
||||
|
||||
# attempt to run using dexec
|
||||
if dexec_eligible:
|
||||
# find and load the module
|
||||
filename, module = self._find_load_module()
|
||||
display.vvvv(
|
||||
"{prefix} found {action} at {fname}".format(
|
||||
prefix=DEXEC_PREFIX,
|
||||
action=self._task.action,
|
||||
fname=filename,
|
||||
),
|
||||
host,
|
||||
)
|
||||
# not using AnsibleModule, return to normal run (eg eos_bgp)
|
||||
if getattr(module, "AnsibleModule", None):
|
||||
# patch and update the module
|
||||
self._patch_update_module(module, task_vars)
|
||||
display.vvvv(
|
||||
"{prefix} running {module}".format(
|
||||
prefix=DEXEC_PREFIX, module=self._task.action
|
||||
),
|
||||
host,
|
||||
)
|
||||
# execute the module, collect result
|
||||
result = self._exec_module(module)
|
||||
display.vvvv("{prefix} complete".format(prefix=DEXEC_PREFIX), host)
|
||||
display.vvvvv(
|
||||
"{prefix} Result: {result}".format(prefix=DEXEC_PREFIX, result=result),
|
||||
host,
|
||||
)
|
||||
|
||||
else:
|
||||
dexec_eligible = False
|
||||
display.vvvv(
|
||||
"{prefix} {module} doesn't support direct execution, disabled".format(
|
||||
prefix=DEXEC_PREFIX, module=self._task.action
|
||||
),
|
||||
host,
|
||||
)
|
||||
|
||||
if not dexec_eligible:
|
||||
result = super(ActionModule, self).run(task_vars=task_vars)
|
||||
|
||||
if config_module and self._task.args.get("backup") and not result.get("failed"):
|
||||
self._handle_backup_option(
|
||||
result,
|
||||
task_vars,
|
||||
self._task.args.get("backup_options"),
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
def _handle_backup_option(self, result, task_vars, backup_options):
|
||||
filename = None
|
||||
backup_path = None
|
||||
try:
|
||||
non_config_regexes = self._connection.cliconf.get_option("non_config_lines", task_vars)
|
||||
except (AttributeError, KeyError):
|
||||
non_config_regexes = []
|
||||
try:
|
||||
content = self._sanitize_contents(
|
||||
contents=result.pop("__backup__"), filters=non_config_regexes
|
||||
)
|
||||
except KeyError:
|
||||
raise AnsibleError("Failed while reading configuration backup")
|
||||
|
||||
if backup_options:
|
||||
filename = backup_options.get("filename")
|
||||
backup_path = backup_options.get("dir_path")
|
||||
|
||||
tstamp = time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(time.time()))
|
||||
if not backup_path:
|
||||
cwd = self._get_working_path()
|
||||
backup_path = os.path.join(cwd, "backup")
|
||||
if not filename:
|
||||
filename = "%s_config.%s" % (
|
||||
task_vars["inventory_hostname"],
|
||||
tstamp,
|
||||
)
|
||||
|
||||
dest = os.path.join(backup_path, filename)
|
||||
if not os.path.exists(backup_path):
|
||||
os.makedirs(backup_path)
|
||||
|
||||
changed = False
|
||||
# Do not overwrite the destination if the contents match.
|
||||
if not os.path.exists(dest) or checksum(dest) != checksum_s(content):
|
||||
try:
|
||||
with open(dest, "w") as output_file:
|
||||
output_file.write(content)
|
||||
except Exception as exc:
|
||||
result["failed"] = True
|
||||
result["msg"] = "Could not write to destination file %s: %s" % (
|
||||
dest,
|
||||
to_text(exc),
|
||||
)
|
||||
return
|
||||
changed = True
|
||||
|
||||
result["backup_path"] = dest
|
||||
result["changed"] = changed
|
||||
|
||||
result["date"], result["time"] = tstamp.split("@")
|
||||
if not (backup_options and backup_options.get("filename")):
|
||||
result["filename"] = os.path.basename(result["backup_path"])
|
||||
result["shortname"] = os.path.splitext(result["backup_path"])[0]
|
||||
|
||||
def _get_working_path(self):
|
||||
cwd = self._loader.get_basedir()
|
||||
if self._task._role is not None:
|
||||
cwd = self._task._role._role_path
|
||||
return cwd
|
||||
|
||||
def _handle_src_option(self, convert_data=True):
|
||||
src = self._task.args.get("src")
|
||||
working_path = self._get_working_path()
|
||||
|
||||
if os.path.isabs(src) or urlsplit("src").scheme:
|
||||
source = src
|
||||
else:
|
||||
source = self._loader.path_dwim_relative(working_path, "templates", src)
|
||||
if not source:
|
||||
source = self._loader.path_dwim_relative(working_path, src)
|
||||
|
||||
if not os.path.exists(source):
|
||||
raise AnsibleError("path specified in src not found")
|
||||
|
||||
try:
|
||||
with open(source, "r") as f:
|
||||
template_data = to_text(f.read())
|
||||
except IOError as e:
|
||||
raise AnsibleError(
|
||||
"unable to load src file {0}, I/O error({1}): {2}".format(
|
||||
source, e.errno, e.strerror
|
||||
)
|
||||
)
|
||||
|
||||
# Create a template search path in the following order:
|
||||
# [working_path, self_role_path, dependent_role_paths, dirname(source)]
|
||||
searchpath = [working_path]
|
||||
if self._task._role is not None:
|
||||
searchpath.append(self._task._role._role_path)
|
||||
if hasattr(self._task, "_block:"):
|
||||
dep_chain = self._task._block.get_dep_chain()
|
||||
if dep_chain is not None:
|
||||
for role in dep_chain:
|
||||
searchpath.append(role._role_path)
|
||||
searchpath.append(os.path.dirname(source))
|
||||
self._templar.environment.loader.searchpath = searchpath
|
||||
self._task.args["src"] = self._templar.template(template_data)
|
||||
|
||||
def _get_network_os(self, task_vars):
|
||||
if "network_os" in self._task.args and self._task.args["network_os"]:
|
||||
display.vvvv("Getting network OS from task argument")
|
||||
network_os = self._task.args["network_os"]
|
||||
elif self._play_context.network_os:
|
||||
display.vvvv("Getting network OS from inventory")
|
||||
network_os = self._play_context.network_os
|
||||
elif (
|
||||
"network_os" in task_vars.get("ansible_facts", {})
|
||||
and task_vars["ansible_facts"]["network_os"]
|
||||
):
|
||||
display.vvvv("Getting network OS from fact")
|
||||
network_os = task_vars["ansible_facts"]["network_os"]
|
||||
else:
|
||||
raise AnsibleError("ansible_network_os must be specified on this host")
|
||||
|
||||
return network_os
|
||||
|
||||
def _check_dexec_eligibility(self, host):
|
||||
"""Check if current python and task are eligble"""
|
||||
dexec = self.get_connection_option("import_modules")
|
||||
|
||||
# log early about dexec
|
||||
if dexec:
|
||||
display.vvvv("{prefix} enabled".format(prefix=DEXEC_PREFIX), host)
|
||||
|
||||
# disable dexec when not PY3
|
||||
if not PY3:
|
||||
dexec = False
|
||||
display.vvvv(
|
||||
"{prefix} disabled for when not Python 3".format(prefix=DEXEC_PREFIX),
|
||||
host=host,
|
||||
)
|
||||
|
||||
# disable dexec when running async
|
||||
if self._task.async_val:
|
||||
dexec = False
|
||||
display.vvvv(
|
||||
"{prefix} disabled for a task using async".format(prefix=DEXEC_PREFIX),
|
||||
host=host,
|
||||
)
|
||||
else:
|
||||
display.vvvv("{prefix} disabled".format(prefix=DEXEC_PREFIX), host)
|
||||
display.vvvv(
|
||||
"{prefix} module execution time may be extended".format(prefix=DEXEC_PREFIX),
|
||||
host,
|
||||
)
|
||||
|
||||
return dexec
|
||||
|
||||
def _find_load_module(self):
|
||||
"""Use the task action to find a module
|
||||
and import it.
|
||||
|
||||
:return filename: The module's filename
|
||||
:rtype filename: str
|
||||
:return module: The loaded module file
|
||||
:rtype module: module
|
||||
"""
|
||||
import importlib
|
||||
|
||||
mloadr = self._shared_loader_obj.module_loader
|
||||
|
||||
# 2.10
|
||||
try:
|
||||
context = mloadr.find_plugin_with_context(
|
||||
self._task.action, collection_list=self._task.collections
|
||||
)
|
||||
filename = context.plugin_resolved_path
|
||||
module = importlib.import_module(context.plugin_resolved_name)
|
||||
# 2.9
|
||||
except AttributeError:
|
||||
fullname, filename = mloadr.find_plugin_with_name(
|
||||
self._task.action, collection_list=self._task.collections
|
||||
)
|
||||
module = importlib.import_module(fullname)
|
||||
return filename, module
|
||||
|
||||
def _patch_update_module(self, module, task_vars):
|
||||
"""Update a module instance, replacing it's AnsibleModule
|
||||
with one that doesn't load params
|
||||
|
||||
:param module: An loaded module
|
||||
:type module: A module file that was loaded
|
||||
:param task_vars: The vars provided to the task
|
||||
:type task_vars: dict
|
||||
"""
|
||||
import copy
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule as _AnsibleModule
|
||||
|
||||
# build an AnsibleModule that doesn't load params
|
||||
class PatchedAnsibleModule(_AnsibleModule):
|
||||
def _load_params(self):
|
||||
pass
|
||||
|
||||
# update the task args w/ all the magic vars
|
||||
self._update_module_args(self._task.action, self._task.args, task_vars)
|
||||
|
||||
# set the params of the ansible module cause we're not using stdin
|
||||
# use a copy so the module doesn't change the original task args
|
||||
PatchedAnsibleModule.params = copy.deepcopy(self._task.args)
|
||||
|
||||
# give the module our revised AnsibleModule
|
||||
module.AnsibleModule = PatchedAnsibleModule
|
||||
|
||||
def _exec_module(self, module):
|
||||
"""exec the module's main() since modules
|
||||
print their result, we need to replace stdout
|
||||
with a buffer. If main() fails, we assume that as stderr
|
||||
Once we collect stdout/stderr, use our super to json load
|
||||
it or handle a traceback
|
||||
|
||||
:param module: An loaded module
|
||||
:type module: A module file that was loaded
|
||||
:return module_result: The result of the module
|
||||
:rtype module_result: dict
|
||||
"""
|
||||
import io
|
||||
import sys
|
||||
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.vars.clean import remove_internal_keys
|
||||
|
||||
# preserve previous stdout, replace with buffer
|
||||
sys_stdout = sys.stdout
|
||||
sys.stdout = io.StringIO()
|
||||
|
||||
stdout = ""
|
||||
stderr = ""
|
||||
# run the module, catch the SystemExit so we continue
|
||||
try:
|
||||
module.main()
|
||||
except SystemExit:
|
||||
# module exited cleanly
|
||||
stdout = sys.stdout.getvalue()
|
||||
except Exception as exc:
|
||||
# dirty module or connection traceback
|
||||
stderr = to_native(exc)
|
||||
|
||||
# restore stdout & stderr
|
||||
sys.stdout = sys_stdout
|
||||
|
||||
# parse the response
|
||||
dict_out = {
|
||||
"stdout": stdout,
|
||||
"stdout_lines": stdout.splitlines(),
|
||||
"stderr": stderr,
|
||||
"stderr_lines": stderr.splitlines(),
|
||||
}
|
||||
data = self._parse_returned_data(dict_out)
|
||||
# Clean up the response like action _execute_module
|
||||
remove_internal_keys(data)
|
||||
|
||||
# split stdout/stderr into lines if needed
|
||||
if "stdout" in data and "stdout_lines" not in data:
|
||||
# if the value is 'False', a default won't catch it.
|
||||
txt = data.get("stdout", None) or ""
|
||||
data["stdout_lines"] = txt.splitlines()
|
||||
if "stderr" in data and "stderr_lines" not in data:
|
||||
# if the value is 'False', a default won't catch it.
|
||||
txt = data.get("stderr", None) or ""
|
||||
data["stderr_lines"] = txt.splitlines()
|
||||
|
||||
return data
|
||||
|
||||
def _sanitize_contents(self, contents, filters):
|
||||
"""remove lines from contents that match
|
||||
regexes specified in the `filters` list
|
||||
"""
|
||||
for x in filters:
|
||||
contents = re.sub(x, "", contents)
|
||||
return contents.strip()
|
||||
246
collection/ansible/netcommon/plugins/action/network_resource.py
Normal file
246
collection/ansible/netcommon/plugins/action/network_resource.py
Normal file
@@ -0,0 +1,246 @@
|
||||
#
|
||||
# Copyright 2021 Red Hat Inc.
|
||||
# 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 copy
|
||||
import glob
|
||||
import os
|
||||
|
||||
from importlib import import_module
|
||||
|
||||
|
||||
try:
|
||||
import yaml
|
||||
|
||||
# use C version if possible for speedup
|
||||
try:
|
||||
from yaml import CSafeLoader as SafeLoader
|
||||
except ImportError:
|
||||
from yaml import SafeLoader
|
||||
HAS_YAML = True
|
||||
except ImportError:
|
||||
HAS_YAML = False
|
||||
|
||||
from ansible.errors import AnsibleActionFail, AnsibleError
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.utils.display import Display
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.action.network import (
|
||||
ActionModule as ActionNetworkModule,
|
||||
)
|
||||
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
class RunMode:
|
||||
RM_LIST = 0 # get list of supported resource modules for given os_name
|
||||
RM_GET = 1 # get resource module facts for given host
|
||||
RM_CONFIG = 1 # push resource module configuration
|
||||
|
||||
|
||||
class ActionModule(ActionNetworkModule):
|
||||
def run(self, task_vars=None):
|
||||
run_mode = None
|
||||
self._task_vars = task_vars
|
||||
|
||||
self._rm_play_context = copy.deepcopy(self._play_context)
|
||||
self._os_name = self._task.args.get("os_name") or self._get_os_name()
|
||||
if not self._os_name:
|
||||
return {"error": "either value of 'os_name' or 'ansible_network_os' should be set"}
|
||||
|
||||
if len(self._os_name.split(".")) != 3:
|
||||
msg = (
|
||||
"OS value name should a fully qualified collection name in the format"
|
||||
" <org-name>.<collection-name>.<plugin-name>"
|
||||
)
|
||||
return {"error": msg}
|
||||
|
||||
self._rm_play_context.network_os = self._os_name
|
||||
|
||||
self._name = self._task.args.get("name")
|
||||
self._config = self._task.args.get("config")
|
||||
self._running_config = self._task.args.get("running_config")
|
||||
self._state = self._task.args.get("state")
|
||||
|
||||
run_mode = self._get_run_mode()
|
||||
|
||||
result = {}
|
||||
if run_mode == RunMode.RM_LIST:
|
||||
result = self._list_resource_modules()
|
||||
elif run_mode in [RunMode.RM_GET, RunMode.RM_CONFIG]:
|
||||
try:
|
||||
result = self._run_resource_module()
|
||||
except AnsibleError as exc:
|
||||
# handle short name redirection not working for ansible-2.9
|
||||
if "was not found" in to_text(exc):
|
||||
result = self._run_resource_module(prefix_os_name=True)
|
||||
else:
|
||||
raise
|
||||
|
||||
result.update(
|
||||
{
|
||||
"ansible_network_os": self._task_vars.get("ansible_network_os"),
|
||||
"ansible_connection": self._task_vars.get("ansible_connection"),
|
||||
}
|
||||
)
|
||||
return result
|
||||
|
||||
def _run_resource_module(self, prefix_os_name=False):
|
||||
new_task = self._task.copy()
|
||||
|
||||
self._module = self._get_resource_module(prefix_os_name=prefix_os_name)
|
||||
if not self._module:
|
||||
msg = "Could not find resource module '%s' for os name '%s'" % (
|
||||
self._name,
|
||||
self._os_name,
|
||||
)
|
||||
raise AnsibleActionFail(msg)
|
||||
|
||||
new_task.action = self._module
|
||||
action = self._shared_loader_obj.action_loader.get(
|
||||
self._rm_play_context.network_os,
|
||||
task=new_task,
|
||||
connection=self._connection,
|
||||
play_context=self._rm_play_context,
|
||||
loader=self._loader,
|
||||
templar=self._templar,
|
||||
shared_loader_obj=self._shared_loader_obj,
|
||||
)
|
||||
display.vvvv("Running resource module %s" % self._module)
|
||||
for option in ["os_name", "name"]:
|
||||
if option in new_task.args:
|
||||
new_task.args.pop(option)
|
||||
|
||||
result = action.run(task_vars=self._task_vars)
|
||||
result.update({"resource_module_name": self._module})
|
||||
return result
|
||||
|
||||
def _get_resource_module(self, prefix_os_name=False):
|
||||
if "." in self._name:
|
||||
if len(self._name.split(".")) != 3:
|
||||
msg = (
|
||||
"name should a fully qualified collection name in the format"
|
||||
" <org-name>.<collection-name>.<resource-module-name>"
|
||||
)
|
||||
raise AnsibleActionFail(msg)
|
||||
fqcn_module_name = self._name
|
||||
else:
|
||||
if prefix_os_name:
|
||||
module_name = self._os_name.split(".")[1] + "_" + self._name
|
||||
else:
|
||||
module_name = self._name
|
||||
|
||||
fqcn_module_name = ".".join(self._os_name.split(".")[:2] + [module_name])
|
||||
|
||||
return fqcn_module_name
|
||||
|
||||
def _get_os_name(self):
|
||||
os_name = None
|
||||
if "network_os" in self._task.args and self._task.args["network_os"]:
|
||||
display.vvvv("Getting OS name from task argument")
|
||||
os_name = self._task.args["network_os"]
|
||||
elif self._play_context.network_os:
|
||||
display.vvvv("Getting OS name from inventory")
|
||||
os_name = self._play_context.network_os
|
||||
elif (
|
||||
"network_os" in self._task_vars.get("ansible_facts", {})
|
||||
and self._task_vars["ansible_facts"]["network_os"]
|
||||
):
|
||||
display.vvvv("Getting OS name from fact")
|
||||
os_name = self._task_vars["ansible_facts"]["network_os"]
|
||||
|
||||
return os_name
|
||||
|
||||
def _is_resource_module(self, docs):
|
||||
doc_obj = yaml.load(docs, SafeLoader)
|
||||
if "config" in doc_obj["options"] and "state" in doc_obj["options"]:
|
||||
return True
|
||||
|
||||
def _get_run_mode(self):
|
||||
error_msg = None
|
||||
if self._config or self._running_config:
|
||||
if not self._name:
|
||||
error_msg = "'name' is required if 'config' option is set"
|
||||
if not self._state:
|
||||
error_msg = "'state' is required if 'config' option is set"
|
||||
run_mode = RunMode.RM_CONFIG
|
||||
elif self._state:
|
||||
if not self._name:
|
||||
error_msg = "'name' is required if 'state' option is set"
|
||||
run_mode = RunMode.RM_GET
|
||||
elif self._name:
|
||||
if not any([self._config, self._running_config, self._state]):
|
||||
error_msg = (
|
||||
"If 'name' is set atleast one of 'config', "
|
||||
"'running_config' or 'state' is required"
|
||||
)
|
||||
else:
|
||||
run_mode = RunMode.RM_LIST
|
||||
|
||||
if error_msg:
|
||||
raise AnsibleActionFail(error_msg)
|
||||
return run_mode
|
||||
|
||||
def _list_resource_modules(self):
|
||||
result = {}
|
||||
resource_modules = []
|
||||
|
||||
self._cref = dict(zip(["corg", "cname", "plugin"], self._os_name.split(".")))
|
||||
|
||||
fact_modulelib = "ansible_collections.{corg}.{cname}.plugins.module_utils.network.{plugin}.facts.facts".format(
|
||||
corg=self._cref["corg"],
|
||||
cname=self._cref["cname"],
|
||||
plugin=self._cref["plugin"],
|
||||
)
|
||||
|
||||
try:
|
||||
display.vvvv("fetching facts list from path %s" % (fact_modulelib))
|
||||
facts_resource_subset = getattr(import_module(fact_modulelib), "FACT_RESOURCE_SUBSETS")
|
||||
resource_modules = sorted(facts_resource_subset.keys())
|
||||
except ModuleNotFoundError:
|
||||
display.vvvv("'%s' is not defined" % (fact_modulelib))
|
||||
except AttributeError:
|
||||
display.vvvv("'FACT_RESOURCE_SUBSETS is not defined in '%s'" % (fact_modulelib))
|
||||
|
||||
# parse module docs to check for 'config' and 'state' options to identify it as resource module
|
||||
if not resource_modules:
|
||||
modulelib = "ansible_collections.{corg}.{cname}.plugins.modules".format(
|
||||
corg=self._cref["corg"], cname=self._cref["cname"]
|
||||
)
|
||||
|
||||
module_dir_path = os.path.dirname(import_module(modulelib).__file__)
|
||||
module_paths = glob.glob(
|
||||
"{module_dir_path}/[!_]*.py".format(module_dir_path=module_dir_path)
|
||||
)
|
||||
|
||||
for module_path in module_paths:
|
||||
module_name = os.path.basename(module_path).split(".")[0]
|
||||
docs = None
|
||||
try:
|
||||
display.vvvv("reading 'DOCUMENTATION' from path %s" % (module_path))
|
||||
docs = getattr(
|
||||
import_module("%s.%s" % (modulelib, module_name)),
|
||||
"DOCUMENTATION",
|
||||
)
|
||||
except ModuleNotFoundError:
|
||||
display.vvvv("'%s' is not defined" % (fact_modulelib))
|
||||
except AttributeError:
|
||||
display.vvvv("'DOCUMENTATION is not defined in '%s'" % (fact_modulelib))
|
||||
|
||||
if docs:
|
||||
if self._is_resource_module(docs):
|
||||
resource_modules.append(module_name.split("_", 1)[1])
|
||||
else:
|
||||
display.vvvvv(
|
||||
"module in path '%s' is not a resource module" % (module_path)
|
||||
)
|
||||
|
||||
result.update({"modules": sorted(resource_modules)})
|
||||
return result
|
||||
118
collection/ansible/netcommon/plugins/action/telnet.py
Normal file
118
collection/ansible/netcommon/plugins/action/telnet.py
Normal file
@@ -0,0 +1,118 @@
|
||||
# (c) 2017, 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
|
||||
|
||||
from time import sleep
|
||||
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.six import text_type
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.compat import telnetlib
|
||||
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
class ActionModule(ActionBase):
|
||||
TRANSFERS_FILES = False
|
||||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
if self._task.environment and any(self._task.environment):
|
||||
self._display.warning("The telnet task does not support the environment keyword")
|
||||
|
||||
result = super(ActionModule, self).run(tmp, task_vars)
|
||||
del tmp # tmp no longer has any effect
|
||||
|
||||
if self._play_context.check_mode:
|
||||
# in --check mode, always skip this module execution
|
||||
result["skipped"] = True
|
||||
result["msg"] = "The telnet task does not support check mode"
|
||||
else:
|
||||
result["changed"] = True
|
||||
result["failed"] = False
|
||||
|
||||
host = to_text(self._task.args.get("host", self._play_context.remote_addr))
|
||||
user = to_text(self._task.args.get("user", self._play_context.remote_user))
|
||||
password = to_text(self._task.args.get("password", self._play_context.password))
|
||||
|
||||
# FIXME, default to play_context?
|
||||
port = int(self._task.args.get("port", 23))
|
||||
timeout = int(self._task.args.get("timeout", 120))
|
||||
pause = int(self._task.args.get("pause", 1))
|
||||
|
||||
send_newline = self._task.args.get("send_newline", False)
|
||||
clrf = self._task.args.get("clrf", False)
|
||||
|
||||
login_prompt = to_text(self._task.args.get("login_prompt", "login: "))
|
||||
password_prompt = to_text(self._task.args.get("password_prompt", "Password: "))
|
||||
prompts = self._task.args.get("prompts", ["\\$ "])
|
||||
commands = self._task.args.get("command") or self._task.args.get("commands")
|
||||
|
||||
if clrf:
|
||||
line_ending = "\r\n"
|
||||
else:
|
||||
line_ending = "\n"
|
||||
|
||||
if isinstance(commands, text_type):
|
||||
commands = commands.split(",")
|
||||
|
||||
if isinstance(commands, list) and commands:
|
||||
self.tn = telnetlib.Telnet(host, port, timeout)
|
||||
|
||||
self.output = bytes()
|
||||
try:
|
||||
if send_newline:
|
||||
self.tn.write(to_bytes(line_ending))
|
||||
|
||||
self.await_prompts([login_prompt], timeout)
|
||||
display.vvvvv(">>>user: %s" % user)
|
||||
self.tn.write(to_bytes(user + line_ending))
|
||||
|
||||
if password:
|
||||
self.await_prompts([password_prompt], timeout)
|
||||
display.vvvvv(">>>password: %s" % password)
|
||||
self.tn.write(to_bytes(password + line_ending))
|
||||
|
||||
self.await_prompts(prompts, timeout)
|
||||
|
||||
for cmd in commands:
|
||||
display.vvvvv(">>> %s" % cmd)
|
||||
self.tn.write(to_bytes(cmd + line_ending))
|
||||
self.await_prompts(prompts, timeout)
|
||||
display.vvvvv("<<< %s" % cmd)
|
||||
sleep(pause)
|
||||
|
||||
self.tn.write(to_bytes("exit" + line_ending))
|
||||
|
||||
except EOFError as e:
|
||||
result["failed"] = True
|
||||
result["msg"] = "Telnet action failed: %s" % to_text(e)
|
||||
except TimeoutError as e:
|
||||
result["failed"] = True
|
||||
result["msg"] = "Telnet timed out trying to find prompt(s): '%s'" % to_text(e)
|
||||
finally:
|
||||
if self.tn:
|
||||
self.tn.close()
|
||||
result["stdout"] = to_text(self.output)
|
||||
result["stdout_lines"] = self.output.splitlines(True)
|
||||
else:
|
||||
result["failed"] = True
|
||||
result["msg"] = "Telnet requires a command to execute"
|
||||
|
||||
return result
|
||||
|
||||
def await_prompts(self, prompts, timeout):
|
||||
index, match, out = self.tn.expect(list(map(to_bytes, prompts)), timeout=timeout)
|
||||
self.output += out
|
||||
if not match:
|
||||
raise TimeoutError(prompts)
|
||||
|
||||
return index
|
||||
47
collection/ansible/netcommon/plugins/become/enable.py
Normal file
47
collection/ansible/netcommon/plugins/become/enable.py
Normal file
@@ -0,0 +1,47 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright: (c) 2018, 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
|
||||
|
||||
DOCUMENTATION = """
|
||||
author:
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
name: enable
|
||||
short_description: Switch to elevated permissions on a network device
|
||||
description:
|
||||
- This become plugins allows elevated permissions on a remote network device.
|
||||
version_added: 1.0.0
|
||||
options:
|
||||
become_pass:
|
||||
description: password
|
||||
ini:
|
||||
- section: enable_become_plugin
|
||||
key: password
|
||||
vars:
|
||||
- name: ansible_become_password
|
||||
- name: ansible_become_pass
|
||||
- name: ansible_enable_pass
|
||||
env:
|
||||
- name: ANSIBLE_BECOME_PASS
|
||||
- name: ANSIBLE_ENABLE_PASS
|
||||
notes:
|
||||
- enable is really implemented in the network connection handler and as such can only
|
||||
be used with network connections.
|
||||
- This plugin ignores the 'become_exe' and 'become_user' settings as it uses an API
|
||||
and not an executable.
|
||||
"""
|
||||
|
||||
from ansible.plugins.become import BecomeBase
|
||||
|
||||
|
||||
class BecomeModule(BecomeBase):
|
||||
name = "ansible.netcommon.enable"
|
||||
|
||||
def build_become_command(self, cmd, shell):
|
||||
# enable is implemented inside the network connection plugins
|
||||
return cmd
|
||||
49
collection/ansible/netcommon/plugins/cache/memory.py
vendored
Normal file
49
collection/ansible/netcommon/plugins/cache/memory.py
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# (c) 2020 Red Hat Inc.
|
||||
# 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
|
||||
|
||||
DOCUMENTATION = """
|
||||
short_description: RAM backed, non persistent cache.
|
||||
description:
|
||||
- RAM backed cache that is not persistent.
|
||||
- Tailored for networking use case.
|
||||
version_added: 2.0.0
|
||||
author:
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
name: memory
|
||||
"""
|
||||
|
||||
from ansible.plugins import AnsiblePlugin
|
||||
|
||||
|
||||
class CacheModule(AnsiblePlugin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CacheModule, self).__init__(*args, **kwargs)
|
||||
self._cache = {}
|
||||
|
||||
def get(self, key):
|
||||
return self._cache.get(key)
|
||||
|
||||
def set(self, key, value):
|
||||
self._cache[key] = value
|
||||
|
||||
def keys(self):
|
||||
return self._cache.keys()
|
||||
|
||||
def flush(self):
|
||||
self._cache = {}
|
||||
|
||||
def lookup(self, key):
|
||||
return self.get(key)
|
||||
|
||||
def populate(self, key, value):
|
||||
self.set(key, value)
|
||||
|
||||
def invalidate(self):
|
||||
self.flush()
|
||||
67
collection/ansible/netcommon/plugins/cliconf/default.py
Normal file
67
collection/ansible/netcommon/plugins/cliconf/default.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# (c) 2023 Red Hat Inc.
|
||||
# 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
|
||||
|
||||
DOCUMENTATION = """
|
||||
author: Ansible Networking Team (@ansible-network)
|
||||
name: default
|
||||
short_description: General purpose cliconf plugin for new platforms
|
||||
description:
|
||||
- This plugin attemts to provide low level abstraction apis for sending and receiving CLI
|
||||
commands from arbitrary network devices.
|
||||
version_added: 5.2.0
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from ansible.errors import AnsibleConnectionFailure
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.cliconf_base import CliconfBase
|
||||
|
||||
|
||||
class Cliconf(CliconfBase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Cliconf, self).__init__(*args, **kwargs)
|
||||
self._device_info = {}
|
||||
|
||||
def get_device_info(self):
|
||||
if not self._device_info:
|
||||
device_info = {}
|
||||
|
||||
device_info["network_os"] = "default"
|
||||
self._device_info = device_info
|
||||
|
||||
return self._device_info
|
||||
|
||||
def get_config(self, flags=None, format=None):
|
||||
network_os = self.get_device_info()["network_os"]
|
||||
raise AnsibleConnectionFailure("get_config is not supported by network_os %s" % network_os)
|
||||
|
||||
def edit_config(self, candidate=None, commit=True, replace=None, comment=None):
|
||||
network_os = self.get_device_info()["network_os"]
|
||||
raise AnsibleConnectionFailure("edit_config is not supported by network_os %s" % network_os)
|
||||
|
||||
def get_capabilities(self):
|
||||
result = super(Cliconf, self).get_capabilities()
|
||||
result["device_operations"] = self.get_device_operations()
|
||||
return json.dumps(result)
|
||||
|
||||
def get_device_operations(self):
|
||||
return {
|
||||
"supports_diff_replace": False,
|
||||
"supports_commit": False,
|
||||
"supports_rollback": False,
|
||||
"supports_defaults": False,
|
||||
"supports_onbox_diff": False,
|
||||
"supports_commit_comment": False,
|
||||
"supports_multiline_delimiter": False,
|
||||
"supports_diff_match": False,
|
||||
"supports_diff_ignore_lines": False,
|
||||
"supports_generate_diff": False,
|
||||
"supports_replace": False,
|
||||
}
|
||||
278
collection/ansible/netcommon/plugins/connection/grpc.py
Normal file
278
collection/ansible/netcommon/plugins/connection/grpc.py
Normal file
@@ -0,0 +1,278 @@
|
||||
# (c) 2022 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
|
||||
|
||||
DOCUMENTATION = """
|
||||
author:
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
name: grpc
|
||||
short_description: Provides a persistent connection using the gRPC protocol
|
||||
description:
|
||||
- This connection plugin provides a connection to remote devices over gRPC and
|
||||
is typically used with devices for sending and receiving RPC calls
|
||||
over gRPC framework.
|
||||
- Note this connection plugin requires the grpcio python library to be installed on the
|
||||
local Ansible controller.
|
||||
version_added: "3.1.0"
|
||||
requirements:
|
||||
- grpcio
|
||||
- protobuf
|
||||
extends_documentation_fragment:
|
||||
- ansible.netcommon.connection_persistent
|
||||
options:
|
||||
host:
|
||||
description:
|
||||
- Specifies the remote device FQDN or IP address to establish the gRPC
|
||||
connection to.
|
||||
default: inventory_hostname
|
||||
type: string
|
||||
vars:
|
||||
- name: ansible_host
|
||||
port:
|
||||
type: int
|
||||
description:
|
||||
- Specifies the port on the remote device that listens for connections
|
||||
when establishing the gRPC connection. If None only the C(host) part will
|
||||
be used.
|
||||
ini:
|
||||
- section: defaults
|
||||
key: remote_port
|
||||
env:
|
||||
- name: ANSIBLE_REMOTE_PORT
|
||||
vars:
|
||||
- name: ansible_port
|
||||
network_os:
|
||||
description:
|
||||
- Configures the device platform network operating system. This value is
|
||||
used to load a device specific grpc plugin to communicate with the remote
|
||||
device.
|
||||
type: string
|
||||
vars:
|
||||
- name: ansible_network_os
|
||||
remote_user:
|
||||
description:
|
||||
- The username used to authenticate to the remote device when the gRPC
|
||||
connection is first established. If the remote_user is not specified,
|
||||
the connection will use the username of the logged in user.
|
||||
- Can be configured from the CLI via the C(--user) or C(-u) options.
|
||||
type: string
|
||||
ini:
|
||||
- section: defaults
|
||||
key: remote_user
|
||||
env:
|
||||
- name: ANSIBLE_REMOTE_USER
|
||||
vars:
|
||||
- name: ansible_user
|
||||
password:
|
||||
description:
|
||||
- Configures the user password used to authenticate to the remote device
|
||||
when first establishing the gRPC connection.
|
||||
type: string
|
||||
vars:
|
||||
- name: ansible_password
|
||||
- name: ansible_ssh_pass
|
||||
private_key_file:
|
||||
description:
|
||||
- The PEM encoded private key file used to authenticate to the
|
||||
remote device when first establishing the grpc connection.
|
||||
type: string
|
||||
ini:
|
||||
- section: grpc_connection
|
||||
key: private_key_file
|
||||
env:
|
||||
- name: ANSIBLE_PRIVATE_KEY_FILE
|
||||
vars:
|
||||
- name: ansible_private_key_file
|
||||
root_certificates_file:
|
||||
description:
|
||||
- The PEM encoded root certificate file used to create a SSL-enabled
|
||||
channel, if the value is None it reads the root certificates from
|
||||
a default location chosen by gRPC at runtime.
|
||||
type: string
|
||||
ini:
|
||||
- section: grpc_connection
|
||||
key: root_certificates_file
|
||||
env:
|
||||
- name: ANSIBLE_ROOT_CERTIFICATES_FILE
|
||||
vars:
|
||||
- name: ansible_root_certificates_file
|
||||
certificate_chain_file:
|
||||
description:
|
||||
- The PEM encoded certificate chain file used to create a SSL-enabled
|
||||
channel. If the value is None, no certificate chain is used.
|
||||
type: string
|
||||
ini:
|
||||
- section: grpc_connection
|
||||
key: certificate_chain_file
|
||||
env:
|
||||
- name: ANSIBLE_CERTIFICATE_CHAIN_FILE
|
||||
vars:
|
||||
- name: ansible_certificate_chain_file
|
||||
ssl_target_name_override:
|
||||
description:
|
||||
- The option overrides SSL target name used for SSL host name checking.
|
||||
The name used for SSL host name checking will be the target parameter
|
||||
(assuming that the secure channel is an SSL channel). If this parameter is
|
||||
specified and the underlying is not an SSL channel, it will just be ignored.
|
||||
type: string
|
||||
ini:
|
||||
- section: grpc_connection
|
||||
key: ssl_target_name_override
|
||||
env:
|
||||
- name: ANSIBLE_GPRC_SSL_TARGET_NAME_OVERRIDE
|
||||
vars:
|
||||
- name: ansible_grpc_ssl_target_name_override
|
||||
grpc_type:
|
||||
description:
|
||||
- This option indicates the grpc type and it can be used
|
||||
in place of network_os. (example cisco.iosxr.iosxr)
|
||||
default: False
|
||||
ini:
|
||||
- section: grpc_connection
|
||||
key: type
|
||||
env:
|
||||
- name: ANSIBLE_GRPC_CONNECTION_TYPE
|
||||
vars:
|
||||
- name: ansible_grpc_connection_type
|
||||
"""
|
||||
|
||||
from importlib import import_module
|
||||
|
||||
from ansible.errors import AnsibleConnectionFailure, AnsibleError
|
||||
from ansible.plugins.connection import NetworkConnectionBase
|
||||
|
||||
|
||||
try:
|
||||
from grpc import insecure_channel, secure_channel, ssl_channel_credentials
|
||||
from grpc.beta import implementations
|
||||
|
||||
HAS_GRPC = True
|
||||
except ImportError:
|
||||
HAS_GRPC = False
|
||||
|
||||
try:
|
||||
from google import protobuf # noqa: F401 # pylint: disable=unused-import
|
||||
|
||||
HAS_PROTOBUF = True
|
||||
except ImportError:
|
||||
HAS_PROTOBUF = False
|
||||
|
||||
|
||||
class Connection(NetworkConnectionBase):
|
||||
"""GRPC connections"""
|
||||
|
||||
transport = "ansible.netcommon.grpc"
|
||||
has_pipelining = False
|
||||
|
||||
def __init__(self, play_context, new_stdin, *args, **kwargs):
|
||||
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
|
||||
|
||||
grpc_type = self._network_os or self.get_option("grpc_type")
|
||||
if grpc_type:
|
||||
if not HAS_PROTOBUF:
|
||||
raise AnsibleError(
|
||||
"protobuf is required to use the grpc connection type. Please run 'pip install protobuf'"
|
||||
)
|
||||
if not self._network_os:
|
||||
self._network_os = grpc_type
|
||||
cref = dict(zip(["corg", "cname", "plugin"], grpc_type.split(".")))
|
||||
grpclib = "ansible_collections.{corg}.{cname}.plugins.sub_plugins.grpc.{plugin}".format(
|
||||
**cref
|
||||
)
|
||||
grpccls = getattr(import_module(grpclib), "Grpc")
|
||||
grpc_obj = grpccls(self)
|
||||
|
||||
if grpc_obj:
|
||||
self._sub_plugin = {
|
||||
"type": "grpc",
|
||||
"name": grpc_type,
|
||||
"obj": grpc_obj,
|
||||
}
|
||||
self.queue_message("log", "loaded gRPC plugin for type %s" % grpc_type)
|
||||
self.queue_message("log", "grpc type is set to %s" % grpc_type)
|
||||
else:
|
||||
raise AnsibleConnectionFailure(
|
||||
"unable to load API plugin for network_os %s" % grpc_type
|
||||
)
|
||||
else:
|
||||
raise AnsibleConnectionFailure(
|
||||
"Unable to automatically determine gRPC implementation type."
|
||||
" Please manually configure ansible_network_os value or grpc_type configuration for this host",
|
||||
)
|
||||
|
||||
def _connect(self):
|
||||
"""
|
||||
Create GRPC connection to target host
|
||||
:return: None
|
||||
"""
|
||||
if not HAS_GRPC:
|
||||
raise AnsibleError(
|
||||
"grpcio is required to use the gRPC connection type. Please run 'pip install grpcio'"
|
||||
)
|
||||
host = self.get_option("host")
|
||||
host = self._play_context.remote_addr
|
||||
if self.connected:
|
||||
self.queue_message("log", "gRPC connection to host %s already exist" % host)
|
||||
return
|
||||
|
||||
port = self.get_option("port")
|
||||
self._target = host if port is None else "%s:%d" % (host, port)
|
||||
self._timeout = self.get_option("persistent_command_timeout")
|
||||
self._login_credentials = [
|
||||
("username", self.get_option("remote_user")),
|
||||
("password", self.get_option("password")),
|
||||
]
|
||||
ssl_target_name_override = self.get_option("ssl_target_name_override")
|
||||
if ssl_target_name_override:
|
||||
self._channel_options = [
|
||||
("grpc.ssl_target_name_override", ssl_target_name_override),
|
||||
]
|
||||
else:
|
||||
self._channel_options = None
|
||||
|
||||
certs = {}
|
||||
private_key_file = self.get_option("private_key_file")
|
||||
root_certificates_file = self.get_option("root_certificates_file")
|
||||
certificate_chain_file = self.get_option("certificate_chain_file")
|
||||
|
||||
try:
|
||||
if root_certificates_file:
|
||||
with open(root_certificates_file, "rb") as f:
|
||||
certs["root_certificates"] = f.read()
|
||||
if private_key_file:
|
||||
with open(private_key_file, "rb") as f:
|
||||
certs["private_key"] = f.read()
|
||||
if certificate_chain_file:
|
||||
with open(certificate_chain_file, "rb") as f:
|
||||
certs["certificate_chain"] = f.read()
|
||||
except Exception as e:
|
||||
raise AnsibleConnectionFailure("Failed to read certificate keys: %s" % e)
|
||||
if certs:
|
||||
creds = ssl_channel_credentials(**certs)
|
||||
channel = secure_channel(self._target, creds, options=self._channel_options)
|
||||
else:
|
||||
channel = insecure_channel(self._target, options=self._channel_options)
|
||||
|
||||
self.queue_message(
|
||||
"vvv",
|
||||
"ESTABLISH GRPC CONNECTION FOR USER: %s on PORT %s TO %s"
|
||||
% (self.get_option("remote_user"), port, host),
|
||||
)
|
||||
self._channel = implementations.Channel(channel)
|
||||
self.queue_message("vvvv", "grpc connection has completed successfully")
|
||||
self._connected = True
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close the active session to the device
|
||||
:return: None
|
||||
"""
|
||||
if self._connected:
|
||||
self.queue_message("vvvv", "closing gRPC connection to target host")
|
||||
self._channel.close()
|
||||
super(Connection, self).close()
|
||||
386
collection/ansible/netcommon/plugins/connection/httpapi.py
Normal file
386
collection/ansible/netcommon/plugins/connection/httpapi.py
Normal file
@@ -0,0 +1,386 @@
|
||||
# (c) 2018 Red Hat Inc.
|
||||
# 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
|
||||
|
||||
DOCUMENTATION = """
|
||||
author:
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
name: httpapi
|
||||
short_description: Use httpapi to run command on network appliances
|
||||
description:
|
||||
- This connection plugin provides a connection to remote devices over a HTTP(S)-based
|
||||
api.
|
||||
version_added: 1.0.0
|
||||
extends_documentation_fragment:
|
||||
- ansible.netcommon.connection_persistent
|
||||
options:
|
||||
host:
|
||||
description:
|
||||
- Specifies the remote device FQDN or IP address to establish the HTTP(S) connection
|
||||
to.
|
||||
default: inventory_hostname
|
||||
type: string
|
||||
vars:
|
||||
- name: inventory_hostname
|
||||
- name: ansible_host
|
||||
port:
|
||||
type: int
|
||||
description:
|
||||
- Specifies the port on the remote device that listens for connections when establishing
|
||||
the HTTP(S) connection.
|
||||
- When unspecified, will pick 80 or 443 based on the value of use_ssl.
|
||||
ini:
|
||||
- section: defaults
|
||||
key: remote_port
|
||||
env:
|
||||
- name: ANSIBLE_REMOTE_PORT
|
||||
vars:
|
||||
- name: ansible_httpapi_port
|
||||
network_os:
|
||||
description:
|
||||
- Configures the device platform network operating system. This value is used
|
||||
to load the correct httpapi plugin to communicate with the remote device
|
||||
type: string
|
||||
vars:
|
||||
- name: ansible_network_os
|
||||
remote_user:
|
||||
description:
|
||||
- The username used to authenticate to the remote device when the API connection
|
||||
is first established. If the remote_user is not specified, the connection will
|
||||
use the username of the logged in user.
|
||||
- Can be configured from the CLI via the C(--user) or C(-u) options.
|
||||
type: string
|
||||
ini:
|
||||
- section: defaults
|
||||
key: remote_user
|
||||
env:
|
||||
- name: ANSIBLE_REMOTE_USER
|
||||
vars:
|
||||
- name: ansible_user
|
||||
password:
|
||||
description:
|
||||
- Configures the user password used to authenticate to the remote device when
|
||||
needed for the device API.
|
||||
type: string
|
||||
vars:
|
||||
- name: ansible_password
|
||||
- name: ansible_httpapi_pass
|
||||
- name: ansible_httpapi_password
|
||||
session_key:
|
||||
type: dict
|
||||
description:
|
||||
- Configures the session key to be used to authenticate to the remote device when
|
||||
needed for the device API.
|
||||
- This should contain a dictionary representing the key name and value for the
|
||||
token.
|
||||
- When specified, I(password) is ignored.
|
||||
vars:
|
||||
- name: ansible_httpapi_session_key
|
||||
ca_path:
|
||||
description:
|
||||
- Path to CA cert bundle to use.
|
||||
type: path
|
||||
version_added: 5.2.0
|
||||
vars:
|
||||
- name: ansible_httpapi_ca_path
|
||||
client_cert:
|
||||
description:
|
||||
- PEM formatted certificate chain file to be used for SSL client
|
||||
authentication. This file can also include the key as well, and if the key
|
||||
is included, I(client_key) is not required
|
||||
version_added: 5.2.0
|
||||
vars:
|
||||
- name: ansible_httpapi_client_cert
|
||||
client_key:
|
||||
description:
|
||||
- PEM formatted file that contains the private key to be used for SSL client
|
||||
authentication. If I(client_cert) contains both the certificate and key,
|
||||
this option is not required.
|
||||
version_added: 5.2.0
|
||||
vars:
|
||||
- name: ansible_httpapi_client_key
|
||||
http_agent:
|
||||
description: User-Agent to use in the request.
|
||||
version_added: 5.2.0
|
||||
vars:
|
||||
- name: ansible_httpapi_http_agent
|
||||
use_ssl:
|
||||
type: boolean
|
||||
description:
|
||||
- Whether to connect using SSL (HTTPS) or not (HTTP).
|
||||
default: false
|
||||
vars:
|
||||
- name: ansible_httpapi_use_ssl
|
||||
validate_certs:
|
||||
type: boolean
|
||||
description:
|
||||
- Whether to validate SSL certificates
|
||||
default: true
|
||||
vars:
|
||||
- name: ansible_httpapi_validate_certs
|
||||
use_proxy:
|
||||
type: boolean
|
||||
description:
|
||||
- Whether to use https_proxy for requests.
|
||||
default: true
|
||||
vars:
|
||||
- name: ansible_httpapi_use_proxy
|
||||
ciphers:
|
||||
description:
|
||||
- SSL/TLS Ciphers to use for requests
|
||||
- 'When a list is provided, all ciphers are joined in order with C(:)'
|
||||
- See the L(OpenSSL Cipher List Format,https://www.openssl.org/docs/manmaster/man1/openssl-ciphers.html#CIPHER-LIST-FORMAT)
|
||||
for more details.
|
||||
- The available ciphers is dependent on the Python and OpenSSL/LibreSSL versions.
|
||||
- This option will have no effect on ansible-core<2.14 but a warning will be emitted.
|
||||
version_added: 5.0.0
|
||||
type: list
|
||||
elements: string
|
||||
vars:
|
||||
- name: ansible_httpapi_ciphers
|
||||
become:
|
||||
type: boolean
|
||||
description:
|
||||
- The become option will instruct the CLI session to attempt privilege escalation
|
||||
on platforms that support it. Normally this means transitioning from user mode
|
||||
to C(enable) mode in the CLI session. If become is set to True and the remote
|
||||
device does not support privilege escalation or the privilege has already been
|
||||
elevated, then this option is silently ignored.
|
||||
- Can be configured from the CLI via the C(--become) or C(-b) options.
|
||||
default: false
|
||||
ini:
|
||||
- section: privilege_escalation
|
||||
key: become
|
||||
env:
|
||||
- name: ANSIBLE_BECOME
|
||||
vars:
|
||||
- name: ansible_become
|
||||
become_method:
|
||||
description:
|
||||
- This option allows the become method to be specified in for handling privilege
|
||||
escalation. Typically the become_method value is set to C(enable) but could
|
||||
be defined as other values.
|
||||
default: sudo
|
||||
type: string
|
||||
ini:
|
||||
- section: privilege_escalation
|
||||
key: become_method
|
||||
env:
|
||||
- name: ANSIBLE_BECOME_METHOD
|
||||
vars:
|
||||
- name: ansible_become_method
|
||||
platform_type:
|
||||
description:
|
||||
- Set type of platform.
|
||||
type: string
|
||||
env:
|
||||
- name: ANSIBLE_PLATFORM_TYPE
|
||||
vars:
|
||||
- name: ansible_platform_type
|
||||
"""
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
from ansible.errors import AnsibleConnectionFailure
|
||||
from ansible.module_utils._text import to_bytes
|
||||
from ansible.module_utils.six import PY3
|
||||
from ansible.module_utils.six.moves import cPickle
|
||||
from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.playbook.play_context import PlayContext
|
||||
from ansible.plugins.connection import ensure_connect
|
||||
from ansible.plugins.loader import httpapi_loader
|
||||
from ansible.release import __version__ as ANSIBLE_CORE_VERSION
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.connection_base import (
|
||||
NetworkConnectionBase,
|
||||
)
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.version import Version
|
||||
|
||||
|
||||
class Connection(NetworkConnectionBase):
|
||||
"""Network API connection"""
|
||||
|
||||
transport = "ansible.netcommon.httpapi"
|
||||
has_pipelining = True
|
||||
|
||||
def __init__(self, play_context, new_stdin, *args, **kwargs):
|
||||
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
|
||||
|
||||
self._auth = None
|
||||
if self._network_os:
|
||||
self.load_platform_plugins(self._network_os)
|
||||
|
||||
def load_platform_plugins(self, platform_type=None):
|
||||
platform_type = platform_type or self.get_option("platform_type")
|
||||
|
||||
if platform_type:
|
||||
self.httpapi = httpapi_loader.get(platform_type, self)
|
||||
if self.httpapi:
|
||||
self._sub_plugin = {
|
||||
"type": "httpapi",
|
||||
"name": self.httpapi._load_name,
|
||||
"obj": self.httpapi,
|
||||
}
|
||||
self.queue_message(
|
||||
"vvvv",
|
||||
"loaded API plugin %s from path %s for platform type %s"
|
||||
% (
|
||||
self.httpapi._load_name,
|
||||
self.httpapi._original_path,
|
||||
platform_type,
|
||||
),
|
||||
)
|
||||
else:
|
||||
raise AnsibleConnectionFailure(
|
||||
"unable to load API plugin for platform type %s" % platform_type
|
||||
)
|
||||
|
||||
else:
|
||||
raise AnsibleConnectionFailure(
|
||||
"Unable to automatically determine host platform type. Please "
|
||||
"manually configure platform_type value for this host"
|
||||
)
|
||||
self.queue_message("log", "platform_type is set to %s" % platform_type)
|
||||
|
||||
@property
|
||||
def _url(self):
|
||||
protocol = "https" if self.get_option("use_ssl") else "http"
|
||||
host = self.get_option("host")
|
||||
port = self.get_option("port") or (443 if protocol == "https" else 80)
|
||||
return "%s://%s:%s" % (protocol, host, port)
|
||||
|
||||
def update_play_context(self, pc_data):
|
||||
"""Updates the play context information for the connection"""
|
||||
pc_data = to_bytes(pc_data)
|
||||
if PY3:
|
||||
pc_data = cPickle.loads(pc_data, encoding="bytes")
|
||||
else:
|
||||
pc_data = cPickle.loads(pc_data)
|
||||
play_context = PlayContext()
|
||||
play_context.deserialize(pc_data)
|
||||
|
||||
self.queue_message("vvvv", "updating play_context for connection")
|
||||
if self._play_context.become ^ play_context.become:
|
||||
self.set_become(play_context)
|
||||
if play_context.become is True:
|
||||
self.queue_message("vvvv", "authorizing connection")
|
||||
else:
|
||||
self.queue_message("vvvv", "deauthorizing connection")
|
||||
|
||||
self._play_context = play_context
|
||||
|
||||
def _connect(self):
|
||||
if not self.connected:
|
||||
self.queue_message(
|
||||
"vvv",
|
||||
"ESTABLISH HTTP(S) CONNECTFOR USER: %s TO %s"
|
||||
% (self._play_context.remote_user, self._url),
|
||||
)
|
||||
self.httpapi.set_become(self._play_context)
|
||||
self._connected = True
|
||||
|
||||
if self.get_option("session_key"):
|
||||
self._auth = self.get_option("session_key")
|
||||
else:
|
||||
self.httpapi.login(self.get_option("remote_user"), self.get_option("password"))
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close the active session to the device
|
||||
"""
|
||||
# only close the connection if its connected.
|
||||
if self._connected:
|
||||
self.queue_message("vvvv", "closing http(s) connection to device")
|
||||
self.logout()
|
||||
|
||||
super(Connection, self).close()
|
||||
|
||||
@ensure_connect
|
||||
def send(self, path, data, retries=None, **kwargs):
|
||||
"""
|
||||
Sends the command to the device over api
|
||||
"""
|
||||
url_kwargs = dict(
|
||||
headers={},
|
||||
use_proxy=self.get_option("use_proxy"),
|
||||
timeout=self.get_option("persistent_command_timeout"),
|
||||
validate_certs=self.get_option("validate_certs"),
|
||||
http_agent=self.get_option("http_agent"),
|
||||
client_cert=self.get_option("client_cert"),
|
||||
client_key=self.get_option("client_key"),
|
||||
ca_path=self.get_option("ca_path"),
|
||||
)
|
||||
url_kwargs.update(kwargs)
|
||||
|
||||
ciphers = self.get_option("ciphers")
|
||||
if ciphers:
|
||||
if Version(ANSIBLE_CORE_VERSION) >= Version("2.14.0"):
|
||||
# Only insert "ciphers" kwarg for ansible-core versions >= 2.14.0.
|
||||
url_kwargs["ciphers"] = ciphers
|
||||
else:
|
||||
# Emit warning when "ansible_httpapi_ciphers" is set but not supported
|
||||
self.queue_message(
|
||||
"warning",
|
||||
"'ansible_httpapi_ciphers' option is unavailable on ansible-core<2.14",
|
||||
)
|
||||
|
||||
if self._auth:
|
||||
# Avoid modifying passed-in headers
|
||||
headers = dict(kwargs.get("headers", {}))
|
||||
headers.update(self._auth)
|
||||
url_kwargs["headers"] = headers
|
||||
else:
|
||||
url_kwargs["force_basic_auth"] = True
|
||||
url_kwargs["url_username"] = self.get_option("remote_user")
|
||||
url_kwargs["url_password"] = self.get_option("password")
|
||||
|
||||
try:
|
||||
url = self._url + path
|
||||
self._log_messages(
|
||||
"send url '%s' with data '%s' and kwargs '%s'" % (url, data, url_kwargs)
|
||||
)
|
||||
response = open_url(url, data=data, **url_kwargs)
|
||||
except HTTPError as exc:
|
||||
is_handled = self.handle_httperror(exc)
|
||||
if is_handled is True:
|
||||
if retries is None:
|
||||
# The default behavior, retry indefinitely until timeout.
|
||||
return self.send(path, data, **kwargs)
|
||||
if retries:
|
||||
return self.send(path, data, retries=retries - 1, **kwargs)
|
||||
raise
|
||||
if is_handled is False:
|
||||
raise
|
||||
response = is_handled
|
||||
except URLError as exc:
|
||||
raise AnsibleConnectionFailure(
|
||||
"Could not connect to {0}: {1}".format(self._url + path, exc.reason)
|
||||
)
|
||||
|
||||
response_buffer = BytesIO()
|
||||
resp_data = response.read()
|
||||
self._log_messages("received response: '%s'" % resp_data)
|
||||
response_buffer.write(resp_data)
|
||||
|
||||
# Try to assign a new auth token if one is given
|
||||
self._auth = self.update_auth(response, response_buffer) or self._auth
|
||||
|
||||
response_buffer.seek(0)
|
||||
|
||||
return response, response_buffer
|
||||
|
||||
def transport_test(self, connect_timeout):
|
||||
"""This method enables wait_for_connection to work.
|
||||
|
||||
The sole purpose of this method is to raise an exception if the API's URL
|
||||
cannot be reached. As such, it does not do anything except attempt to
|
||||
request the root URL with no error handling.
|
||||
"""
|
||||
|
||||
open_url(self._url, timeout=connect_timeout)
|
||||
623
collection/ansible/netcommon/plugins/connection/libssh.py
Normal file
623
collection/ansible/netcommon/plugins/connection/libssh.py
Normal file
@@ -0,0 +1,623 @@
|
||||
# (c) 2020 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
|
||||
|
||||
DOCUMENTATION = """
|
||||
author:
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
name: libssh
|
||||
short_description: Run tasks using libssh for ssh connection
|
||||
description:
|
||||
- Use the ansible-pylibssh python bindings to connect to targets
|
||||
- The python bindings use libssh C library (https://www.libssh.org/) to connect to targets
|
||||
- This plugin borrows a lot of settings from the ssh plugin as they both cover the same protocol.
|
||||
version_added: 1.1.0
|
||||
options:
|
||||
remote_addr:
|
||||
description:
|
||||
- Address of the remote target
|
||||
type: string
|
||||
default: inventory_hostname
|
||||
vars:
|
||||
- name: inventory_hostname
|
||||
- name: ansible_host
|
||||
- name: ansible_ssh_host
|
||||
- name: ansible_libssh_host
|
||||
remote_user:
|
||||
description:
|
||||
- User to login/authenticate as
|
||||
- Can be set from the CLI via the C(--user) or C(-u) options.
|
||||
type: string
|
||||
vars:
|
||||
- name: ansible_user
|
||||
- name: ansible_ssh_user
|
||||
- name: ansible_libssh_user
|
||||
env:
|
||||
- name: ANSIBLE_REMOTE_USER
|
||||
- name: ANSIBLE_LIBSSH_REMOTE_USER
|
||||
ini:
|
||||
- section: defaults
|
||||
key: remote_user
|
||||
- section: libssh_connection
|
||||
key: remote_user
|
||||
password:
|
||||
description:
|
||||
- Secret used to either login the ssh server or as a passphrase for ssh keys that require it
|
||||
- Can be set from the CLI via the C(--ask-pass) option.
|
||||
type: string
|
||||
vars:
|
||||
- name: ansible_password
|
||||
- name: ansible_ssh_pass
|
||||
- name: ansible_ssh_password
|
||||
- name: ansible_libssh_pass
|
||||
- name: ansible_libssh_password
|
||||
password_prompt:
|
||||
description:
|
||||
- Text to match when using keyboard-interactive authentication to determine if the prompt is
|
||||
for the password.
|
||||
- Requires ansible-pylibssh version >= 1.0.0
|
||||
type: string
|
||||
vars:
|
||||
- name: ansible_libssh_password_prompt
|
||||
version_added: 3.1.0
|
||||
host_key_auto_add:
|
||||
description: 'TODO: write it'
|
||||
env: [{name: ANSIBLE_LIBSSH_HOST_KEY_AUTO_ADD}]
|
||||
ini:
|
||||
- {key: host_key_auto_add, section: libssh_connection}
|
||||
type: boolean
|
||||
look_for_keys:
|
||||
default: True
|
||||
description: 'TODO: write it'
|
||||
env: [{name: ANSIBLE_LIBSSH_LOOK_FOR_KEYS}]
|
||||
ini:
|
||||
- {key: look_for_keys, section: libssh_connection}
|
||||
type: boolean
|
||||
proxy_command:
|
||||
default: ''
|
||||
description:
|
||||
- Proxy information for running the connection via a jumphost.
|
||||
- Also this plugin will scan 'ssh_args', 'ssh_extra_args' and 'ssh_common_args' from the 'ssh' plugin settings for proxy information if set.
|
||||
type: string
|
||||
env:
|
||||
- name: ANSIBLE_LIBSSH_PROXY_COMMAND
|
||||
ini:
|
||||
- {key: proxy_command, section: libssh_connection}
|
||||
vars:
|
||||
- name: ansible_paramiko_proxy_command
|
||||
- name: ansible_libssh_proxy_command
|
||||
pty:
|
||||
default: True
|
||||
description: 'TODO: write it'
|
||||
env:
|
||||
- name: ANSIBLE_LIBSSH_PTY
|
||||
ini:
|
||||
- section: libssh_connection
|
||||
key: pty
|
||||
type: boolean
|
||||
host_key_checking:
|
||||
description: 'Set this to "False" if you want to avoid host key checking by the underlying tools Ansible uses to connect to the host'
|
||||
type: boolean
|
||||
default: True
|
||||
env:
|
||||
- name: ANSIBLE_HOST_KEY_CHECKING
|
||||
- name: ANSIBLE_SSH_HOST_KEY_CHECKING
|
||||
- name: ANSIBLE_LIBSSH_HOST_KEY_CHECKING
|
||||
ini:
|
||||
- section: defaults
|
||||
key: host_key_checking
|
||||
- section: libssh_connection
|
||||
key: host_key_checking
|
||||
vars:
|
||||
- name: ansible_host_key_checking
|
||||
- name: ansible_ssh_host_key_checking
|
||||
- name: ansible_libssh_host_key_checking
|
||||
use_persistent_connections:
|
||||
description: 'Toggles the use of persistence for connections'
|
||||
type: boolean
|
||||
default: False
|
||||
env:
|
||||
- name: ANSIBLE_USE_PERSISTENT_CONNECTIONS
|
||||
ini:
|
||||
- section: defaults
|
||||
key: use_persistent_connections
|
||||
ssh_args:
|
||||
version_added: 3.2.0
|
||||
description:
|
||||
- Arguments to pass to all ssh CLI tools.
|
||||
- ProxyCommand is the only supported argument.
|
||||
- This option is deprecated in favor of I(proxy_command) and will be removed
|
||||
in a release after 2026-01-01.
|
||||
type: string
|
||||
ini:
|
||||
- section: 'ssh_connection'
|
||||
key: 'ssh_args'
|
||||
env:
|
||||
- name: ANSIBLE_SSH_ARGS
|
||||
vars:
|
||||
- name: ansible_ssh_args
|
||||
cli:
|
||||
- name: ssh_args
|
||||
ssh_common_args:
|
||||
version_added: 3.2.0
|
||||
description:
|
||||
- Common extra arguments for all ssh CLI tools.
|
||||
- ProxyCommand is the only supported argument.
|
||||
- This option is deprecated in favor of I(proxy_command) and will be removed
|
||||
in a release after 2026-01-01.
|
||||
type: string
|
||||
ini:
|
||||
- section: 'ssh_connection'
|
||||
key: 'ssh_common_args'
|
||||
env:
|
||||
- name: ANSIBLE_SSH_COMMON_ARGS
|
||||
vars:
|
||||
- name: ansible_ssh_common_args
|
||||
cli:
|
||||
- name: ssh_common_args
|
||||
ssh_extra_args:
|
||||
version_added: 3.2.0
|
||||
description:
|
||||
- Extra arguments exclusive to the 'ssh' CLI tool.
|
||||
- ProxyCommand is the only supported argument.
|
||||
- This option is deprecated in favor of I(proxy_command) and will be removed
|
||||
in a release after 2026-01-01.
|
||||
type: string
|
||||
vars:
|
||||
- name: ansible_ssh_extra_args
|
||||
env:
|
||||
- name: ANSIBLE_SSH_EXTRA_ARGS
|
||||
ini:
|
||||
- key: ssh_extra_args
|
||||
section: ssh_connection
|
||||
cli:
|
||||
- name: ssh_extra_args
|
||||
config_file:
|
||||
version_added: 5.1.0
|
||||
description: Alternate SSH config file location
|
||||
type: path
|
||||
env:
|
||||
- name: ANSIBLE_LIBSSH_CONFIG_FILE
|
||||
ini:
|
||||
- section: libssh_connection
|
||||
key: config_file
|
||||
vars:
|
||||
- name: ansible_libssh_config_file
|
||||
# TODO:
|
||||
#timeout=self._play_context.timeout,
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import socket
|
||||
import sys
|
||||
|
||||
from termios import TCIFLUSH, tcflush
|
||||
|
||||
from ansible.errors import AnsibleConnectionFailure, AnsibleError, AnsibleFileNotFound
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.basic import missing_required_lib
|
||||
from ansible.module_utils.six.moves import input
|
||||
from ansible.plugins.connection import ConnectionBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.version import Version
|
||||
|
||||
|
||||
display = Display()
|
||||
|
||||
try:
|
||||
from pylibsshext import __version__ as PYLIBSSH_VERSION
|
||||
from pylibsshext.errors import LibsshSCPException, LibsshSessionException
|
||||
from pylibsshext.session import Session
|
||||
|
||||
HAS_PYLIBSSH = True
|
||||
except ImportError:
|
||||
HAS_PYLIBSSH = False
|
||||
|
||||
|
||||
AUTHENTICITY_MSG = """
|
||||
libssh: The authenticity of host '%s' can't be established due to '%s'.
|
||||
The %s key fingerprint is %s.
|
||||
Are you sure you want to continue connecting (yes/no)?
|
||||
"""
|
||||
|
||||
# SSH Options Regex
|
||||
SETTINGS_REGEX = re.compile(r"(\w+)(?:\s*=\s*|\s+)(.+)")
|
||||
|
||||
|
||||
class MyAddPolicy(object):
|
||||
"""
|
||||
Based on AutoAddPolicy in paramiko so we can determine when keys are added
|
||||
|
||||
and also prompt for input.
|
||||
|
||||
Policy for automatically adding the hostname and new host key to the
|
||||
local L{HostKeys} object, and saving it. This is used by L{SSHClient}.
|
||||
"""
|
||||
|
||||
def __init__(self, new_stdin, connection):
|
||||
self._new_stdin = new_stdin
|
||||
self.connection = connection
|
||||
self._options = connection._options
|
||||
|
||||
def missing_host_key(self, session, hostname, username, key_type, fingerprint, message):
|
||||
if all(
|
||||
(
|
||||
self._options["host_key_checking"],
|
||||
not self._options["host_key_auto_add"],
|
||||
)
|
||||
):
|
||||
if (
|
||||
self.connection.get_option("use_persistent_connections")
|
||||
or self.connection.force_persistence
|
||||
):
|
||||
# don't print the prompt string since the user cannot respond
|
||||
# to the question anyway
|
||||
raise AnsibleError(
|
||||
AUTHENTICITY_MSG.rsplit("\n", 2)[0] % (hostname, message, key_type, fingerprint)
|
||||
)
|
||||
|
||||
self.connection.connection_lock()
|
||||
old_stdin = sys.stdin
|
||||
sys.stdin = self._new_stdin
|
||||
|
||||
# clear out any premature input on sys.stdin
|
||||
tcflush(sys.stdin, TCIFLUSH)
|
||||
|
||||
inp = input(AUTHENTICITY_MSG % (hostname, message, key_type, fingerprint))
|
||||
sys.stdin = old_stdin
|
||||
|
||||
self.connection.connection_unlock()
|
||||
if inp not in ["yes", "y", ""]:
|
||||
raise AnsibleError("host connection rejected by user")
|
||||
|
||||
session.hostkey_auto_add(username)
|
||||
|
||||
# host keys are actually saved in close() function below
|
||||
# in order to control ordering.
|
||||
|
||||
|
||||
# keep connection objects on a per host basis to avoid repeated attempts to reconnect
|
||||
SSH_CONNECTION_CACHE = {}
|
||||
SFTP_CONNECTION_CACHE = {}
|
||||
|
||||
|
||||
class Connection(ConnectionBase):
|
||||
"""SSH based connections with Paramiko"""
|
||||
|
||||
transport = "ansible.netcommon.libssh"
|
||||
_log_channel = None
|
||||
|
||||
def _cache_key(self):
|
||||
return "%s__%s__" % (
|
||||
self._play_context.remote_addr,
|
||||
self._play_context.remote_user,
|
||||
)
|
||||
|
||||
def _connect(self):
|
||||
cache_key = self._cache_key()
|
||||
if cache_key in SSH_CONNECTION_CACHE:
|
||||
self.ssh = SSH_CONNECTION_CACHE[cache_key]
|
||||
else:
|
||||
self.ssh = SSH_CONNECTION_CACHE[cache_key] = self._connect_uncached()
|
||||
return self
|
||||
|
||||
def _set_log_channel(self, name):
|
||||
self._log_channel = name
|
||||
|
||||
def _get_proxy_command(self, port=22):
|
||||
proxy_command = None
|
||||
# Parse ansible_ssh_common_args, specifically looking for ProxyCommand
|
||||
ssh_args = [
|
||||
self.get_option("ssh_extra_args") or "",
|
||||
self.get_option("ssh_common_args") or "",
|
||||
self.get_option("ssh_args") or "",
|
||||
]
|
||||
|
||||
if any(ssh_args):
|
||||
display.warning(
|
||||
"The ssh_*_args options are deprecated and will be removed in a release after 2026-01-01. Please use the proxy_command option instead."
|
||||
)
|
||||
args = self._split_ssh_args(" ".join(ssh_args))
|
||||
for i, arg in enumerate(args):
|
||||
if arg.lower() == "proxycommand":
|
||||
# _split_ssh_args split ProxyCommand from the command itself
|
||||
proxy_command = args[i + 1]
|
||||
else:
|
||||
# ProxyCommand and the command itself are a single string
|
||||
match = SETTINGS_REGEX.match(arg)
|
||||
if match:
|
||||
if match.group(1).lower() == "proxycommand":
|
||||
proxy_command = match.group(2)
|
||||
|
||||
if proxy_command:
|
||||
break
|
||||
|
||||
proxy_command = proxy_command or self.get_option("proxy_command")
|
||||
|
||||
if proxy_command:
|
||||
replacers = {
|
||||
"%h": self._play_context.remote_addr,
|
||||
"%p": port,
|
||||
"%r": self._play_context.remote_user,
|
||||
}
|
||||
for find, replace in replacers.items():
|
||||
proxy_command = proxy_command.replace(find, str(replace))
|
||||
|
||||
return proxy_command
|
||||
|
||||
def _connect_uncached(self):
|
||||
"""activates the connection object"""
|
||||
|
||||
if not HAS_PYLIBSSH:
|
||||
raise AnsibleError(missing_required_lib("ansible-pylibssh"))
|
||||
display.vvv(
|
||||
"USING PYLIBSSH VERSION %s" % PYLIBSSH_VERSION,
|
||||
host=self._play_context.remote_addr,
|
||||
)
|
||||
|
||||
ssh_connect_kwargs = {}
|
||||
|
||||
remote_user = self.get_option("remote_user")
|
||||
remote_addr = self.get_option("remote_addr")
|
||||
port = self._play_context.port or 22
|
||||
display.vvv(
|
||||
"ESTABLISH LIBSSH CONNECTION FOR USER: %s on PORT %s TO %s"
|
||||
% (remote_user, port, remote_addr),
|
||||
host=remote_addr,
|
||||
)
|
||||
|
||||
self.ssh = Session()
|
||||
|
||||
if self._play_context.verbosity > 3:
|
||||
self.ssh.set_log_level(logging.INFO)
|
||||
|
||||
self.keyfile = os.path.expanduser("~/.ssh/known_hosts")
|
||||
|
||||
proxy_command = self._get_proxy_command(port)
|
||||
|
||||
try:
|
||||
private_key = None
|
||||
if self._play_context.private_key_file:
|
||||
with open(os.path.expanduser(self._play_context.private_key_file)) as fp:
|
||||
b_content = fp.read()
|
||||
private_key = to_bytes(b_content, errors="surrogate_or_strict")
|
||||
|
||||
if proxy_command:
|
||||
ssh_connect_kwargs["proxycommand"] = proxy_command
|
||||
|
||||
if self.get_option("config_file"):
|
||||
ssh_connect_kwargs["config_file"] = self.get_option("config_file")
|
||||
|
||||
if self.get_option("password_prompt") and (Version(PYLIBSSH_VERSION) < "1.0.0"):
|
||||
raise AnsibleError(
|
||||
"Configuring password prompt is not supported in ansible-pylibssh version %s. "
|
||||
"Please upgrade to ansible-pylibssh 1.0.0 or newer." % PYLIBSSH_VERSION
|
||||
)
|
||||
|
||||
self.ssh.set_missing_host_key_policy(MyAddPolicy(self._new_stdin, self))
|
||||
|
||||
self.ssh.connect(
|
||||
host=remote_addr.lower(),
|
||||
user=remote_user,
|
||||
look_for_keys=self.get_option("look_for_keys"),
|
||||
host_key_checking=self.get_option("host_key_checking"),
|
||||
password=self.get_option("password"),
|
||||
password_prompt=self.get_option("password_prompt"),
|
||||
private_key=private_key,
|
||||
timeout=self._play_context.timeout,
|
||||
port=port,
|
||||
**ssh_connect_kwargs,
|
||||
)
|
||||
except LibsshSessionException as e:
|
||||
msg = "ssh connection failed: " + to_text(e)
|
||||
raise AnsibleConnectionFailure(msg)
|
||||
except Exception as e:
|
||||
raise AnsibleConnectionFailure(to_text(e))
|
||||
|
||||
display.vvv("ssh connection is OK: " + str(self.ssh))
|
||||
return self.ssh
|
||||
|
||||
def exec_command(self, cmd, in_data=None, sudoable=True):
|
||||
"""run a command on the remote host"""
|
||||
|
||||
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
||||
|
||||
if in_data:
|
||||
raise AnsibleError(
|
||||
"Internal Error: this module does not support optimized module pipelining"
|
||||
)
|
||||
|
||||
bufsize = 4096
|
||||
|
||||
try:
|
||||
self.chan = self.ssh.new_channel()
|
||||
except Exception as e:
|
||||
text_e = to_text(e)
|
||||
msg = "Failed to open session"
|
||||
if text_e:
|
||||
msg += ": %s" % text_e
|
||||
raise AnsibleConnectionFailure(to_native(msg))
|
||||
|
||||
# sudo usually requires a PTY (cf. requiretty option), therefore
|
||||
# we give it one by default (pty=True in ansible.cfg), and we try
|
||||
# to initialise from the calling environment when sudoable is enabled
|
||||
if self.get_option("pty") and sudoable:
|
||||
self.chan.request_shell()
|
||||
|
||||
display.vvv("EXEC %s" % cmd, host=self._play_context.remote_addr)
|
||||
|
||||
cmd = to_bytes(cmd, errors="surrogate_or_strict")
|
||||
|
||||
result = None
|
||||
no_prompt_out = b""
|
||||
no_prompt_err = b""
|
||||
become_output = b""
|
||||
out = b""
|
||||
err = b""
|
||||
|
||||
try:
|
||||
if self.become and self.become.expect_prompt():
|
||||
passprompt = False
|
||||
become_sucess = False
|
||||
self.chan.sendall(cmd)
|
||||
|
||||
while not (become_sucess or passprompt):
|
||||
display.debug("Waiting for Privilege Escalation input")
|
||||
self.chan.poll(timeout=self._play_context.timeout)
|
||||
chunk = self.chan.recv(bufsize)
|
||||
display.debug("chunk is: %s" % chunk)
|
||||
|
||||
if not chunk:
|
||||
if b"unknown user" in become_output:
|
||||
n_become_user = to_native(
|
||||
self.become.get_option(
|
||||
"become_user",
|
||||
playcontext=self._play_context,
|
||||
)
|
||||
)
|
||||
raise AnsibleError("user %s does not exist" % n_become_user)
|
||||
else:
|
||||
break
|
||||
# raise AnsibleError('ssh connection closed waiting for password prompt')
|
||||
become_output += chunk
|
||||
# need to check every line because we might get lectured
|
||||
# and we might get the middle of a line in a chunk
|
||||
for line in become_output.splitlines(True):
|
||||
if self.become.check_success(line):
|
||||
become_sucess = True
|
||||
break
|
||||
if self.become.check_password_prompt(line):
|
||||
passprompt = True
|
||||
break
|
||||
if passprompt:
|
||||
if self.become:
|
||||
become_pass = self.become.get_option(
|
||||
"become_pass", playcontext=self._play_context
|
||||
)
|
||||
self.chan.sendall(
|
||||
to_bytes(become_pass, errors="surrogate_or_strict") + b"\n"
|
||||
)
|
||||
else:
|
||||
raise AnsibleError("A password is required but none was supplied")
|
||||
else:
|
||||
no_prompt_out += become_output
|
||||
no_prompt_err += become_output
|
||||
else:
|
||||
result = self.chan.exec_command(to_text(cmd, errors="surrogate_or_strict"))
|
||||
except socket.timeout:
|
||||
raise AnsibleError("ssh timed out waiting for privilege escalation.\n" + become_output)
|
||||
|
||||
if result:
|
||||
rc = result.returncode
|
||||
out = result.stdout
|
||||
err = result.stderr
|
||||
else:
|
||||
rc = self.chan.get_channel_exit_status()
|
||||
return rc, out, err
|
||||
|
||||
def put_file(self, in_path, out_path, proto="sftp"):
|
||||
"""transfer a file from local to remote"""
|
||||
|
||||
super(Connection, self).put_file(in_path, out_path)
|
||||
|
||||
display.vvv(
|
||||
"PUT %s TO %s" % (in_path, out_path),
|
||||
host=self._play_context.remote_addr,
|
||||
)
|
||||
|
||||
if not os.path.exists(to_bytes(in_path, errors="surrogate_or_strict")):
|
||||
raise AnsibleFileNotFound("file or module does not exist: %s" % in_path)
|
||||
|
||||
if proto == "sftp":
|
||||
try:
|
||||
self.sftp = self.ssh.sftp()
|
||||
except Exception as e:
|
||||
raise AnsibleError("failed to open a SFTP connection (%s)" % e)
|
||||
|
||||
try:
|
||||
self.sftp.put(
|
||||
to_bytes(in_path, errors="surrogate_or_strict"),
|
||||
to_bytes(out_path, errors="surrogate_or_strict"),
|
||||
)
|
||||
except IOError:
|
||||
raise AnsibleError("failed to transfer file to %s" % out_path)
|
||||
elif proto == "scp":
|
||||
scp = self.ssh.scp()
|
||||
try:
|
||||
scp.put(in_path, out_path)
|
||||
except LibsshSCPException as exc:
|
||||
raise AnsibleError("Error transferring file to %s: %s" % (out_path, to_text(exc)))
|
||||
else:
|
||||
raise AnsibleError("Don't know how to transfer file over protocol %s" % proto)
|
||||
|
||||
def _connect_sftp(self):
|
||||
cache_key = "%s__%s__" % (
|
||||
self._play_context.remote_addr,
|
||||
self._play_context.remote_user,
|
||||
)
|
||||
if cache_key in SFTP_CONNECTION_CACHE:
|
||||
return SFTP_CONNECTION_CACHE[cache_key]
|
||||
else:
|
||||
result = SFTP_CONNECTION_CACHE[cache_key] = self._connect().ssh.sftp()
|
||||
return result
|
||||
|
||||
def fetch_file(self, in_path, out_path, proto="sftp"):
|
||||
"""save a remote file to the specified path"""
|
||||
|
||||
super(Connection, self).fetch_file(in_path, out_path)
|
||||
|
||||
display.vvv(
|
||||
"FETCH %s TO %s" % (in_path, out_path),
|
||||
host=self._play_context.remote_addr,
|
||||
)
|
||||
|
||||
if proto == "sftp":
|
||||
try:
|
||||
self.sftp = self._connect_sftp()
|
||||
except Exception as e:
|
||||
raise AnsibleError("failed to open a SFTP connection (%s)" % to_native(e))
|
||||
|
||||
try:
|
||||
self.sftp.get(
|
||||
to_bytes(in_path, errors="surrogate_or_strict"),
|
||||
to_bytes(out_path, errors="surrogate_or_strict"),
|
||||
)
|
||||
except IOError:
|
||||
raise AnsibleError("failed to transfer file from %s" % in_path)
|
||||
elif proto == "scp":
|
||||
scp = self.ssh.scp()
|
||||
try:
|
||||
scp.get(out_path, in_path)
|
||||
except LibsshSCPException as exc:
|
||||
raise AnsibleError("Error transferring file from %s: %s" % (out_path, to_text(exc)))
|
||||
else:
|
||||
raise AnsibleError("Don't know how to transfer file over protocol %s" % proto)
|
||||
|
||||
def reset(self):
|
||||
self.close()
|
||||
self._connect()
|
||||
|
||||
def close(self):
|
||||
"""terminate the connection"""
|
||||
|
||||
cache_key = self._cache_key()
|
||||
SSH_CONNECTION_CACHE.pop(cache_key, None)
|
||||
SFTP_CONNECTION_CACHE.pop(cache_key, None)
|
||||
|
||||
if hasattr(self, "sftp"):
|
||||
if self.sftp is not None:
|
||||
self.sftp.close()
|
||||
|
||||
if hasattr(self, "chan"):
|
||||
if self.chan is not None:
|
||||
self.chan.close()
|
||||
|
||||
self.ssh.close()
|
||||
self._connected = False
|
||||
435
collection/ansible/netcommon/plugins/connection/netconf.py
Normal file
435
collection/ansible/netcommon/plugins/connection/netconf.py
Normal file
@@ -0,0 +1,435 @@
|
||||
# (c) 2016 Red Hat Inc.
|
||||
# (c) 2017 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
|
||||
|
||||
DOCUMENTATION = """
|
||||
author:
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
name: netconf
|
||||
short_description: Provides a persistent connection using the netconf protocol
|
||||
description:
|
||||
- This connection plugin provides a connection to remote devices over the SSH NETCONF
|
||||
subsystem. This connection plugin is typically used by network devices for sending
|
||||
and receiving RPC calls over NETCONF.
|
||||
- Note this connection plugin requires ncclient to be installed on the local Ansible
|
||||
controller.
|
||||
version_added: 1.0.0
|
||||
requirements:
|
||||
- ncclient
|
||||
extends_documentation_fragment:
|
||||
- ansible.netcommon.connection_persistent
|
||||
options:
|
||||
host:
|
||||
description:
|
||||
- Specifies the remote device FQDN or IP address to establish the SSH connection
|
||||
to.
|
||||
default: inventory_hostname
|
||||
type: string
|
||||
vars:
|
||||
- name: inventory_hostname
|
||||
- name: ansible_host
|
||||
port:
|
||||
type: int
|
||||
description:
|
||||
- Specifies the port on the remote device that listens for connections when establishing
|
||||
the SSH connection.
|
||||
default: 830
|
||||
ini:
|
||||
- section: defaults
|
||||
key: remote_port
|
||||
env:
|
||||
- name: ANSIBLE_REMOTE_PORT
|
||||
vars:
|
||||
- name: ansible_port
|
||||
network_os:
|
||||
description:
|
||||
- Configures the device platform network operating system. This value is used
|
||||
to load a device specific netconf plugin. If this option is not configured
|
||||
(or set to C(auto)), then Ansible will attempt to guess the correct network_os
|
||||
to use. If it can not guess a network_os correctly it will use C(default).
|
||||
type: string
|
||||
vars:
|
||||
- name: ansible_network_os
|
||||
remote_user:
|
||||
description:
|
||||
- The username used to authenticate to the remote device when the SSH connection
|
||||
is first established. If the remote_user is not specified, the connection will
|
||||
use the username of the logged in user.
|
||||
- Can be configured from the CLI via the C(--user) or C(-u) options.
|
||||
type: string
|
||||
ini:
|
||||
- section: defaults
|
||||
key: remote_user
|
||||
env:
|
||||
- name: ANSIBLE_REMOTE_USER
|
||||
vars:
|
||||
- name: ansible_user
|
||||
password:
|
||||
description:
|
||||
- Configures the user password used to authenticate to the remote device when
|
||||
first establishing the SSH connection.
|
||||
type: string
|
||||
vars:
|
||||
- name: ansible_password
|
||||
- name: ansible_ssh_pass
|
||||
- name: ansible_ssh_password
|
||||
- name: ansible_netconf_password
|
||||
private_key_file:
|
||||
description:
|
||||
- The private SSH key or certificate file used to authenticate to the remote device
|
||||
when first establishing the SSH connection.
|
||||
type: string
|
||||
ini:
|
||||
- section: defaults
|
||||
key: private_key_file
|
||||
env:
|
||||
- name: ANSIBLE_PRIVATE_KEY_FILE
|
||||
vars:
|
||||
- name: ansible_private_key_file
|
||||
look_for_keys:
|
||||
default: true
|
||||
description:
|
||||
- Enables looking for ssh keys in the usual locations for ssh keys (e.g. :file:`~/.ssh/id_*`).
|
||||
env:
|
||||
- name: ANSIBLE_PARAMIKO_LOOK_FOR_KEYS
|
||||
ini:
|
||||
- section: paramiko_connection
|
||||
key: look_for_keys
|
||||
type: boolean
|
||||
host_key_checking:
|
||||
description: Set this to "False" if you want to avoid host key checking by the
|
||||
underlying tools Ansible uses to connect to the host
|
||||
type: boolean
|
||||
default: true
|
||||
env:
|
||||
- name: ANSIBLE_HOST_KEY_CHECKING
|
||||
- name: ANSIBLE_SSH_HOST_KEY_CHECKING
|
||||
- name: ANSIBLE_NETCONF_HOST_KEY_CHECKING
|
||||
ini:
|
||||
- section: defaults
|
||||
key: host_key_checking
|
||||
- section: paramiko_connection
|
||||
key: host_key_checking
|
||||
vars:
|
||||
- name: ansible_host_key_checking
|
||||
- name: ansible_ssh_host_key_checking
|
||||
- name: ansible_netconf_host_key_checking
|
||||
proxy_command:
|
||||
default: ''
|
||||
description:
|
||||
- Proxy information for running the connection via a jumphost.
|
||||
- This requires ncclient >= 0.6.10 to be installed on the controller.
|
||||
type: string
|
||||
env:
|
||||
- name: ANSIBLE_NETCONF_PROXY_COMMAND
|
||||
ini:
|
||||
- {key: proxy_command, section: paramiko_connection}
|
||||
vars:
|
||||
- name: ansible_paramiko_proxy_command
|
||||
- name: ansible_netconf_proxy_command
|
||||
netconf_ssh_config:
|
||||
description:
|
||||
- This variable is used to enable bastion/jump host with netconf connection. If
|
||||
set to True the bastion/jump host ssh settings should be present in ~/.ssh/config
|
||||
file, alternatively it can be set to custom ssh configuration file path to read
|
||||
the bastion/jump host settings.
|
||||
type: string
|
||||
ini:
|
||||
- section: netconf_connection
|
||||
key: ssh_config
|
||||
env:
|
||||
- name: ANSIBLE_NETCONF_SSH_CONFIG
|
||||
vars:
|
||||
- name: ansible_netconf_ssh_config
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
from ansible.errors import AnsibleConnectionFailure, AnsibleError
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.basic import missing_required_lib
|
||||
from ansible.module_utils.parsing.convert_bool import BOOLEANS_FALSE, BOOLEANS_TRUE
|
||||
from ansible.module_utils.six import PY3
|
||||
from ansible.module_utils.six.moves import cPickle
|
||||
from ansible.playbook.play_context import PlayContext
|
||||
from ansible.plugins.connection import ensure_connect
|
||||
from ansible.plugins.loader import netconf_loader
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.connection_base import (
|
||||
NetworkConnectionBase,
|
||||
)
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.version import Version
|
||||
|
||||
|
||||
try:
|
||||
from ncclient import __version__ as NCCLIENT_VERSION
|
||||
from ncclient import manager
|
||||
from ncclient.operations import RPCError
|
||||
from ncclient.transport.errors import AuthenticationError, SSHUnknownHostError
|
||||
from ncclient.xml_ import to_ele, to_xml
|
||||
from paramiko import ProxyCommand
|
||||
|
||||
HAS_NCCLIENT = True
|
||||
NCCLIENT_IMP_ERR = None
|
||||
# paramiko and gssapi are incompatible and raise AttributeError not ImportError
|
||||
# When running in FIPS mode, cryptography raises InternalError
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1778939
|
||||
except Exception as err:
|
||||
HAS_NCCLIENT = False
|
||||
NCCLIENT_IMP_ERR = err
|
||||
|
||||
logging.getLogger("ncclient").setLevel(logging.INFO)
|
||||
|
||||
|
||||
class Connection(NetworkConnectionBase):
|
||||
"""NetConf connections"""
|
||||
|
||||
transport = "ansible.netcommon.netconf"
|
||||
has_pipelining = False
|
||||
|
||||
def __init__(self, play_context, new_stdin, *args, **kwargs):
|
||||
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
|
||||
|
||||
# If network_os is not specified then set the network os to auto
|
||||
# This will be used to trigger the use of guess_network_os when connecting.
|
||||
self._network_os = self._network_os or "auto"
|
||||
|
||||
self.netconf = netconf_loader.get(self._network_os, self)
|
||||
if self.netconf:
|
||||
self._sub_plugin = {
|
||||
"type": "netconf",
|
||||
"name": self.netconf._load_name,
|
||||
"obj": self.netconf,
|
||||
}
|
||||
self.queue_message(
|
||||
"vvvv",
|
||||
"loaded netconf plugin %s from path %s for network_os %s"
|
||||
% (
|
||||
self.netconf._load_name,
|
||||
self.netconf._original_path,
|
||||
self._network_os,
|
||||
),
|
||||
)
|
||||
else:
|
||||
self.netconf = netconf_loader.get("default", self)
|
||||
self._sub_plugin = {
|
||||
"type": "netconf",
|
||||
"name": "default",
|
||||
"obj": self.netconf,
|
||||
}
|
||||
self.queue_message(
|
||||
"vvvv",
|
||||
"unable to load netconf plugin for network_os %s, falling back to default plugin"
|
||||
% self._network_os,
|
||||
)
|
||||
|
||||
self.queue_message("log", "network_os is set to %s" % self._network_os)
|
||||
self._manager = None
|
||||
self.key_filename = None
|
||||
self._ssh_config = None
|
||||
|
||||
def exec_command(self, cmd, in_data=None, sudoable=True):
|
||||
"""Sends the request to the node and returns the reply
|
||||
The method accepts two forms of request. The first form is as a byte
|
||||
string that represents xml string be send over netconf session.
|
||||
The second form is a json-rpc (2.0) byte string.
|
||||
"""
|
||||
if self._manager:
|
||||
# to_ele operates on native strings
|
||||
request = to_ele(to_native(cmd, errors="surrogate_or_strict"))
|
||||
|
||||
if request is None:
|
||||
return "unable to parse request"
|
||||
|
||||
try:
|
||||
reply = self._manager.rpc(request)
|
||||
except RPCError as exc:
|
||||
error = self.internal_error(
|
||||
data=to_text(to_xml(exc.xml), errors="surrogate_or_strict")
|
||||
)
|
||||
return json.dumps(error)
|
||||
|
||||
return reply.data_xml
|
||||
else:
|
||||
return super(Connection, self).exec_command(cmd, in_data, sudoable)
|
||||
|
||||
def update_play_context(self, pc_data):
|
||||
"""Updates the play context information for the connection"""
|
||||
pc_data = to_bytes(pc_data)
|
||||
if PY3:
|
||||
pc_data = cPickle.loads(pc_data, encoding="bytes")
|
||||
else:
|
||||
pc_data = cPickle.loads(pc_data)
|
||||
play_context = PlayContext()
|
||||
play_context.deserialize(pc_data)
|
||||
self._play_context = play_context
|
||||
|
||||
@property
|
||||
@ensure_connect
|
||||
def manager(self):
|
||||
return self._manager
|
||||
|
||||
def _get_proxy_command(self, port=22):
|
||||
proxy_command = None
|
||||
|
||||
# TO-DO: Add logic to scan ssh_* args to read ProxyCommand
|
||||
|
||||
proxy_command = self.get_option("proxy_command")
|
||||
|
||||
sock = None
|
||||
if proxy_command:
|
||||
if Version(NCCLIENT_VERSION) < "0.6.10":
|
||||
raise AnsibleError(
|
||||
"Configuring jumphost settings through ProxyCommand is unsupported in ncclient version %s. "
|
||||
"Please upgrade to ncclient 0.6.10 or newer." % NCCLIENT_VERSION
|
||||
)
|
||||
|
||||
replacers = {
|
||||
"%h": self._play_context.remote_addr,
|
||||
"%p": port,
|
||||
"%r": self._play_context.remote_user,
|
||||
}
|
||||
|
||||
for find, replace in replacers.items():
|
||||
proxy_command = proxy_command.replace(find, str(replace))
|
||||
sock = ProxyCommand(proxy_command)
|
||||
|
||||
return sock
|
||||
|
||||
def _connect(self):
|
||||
if not HAS_NCCLIENT:
|
||||
raise AnsibleError(
|
||||
"%s: %s"
|
||||
% (
|
||||
missing_required_lib("ncclient"),
|
||||
to_native(NCCLIENT_IMP_ERR),
|
||||
)
|
||||
)
|
||||
|
||||
self.queue_message("log", "ssh connection done, starting ncclient")
|
||||
|
||||
allow_agent = True
|
||||
if self._play_context.password is not None:
|
||||
allow_agent = False
|
||||
setattr(self._play_context, "allow_agent", allow_agent)
|
||||
|
||||
self.key_filename = self._play_context.private_key_file or self.get_option(
|
||||
"private_key_file"
|
||||
)
|
||||
if self.key_filename:
|
||||
self.key_filename = str(os.path.expanduser(self.key_filename))
|
||||
|
||||
self._ssh_config = self.get_option("netconf_ssh_config")
|
||||
if self._ssh_config in BOOLEANS_TRUE:
|
||||
self._ssh_config = True
|
||||
elif self._ssh_config in BOOLEANS_FALSE:
|
||||
self._ssh_config = None
|
||||
|
||||
# Try to guess the network_os if the network_os is set to auto
|
||||
if self._network_os == "auto":
|
||||
for cls in netconf_loader.all(class_only=True):
|
||||
network_os = cls.guess_network_os(self)
|
||||
if network_os:
|
||||
self.queue_message("vvv", "discovered network_os %s" % network_os)
|
||||
self._network_os = network_os
|
||||
|
||||
# If we have tried to detect the network_os but were unable to i.e. network_os is still 'auto'
|
||||
# then use default as the network_os
|
||||
|
||||
if self._network_os == "auto":
|
||||
# Network os not discovered. Set it to default
|
||||
self.queue_message(
|
||||
"vvv",
|
||||
"Unable to discover network_os. Falling back to default.",
|
||||
)
|
||||
self._network_os = "default"
|
||||
try:
|
||||
ncclient_device_handler = self.netconf.get_option("ncclient_device_handler")
|
||||
except KeyError:
|
||||
ncclient_device_handler = "default"
|
||||
self.queue_message(
|
||||
"vvv",
|
||||
"identified ncclient device handler: %s." % ncclient_device_handler,
|
||||
)
|
||||
device_params = {"name": ncclient_device_handler}
|
||||
|
||||
try:
|
||||
port = self._play_context.port or 830
|
||||
self.queue_message(
|
||||
"vvv",
|
||||
"ESTABLISH NETCONF SSH CONNECTION FOR USER: %s on PORT %s TO %s WITH SSH_CONFIG = %s"
|
||||
% (
|
||||
self._play_context.remote_user,
|
||||
port,
|
||||
self._play_context.remote_addr,
|
||||
self._ssh_config,
|
||||
),
|
||||
)
|
||||
|
||||
params = dict(
|
||||
host=self._play_context.remote_addr,
|
||||
port=port,
|
||||
username=self._play_context.remote_user,
|
||||
password=self._play_context.password,
|
||||
key_filename=self.key_filename,
|
||||
hostkey_verify=self.get_option("host_key_checking"),
|
||||
look_for_keys=self.get_option("look_for_keys"),
|
||||
device_params=device_params,
|
||||
allow_agent=self._play_context.allow_agent,
|
||||
timeout=self.get_option("persistent_connect_timeout"),
|
||||
ssh_config=self._ssh_config,
|
||||
)
|
||||
# sock is only supported by ncclient >= 0.6.10, and will error if
|
||||
# included on older versions. We check the version in
|
||||
# _get_proxy_command, so if this returns a value, the version is
|
||||
# fine and we have something to send. Otherwise, don't even send
|
||||
# the option to support older versions of ncclient
|
||||
sock = self._get_proxy_command(port)
|
||||
if sock:
|
||||
params["sock"] = sock
|
||||
|
||||
self._manager = manager.connect(**params)
|
||||
|
||||
self._manager._timeout = self.get_option("persistent_command_timeout")
|
||||
except SSHUnknownHostError as exc:
|
||||
raise AnsibleConnectionFailure(to_native(exc))
|
||||
except AuthenticationError as exc:
|
||||
if str(exc).startswith("FileNotFoundError"):
|
||||
raise AnsibleError(
|
||||
"Encountered FileNotFoundError in ncclient connect. Does {0} exist?".format(
|
||||
self.key_filename
|
||||
)
|
||||
)
|
||||
raise
|
||||
except ImportError:
|
||||
raise AnsibleError(
|
||||
"connection=netconf is not supported on {0}".format(self._network_os)
|
||||
)
|
||||
|
||||
if not self._manager.connected:
|
||||
return 1, b"", b"not connected"
|
||||
|
||||
self.queue_message("log", "ncclient manager object created successfully")
|
||||
|
||||
self._connected = True
|
||||
|
||||
super(Connection, self)._connect()
|
||||
|
||||
return (
|
||||
0,
|
||||
to_bytes(self._manager.session_id, errors="surrogate_or_strict"),
|
||||
b"",
|
||||
)
|
||||
|
||||
def close(self):
|
||||
if self._manager:
|
||||
self._manager.close_session()
|
||||
super(Connection, self).close()
|
||||
1309
collection/ansible/netcommon/plugins/connection/network_cli.py
Normal file
1309
collection/ansible/netcommon/plugins/connection/network_cli.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,82 @@
|
||||
# 2017 Red Hat Inc.
|
||||
# (c) 2017 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
|
||||
|
||||
DOCUMENTATION = """
|
||||
author:
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
name: persistent
|
||||
short_description: Use a persistent unix socket for connection
|
||||
description:
|
||||
- This is a helper plugin to allow making other connections persistent.
|
||||
version_added: 1.0.0
|
||||
extends_documentation_fragment:
|
||||
- ansible.netcommon.connection_persistent
|
||||
"""
|
||||
from ansible.executor.task_executor import start_connection
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection as SocketConnection
|
||||
from ansible.plugins.connection import ConnectionBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
class Connection(ConnectionBase):
|
||||
"""Local based connections"""
|
||||
|
||||
transport = "ansible.netcommon.persistent"
|
||||
has_pipelining = False
|
||||
|
||||
def __init__(self, play_context, new_stdin, *args, **kwargs):
|
||||
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
|
||||
self._task_uuid = to_text(kwargs.get("task_uuid", ""))
|
||||
|
||||
def _connect(self):
|
||||
self._connected = True
|
||||
return self
|
||||
|
||||
def exec_command(self, cmd, in_data=None, sudoable=True):
|
||||
display.vvvv(
|
||||
"exec_command(), socket_path=%s" % self.socket_path,
|
||||
host=self._play_context.remote_addr,
|
||||
)
|
||||
connection = SocketConnection(self.socket_path)
|
||||
out = connection.exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
||||
return 0, out, ""
|
||||
|
||||
def put_file(self, in_path, out_path):
|
||||
pass
|
||||
|
||||
def fetch_file(self, in_path, out_path):
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
self._connected = False
|
||||
|
||||
def run(self):
|
||||
"""Returns the path of the persistent connection socket.
|
||||
|
||||
Attempts to ensure (within playcontext.timeout seconds) that the
|
||||
socket path exists. If the path exists (or the timeout has expired),
|
||||
returns the socket path.
|
||||
"""
|
||||
display.vvvv(
|
||||
"starting connection from persistent connection plugin",
|
||||
host=self._play_context.remote_addr,
|
||||
)
|
||||
variables = {"ansible_command_timeout": self.get_option("persistent_command_timeout")}
|
||||
socket_path = start_connection(self._play_context, variables, self._task_uuid)
|
||||
display.vvvv(
|
||||
"local domain socket path is %s" % socket_path,
|
||||
host=self._play_context.remote_addr,
|
||||
)
|
||||
setattr(self, "_socket_path", socket_path)
|
||||
return socket_path
|
||||
@@ -0,0 +1,78 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 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
|
||||
|
||||
|
||||
class ModuleDocFragment(object):
|
||||
# Standard files documentation fragment
|
||||
DOCUMENTATION = r"""
|
||||
options:
|
||||
import_modules:
|
||||
type: boolean
|
||||
description:
|
||||
- Reduce CPU usage and network module execution time
|
||||
by enabling direct execution. Instead of the module being packaged
|
||||
and executed by the shell, it will be directly executed by the Ansible
|
||||
control node using the same python interpreter as the Ansible process.
|
||||
Note- Incompatible with C(asynchronous mode).
|
||||
Note- Python 3 and Ansible 2.9.16 or greater required.
|
||||
Note- With Ansible 2.9.x fully qualified modules names are required in tasks.
|
||||
default: true
|
||||
ini:
|
||||
- section: ansible_network
|
||||
key: import_modules
|
||||
env:
|
||||
- name: ANSIBLE_NETWORK_IMPORT_MODULES
|
||||
vars:
|
||||
- name: ansible_network_import_modules
|
||||
persistent_connect_timeout:
|
||||
type: int
|
||||
description:
|
||||
- Configures, in seconds, the amount of time to wait when trying to initially
|
||||
establish a persistent connection. If this value expires before the connection
|
||||
to the remote device is completed, the connection will fail.
|
||||
default: 30
|
||||
ini:
|
||||
- section: persistent_connection
|
||||
key: connect_timeout
|
||||
env:
|
||||
- name: ANSIBLE_PERSISTENT_CONNECT_TIMEOUT
|
||||
vars:
|
||||
- name: ansible_connect_timeout
|
||||
persistent_command_timeout:
|
||||
type: int
|
||||
description:
|
||||
- Configures, in seconds, the amount of time to wait for a command to
|
||||
return from the remote device. If this timer is exceeded before the
|
||||
command returns, the connection plugin will raise an exception and
|
||||
close.
|
||||
default: 30
|
||||
ini:
|
||||
- section: persistent_connection
|
||||
key: command_timeout
|
||||
env:
|
||||
- name: ANSIBLE_PERSISTENT_COMMAND_TIMEOUT
|
||||
vars:
|
||||
- name: ansible_command_timeout
|
||||
persistent_log_messages:
|
||||
type: boolean
|
||||
description:
|
||||
- This flag will enable logging the command executed and response received from
|
||||
target device in the ansible log file. For this option to work 'log_path' ansible
|
||||
configuration option is required to be set to a file path with write access.
|
||||
- Be sure to fully understand the security implications of enabling this
|
||||
option as it could create a security vulnerability by logging sensitive information in log file.
|
||||
default: False
|
||||
ini:
|
||||
- section: persistent_connection
|
||||
key: log_messages
|
||||
env:
|
||||
- name: ANSIBLE_PERSISTENT_LOG_MESSAGES
|
||||
vars:
|
||||
- name: ansible_persistent_log_messages
|
||||
"""
|
||||
@@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
# Copyright: (c) 2019 Ansible, Inc
|
||||
# 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
|
||||
|
||||
|
||||
class ModuleDocFragment(object):
|
||||
# Standard files documentation fragment
|
||||
DOCUMENTATION = r"""options: {}
|
||||
notes:
|
||||
- This module is supported on C(ansible_network_os) network platforms. See the :ref:`Network
|
||||
Platform Options <platform_options>` for details.
|
||||
"""
|
||||
109
collection/ansible/netcommon/plugins/filter/comp_type5.py
Normal file
109
collection/ansible/netcommon/plugins/filter/comp_type5.py
Normal file
@@ -0,0 +1,109 @@
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2023 Red Hat
|
||||
# GNU General Public License v3.0+
|
||||
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
#
|
||||
|
||||
"""
|
||||
The comp_type5 filter plugin
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
name: comp_type5
|
||||
author: Ken Celenza (@itdependsnetworks)
|
||||
version_added: "1.0.0"
|
||||
short_description: The comp_type5 filter plugin.
|
||||
description:
|
||||
- The filter confirms configuration idempotency on use of type5_pw.
|
||||
notes:
|
||||
- The filter confirms configuration idempotency on use of type5_pw.
|
||||
- Can be used to validate password post hashing
|
||||
username cisco secret 5 {{ ansible_ssh_pass | ansible.netcommon.comp_type5(encrypted, True) }}
|
||||
options:
|
||||
unencrypted_password:
|
||||
description:
|
||||
- The unencrypted text.
|
||||
type: str
|
||||
required: True
|
||||
encrypted_password:
|
||||
description:
|
||||
- The encrypted text.
|
||||
type: str
|
||||
required: True
|
||||
return_original:
|
||||
description:
|
||||
- Return the original text.
|
||||
type: bool
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
# Using comp_type5
|
||||
|
||||
# playbook
|
||||
|
||||
- name: Set the facts
|
||||
ansible.builtin.set_fact:
|
||||
unencrypted_password: "cisco@123"
|
||||
encrypted_password: "$1$avs$uSTOEMh65ADDBREAKqzvpb9yBMpzd/"
|
||||
|
||||
- name: Invoke comp_type5
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ unencrypted_password | ansible.netcommon.comp_type5(encrypted_password, False) }}"
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Set the facts]
|
||||
# ok: [35.155.113.92] => changed=false
|
||||
# ansible_facts:
|
||||
# encrypted_password: $1$avs$uSTOEMh65ADDBREAKqzvpb9yBMpzd/
|
||||
# unencrypted_password: cisco@123
|
||||
|
||||
# TASK [Invoke comp_type5]
|
||||
# ok: [35.155.113.92] =>
|
||||
# msg: true
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import (
|
||||
AnsibleArgSpecValidator,
|
||||
)
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.comp_type5 import comp_type5
|
||||
|
||||
|
||||
try:
|
||||
from jinja2.filters import pass_environment
|
||||
except ImportError:
|
||||
from jinja2.filters import environmentfilter as pass_environment
|
||||
|
||||
|
||||
@pass_environment
|
||||
def _comp_type5(*args, **kwargs):
|
||||
"""Extend vlan data"""
|
||||
|
||||
keys = [
|
||||
"unencrypted_password",
|
||||
"encrypted_password",
|
||||
"return_original",
|
||||
]
|
||||
data = dict(zip(keys, args[1:]))
|
||||
data.update(kwargs)
|
||||
aav = AnsibleArgSpecValidator(data=data, schema=DOCUMENTATION, name="comp_type5")
|
||||
valid, errors, updated_data = aav.validate()
|
||||
if not valid:
|
||||
raise AnsibleFilterError(errors)
|
||||
return comp_type5(**updated_data)
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
"""comp_type5"""
|
||||
|
||||
def filters(self):
|
||||
"""a mapping of filter names to functions"""
|
||||
return {"comp_type5": _comp_type5}
|
||||
96
collection/ansible/netcommon/plugins/filter/hash_salt.py
Normal file
96
collection/ansible/netcommon/plugins/filter/hash_salt.py
Normal file
@@ -0,0 +1,96 @@
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2023 Red Hat
|
||||
# GNU General Public License v3.0+
|
||||
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
#
|
||||
|
||||
"""
|
||||
The hash_salt filter plugin
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
name: hash_salt
|
||||
author: Ken Celenza (@itdependsnetworks)
|
||||
version_added: "1.0.0"
|
||||
short_description: The hash_salt filter plugin.
|
||||
description:
|
||||
- The filter plugin produces the salt from a hashed password.
|
||||
- Using the parameters below - C(password | ansible.netcommon.hash_salt(template.yml))
|
||||
notes:
|
||||
- The filter plugin produces the salt from a hashed password.
|
||||
options:
|
||||
password:
|
||||
description:
|
||||
- This source data on which hash_salt invokes.
|
||||
- For example C(password | ansible.netcommon.hash_salt),
|
||||
in this case C(password) represents the hashed password.
|
||||
type: str
|
||||
required: True
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
# Using hash_salt
|
||||
|
||||
# playbook
|
||||
|
||||
- name: Set the facts
|
||||
ansible.builtin.set_fact:
|
||||
password: "$1$avs$uSTOEMh65ADDBREAKqzvpb9yBMpzd/"
|
||||
|
||||
- name: Invoke hash_salt
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ password | ansible.netcommon.hash_salt() }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Set the facts]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# password: $1$avs$uSTOEMh65ADDBREAKqzvpb9yBMpzd/
|
||||
|
||||
# TASK [Invoke hash_salt]
|
||||
# ok: [host] =>
|
||||
# msg: avs
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import (
|
||||
AnsibleArgSpecValidator,
|
||||
)
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.hash_salt import hash_salt
|
||||
|
||||
|
||||
try:
|
||||
from jinja2.filters import pass_environment
|
||||
except ImportError:
|
||||
from jinja2.filters import environmentfilter as pass_environment
|
||||
|
||||
|
||||
@pass_environment
|
||||
def _hash_salt(*args, **kwargs):
|
||||
"""Extend vlan data"""
|
||||
|
||||
keys = ["password"]
|
||||
data = dict(zip(keys, args[1:]))
|
||||
data.update(kwargs)
|
||||
aav = AnsibleArgSpecValidator(data=data, schema=DOCUMENTATION, name="hash_salt")
|
||||
valid, errors, updated_data = aav.validate()
|
||||
if not valid:
|
||||
raise AnsibleFilterError(errors)
|
||||
return hash_salt(**updated_data)
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
"""hash_salt"""
|
||||
|
||||
def filters(self):
|
||||
"""a mapping of filter names to functions"""
|
||||
return {"hash_salt": _hash_salt}
|
||||
164
collection/ansible/netcommon/plugins/filter/parse_cli.py
Normal file
164
collection/ansible/netcommon/plugins/filter/parse_cli.py
Normal file
@@ -0,0 +1,164 @@
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2023 Red Hat
|
||||
# GNU General Public License v3.0+
|
||||
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
#
|
||||
|
||||
"""
|
||||
The parse_cli filter plugin
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
name: parse_cli
|
||||
author: Peter Sprygada (@privateip)
|
||||
version_added: "1.0.0"
|
||||
short_description: parse_cli filter plugin.
|
||||
description:
|
||||
- The filter plugins converts the output of a network device
|
||||
CLI command into structured JSON output.
|
||||
- Using the parameters below - C(xml_data | ansible.netcommon.parse_cli(template.yml))
|
||||
notes:
|
||||
- The parse_cli filter will load the spec file and pass the command output through it,
|
||||
returning JSON output. The YAML spec file defines how to parse the CLI output
|
||||
options:
|
||||
output:
|
||||
description:
|
||||
- This source data on which parse_cli invokes.
|
||||
type: raw
|
||||
required: True
|
||||
tmpl:
|
||||
description:
|
||||
- The spec file should be valid formatted YAML.
|
||||
It defines how to parse the CLI output and return JSON data.
|
||||
- For example C(cli_data | ansible.netcommon.parse_cli(template.yml)),
|
||||
in this case C(cli_data) represents cli output.
|
||||
type: str
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
# Using parse_cli
|
||||
|
||||
# outputConfig
|
||||
|
||||
# ip dhcp pool Data
|
||||
# import all
|
||||
# network 192.168.1.0 255.255.255.0
|
||||
# update dns
|
||||
# default-router 192.168.1.1
|
||||
# dns-server 192.168.1.1 8.8.8.8
|
||||
# option 42 ip 192.168.1.1
|
||||
# domain-name test.local
|
||||
# lease 8
|
||||
|
||||
# pconnection.yml
|
||||
|
||||
# ---
|
||||
# vars:
|
||||
# dhcp_pool:
|
||||
# name: "{{ item.name }}"
|
||||
# network: "{{ item.network_ip }}"
|
||||
# subnet: "{{ item.network_subnet }}"
|
||||
# dns_servers: "{{ item.dns_servers_1 }}{{ item.dns_servers_2 }}"
|
||||
# domain_name: "{{ item.domain_name_0 }}{{ item.domain_name_1 }}{{ item.domain_name_2 }}{{ item.domain_name_3 }}"
|
||||
# options: "{{ item.options_1 }}{{ item.options_2 }}"
|
||||
# lease_days: "{{ item.lease_days }}"
|
||||
# lease_hours: "{{ item.lease_hours }}"
|
||||
# lease_minutes: "{{ item.lease_minutes }}"
|
||||
|
||||
# keys:
|
||||
# dhcp_pools:
|
||||
# value: "{{ dhcp_pool }}"
|
||||
# items: "^ip dhcp pool (
|
||||
# ?P<name>[^\\n]+)\\s+(?:import (?P<import_all>all)\\s*)?(?:network (?P<network_ip>[\\d.]+)
|
||||
# (?P<network_subnet>[\\d.]+)?\\s*)?(?:update dns\\s*)?(?:host (?P<host_ip>[\\d.]+)
|
||||
# (?P<host_subnet>[\\d.]+)\\s*)?(?:domain-name (?P<domain_name_0>[\\w._-]+)\\s+)?
|
||||
# (?:default-router (?P<default_router>[\\d.]+)\\s*)?(?:dns-server
|
||||
# (?P<dns_servers_1>(?:[\\d.]+ ?)+ ?)+\\s*)?(?:domain-name (?P<domain_name_1>[\\w._-]+)\\s+)?
|
||||
# (?P<options_1>(?:option [^\\n]+\\n*\\s*)*)?(?:domain-name (?P<domain_name_2>[\\w._-]+)\\s+)?(?P<options_2>(?:option [^\\n]+\\n*\\s*)*)?
|
||||
# (?:dns-server (?P<dns_servers_2>(?:[\\d.]+ ?)+ ?)+\\s*)?(?:domain-name
|
||||
# (?P<domain_name_3>[\\w._-]+)\\s*)?(lease (?P<lease_days>\\d+)(?: (?P<lease_hours>\\d+))?(?: (?P<lease_minutes>\\d+))?\\s*)?(?:update arp)?"
|
||||
|
||||
# playbook
|
||||
|
||||
- name: Add config data
|
||||
ansible.builtin.set_fact:
|
||||
opconfig: "{{lookup('ansible.builtin.file', 'outputConfig') }}"
|
||||
|
||||
- name: Parse Data
|
||||
ansible.builtin.set_fact:
|
||||
output: "{{ opconfig | parse_cli('pconnection.yml') }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Add config data]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# xml: |-
|
||||
# ip dhcp pool Data
|
||||
# import all
|
||||
# network 192.168.1.0 255.255.255.0
|
||||
# update dns
|
||||
# default-router 192.168.1.1
|
||||
# dns-server 192.168.1.1 8.8.8.8
|
||||
# option 42 ip 192.168.1.1
|
||||
# domain-name test.local
|
||||
# lease 8
|
||||
|
||||
# TASK [Parse Data]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# output:
|
||||
# dhcp_pools:
|
||||
# - dns_servers: 192.168.1.1 8.8.8.8
|
||||
# domain_name: test.local
|
||||
# lease_days: 8
|
||||
# lease_hours: null
|
||||
# lease_minutes: null
|
||||
# name: Data
|
||||
# network: 192.168.1.0
|
||||
# options: |-
|
||||
# option 42 ip 192.168.1.1
|
||||
# subnet: 255.255.255.0
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import (
|
||||
AnsibleArgSpecValidator,
|
||||
)
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.parse_cli import parse_cli
|
||||
|
||||
|
||||
try:
|
||||
from jinja2.filters import pass_environment
|
||||
except ImportError:
|
||||
from jinja2.filters import environmentfilter as pass_environment
|
||||
|
||||
|
||||
@pass_environment
|
||||
def _parse_cli(*args, **kwargs):
|
||||
"""Extend vlan data"""
|
||||
|
||||
keys = ["output", "tmpl"]
|
||||
data = dict(zip(keys, args[1:]))
|
||||
data.update(kwargs)
|
||||
aav = AnsibleArgSpecValidator(data=data, schema=DOCUMENTATION, name="parse_cli")
|
||||
valid, errors, updated_data = aav.validate()
|
||||
if not valid:
|
||||
raise AnsibleFilterError(errors)
|
||||
return parse_cli(**updated_data)
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
"""parse_cli"""
|
||||
|
||||
def filters(self):
|
||||
"""a mapping of filter names to functions"""
|
||||
return {"parse_cli": _parse_cli}
|
||||
121
collection/ansible/netcommon/plugins/filter/parse_cli_textfsm.py
Normal file
121
collection/ansible/netcommon/plugins/filter/parse_cli_textfsm.py
Normal file
@@ -0,0 +1,121 @@
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2023 Red Hat
|
||||
# GNU General Public License v3.0+
|
||||
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
#
|
||||
|
||||
"""
|
||||
The parse_cli_textfsm filter plugin
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
name: parse_cli_textfsm
|
||||
author: Peter Sprygada (@privateip)
|
||||
version_added: "1.0.0"
|
||||
short_description: parse_cli_textfsm filter plugin.
|
||||
description:
|
||||
- The network filters also support parsing the output of a CLI command using the TextFSM library.
|
||||
To parse the CLI output with TextFSM use this filter.
|
||||
- Using the parameters below - C(data | ansible.netcommon.parse_cli_textfsm(template.yml))
|
||||
notes:
|
||||
- Use of the TextFSM filter requires the TextFSM library to be installed.
|
||||
options:
|
||||
value:
|
||||
description:
|
||||
- This source data on which parse_cli_textfsm invokes.
|
||||
type: raw
|
||||
required: True
|
||||
template:
|
||||
description:
|
||||
- The template to compare it with.
|
||||
- For example C(data | ansible.netcommon.parse_cli_textfsm(template.yml)),
|
||||
in this case C(data) represents this option.
|
||||
type: str
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
# Using parse_cli_textfsm
|
||||
|
||||
- name: "Fetch command output"
|
||||
cisco.ios.ios_command:
|
||||
commands:
|
||||
- show lldp neighbors
|
||||
register: lldp_output
|
||||
|
||||
- name: "Invoke parse_cli_textfsm"
|
||||
ansible.builtin.set_fact:
|
||||
device_neighbors: "{{ lldp_output.stdout[0] | parse_cli_textfsm('~/ntc-templates/templates/cisco_ios_show_lldp_neighbors.textfsm') }}"
|
||||
|
||||
- name: "Debug"
|
||||
ansible.builtindebug:
|
||||
msg: "{{ device_neighbors }}"
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Fetch command output]
|
||||
# ok: [rtr-2]
|
||||
|
||||
# TASK [Invoke parse_cli_textfsm]
|
||||
# ok: [rtr-1]
|
||||
|
||||
# TASK [Debug]
|
||||
# ok: [rtr-1] => {
|
||||
# "msg": [
|
||||
# {
|
||||
# "CAPABILITIES": "R",
|
||||
# "LOCAL_INTERFACE": "Gi0/0",
|
||||
# "NEIGHBOR": "rtr-3",
|
||||
# "NEIGHBOR_INTERFACE": "Gi0/0"
|
||||
# },
|
||||
# {
|
||||
# "CAPABILITIES": "R",
|
||||
# "LOCAL_INTERFACE": "Gi0/1",
|
||||
# "NEIGHBOR": "rtr-1",
|
||||
# "NEIGHBOR_INTERFACE": "Gi0/1"
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import (
|
||||
AnsibleArgSpecValidator,
|
||||
)
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.parse_cli_textfsm import (
|
||||
parse_cli_textfsm,
|
||||
)
|
||||
|
||||
|
||||
try:
|
||||
from jinja2.filters import pass_environment
|
||||
except ImportError:
|
||||
from jinja2.filters import environmentfilter as pass_environment
|
||||
|
||||
|
||||
@pass_environment
|
||||
def _parse_cli_textfsm(*args, **kwargs):
|
||||
"""Extend vlan data"""
|
||||
|
||||
keys = ["value", "template"]
|
||||
data = dict(zip(keys, args[1:]))
|
||||
data.update(kwargs)
|
||||
aav = AnsibleArgSpecValidator(data=data, schema=DOCUMENTATION, name="parse_cli_textfsm")
|
||||
valid, errors, updated_data = aav.validate()
|
||||
if not valid:
|
||||
raise AnsibleFilterError(errors)
|
||||
return parse_cli_textfsm(**updated_data)
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
"""parse_cli_textfsm"""
|
||||
|
||||
def filters(self):
|
||||
"""a mapping of filter names to functions"""
|
||||
return {"parse_cli_textfsm": _parse_cli_textfsm}
|
||||
195
collection/ansible/netcommon/plugins/filter/parse_xml.py
Normal file
195
collection/ansible/netcommon/plugins/filter/parse_xml.py
Normal file
@@ -0,0 +1,195 @@
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2023 Red Hat
|
||||
# GNU General Public License v3.0+
|
||||
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
#
|
||||
|
||||
"""
|
||||
The parse_xml filter plugin
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
name: parse_xml
|
||||
author: Ganesh Nalawade (@ganeshrn)
|
||||
version_added: "1.0.0"
|
||||
short_description: The parse_xml filter plugin.
|
||||
description:
|
||||
- This filter will load the spec file and pass the command output
|
||||
through it, returning JSON output.
|
||||
- The YAML spec file defines how to parse the CLI output.
|
||||
notes:
|
||||
- To convert the XML output of a network device command into structured JSON output.
|
||||
options:
|
||||
output:
|
||||
description:
|
||||
- This source xml on which parse_xml invokes.
|
||||
type: raw
|
||||
required: True
|
||||
tmpl:
|
||||
description:
|
||||
- The spec file should be valid formatted YAML.
|
||||
It defines how to parse the XML output and return JSON data.
|
||||
- For example C(xml_data | ansible.netcommon.parse_xml(template.yml)),
|
||||
in this case C(xml_data) represents xml data option.
|
||||
type: str
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
# Using parse_xml
|
||||
|
||||
# example_output.xml
|
||||
|
||||
# <?xml version="1.0" encoding="UTF-8"?>
|
||||
# <rpc-reply message-id="urn:uuid:0cadb4e8-5bba-47f4-986e-72906227007f">
|
||||
# <data>
|
||||
# <ntp>
|
||||
# <nodes>
|
||||
# <node>
|
||||
# <node>0/0/CPU0</node>
|
||||
# <associations>
|
||||
# <is-ntp-enabled>true</is-ntp-enabled>
|
||||
# <sys-leap>ntp-leap-no-warning</sys-leap>
|
||||
# <peer-summary-info>
|
||||
# <peer-info-common>
|
||||
# <host-mode>ntp-mode-client</host-mode>
|
||||
# <is-configured>true</is-configured>
|
||||
# <address>10.1.1.1</address>
|
||||
# <reachability>0</reachability>
|
||||
# </peer-info-common>
|
||||
# <time-since>-1</time-since>
|
||||
# </peer-summary-info>
|
||||
# <peer-summary-info>
|
||||
# <peer-info-common>
|
||||
# <host-mode>ntp-mode-client</host-mode>
|
||||
# <is-configured>true</is-configured>
|
||||
# <address>172.16.252.29</address>
|
||||
# <reachability>255</reachability>
|
||||
# </peer-info-common>
|
||||
# <time-since>991</time-since>
|
||||
# </peer-summary-info>
|
||||
# </associations>
|
||||
# </node>
|
||||
# </nodes>
|
||||
# </ntp>
|
||||
# </data>
|
||||
# </rpc-reply>
|
||||
|
||||
# parse_xml.yml
|
||||
|
||||
# ---
|
||||
# vars:
|
||||
# ntp_peers:
|
||||
# address: "{{ item.address }}"
|
||||
# reachability: "{{ item.reachability}}"
|
||||
# keys:
|
||||
# result:
|
||||
# value: "{{ ntp_peers }}"
|
||||
# top: data/ntp/nodes/node/associations
|
||||
# items:
|
||||
# address: peer-summary-info/peer-info-common/address
|
||||
# reachability: peer-summary-info/peer-info-common/reachability
|
||||
|
||||
|
||||
- name: Facts setup
|
||||
ansible.builtin.set_fact:
|
||||
xml: "{{ lookup('file', 'example_output.xml') }}"
|
||||
|
||||
- name: Parse xml invocation
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ xml | ansible.netcommon.parse_xml('parse_xml.yml') }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [set xml Data]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# xml: |-
|
||||
# <?xml version="1.0" encoding="UTF-8"?>
|
||||
# <rpc-reply message-id="urn:uuid:0cadb4e8-5bba-47f4-986e-72906227007f">
|
||||
# <data>
|
||||
# <ntp>
|
||||
# <nodes>
|
||||
# <node>
|
||||
# <node>0/0/CPU0</node>
|
||||
# <associations>
|
||||
# <is-ntp-enabled>true</is-ntp-enabled>
|
||||
# <sys-leap>ntp-leap-no-warning</sys-leap>
|
||||
# <peer-summary-info>
|
||||
# <peer-info-common>
|
||||
# <host-mode>ntp-mode-client</host-mode>
|
||||
# <is-configured>true</is-configured>
|
||||
# <address>10.1.1.1</address>
|
||||
# <reachability>0</reachability>
|
||||
# </peer-info-common>
|
||||
# <time-since>-1</time-since>
|
||||
# </peer-summary-info>
|
||||
# <peer-summary-info>
|
||||
# <peer-info-common>
|
||||
# <host-mode>ntp-mode-client</host-mode>
|
||||
# <is-configured>true</is-configured>
|
||||
# <address>172.16.252.29</address>
|
||||
# <reachability>255</reachability>
|
||||
# </peer-info-common>
|
||||
# <time-since>991</time-since>
|
||||
# </peer-summary-info>
|
||||
# </associations>
|
||||
# </node>
|
||||
# </nodes>
|
||||
# </ntp>
|
||||
# </data>
|
||||
# </rpc-reply>
|
||||
|
||||
# TASK [Parse Data]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# output:
|
||||
# result:
|
||||
# - address:
|
||||
# - 10.1.1.1
|
||||
# - 172.16.252.29
|
||||
# reachability:
|
||||
# - '0'
|
||||
# - '255'
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import (
|
||||
AnsibleArgSpecValidator,
|
||||
)
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.parse_xml import parse_xml
|
||||
|
||||
|
||||
try:
|
||||
from jinja2.filters import pass_environment
|
||||
except ImportError:
|
||||
from jinja2.filters import environmentfilter as pass_environment
|
||||
|
||||
|
||||
@pass_environment
|
||||
def _parse_xml(*args, **kwargs):
|
||||
"""Extend vlan data"""
|
||||
|
||||
keys = ["output", "tmpl"]
|
||||
data = dict(zip(keys, args[1:]))
|
||||
data.update(kwargs)
|
||||
aav = AnsibleArgSpecValidator(data=data, schema=DOCUMENTATION, name="parse_xml")
|
||||
valid, errors, updated_data = aav.validate()
|
||||
if not valid:
|
||||
raise AnsibleFilterError(errors)
|
||||
return parse_xml(**updated_data)
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
"""parse_xml"""
|
||||
|
||||
def filters(self):
|
||||
"""a mapping of filter names to functions"""
|
||||
return {"parse_xml": _parse_xml}
|
||||
1026
collection/ansible/netcommon/plugins/filter/pop_ace.py
Normal file
1026
collection/ansible/netcommon/plugins/filter/pop_ace.py
Normal file
File diff suppressed because it is too large
Load Diff
96
collection/ansible/netcommon/plugins/filter/type5_pw.py
Normal file
96
collection/ansible/netcommon/plugins/filter/type5_pw.py
Normal file
@@ -0,0 +1,96 @@
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2023 Red Hat
|
||||
# GNU General Public License v3.0+
|
||||
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
#
|
||||
|
||||
"""
|
||||
The type5_pw filter plugin
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
name: type5_pw
|
||||
author: Ken Celenza (@itdependsnetworks)
|
||||
version_added: "1.0.0"
|
||||
short_description: The type5_pw filter plugin.
|
||||
description:
|
||||
- Filter plugin to produce cisco type5 hashed password.
|
||||
- Using the parameters below - C(xml_data | ansible.netcommon.type5_pw(template.yml))
|
||||
notes:
|
||||
- The filter plugin generates cisco type5 hashed password.
|
||||
options:
|
||||
password:
|
||||
description:
|
||||
- The password to be hashed.
|
||||
type: str
|
||||
required: True
|
||||
salt:
|
||||
description:
|
||||
- Mention the salt to hash the password.
|
||||
type: str
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
# Using type5_pw
|
||||
|
||||
- name: Set some facts
|
||||
ansible.builtin.set_fact:
|
||||
password: "cisco@123"
|
||||
|
||||
- name: Filter type5_pw invocation
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ password | ansible.netcommon.type5_pw(salt='avs') }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Set some facts]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# password: cisco@123
|
||||
|
||||
# TASK [Filter type5_pw invocation]
|
||||
# ok: [host] =>
|
||||
# msg: $1$avs$uSTOEMh65qzvpb9yBMpzd/
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import (
|
||||
AnsibleArgSpecValidator,
|
||||
)
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.type5_pw import type5_pw
|
||||
|
||||
|
||||
try:
|
||||
from jinja2.filters import pass_environment
|
||||
except ImportError:
|
||||
from jinja2.filters import environmentfilter as pass_environment
|
||||
|
||||
|
||||
@pass_environment
|
||||
def _type5_pw(*args, **kwargs):
|
||||
"""Extend vlan data"""
|
||||
|
||||
keys = ["password", "salt"]
|
||||
data = dict(zip(keys, args[1:]))
|
||||
data.update(kwargs)
|
||||
aav = AnsibleArgSpecValidator(data=data, schema=DOCUMENTATION, name="type5_pw")
|
||||
valid, errors, updated_data = aav.validate()
|
||||
if not valid:
|
||||
raise AnsibleFilterError(errors)
|
||||
return type5_pw(**updated_data)
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
"""type5_pw"""
|
||||
|
||||
def filters(self):
|
||||
"""a mapping of filter names to functions"""
|
||||
return {"type5_pw": _type5_pw}
|
||||
101
collection/ansible/netcommon/plugins/filter/vlan_expander.py
Normal file
101
collection/ansible/netcommon/plugins/filter/vlan_expander.py
Normal file
@@ -0,0 +1,101 @@
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2023 Red Hat
|
||||
# GNU General Public License v3.0+
|
||||
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
#
|
||||
|
||||
"""
|
||||
The vlan_expander filter plugin
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
name: vlan_expander
|
||||
author: Akira Yokochi (@akira6592)
|
||||
version_added: "2.3.0"
|
||||
short_description: The vlan_expander filter plugin.
|
||||
description:
|
||||
- Expand shorthand list of VLANs to list all VLANs. Inverse of vlan_parser
|
||||
- Using the parameters below - C(vlans_data | ansible.netcommon.vlan_expander)
|
||||
notes:
|
||||
- The filter plugin extends vlans when data provided in range or comma separated.
|
||||
options:
|
||||
data:
|
||||
description:
|
||||
- This option represents a string containing the range of vlans.
|
||||
type: str
|
||||
required: True
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
# Using vlan_expander
|
||||
|
||||
- name: Setting host facts for vlan_expander filter plugin
|
||||
ansible.builtin.set_fact:
|
||||
vlan_ranges: "1,10-12,15,20-22"
|
||||
|
||||
- name: Invoke vlan_expander filter plugin
|
||||
ansible.builtin.set_fact:
|
||||
extended_vlans: "{{ vlan_ranges | ansible.netcommon.vlan_expander }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Setting host facts for vlan_expander filter plugin]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# vlan_ranges: 1,10-12,15,20-22
|
||||
|
||||
# TASK [Invoke vlan_expander filter plugin]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# extended_vlans:
|
||||
# - 1
|
||||
# - 10
|
||||
# - 11
|
||||
# - 12
|
||||
# - 15
|
||||
# - 20
|
||||
# - 21
|
||||
# - 22
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import (
|
||||
AnsibleArgSpecValidator,
|
||||
)
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.vlan_expander import vlan_expander
|
||||
|
||||
|
||||
try:
|
||||
from jinja2.filters import pass_environment
|
||||
except ImportError:
|
||||
from jinja2.filters import environmentfilter as pass_environment
|
||||
|
||||
|
||||
@pass_environment
|
||||
def _vlan_expander(*args, **kwargs):
|
||||
"""Extend vlan data"""
|
||||
|
||||
keys = ["data"]
|
||||
data = dict(zip(keys, args[1:]))
|
||||
data.update(kwargs)
|
||||
aav = AnsibleArgSpecValidator(data=data, schema=DOCUMENTATION, name="vlan_expander")
|
||||
valid, errors, updated_data = aav.validate()
|
||||
if not valid:
|
||||
raise AnsibleFilterError(errors)
|
||||
return vlan_expander(**updated_data)
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
"""vlan_expander"""
|
||||
|
||||
def filters(self):
|
||||
"""a mapping of filter names to functions"""
|
||||
return {"vlan_expander": _vlan_expander}
|
||||
137
collection/ansible/netcommon/plugins/filter/vlan_parser.py
Normal file
137
collection/ansible/netcommon/plugins/filter/vlan_parser.py
Normal file
@@ -0,0 +1,137 @@
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2023 Red Hat
|
||||
# GNU General Public License v3.0+
|
||||
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
#
|
||||
|
||||
"""
|
||||
The vlan_parser filter plugin
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
name: vlan_parser
|
||||
author: Steve Dodd (@idahood)
|
||||
version_added: "1.0.0"
|
||||
short_description: The vlan_parser filter plugin.
|
||||
description:
|
||||
- The filter plugin converts a list of vlans to IOS like vlan configuration.
|
||||
- Converts list to a list of range of numbers into multiple lists.
|
||||
- C(vlans_data | ansible.netcommon.vlan_parser(first_line_len = 20, other_line_len=20))
|
||||
notes:
|
||||
- The filter plugin extends vlans when data provided in range or comma separated.
|
||||
options:
|
||||
data:
|
||||
description:
|
||||
- This option represents a list containing vlans.
|
||||
type: list
|
||||
required: True
|
||||
first_line_len:
|
||||
description:
|
||||
- The first line of the list can be first_line_len characters long.
|
||||
type: int
|
||||
default: 48
|
||||
other_line_len:
|
||||
description:
|
||||
- The subsequent list lines can be other_line_len characters.
|
||||
type: int
|
||||
default: 44
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
# Using vlan_parser
|
||||
|
||||
- name: Setting host facts for vlan_parser filter plugin
|
||||
ansible.builtin.set_fact:
|
||||
vlans:
|
||||
[
|
||||
100,
|
||||
1688,
|
||||
3002,
|
||||
3003,
|
||||
3004,
|
||||
3005,
|
||||
3102,
|
||||
3103,
|
||||
3104,
|
||||
3105,
|
||||
3802,
|
||||
3900,
|
||||
3998,
|
||||
3999,
|
||||
]
|
||||
|
||||
- name: Invoke vlan_parser filter plugin
|
||||
ansible.builtin.set_fact:
|
||||
vlans_ranges: "{{ vlans | ansible.netcommon.vlan_parser(first_line_len = 20, other_line_len=20) }}"
|
||||
|
||||
|
||||
# Task Output
|
||||
# -----------
|
||||
#
|
||||
# TASK [Setting host facts for vlan_parser filter plugin]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# vlans:
|
||||
# - 100
|
||||
# - 1688
|
||||
# - 3002
|
||||
# - 3003
|
||||
# - 3004
|
||||
# - 3005
|
||||
# - 3102
|
||||
# - 3103
|
||||
# - 3104
|
||||
# - 3105
|
||||
# - 3802
|
||||
# - 3900
|
||||
# - 3998
|
||||
# - 3999
|
||||
|
||||
# TASK [Invoke vlan_parser filter plugin]
|
||||
# ok: [host] => changed=false
|
||||
# ansible_facts:
|
||||
# msg:
|
||||
# - 100,1688,3002-3005
|
||||
# - 3102-3105,3802,3900
|
||||
# - 3998,3999
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import (
|
||||
AnsibleArgSpecValidator,
|
||||
)
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.vlan_parser import vlan_parser
|
||||
|
||||
|
||||
try:
|
||||
from jinja2.filters import pass_environment
|
||||
except ImportError:
|
||||
from jinja2.filters import environmentfilter as pass_environment
|
||||
|
||||
|
||||
@pass_environment
|
||||
def _vlan_parser(*args, **kwargs):
|
||||
"""Extend vlan data"""
|
||||
|
||||
keys = ["data", "first_line_len", "other_line_len"]
|
||||
data = dict(zip(keys, args[1:]))
|
||||
data.update(kwargs)
|
||||
aav = AnsibleArgSpecValidator(data=data, schema=DOCUMENTATION, name="vlan_parser")
|
||||
valid, errors, updated_data = aav.validate()
|
||||
if not valid:
|
||||
raise AnsibleFilterError(errors)
|
||||
return vlan_parser(**updated_data)
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
"""vlan_parser"""
|
||||
|
||||
def filters(self):
|
||||
"""a mapping of filter names to functions"""
|
||||
return {"vlan_parser": _vlan_parser}
|
||||
81
collection/ansible/netcommon/plugins/httpapi/restconf.py
Normal file
81
collection/ansible/netcommon/plugins/httpapi/restconf.py
Normal file
@@ -0,0 +1,81 @@
|
||||
# Copyright (c) 2018 Cisco and/or its affiliates.
|
||||
# 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
|
||||
|
||||
DOCUMENTATION = """
|
||||
author:
|
||||
- Ansible Networking Team (@ansible-network)
|
||||
name: restconf
|
||||
short_description: HttpApi Plugin for devices supporting Restconf API
|
||||
description:
|
||||
- This HttpApi plugin provides methods to connect to Restconf API endpoints.
|
||||
version_added: 1.0.0
|
||||
options:
|
||||
root_path:
|
||||
type: str
|
||||
description:
|
||||
- Specifies the location of the Restconf root.
|
||||
default: /restconf
|
||||
vars:
|
||||
- name: ansible_httpapi_restconf_root
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import ConnectionError
|
||||
from ansible.module_utils.six.moves.urllib.error import HTTPError
|
||||
|
||||
from ansible_collections.ansible.netcommon.plugins.plugin_utils.httpapi_base import HttpApiBase
|
||||
|
||||
|
||||
CONTENT_TYPE = "application/yang-data+json"
|
||||
|
||||
|
||||
class HttpApi(HttpApiBase):
|
||||
def send_request(self, data, **message_kwargs):
|
||||
if data:
|
||||
data = json.dumps(data)
|
||||
|
||||
path = "/".join(
|
||||
[
|
||||
self.get_option("root_path").rstrip("/"),
|
||||
message_kwargs.get("path", "").lstrip("/"),
|
||||
]
|
||||
)
|
||||
|
||||
headers = {
|
||||
"Content-Type": message_kwargs.get("content_type") or CONTENT_TYPE,
|
||||
"Accept": message_kwargs.get("accept") or CONTENT_TYPE,
|
||||
}
|
||||
response, response_data = self.connection.send(
|
||||
path, data, headers=headers, method=message_kwargs.get("method")
|
||||
)
|
||||
|
||||
return handle_response(response, response_data)
|
||||
|
||||
|
||||
def handle_response(response, response_data):
|
||||
try:
|
||||
response_data = json.loads(response_data.read())
|
||||
except ValueError:
|
||||
response_data.seek(0)
|
||||
response_data = response_data.read()
|
||||
|
||||
if isinstance(response, HTTPError):
|
||||
if response_data:
|
||||
if "errors" in response_data:
|
||||
errors = response_data["errors"]["error"]
|
||||
error_text = "\n".join((error["error-message"] for error in errors))
|
||||
else:
|
||||
error_text = response_data
|
||||
|
||||
raise ConnectionError(error_text, code=response.code)
|
||||
raise ConnectionError(to_text(response), code=response.code)
|
||||
|
||||
return response_data
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user