From 880e9fe76566e1f9aa18564e3af3af6d96843c18 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 16 Jan 2024 20:47:12 -0500 Subject: [PATCH 001/358] added circle ci config file --- .circleci/config.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000..e69de29bb2 From 087cd89065611df22144b78bddb90f63dfe6d1ea Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 16 Jan 2024 22:11:50 -0500 Subject: [PATCH 002/358] Added install dependencies step to config.yml --- .circleci/config.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index e69de29bb2..eb784e2737 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -0,0 +1,25 @@ + version: 2.1 + + jobs: + build: + parameters: + py_version: + type: string + default: 3.8.10 + + ansible_version: + type: string + default: 2.12.3 + + working_directory: ~/repo + machine: true + + steps: + - checkout + + - run: + name: Install Dependencies + command: | + sudo apt-get update + sudo apt-get install -y libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils + From ffae4ce9e6ebb8a657723f63cb31a01f8ea25d24 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 16 Jan 2024 22:18:00 -0500 Subject: [PATCH 003/358] Added install dependencies step to config.yml --- .circleci/config.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index eb784e2737..a3b8c0dd2b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,11 +5,11 @@ parameters: py_version: type: string - default: 3.8.10 + default: "3.8.10" ansible_version: type: string - default: 2.12.3 + default: "2.12.3" working_directory: ~/repo machine: true @@ -23,3 +23,7 @@ sudo apt-get update sudo apt-get install -y libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils + workflows: + test-build: + jobs: + - build \ No newline at end of file From 7bc2ae4c48878074115c157959ab5d6148982c6f Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 16 Jan 2024 22:20:18 -0500 Subject: [PATCH 004/358] Added install dependencies step to config.yml --- .circleci/config.yml | 46 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a3b8c0dd2b..6376f1001d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,29 +1,29 @@ - version: 2.1 +version: 2.1 - jobs: - build: - parameters: - py_version: - type: string - default: "3.8.10" +jobs: + build: + parameters: + py_version: + type: string + default: "3.8.10" - ansible_version: - type: string - default: "2.12.3" + ansible_version: + type: string + default: "2.12.3" - working_directory: ~/repo - machine: true + working_directory: ~/repo + machine: true - steps: - - checkout + steps: + - checkout - - run: - name: Install Dependencies - command: | - sudo apt-get update - sudo apt-get install -y libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils + - run: + name: Install Dependencies + command: | + sudo apt-get update + sudo apt-get install -y libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils - workflows: - test-build: - jobs: - - build \ No newline at end of file +workflows: + test-build: + jobs: + - build \ No newline at end of file From f84cc56c93b41f2f9e4de78b0a7a12688727aff8 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 16 Jan 2024 22:22:34 -0500 Subject: [PATCH 005/358] Added install dependencies step to config.yml --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6376f1001d..cf7a759b44 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,10 +18,10 @@ jobs: - checkout - run: - name: Install Dependencies - command: | - sudo apt-get update - sudo apt-get install -y libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils + name: Install Dependencies + command: | + sudo apt-get update + sudo apt-get install -y libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils workflows: test-build: From 237dda779aa78b9cac96d16d6c5f7887c9af517a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 16 Jan 2024 22:36:24 -0500 Subject: [PATCH 006/358] Added python installation steps --- .circleci/config.yml | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cf7a759b44..0deb21427e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,10 +18,24 @@ jobs: - checkout - run: - name: Install Dependencies + name: Install Dependencies and Pyenv command: | - sudo apt-get update - sudo apt-get install -y libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils + sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils + curl https://pyenv.run | bash + echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> $HOME/.bashrc + echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc + echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc + exec "$SHELL" + + - run: + name: Install Python version << parameters.py_version >> in Pyenv + command: | + pyenv install << parameters.py_version >> + pyenv global << parameters.py_version >> + pyenv rehash + pyenv versions + pyenv version + cat ~/.pyenv/version workflows: test-build: From 2351a30cb9f6a70174818f9b18f5c5f5550d3207 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 01:03:54 -0500 Subject: [PATCH 007/358] Added Python Installation steps --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0deb21427e..5851631073 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -20,6 +20,7 @@ jobs: - run: name: Install Dependencies and Pyenv command: | + sudo apt-get update sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils curl https://pyenv.run | bash echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> $HOME/.bashrc From 079933531005fe388917638a78429810088f52b2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 01:23:59 -0500 Subject: [PATCH 008/358] Added Python Installation steps --- .circleci/config.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5851631073..25360e5d9a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,6 +2,9 @@ version: 2.1 jobs: build: + docker: + - image: ubuntu:20.04 + parameters: py_version: type: string @@ -12,7 +15,7 @@ jobs: default: "2.12.3" working_directory: ~/repo - machine: true + #machine: true steps: - checkout @@ -20,6 +23,7 @@ jobs: - run: name: Install Dependencies and Pyenv command: | + set -x sudo apt-get update sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils curl https://pyenv.run | bash From b1c6d242cc8c52ba4948b85c8043151bfd8ebeea Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 01:25:55 -0500 Subject: [PATCH 009/358] Added Python Installation steps --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 25360e5d9a..62aca79a07 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ version: 2.1 jobs: build: docker: - - image: ubuntu:20.04 + - image: cimg/base:2024.01 parameters: py_version: From dce6720e000c6e899f1014581fc705e861b24a86 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 01:33:27 -0500 Subject: [PATCH 010/358] Added Python Installation steps --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 62aca79a07..86ec1ebcfa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ version: 2.1 jobs: build: docker: - - image: cimg/base:2024.01 + - image: cimg/base:current parameters: py_version: @@ -30,7 +30,7 @@ jobs: echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> $HOME/.bashrc echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc - exec "$SHELL" + source $HOME/.bashrc - run: name: Install Python version << parameters.py_version >> in Pyenv From 177e3609d1bef55e79f9198d71fd132d0cd32ef9 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 01:47:24 -0500 Subject: [PATCH 011/358] Added Python Installation steps --- .circleci/config.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 86ec1ebcfa..73e2a17b4b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -30,7 +30,10 @@ jobs: echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> $HOME/.bashrc echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc - source $HOME/.bashrc + cat $HOME/.bashrc + #After Reloading the shell (exec "$SHELL") CICD pipeline to exhibits unexpected behaviour hence reloading environment variables with below command + source $HOME/.bashrc + - run: name: Install Python version << parameters.py_version >> in Pyenv From 978c2503aeca7b73c8424f621dd88c80582e4791 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 01:48:10 -0500 Subject: [PATCH 012/358] Added Python Installation steps --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 73e2a17b4b..23373dd46a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,7 +31,6 @@ jobs: echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc cat $HOME/.bashrc - #After Reloading the shell (exec "$SHELL") CICD pipeline to exhibits unexpected behaviour hence reloading environment variables with below command source $HOME/.bashrc From 6701680b625f06a597536e984631dad3853d507a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 01:54:29 -0500 Subject: [PATCH 013/358] Added Python Installation steps --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 23373dd46a..bc39f5667e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,7 +31,7 @@ jobs: echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc cat $HOME/.bashrc - source $HOME/.bashrc + bash -l -c 'echo "Shell reloaded"' - run: From e4424fc697fb5ed13ea99711d53f984870517819 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 01:57:42 -0500 Subject: [PATCH 014/358] Added Python Installation steps --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bc39f5667e..81abf60200 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,12 +26,12 @@ jobs: set -x sudo apt-get update sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils - curl https://pyenv.run | bash + git clone https://github.com/pyenv/pyenv.git ~/.pyenv echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> $HOME/.bashrc echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc cat $HOME/.bashrc - bash -l -c 'echo "Shell reloaded"' + source $HOME/.bashrc - run: From b77b3d02658efc59beac7936fe890d668644c9ff Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:00:24 -0500 Subject: [PATCH 015/358] Added Python Installation steps --- .circleci/config.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 81abf60200..9c38e8709f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,16 +27,15 @@ jobs: sudo apt-get update sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils git clone https://github.com/pyenv/pyenv.git ~/.pyenv + + - run: + name: Install Python version << parameters.py_version >> in Pyenv + command: | echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> $HOME/.bashrc echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc cat $HOME/.bashrc source $HOME/.bashrc - - - - run: - name: Install Python version << parameters.py_version >> in Pyenv - command: | pyenv install << parameters.py_version >> pyenv global << parameters.py_version >> pyenv rehash From 414ee4289dec8a49c70408ff8ecb0ea953562143 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:02:49 -0500 Subject: [PATCH 016/358] Added Python Installation steps --- .circleci/config.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9c38e8709f..0ccbca57fb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,11 +31,10 @@ jobs: - run: name: Install Python version << parameters.py_version >> in Pyenv command: | - echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> $HOME/.bashrc - echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc - echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc - cat $HOME/.bashrc - source $HOME/.bashrc + set -x + export PATH="$HOME/.pyenv/bin:$PATH" + eval "$(pyenv init --path)" + eval "$(pyenv virtualenv-init -)" pyenv install << parameters.py_version >> pyenv global << parameters.py_version >> pyenv rehash From aeba67b5a1374342b1bb03b9e923c241d8e2d4f6 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:10:48 -0500 Subject: [PATCH 017/358] Setup virtual env and install ansible --- .circleci/config.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0ccbca57fb..c39d19ed96 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -41,6 +41,21 @@ jobs: pyenv versions pyenv version cat ~/.pyenv/version + - run: + name: Create Python << parameters.py_version >> Virtual Environment + command: | + pyenv virtualenv << parameters.py_version >> ansible + + - run: + name: Activate Virtual Environment, Install Dependencies and install Ansible + command: | + pyenv local ansible + pip install --upgrade pip + pip install jinja2 + pip install PyYAML + pip install cryptography + pip install paramiko + pip install ansible workflows: test-build: From 32b2e1a7551a1e1cfca9bcd6e23708daee2ed3a2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:22:15 -0500 Subject: [PATCH 018/358] Activate virtual environment and install ansible --- .circleci/config.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c39d19ed96..76056524ac 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,6 +17,10 @@ jobs: working_directory: ~/repo #machine: true + environment: + PATH: "$HOME/.pyenv/bin:$PATH" + PYENV_ROOT: "$HOME/.pyenv" + steps: - checkout @@ -27,14 +31,16 @@ jobs: sudo apt-get update sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils git clone https://github.com/pyenv/pyenv.git ~/.pyenv + echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> $HOME/.bashrc + echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc + echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc + cat $HOME/.bashrc + source $HOME/.bashrc - run: name: Install Python version << parameters.py_version >> in Pyenv command: | set -x - export PATH="$HOME/.pyenv/bin:$PATH" - eval "$(pyenv init --path)" - eval "$(pyenv virtualenv-init -)" pyenv install << parameters.py_version >> pyenv global << parameters.py_version >> pyenv rehash @@ -45,10 +51,13 @@ jobs: name: Create Python << parameters.py_version >> Virtual Environment command: | pyenv virtualenv << parameters.py_version >> ansible + python --version + pip --version - run: name: Activate Virtual Environment, Install Dependencies and install Ansible command: | + set -x pyenv local ansible pip install --upgrade pip pip install jinja2 From 9e3159e066da6db5b982a2d367ec86cd37041715 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:25:24 -0500 Subject: [PATCH 019/358] step to activate venv and install ansible --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 76056524ac..ed9f416270 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -65,6 +65,7 @@ jobs: pip install cryptography pip install paramiko pip install ansible + ansible --version workflows: test-build: From 7b8fb7b5cc3d3fce3a1a13a3c99e6f6da46f82b5 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:30:14 -0500 Subject: [PATCH 020/358] step to activate venv and install ansible --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index ed9f416270..57a1167842 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -66,6 +66,7 @@ jobs: pip install paramiko pip install ansible ansible --version + pwd workflows: test-build: From 713d56ca67d1f0280eebfec63dc2e609ac148750 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:31:31 -0500 Subject: [PATCH 021/358] step to activate venv and install ansible --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 57a1167842..574b2515c6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,9 +17,9 @@ jobs: working_directory: ~/repo #machine: true - environment: - PATH: "$HOME/.pyenv/bin:$PATH" - PYENV_ROOT: "$HOME/.pyenv" + #environment: + # PATH: "$HOME/.pyenv/bin:$PATH" + # PYENV_ROOT: "$HOME/.pyenv" steps: - checkout From d6ff4df2332cc2282d9982d1bea2518bc85acc40 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:37:52 -0500 Subject: [PATCH 022/358] step to activate venv and install ansible --- .circleci/config.yml | 84 +++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 574b2515c6..5fb9036505 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,48 +25,52 @@ jobs: - checkout - run: - name: Install Dependencies and Pyenv - command: | - set -x - sudo apt-get update - sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils - git clone https://github.com/pyenv/pyenv.git ~/.pyenv - echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> $HOME/.bashrc - echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc - echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc - cat $HOME/.bashrc - source $HOME/.bashrc + name: Install Dependencies and Pyenv + command: | + set -x + sudo apt-get update + sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils + git clone https://github.com/pyenv/pyenv.git ~/.pyenv + echo -e '#!/bin/bash\n\nexport PATH="$HOME/.pyenv/bin:$PATH"\n'\ + 'eval "$(pyenv init --path)"\n'\ + 'eval "$(pyenv virtualenv-init -)"' > ~/.pyenv_setup.sh + chmod +x ~/.pyenv_setup.sh - - run: - name: Install Python version << parameters.py_version >> in Pyenv - command: | - set -x - pyenv install << parameters.py_version >> - pyenv global << parameters.py_version >> - pyenv rehash - pyenv versions - pyenv version - cat ~/.pyenv/version - - run: - name: Create Python << parameters.py_version >> Virtual Environment - command: | - pyenv virtualenv << parameters.py_version >> ansible - python --version - pip --version + - run: + name: Setup Pyenv + command: | + set -x + source ~/.pyenv_setup.sh - - run: - name: Activate Virtual Environment, Install Dependencies and install Ansible - command: | - set -x - pyenv local ansible - pip install --upgrade pip - pip install jinja2 - pip install PyYAML - pip install cryptography - pip install paramiko - pip install ansible - ansible --version - pwd + - run: + name: Install Python version << parameters.py_version >> in Pyenv + command: | + set -x + pyenv install << parameters.py_version >> + pyenv global << parameters.py_version >> + pyenv rehash + pyenv versions + pyenv version + cat ~/.pyenv/version + + - run: + name: Create Python << parameters.py_version >> Virtual Environment + command: | + set -x + pyenv virtualenv << parameters.py_version >> ansible + + - run: + name: Activate Virtual Environment, Install Dependencies, and install Ansible + command: | + set -x + pyenv local ansible + pip install --upgrade pip + pip install jinja2 + pip install PyYAML + pip install cryptography + pip install paramiko + pip install ansible + pwd workflows: test-build: From 7843e1a5ff19214b270dc2c1b6e512ee489b527e Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:41:20 -0500 Subject: [PATCH 023/358] step to activate venv and install ansible --- .circleci/config.yml | 85 +++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5fb9036505..618efb751a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,52 +25,49 @@ jobs: - checkout - run: - name: Install Dependencies and Pyenv - command: | - set -x - sudo apt-get update - sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils - git clone https://github.com/pyenv/pyenv.git ~/.pyenv - echo -e '#!/bin/bash\n\nexport PATH="$HOME/.pyenv/bin:$PATH"\n'\ - 'eval "$(pyenv init --path)"\n'\ - 'eval "$(pyenv virtualenv-init -)"' > ~/.pyenv_setup.sh - chmod +x ~/.pyenv_setup.sh + name: Install Dependencies and Pyenv + command: | + set -x + sudo apt-get update + sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils + git clone https://github.com/pyenv/pyenv.git ~/.pyenv + echo -e '#!/bin/bash\n\nexport PATH="$HOME/.pyenv/bin:$PATH"\n'\ + 'eval "$(pyenv init --path)"\n'\ + 'eval "$(pyenv virtualenv-init -)"' > ~/.pyenv_setup.sh + chmod +x ~/.pyenv_setup.sh - - run: - name: Setup Pyenv - command: | - set -x - source ~/.pyenv_setup.sh - - - run: - name: Install Python version << parameters.py_version >> in Pyenv - command: | - set -x - pyenv install << parameters.py_version >> - pyenv global << parameters.py_version >> - pyenv rehash - pyenv versions - pyenv version - cat ~/.pyenv/version - - - run: - name: Create Python << parameters.py_version >> Virtual Environment - command: | - set -x - pyenv virtualenv << parameters.py_version >> ansible + - run: + name: Install Python version << parameters.py_version >> in Pyenv + command: | + set -x + source ~/.pyenv_setup.sh + pyenv install << parameters.py_version >> + pyenv global << parameters.py_version >> + pyenv rehash + pyenv versions + pyenv version + cat ~/.pyenv/version + - run: + name: Create Python << parameters.py_version >> Virtual Environment + command: | + set -x + pyenv virtualenv << parameters.py_version >> ansible + python --version + pip --version - - run: - name: Activate Virtual Environment, Install Dependencies, and install Ansible - command: | - set -x - pyenv local ansible - pip install --upgrade pip - pip install jinja2 - pip install PyYAML - pip install cryptography - pip install paramiko - pip install ansible - pwd + - run: + name: Activate Virtual Environment, Install Dependencies and install Ansible + command: | + set -x + pyenv local ansible + pip install --upgrade pip + pip install jinja2 + pip install PyYAML + pip install cryptography + pip install paramiko + pip install ansible + ansible --version + pwd workflows: test-build: From f4045923d8df2002d80342586651f678d0953352 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:45:23 -0500 Subject: [PATCH 024/358] step to activate venv and install ansible --- .circleci/config.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 618efb751a..43b4b638da 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,17 +48,13 @@ jobs: pyenv version cat ~/.pyenv/version - run: - name: Create Python << parameters.py_version >> Virtual Environment + name: Create Python << parameters.py_version >> Virtual Environment, Activate Virtual Environment, Install Dependencies and install Ansible command: | set -x + source ~/.pyenv_setup.sh pyenv virtualenv << parameters.py_version >> ansible python --version pip --version - - - run: - name: Activate Virtual Environment, Install Dependencies and install Ansible - command: | - set -x pyenv local ansible pip install --upgrade pip pip install jinja2 @@ -67,7 +63,6 @@ jobs: pip install paramiko pip install ansible ansible --version - pwd workflows: test-build: From 318e3e8822b788c65939c4ac95b3c4a845292474 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:54:36 -0500 Subject: [PATCH 025/358] step to activate venv and install ansible --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 43b4b638da..6990f8edaa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -43,7 +43,6 @@ jobs: source ~/.pyenv_setup.sh pyenv install << parameters.py_version >> pyenv global << parameters.py_version >> - pyenv rehash pyenv versions pyenv version cat ~/.pyenv/version From fa8cfba1cc20ad85c6eda743e2868b99205f3932 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 02:57:14 -0500 Subject: [PATCH 026/358] step to activate venv and install ansible --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6990f8edaa..6563c7c9c0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,7 +50,6 @@ jobs: name: Create Python << parameters.py_version >> Virtual Environment, Activate Virtual Environment, Install Dependencies and install Ansible command: | set -x - source ~/.pyenv_setup.sh pyenv virtualenv << parameters.py_version >> ansible python --version pip --version @@ -61,7 +60,9 @@ jobs: pip install cryptography pip install paramiko pip install ansible + pip install dnacentersdk ansible --version + dnacentersdk --version workflows: test-build: From ae3628c37e4e06841a7e65f3f08ea5313e99a39f Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 17:01:45 -0500 Subject: [PATCH 027/358] step to activate venv and install ansible --- .circleci/config.yml | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6563c7c9c0..9e44731b8a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,10 +10,6 @@ jobs: type: string default: "3.8.10" - ansible_version: - type: string - default: "2.12.3" - working_directory: ~/repo #machine: true @@ -37,7 +33,7 @@ jobs: chmod +x ~/.pyenv_setup.sh - run: - name: Install Python version << parameters.py_version >> in Pyenv + name: Create Python << parameters.py_version >> Virtual Environment, Activate Virtual Environment, Install Dependencies and install Ansible command: | set -x source ~/.pyenv_setup.sh @@ -46,24 +42,22 @@ jobs: pyenv versions pyenv version cat ~/.pyenv/version - - run: - name: Create Python << parameters.py_version >> Virtual Environment, Activate Virtual Environment, Install Dependencies and install Ansible - command: | - set -x pyenv virtualenv << parameters.py_version >> ansible python --version pip --version pyenv local ansible pip install --upgrade pip - pip install jinja2 - pip install PyYAML - pip install cryptography - pip install paramiko - pip install ansible - pip install dnacentersdk + pip install jinja2 PyYAML cryptography paramiko + pip install ansible dnacentersdk ansible --version dnacentersdk --version + - run: + name: + command: | + set -x + + workflows: test-build: jobs: From aa66b4462793c9511c9749fb232832ac653bb9ff Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 17:17:59 -0500 Subject: [PATCH 028/358] step to activate venv and install ansible --- .circleci/config.yml | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9e44731b8a..fa80b6804d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,40 +24,17 @@ jobs: name: Install Dependencies and Pyenv command: | set -x - sudo apt-get update - sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils - git clone https://github.com/pyenv/pyenv.git ~/.pyenv - echo -e '#!/bin/bash\n\nexport PATH="$HOME/.pyenv/bin:$PATH"\n'\ - 'eval "$(pyenv init --path)"\n'\ - 'eval "$(pyenv virtualenv-init -)"' > ~/.pyenv_setup.sh - chmod +x ~/.pyenv_setup.sh - - - run: - name: Create Python << parameters.py_version >> Virtual Environment, Activate Virtual Environment, Install Dependencies and install Ansible - command: | - set -x - source ~/.pyenv_setup.sh - pyenv install << parameters.py_version >> - pyenv global << parameters.py_version >> - pyenv versions - pyenv version - cat ~/.pyenv/version - pyenv virtualenv << parameters.py_version >> ansible - python --version - pip --version - pyenv local ansible - pip install --upgrade pip - pip install jinja2 PyYAML cryptography paramiko + pyenv local python_<< parameters.py_version >> + export PYENV_ROOT="/home/circleci/.pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" + export PATH="$PYENV_ROOT/shims/python3:$PATH" + export PATH="$PYENV_ROOT/shims/python:$PATH" + export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" + export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" pip install ansible dnacentersdk ansible --version dnacentersdk --version - - run: - name: - command: | - set -x - - workflows: test-build: jobs: From ad02a08c58fb8379c42f87df3ae1dc9038a82e89 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 17:22:23 -0500 Subject: [PATCH 029/358] step to activate venv and install ansible --- .circleci/config.yml | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fa80b6804d..6f35ba0a22 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,13 +24,36 @@ jobs: name: Install Dependencies and Pyenv command: | set -x - pyenv local python_<< parameters.py_version >> - export PYENV_ROOT="/home/circleci/.pyenv" - export PATH="$PYENV_ROOT/bin:$PATH" - export PATH="$PYENV_ROOT/shims/python3:$PATH" - export PATH="$PYENV_ROOT/shims/python:$PATH" - export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" - export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" + sudo apt-get update + sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils + git clone https://github.com/pyenv/pyenv.git ~/.pyenv + echo -e '#!/bin/bash\n\nexport PATH="$HOME/.pyenv/bin:$PATH"\n'\ + 'eval "$(pyenv init --path)"\n'\ + 'eval "$(pyenv virtualenv-init -)"' > ~/.pyenv_setup.sh + chmod +x ~/.pyenv_setup.sh + + - run: + name: Create Python << parameters.py_version >> Virtual Environment, Activate Virtual Environment, Install Dependencies and install Ansible + command: | + set -x + source ~/.pyenv_setup.sh + pyenv install << parameters.py_version >> + pyenv global << parameters.py_version >> + pyenv versions + pyenv version + cat ~/.pyenv/version + + - run: + name: + command: | + set -x + pip install pyenv-virtualenv + pyenv virtualenv << parameters.py_version >> ansible + python --version + pip --version + pyenv local ansible + pip install --upgrade pip + pip install jinja2 PyYAML cryptography paramiko pip install ansible dnacentersdk ansible --version dnacentersdk --version From d819f3583b03586907dda83e3cd31b2be17b9513 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 17:35:27 -0500 Subject: [PATCH 030/358] step to activate venv and install ansible --- .circleci/config.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6f35ba0a22..a1fd377941 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -33,7 +33,7 @@ jobs: chmod +x ~/.pyenv_setup.sh - run: - name: Create Python << parameters.py_version >> Virtual Environment, Activate Virtual Environment, Install Dependencies and install Ansible + name: Install Python << parameters.py_version >> using pyenv, Create Python << parameters.py_version >> Virtual Environment, Activate Virtual Environment, Install Dependencies and install Ansible command: | set -x source ~/.pyenv_setup.sh @@ -42,11 +42,6 @@ jobs: pyenv versions pyenv version cat ~/.pyenv/version - - - run: - name: - command: | - set -x pip install pyenv-virtualenv pyenv virtualenv << parameters.py_version >> ansible python --version @@ -57,6 +52,9 @@ jobs: pip install ansible dnacentersdk ansible --version dnacentersdk --version + + + workflows: test-build: From ab5eb606e871192175bba06c1b3bed2f65bbf16f Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 17:53:58 -0500 Subject: [PATCH 031/358] step to activate venv and install ansible --- .circleci/config.yml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a1fd377941..e21354363c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,6 +27,7 @@ jobs: sudo apt-get update sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils git clone https://github.com/pyenv/pyenv.git ~/.pyenv + git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv echo -e '#!/bin/bash\n\nexport PATH="$HOME/.pyenv/bin:$PATH"\n'\ 'eval "$(pyenv init --path)"\n'\ 'eval "$(pyenv virtualenv-init -)"' > ~/.pyenv_setup.sh @@ -39,19 +40,15 @@ jobs: source ~/.pyenv_setup.sh pyenv install << parameters.py_version >> pyenv global << parameters.py_version >> + pyenv shell << parameters.py_version >> + python -m ensurepip --default-pip + pyenv which pip + pyenv which python pyenv versions pyenv version cat ~/.pyenv/version - pip install pyenv-virtualenv - pyenv virtualenv << parameters.py_version >> ansible - python --version - pip --version - pyenv local ansible - pip install --upgrade pip - pip install jinja2 PyYAML cryptography paramiko - pip install ansible dnacentersdk - ansible --version - dnacentersdk --version + + From 55bc0f4e14370e72fba8fbe5176674c5ae3d12dc Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 18:06:39 -0500 Subject: [PATCH 032/358] step to activate venv and install ansible --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e21354363c..743b01956b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,7 +27,7 @@ jobs: sudo apt-get update sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils git clone https://github.com/pyenv/pyenv.git ~/.pyenv - git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv + git clone https://github.com/pyenv/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv echo -e '#!/bin/bash\n\nexport PATH="$HOME/.pyenv/bin:$PATH"\n'\ 'eval "$(pyenv init --path)"\n'\ 'eval "$(pyenv virtualenv-init -)"' > ~/.pyenv_setup.sh From 0664f37aaf6e72735ef7c7415abda27e6a8b0077 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 18:10:01 -0500 Subject: [PATCH 033/358] step to activate venv and install ansible --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 743b01956b..e273e6629f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -40,6 +40,7 @@ jobs: source ~/.pyenv_setup.sh pyenv install << parameters.py_version >> pyenv global << parameters.py_version >> + pyenv init pyenv shell << parameters.py_version >> python -m ensurepip --default-pip pyenv which pip From 1d615d103c04746b48ecfe8941d83888cb24f79e Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 18:14:09 -0500 Subject: [PATCH 034/358] step to activate venv and install ansible --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e273e6629f..88afb5c446 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -40,7 +40,8 @@ jobs: source ~/.pyenv_setup.sh pyenv install << parameters.py_version >> pyenv global << parameters.py_version >> - pyenv init + export PYENV_ROOT="/home/circleci/.pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" pyenv shell << parameters.py_version >> python -m ensurepip --default-pip pyenv which pip From 348148677348b92840658e310e09d0ff360b9da9 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 18:19:32 -0500 Subject: [PATCH 035/358] step to activate venv and install ansible --- .circleci/config.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 88afb5c446..fa03d75f2e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -40,8 +40,10 @@ jobs: source ~/.pyenv_setup.sh pyenv install << parameters.py_version >> pyenv global << parameters.py_version >> - export PYENV_ROOT="/home/circleci/.pyenv" - export PATH="$PYENV_ROOT/bin:$PATH" + echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc + echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc + echo 'eval "$(pyenv init -)"' >> ~/.bashrc + source ~/.bashrc pyenv shell << parameters.py_version >> python -m ensurepip --default-pip pyenv which pip From 111e0b627a927ec1dadee307d68818030b352718 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 18:53:16 -0500 Subject: [PATCH 036/358] step to activate venv and install ansible --- .circleci/config.yml | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fa03d75f2e..f8948f9fbb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -37,15 +37,32 @@ jobs: name: Install Python << parameters.py_version >> using pyenv, Create Python << parameters.py_version >> Virtual Environment, Activate Virtual Environment, Install Dependencies and install Ansible command: | set -x + + #Loading pyenv configuration source ~/.pyenv_setup.sh + + #Installing Python pyenv install << parameters.py_version >> + + #Set Global Python version pyenv global << parameters.py_version >> - echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc - echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc - echo 'eval "$(pyenv init -)"' >> ~/.bashrc + + # Append pyenv-related configuration to ~/.bashrc + cat <<'EOF' >> ~/.bashrc + export PYENV_ROOT="$HOME/.pyenv" + [[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH" + eval "$(pyenv init -)" + EOF + + # Reload the shell to apply changes source ~/.bashrc + pyenv shell << parameters.py_version >> + + #Install pip python -m ensurepip --default-pip + + #Crosschecking setup pyenv which pip pyenv which python pyenv versions From 40c385360783f52d985208580f2b6548f0c851b6 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 18:57:33 -0500 Subject: [PATCH 037/358] step to activate venv and install ansible --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f8948f9fbb..275b30f671 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,10 +49,10 @@ jobs: # Append pyenv-related configuration to ~/.bashrc cat <<'EOF' >> ~/.bashrc - export PYENV_ROOT="$HOME/.pyenv" - [[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH" - eval "$(pyenv init -)" - EOF + export PYENV_ROOT="$HOME/.pyenv" + [[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH" + eval "$(pyenv init -)" + EOF # Reload the shell to apply changes source ~/.bashrc From d79fb6b894624d5d4e6216f1b100cda84cccf553 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 19:05:22 -0500 Subject: [PATCH 038/358] step to activate venv and install ansible --- .circleci/config.yml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 275b30f671..bc7e43bb26 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,31 +38,32 @@ jobs: command: | set -x - #Loading pyenv configuration + # Loading pyenv configuration source ~/.pyenv_setup.sh - #Installing Python + # Installing Python pyenv install << parameters.py_version >> - #Set Global Python version + # Set Global Python version pyenv global << parameters.py_version >> - # Append pyenv-related configuration to ~/.bashrc - cat <<'EOF' >> ~/.bashrc - export PYENV_ROOT="$HOME/.pyenv" - [[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH" - eval "$(pyenv init -)" - EOF + export PYENV_ROOT="/home/circleci/.pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" + export PATH="$PYENV_ROOT/shims/python3:$PATH" + export PATH="$PYENV_ROOT/shims/python:$PATH" + export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" + export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" - # Reload the shell to apply changes - source ~/.bashrc + + # Reload the shell to apply changes + # source ~/.bashrc pyenv shell << parameters.py_version >> - #Install pip + # Install pip python -m ensurepip --default-pip - #Crosschecking setup + # Crosschecking setup pyenv which pip pyenv which python pyenv versions From 595324b531b1cf98ed6df5c55ec690d7d1888fe4 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 19:06:31 -0500 Subject: [PATCH 039/358] step to activate venv and install ansible --- .circleci/config.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bc7e43bb26..00e7bad26c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,13 +38,13 @@ jobs: command: | set -x - # Loading pyenv configuration + # Loading pyenv configuration source ~/.pyenv_setup.sh - # Installing Python + # Installing Python pyenv install << parameters.py_version >> - # Set Global Python version + # Set Global Python version pyenv global << parameters.py_version >> export PYENV_ROOT="/home/circleci/.pyenv" @@ -55,15 +55,15 @@ jobs: export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" - # Reload the shell to apply changes - # source ~/.bashrc + # Reload the shell to apply changes + # source ~/.bashrc pyenv shell << parameters.py_version >> - # Install pip + # Install pip python -m ensurepip --default-pip - # Crosschecking setup + # Crosschecking setup pyenv which pip pyenv which python pyenv versions From 9127eec9e7be2e0b78c8f75c4a52175bef51dfd2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 19:32:16 -0500 Subject: [PATCH 040/358] step to activate venv and install ansible --- .circleci/config.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 00e7bad26c..61619f411f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,16 +47,13 @@ jobs: # Set Global Python version pyenv global << parameters.py_version >> - export PYENV_ROOT="/home/circleci/.pyenv" - export PATH="$PYENV_ROOT/bin:$PATH" - export PATH="$PYENV_ROOT/shims/python3:$PATH" - export PATH="$PYENV_ROOT/shims/python:$PATH" - export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" - export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" - + # Appending pyenv-related configuration to ~/.bashrc + echo 'export PYENV_ROOT="$HOME/.pyenv"' >> $HOME/.bash_profile + echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> $HOME/.bash_profile + echo 'eval "$(pyenv init -)"' >> $HOME/.bash_profile # Reload the shell to apply changes - # source ~/.bashrc + exec $SHELL pyenv shell << parameters.py_version >> From 8e3ce7b9ca3a311d6dada13591db7a7ae22ac676 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 19:40:02 -0500 Subject: [PATCH 041/358] step to activate venv and install ansible --- .circleci/config.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 61619f411f..8366812da7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -41,20 +41,24 @@ jobs: # Loading pyenv configuration source ~/.pyenv_setup.sh - # Installing Python - pyenv install << parameters.py_version >> - - # Set Global Python version - pyenv global << parameters.py_version >> - # Appending pyenv-related configuration to ~/.bashrc echo 'export PYENV_ROOT="$HOME/.pyenv"' >> $HOME/.bash_profile echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> $HOME/.bash_profile echo 'eval "$(pyenv init -)"' >> $HOME/.bash_profile # Reload the shell to apply changes - exec $SHELL + # exec $SHELL + + #Source the bash file again + source $HOME/.bash_profile + + # Installing Python + pyenv install << parameters.py_version >> + + # Set Global Python version + pyenv global << parameters.py_version >> + # Set PYENV_VERSION version in shell pyenv shell << parameters.py_version >> # Install pip From 41fec8da40acb3b1b9c8a94a64b574832317e67c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 19:44:53 -0500 Subject: [PATCH 042/358] step to activate venv and install ansible --- .circleci/config.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8366812da7..1c6c6696b8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -70,11 +70,16 @@ jobs: pyenv versions pyenv version cat ~/.pyenv/version - - - - + # Activate Virtual Environment and Install ansible, dnacentersdk + pip install --upgrade pip + pip install pyenv-virtualenv + pyenv virtualenv << parameters.py_version >> ansible + pyenv local ansible + pip install jinja2 PyYAML cryptography paramiko + pip install ansible dnacentersdk + ansible --version + dnacentersdk --version workflows: test-build: From ba36d2094c8521f46b1d1ba4d495ce46cf5d0cb9 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 19:49:29 -0500 Subject: [PATCH 043/358] step to activate venv and install ansible --- .circleci/config.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1c6c6696b8..9b9a998ace 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,7 +27,6 @@ jobs: sudo apt-get update sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils git clone https://github.com/pyenv/pyenv.git ~/.pyenv - git clone https://github.com/pyenv/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv echo -e '#!/bin/bash\n\nexport PATH="$HOME/.pyenv/bin:$PATH"\n'\ 'eval "$(pyenv init --path)"\n'\ 'eval "$(pyenv virtualenv-init -)"' > ~/.pyenv_setup.sh @@ -71,11 +70,15 @@ jobs: pyenv version cat ~/.pyenv/version - # Activate Virtual Environment and Install ansible, dnacentersdk - pip install --upgrade pip - pip install pyenv-virtualenv + # Activate Virtual Environment + # pip install pyenv-virtualenv + git clone https://github.com/pyenv/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv pyenv virtualenv << parameters.py_version >> ansible pyenv local ansible + + + # Install ansible, dnacentersdk + pip install --upgrade pip pip install jinja2 PyYAML cryptography paramiko pip install ansible dnacentersdk ansible --version From 34046638ad821651f73b97fa3de5c1acfa7bda9d Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 19:57:05 -0500 Subject: [PATCH 044/358] step to activate venv and install ansible --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9b9a998ace..a71dcec1c5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -71,16 +71,16 @@ jobs: cat ~/.pyenv/version # Activate Virtual Environment - # pip install pyenv-virtualenv git clone https://github.com/pyenv/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv pyenv virtualenv << parameters.py_version >> ansible pyenv local ansible - # Install ansible, dnacentersdk pip install --upgrade pip pip install jinja2 PyYAML cryptography paramiko - pip install ansible dnacentersdk + pyenv global system << parameters.py_version >> + pip install ansible + pip install dnacentersdk ansible --version dnacentersdk --version From 8003b99ed5493417c01de9aa0854dcc0a5ecc498 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 20:02:03 -0500 Subject: [PATCH 045/358] step to activate venv and install ansible --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index a71dcec1c5..2ab95a1161 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,6 +51,9 @@ jobs: #Source the bash file again source $HOME/.bash_profile + # Bug fix for No module named '_ctypes' + sudo apt-get install libffi-dev + # Installing Python pyenv install << parameters.py_version >> From 53fd8fbf7e878a92387b9397f52fb59b6364a2cd Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 17 Jan 2024 20:27:44 -0500 Subject: [PATCH 046/358] step to activate venv and install ansible --- .circleci/config.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2ab95a1161..669a860a34 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,6 +10,10 @@ jobs: type: string default: "3.8.10" + ansible_cisco_dnac_version: + type: string + default: "6.9.0" + working_directory: ~/repo #machine: true @@ -85,7 +89,12 @@ jobs: pip install ansible pip install dnacentersdk ansible --version - dnacentersdk --version + + # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs + ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" + + + workflows: test-build: From e44912cdbf130f3347042677e8639d938ef1bbca Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 22 Jan 2024 20:35:09 -0500 Subject: [PATCH 047/358] machine runner setup test --- .circleci/config.yml | 73 ++++++-------------------------------------- 1 file changed, 9 insertions(+), 64 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 669a860a34..2be07ea17b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,86 +6,33 @@ jobs: - image: cimg/base:current parameters: - py_version: - type: string - default: "3.8.10" - ansible_cisco_dnac_version: type: string default: "6.9.0" working_directory: ~/repo - #machine: true - - #environment: - # PATH: "$HOME/.pyenv/bin:$PATH" - # PYENV_ROOT: "$HOME/.pyenv" + machine: true + resource_class: rukapse/dnacenter-ansible steps: - checkout - run: - name: Install Dependencies and Pyenv - command: | - set -x - sudo apt-get update - sudo apt-get install -y --no-install-recommends libssl-dev libreadline-dev sqlite3 libsqlite3-dev zlib1g-dev xz-utils - git clone https://github.com/pyenv/pyenv.git ~/.pyenv - echo -e '#!/bin/bash\n\nexport PATH="$HOME/.pyenv/bin:$PATH"\n'\ - 'eval "$(pyenv init --path)"\n'\ - 'eval "$(pyenv virtualenv-init -)"' > ~/.pyenv_setup.sh - chmod +x ~/.pyenv_setup.sh - - - run: - name: Install Python << parameters.py_version >> using pyenv, Create Python << parameters.py_version >> Virtual Environment, Activate Virtual Environment, Install Dependencies and install Ansible + name: Activate Virtual Environment, Install ansible and Build collection tarball command: | set -x - - # Loading pyenv configuration - source ~/.pyenv_setup.sh - - # Appending pyenv-related configuration to ~/.bashrc - echo 'export PYENV_ROOT="$HOME/.pyenv"' >> $HOME/.bash_profile - echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> $HOME/.bash_profile - echo 'eval "$(pyenv init -)"' >> $HOME/.bash_profile - - # Reload the shell to apply changes - # exec $SHELL - - #Source the bash file again - source $HOME/.bash_profile - - # Bug fix for No module named '_ctypes' - sudo apt-get install libffi-dev - - # Installing Python - pyenv install << parameters.py_version >> - - # Set Global Python version - pyenv global << parameters.py_version >> - - # Set PYENV_VERSION version in shell - pyenv shell << parameters.py_version >> - - # Install pip - python -m ensurepip --default-pip - - # Crosschecking setup - pyenv which pip - pyenv which python - pyenv versions - pyenv version - cat ~/.pyenv/version - # Activate Virtual Environment - git clone https://github.com/pyenv/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv - pyenv virtualenv << parameters.py_version >> ansible pyenv local ansible + export PYENV_ROOT="/home/circleci/.pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" + export PATH="$PYENV_ROOT/shims/python3:$PATH" + export PATH="$PYENV_ROOT/shims/python:$PATH" + export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" + export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" # Install ansible, dnacentersdk pip install --upgrade pip pip install jinja2 PyYAML cryptography paramiko - pyenv global system << parameters.py_version >> pip install ansible pip install dnacentersdk ansible --version @@ -94,8 +41,6 @@ jobs: ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" - - workflows: test-build: jobs: From 32182744337e963686fe09f885ee6bcc2c993493 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 22 Jan 2024 20:38:01 -0500 Subject: [PATCH 048/358] machine runner setup test --- .circleci/config.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2be07ea17b..0e68cfd0da 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,8 +2,6 @@ version: 2.1 jobs: build: - docker: - - image: cimg/base:current parameters: ansible_cisco_dnac_version: From 8e44e3b26472681b10394ebe72043494710033bf Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 22 Jan 2024 22:31:14 -0500 Subject: [PATCH 049/358] machine runner setup test --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0e68cfd0da..bd7ccfbc73 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,6 +2,8 @@ version: 2.1 jobs: build: + machine: true + resource_class: rukapse/dnacenter-ansible parameters: ansible_cisco_dnac_version: @@ -9,9 +11,7 @@ jobs: default: "6.9.0" working_directory: ~/repo - machine: true - resource_class: rukapse/dnacenter-ansible - + steps: - checkout From 62c1d52f902bc54f502e2b9ec9218d934c3eb23d Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 22 Jan 2024 22:42:10 -0500 Subject: [PATCH 050/358] machine runner setup test --- .circleci/config.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bd7ccfbc73..35a28c2a1c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,14 +2,15 @@ version: 2.1 jobs: build: - machine: true - resource_class: rukapse/dnacenter-ansible - + parameters: ansible_cisco_dnac_version: type: string default: "6.9.0" + machine: true + resource_class: rukapse/dnacenter-ansible + working_directory: ~/repo steps: From 2f468cd9a3743dac7b23c248d88267e9276261fe Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 22 Jan 2024 22:47:44 -0500 Subject: [PATCH 051/358] machine runner setup test --- .circleci/config.yml | 47 ++++++-------------------------------------- 1 file changed, 6 insertions(+), 41 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 35a28c2a1c..c4844ce956 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,46 +1,11 @@ version: 2.1 - +workflows: + testing: + jobs: + - runner-test jobs: - build: - - parameters: - ansible_cisco_dnac_version: - type: string - default: "6.9.0" - + runner-test: machine: true resource_class: rukapse/dnacenter-ansible - - working_directory: ~/repo - steps: - - checkout - - - run: - name: Activate Virtual Environment, Install ansible and Build collection tarball - command: | - set -x - # Activate Virtual Environment - pyenv local ansible - export PYENV_ROOT="/home/circleci/.pyenv" - export PATH="$PYENV_ROOT/bin:$PATH" - export PATH="$PYENV_ROOT/shims/python3:$PATH" - export PATH="$PYENV_ROOT/shims/python:$PATH" - export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" - export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" - - # Install ansible, dnacentersdk - pip install --upgrade pip - pip install jinja2 PyYAML cryptography paramiko - pip install ansible - pip install dnacentersdk - ansible --version - - # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs - ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" - - -workflows: - test-build: - jobs: - - build \ No newline at end of file + - run: echo "Hi I'm on Runners!" \ No newline at end of file From e09980bb8bd52bdc79c3da79306b81af8e3c0151 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 23 Jan 2024 00:22:01 -0500 Subject: [PATCH 052/358] machine runner setup test --- .circleci/config.yml | 48 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c4844ce956..47df0abf74 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,11 +1,47 @@ version: 2.1 -workflows: - testing: - jobs: - - runner-test + + jobs: - runner-test: + build: + + parameters: + ansible_cisco_dnac_version: + type: string + default: "6.9.0" + machine: true resource_class: rukapse/dnacenter-ansible + + working_directory: ~/repo + steps: - - run: echo "Hi I'm on Runners!" \ No newline at end of file + - checkout + + - run: + name: Activate Virtual Environment, Install ansible and Build collection tarball + command: | + set -x + # Activate Virtual Environment + pyenv local ansible + export PYENV_ROOT="/home/circleci/.pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" + export PATH="$PYENV_ROOT/shims/python3:$PATH" + export PATH="$PYENV_ROOT/shims/python:$PATH" + export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" + export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" + + # Install ansible, dnacentersdk + pip install --upgrade pip + pip install jinja2 PyYAML cryptography paramiko + pip install ansible + pip install dnacentersdk + ansible --version + + # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs + ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" + + +workflows: + testing: + jobs: + - runner-test \ No newline at end of file From 6e70ff0badc964d318a3981f0e7f0e7ea28685a4 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 23 Jan 2024 00:22:45 -0500 Subject: [PATCH 053/358] machine runner setup test --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 47df0abf74..7928e45166 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -44,4 +44,4 @@ jobs: workflows: testing: jobs: - - runner-test \ No newline at end of file + - build \ No newline at end of file From 3c08877a0fde74bf0380ac35cd61b78071a91cc3 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 23 Jan 2024 00:50:50 -0500 Subject: [PATCH 054/358] machine runner setup test --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7928e45166..09c58ebb43 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,7 +11,6 @@ jobs: machine: true resource_class: rukapse/dnacenter-ansible - working_directory: ~/repo steps: From f641f133df6353a39aaec8f922ba880f76c1e42c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 1 Feb 2024 15:34:34 -0500 Subject: [PATCH 055/358] test setup --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 09c58ebb43..1fa0a037f4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -36,6 +36,7 @@ jobs: pip install dnacentersdk ansible --version + # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" From fbbf8ee1171607a03f210e25f9f181155f89a6e2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 1 Feb 2024 16:08:44 -0500 Subject: [PATCH 056/358] test setup --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1fa0a037f4..09c58ebb43 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -36,7 +36,6 @@ jobs: pip install dnacentersdk ansible --version - # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" From 07a00c4cd2e811957042aeb375091c0f92fe4938 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 1 Feb 2024 16:37:55 -0500 Subject: [PATCH 057/358] test setup --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 09c58ebb43..8fd836b914 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -39,7 +39,6 @@ jobs: # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" - workflows: testing: jobs: From 48d11147b10c6e691a58009da489efc39ced5c71 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 13:29:30 -0500 Subject: [PATCH 058/358] test build job --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8fd836b914..ea843dcddb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -20,6 +20,7 @@ jobs: name: Activate Virtual Environment, Install ansible and Build collection tarball command: | set -x + # Activate Virtual Environment pyenv local ansible export PYENV_ROOT="/home/circleci/.pyenv" @@ -28,7 +29,7 @@ jobs: export PATH="$PYENV_ROOT/shims/python:$PATH" export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" - + # Install ansible, dnacentersdk pip install --upgrade pip pip install jinja2 PyYAML cryptography paramiko From 24ee8f8f26d2c0c59198686c9be0b2a3a8f9b7fa Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 14:37:16 -0500 Subject: [PATCH 059/358] test build job --- .circleci/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ea843dcddb..44cb18ea4a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,8 +19,7 @@ jobs: - run: name: Activate Virtual Environment, Install ansible and Build collection tarball command: | - set -x - + set -x # Activate Virtual Environment pyenv local ansible export PYENV_ROOT="/home/circleci/.pyenv" From 19b7d8b0d0f78fd4652c13f2e8a8505d62606c5e Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 14:44:27 -0500 Subject: [PATCH 060/358] test build job --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 44cb18ea4a..b3d0c32d0d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,6 +14,10 @@ jobs: working_directory: ~/repo steps: + - add_ssh_keys: + fingerprints: + - "SHA256:QM0ooGGjHvw663Ti2XAh4BTnwXt3LxOyxAMr7TMSRM8" + - checkout - run: From 97a5de3bf00529d4bee377b684b0e9e6ea708e82 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 14:55:49 -0500 Subject: [PATCH 061/358] test build job --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b3d0c32d0d..8594ce4aa1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,8 +16,8 @@ jobs: steps: - add_ssh_keys: fingerprints: - - "SHA256:QM0ooGGjHvw663Ti2XAh4BTnwXt3LxOyxAMr7TMSRM8" - + - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" + - checkout - run: From 627c11efb6cbc218ed50fdf0507f977f1fd2f2bc Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 15:05:33 -0500 Subject: [PATCH 062/358] test build job --- .circleci/config.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8594ce4aa1..44cb18ea4a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,10 +14,6 @@ jobs: working_directory: ~/repo steps: - - add_ssh_keys: - fingerprints: - - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - - checkout - run: From 9773261a8f957412ddb24ca9d5ddb98f897e3da5 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 15:08:40 -0500 Subject: [PATCH 063/358] test build job --- .circleci/config.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 44cb18ea4a..d6005beb02 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,7 +14,10 @@ jobs: working_directory: ~/repo steps: - - checkout + - checkout: + key: + fingerprint: "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" + path: "~/my-repo" - run: name: Activate Virtual Environment, Install ansible and Build collection tarball From 28a9b27eda76d1ec98516ed863ea58c183daf6b2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 15:10:38 -0500 Subject: [PATCH 064/358] test build job --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d6005beb02..9d1c71c343 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,9 +15,9 @@ jobs: steps: - checkout: - key: - fingerprint: "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - path: "~/my-repo" + - add_ssh_keys: + fingerprints: + - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - run: name: Activate Virtual Environment, Install ansible and Build collection tarball From 4bc47173c6477e2e9c084e8d4091b2c3595c40f8 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 15:11:35 -0500 Subject: [PATCH 065/358] test build job --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9d1c71c343..36811fdf8a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,8 +16,8 @@ jobs: steps: - checkout: - add_ssh_keys: - fingerprints: - - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" + fingerprints: + - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - run: name: Activate Virtual Environment, Install ansible and Build collection tarball From 8ba321381e2ae3d3f59cc7eff1437ecf8eaf30f1 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 15:12:52 -0500 Subject: [PATCH 066/358] test build job --- .circleci/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 36811fdf8a..4f87d97fa4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,11 +14,10 @@ jobs: working_directory: ~/repo steps: - - checkout: + - checkout - add_ssh_keys: fingerprints: - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - - run: name: Activate Virtual Environment, Install ansible and Build collection tarball command: | From f25edae0fc828d3337de700dcc24879ad3314585 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 15:21:04 -0500 Subject: [PATCH 067/358] test build job --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4f87d97fa4..a1fa9da883 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,9 +15,11 @@ jobs: steps: - checkout + - add_ssh_keys: fingerprints: - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" + - run: name: Activate Virtual Environment, Install ansible and Build collection tarball command: | From 670df24e64c3b70e0cb9178c7882cef578835853 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 15:37:30 -0500 Subject: [PATCH 068/358] test build job --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a1fa9da883..6a92779437 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,7 +15,7 @@ jobs: steps: - checkout - + - add_ssh_keys: fingerprints: - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" From baba70885c974513cb6638133a270f595a0877fe Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 15:39:45 -0500 Subject: [PATCH 069/358] test build job --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6a92779437..9ce7daf21d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,6 +14,10 @@ jobs: working_directory: ~/repo steps: + - run: + name: Debug SSH key + command: cat ~/.ssh/id_rsa + - checkout - add_ssh_keys: From 6ec9783bc82654fd04fab1772d676b8adad78f68 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 15:41:11 -0500 Subject: [PATCH 070/358] test build job --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9ce7daf21d..6eb208491c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,15 +15,15 @@ jobs: steps: - run: - name: Debug SSH key - command: cat ~/.ssh/id_rsa - - - checkout + name: Debug SSH key + command: cat ~/.ssh/id_rsa - add_ssh_keys: fingerprints: - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" + - checkout + - run: name: Activate Virtual Environment, Install ansible and Build collection tarball command: | From 95965729b252198d419b6dad271310d0f3917c9d Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 15:45:02 -0500 Subject: [PATCH 071/358] test build job --- .circleci/config.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6eb208491c..69083355b4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,9 +18,13 @@ jobs: name: Debug SSH key command: cat ~/.ssh/id_rsa - - add_ssh_keys: - fingerprints: - - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" + - run: + name: Set up SSH key + command: echo -e "Host github.com\n IdentityFile ~/.ssh/id_rsa" > ~/.ssh/config + + # - add_ssh_keys: + # fingerprints: + # - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - checkout From 2ed0fa50d0371e26cc4470dd909d643b9538463c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 15:57:22 -0500 Subject: [PATCH 072/358] test build job --- .circleci/config.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 69083355b4..e354924807 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,14 +14,18 @@ jobs: working_directory: ~/repo steps: - - run: - name: Debug SSH key - command: cat ~/.ssh/id_rsa - run: name: Set up SSH key command: echo -e "Host github.com\n IdentityFile ~/.ssh/id_rsa" > ~/.ssh/config + - run: + name: Debug SSH key and Connectivity + command: | + cat ~/.ssh/id_rsa + ls -la ~/.ssh + ssh -Tvvv git@github.com + # - add_ssh_keys: # fingerprints: # - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" From cffcc35bd12ded3e896f500c09218e60e82f9891 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 16:09:53 -0500 Subject: [PATCH 073/358] test build job --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e354924807..93d316192b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,6 +19,10 @@ jobs: name: Set up SSH key command: echo -e "Host github.com\n IdentityFile ~/.ssh/id_rsa" > ~/.ssh/config + - add_ssh_keys: + fingerprints: + - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" + - run: name: Debug SSH key and Connectivity command: | @@ -26,10 +30,6 @@ jobs: ls -la ~/.ssh ssh -Tvvv git@github.com - # - add_ssh_keys: - # fingerprints: - # - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - - checkout - run: From 0c78fcb962f2fd05950e46195397e61e25c3617a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 16:14:14 -0500 Subject: [PATCH 074/358] test build job --- .circleci/config.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 93d316192b..e2af71b146 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,15 +14,6 @@ jobs: working_directory: ~/repo steps: - - - run: - name: Set up SSH key - command: echo -e "Host github.com\n IdentityFile ~/.ssh/id_rsa" > ~/.ssh/config - - - add_ssh_keys: - fingerprints: - - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - - run: name: Debug SSH key and Connectivity command: | From f24927c9a9fad0c8c9d9dcf7b987c39fbe9c19a9 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 16:17:14 -0500 Subject: [PATCH 075/358] test build job --- .circleci/config.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e2af71b146..91ebdcfac1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,13 +14,6 @@ jobs: working_directory: ~/repo steps: - - run: - name: Debug SSH key and Connectivity - command: | - cat ~/.ssh/id_rsa - ls -la ~/.ssh - ssh -Tvvv git@github.com - - checkout - run: From 5a865db26d7a0fdb70fbb91f16fbe41aafde041a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 16:40:21 -0500 Subject: [PATCH 076/358] test build job --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 91ebdcfac1..afeb67f35a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,7 +11,6 @@ jobs: machine: true resource_class: rukapse/dnacenter-ansible - working_directory: ~/repo steps: - checkout From 13cc53e2c2a711602b65a42e1d8f429dc9a6d453 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 16:50:33 -0500 Subject: [PATCH 077/358] test build job --- .circleci/config.yml | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index afeb67f35a..f4fde7fbaa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,30 +13,13 @@ jobs: resource_class: rukapse/dnacenter-ansible steps: + - add_ssh_keys: + fingerprints: + - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" + skip-add: true - checkout - - - run: - name: Activate Virtual Environment, Install ansible and Build collection tarball - command: | - set -x - # Activate Virtual Environment - pyenv local ansible - export PYENV_ROOT="/home/circleci/.pyenv" - export PATH="$PYENV_ROOT/bin:$PATH" - export PATH="$PYENV_ROOT/shims/python3:$PATH" - export PATH="$PYENV_ROOT/shims/python:$PATH" - export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" - export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" - - # Install ansible, dnacentersdk - pip install --upgrade pip - pip install jinja2 PyYAML cryptography paramiko - pip install ansible - pip install dnacentersdk - ansible --version - # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs - ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" + workflows: testing: From d565a28567b93bbc544b2f3c764c7549b1f39612 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 16:56:02 -0500 Subject: [PATCH 078/358] test build job --- .circleci/config.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f4fde7fbaa..ccdefdc063 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,11 +13,11 @@ jobs: resource_class: rukapse/dnacenter-ansible steps: - - add_ssh_keys: - fingerprints: - - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - skip-add: true - - checkout + - checkout: + path: ~/repo + key: + fingerprint: "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" + type: rsa From b62ddce5fa02e961b293dad5dec1fbfc2fe87f1a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 17:02:55 -0500 Subject: [PATCH 079/358] test build job --- .circleci/config.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ccdefdc063..656101b1ee 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,13 +13,7 @@ jobs: resource_class: rukapse/dnacenter-ansible steps: - - checkout: - path: ~/repo - key: - fingerprint: "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - type: rsa - - + - checkout workflows: testing: From 55e9c9c2e3d365c1a537a39991c7bf3a29751be8 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 17:09:02 -0500 Subject: [PATCH 080/358] test build job --- .circleci/config.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 656101b1ee..e942af39e8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,7 +13,12 @@ jobs: resource_class: rukapse/dnacenter-ansible steps: - - checkout + - run: + name: Confirm SSH keys + command: | + ssh-add -l + ls -l ~/.ssh + - checkout workflows: testing: From 01f3740990cb164cb12d4c7f42b0d02a483ddc87 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 17:11:00 -0500 Subject: [PATCH 081/358] test build job --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index e942af39e8..527333d82b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,6 +18,9 @@ jobs: command: | ssh-add -l ls -l ~/.ssh + - add_ssh_keys: + fingerprints: + - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - checkout workflows: From dcb673fc6551ed2df347a02065afc7fb7cb48ff5 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 17:47:03 -0500 Subject: [PATCH 082/358] test build job --- .circleci/config.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 527333d82b..0b86527dc3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,15 +13,9 @@ jobs: resource_class: rukapse/dnacenter-ansible steps: - - run: - name: Confirm SSH keys - command: | - ssh-add -l - ls -l ~/.ssh - - add_ssh_keys: - fingerprints: - - "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" - - checkout + - checkout: + github: + fingerprint: "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" workflows: testing: From 164ca2ba43f3a2bd500062d9b5ea99afafc72b8d Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 19:27:39 -0500 Subject: [PATCH 083/358] test build job --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0b86527dc3..5e609df227 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,8 +14,8 @@ jobs: steps: - checkout: - github: - fingerprint: "SHA256:J0xQGHm/j7txCuHdPam0+Ty+9VpEELCMJo8eYptUYO0" + git: + url: https://github.com/rukapse/dnacenter-ansible.git workflows: testing: From dafe84dda58d60d5b9be18f6058b16ee318c06a1 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 19:34:11 -0500 Subject: [PATCH 084/358] test build job --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5e609df227..85df3f1336 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,8 @@ jobs: - checkout: git: url: https://github.com/rukapse/dnacenter-ansible.git - + submodules: false # Disable submodules, as they may still use SSH + depth: 1 workflows: testing: jobs: From a8de26f7d8d3c033d68784f13b49ca61204fed4e Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 19:36:07 -0500 Subject: [PATCH 085/358] test build job --- .circleci/config.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 85df3f1336..8ab186f682 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,11 +13,10 @@ jobs: resource_class: rukapse/dnacenter-ansible steps: - - checkout: - git: - url: https://github.com/rukapse/dnacenter-ansible.git - submodules: false # Disable submodules, as they may still use SSH - depth: 1 + - run: + name: Clone Git repository + command: git clone --depth=1 https://github.com/rukapse/dnacenter-ansible.git + workflows: testing: jobs: From 801198bbb09e3c2998bdb8dcab4c8929ae943bea Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 19:54:31 -0500 Subject: [PATCH 086/358] test build job --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8ab186f682..75ab265c4e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,7 +15,7 @@ jobs: steps: - run: name: Clone Git repository - command: git clone --depth=1 https://github.com/rukapse/dnacenter-ansible.git + command: git clone --depth=1 https://github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git workflows: testing: From 56663c3c7b5a8167aecf3896106a21388913e333 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 19:56:10 -0500 Subject: [PATCH 087/358] test build job --- .circleci/config.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 75ab265c4e..9d2a42992a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,8 +14,14 @@ jobs: steps: - run: - name: Clone Git repository - command: git clone --depth=1 https://github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git + name: Debug Information + command: | + echo "CIRCLE_PROJECT_USERNAME: $CIRCLE_PROJECT_USERNAME" + echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" + echo "Cloning repository..." + git clone --depth=1 https://github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git + cd $CIRCLE_PROJECT_REPONAME + git rev-parse HEAD workflows: testing: From 93f6c100ce3a76d61f293c10924c11397f6a91be Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 20:00:26 -0500 Subject: [PATCH 088/358] test build job --- .circleci/config.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9d2a42992a..608a1d4f2a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,14 +14,8 @@ jobs: steps: - run: - name: Debug Information - command: | - echo "CIRCLE_PROJECT_USERNAME: $CIRCLE_PROJECT_USERNAME" - echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" - echo "Cloning repository..." - git clone --depth=1 https://github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git - cd $CIRCLE_PROJECT_REPONAME - git rev-parse HEAD + name: Clone Git repository + command: git clone --depth=1 $REPO_URL workflows: testing: From d7ad7b2395bbf0d2e7a5f6ff6fac0b0aaca9b7a8 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 20:02:34 -0500 Subject: [PATCH 089/358] test build job --- .circleci/config.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 608a1d4f2a..22bd6cad0a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,7 +14,18 @@ jobs: steps: - run: - name: Clone Git repository + name: Debug Information + command: | + echo "REPO_URL: $REPO_URL" + env + + - checkout: + git: + depth: 1 + url: $REPO_URL + + - run: + name: Custom Git Clone command: git clone --depth=1 $REPO_URL workflows: From 5e0558750846daa5ea494233c9055fda9606e521 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 20:40:33 -0500 Subject: [PATCH 090/358] test build job --- .circleci/config.yml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 22bd6cad0a..cda34284c2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,22 +11,23 @@ jobs: machine: true resource_class: rukapse/dnacenter-ansible - + + environment: + CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> + REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> + CIRCLE_PROJECT_USERNAME: << pipeline.trigger_parameters.github_app.user_name >> + + steps: - run: name: Debug Information command: | + set -x + echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" echo "REPO_URL: $REPO_URL" + echo "CIRCLE_PROJECT_USERNAME: $CIRCLE_PROJECT_USERNAME" env - - checkout: - git: - depth: 1 - url: $REPO_URL - - - run: - name: Custom Git Clone - command: git clone --depth=1 $REPO_URL workflows: testing: From c1c29ce45162a19a35d27e7b171341ab147a5a6b Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 20:42:03 -0500 Subject: [PATCH 091/358] test build job --- .circleci/config.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index cda34284c2..5048574400 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,6 +27,11 @@ jobs: echo "REPO_URL: $REPO_URL" echo "CIRCLE_PROJECT_USERNAME: $CIRCLE_PROJECT_USERNAME" env + + - checkout: + git: + depth: 1 + url: $REPO_URL workflows: From 0d4429a893c03306f0ab52645107b5f422c03406 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 20:43:10 -0500 Subject: [PATCH 092/358] test build job --- .circleci/config.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5048574400..67757ece9d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,10 +28,9 @@ jobs: echo "CIRCLE_PROJECT_USERNAME: $CIRCLE_PROJECT_USERNAME" env - - checkout: - git: - depth: 1 - url: $REPO_URL + - run: + name: Custom Git Clone + command: git clone --depth=1 $REPO_URL workflows: From 9e568b6b6c9f1a543fb31e0959b1b46fc85736be Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 21:33:13 -0500 Subject: [PATCH 093/358] test build job --- .circleci/config.yml | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 67757ece9d..0a0d7ba9a9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,27 +11,45 @@ jobs: machine: true resource_class: rukapse/dnacenter-ansible + working_directory: ~/repo environment: - CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> - CIRCLE_PROJECT_USERNAME: << pipeline.trigger_parameters.github_app.user_name >> - steps: - run: name: Debug Information command: | set -x - echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" echo "REPO_URL: $REPO_URL" - echo "CIRCLE_PROJECT_USERNAME: $CIRCLE_PROJECT_USERNAME" env - + - run: name: Custom Git Clone command: git clone --depth=1 $REPO_URL + - run: + name: Activate Virtual Environment, Install ansible and Build collection tarball + command: | + set -x + # Activate Virtual Environment + pyenv local ansible + export PYENV_ROOT="/home/circleci/.pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" + export PATH="$PYENV_ROOT/shims/python3:$PATH" + export PATH="$PYENV_ROOT/shims/python:$PATH" + export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" + export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" + + # Install ansible, dnacentersdk + pip install --upgrade pip + pip install jinja2 PyYAML cryptography paramiko + pip install ansible + pip install dnacentersdk + ansible --version + + # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs + ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" workflows: testing: From c51bbae1ea24b4344380a765b626ba57c7b496f2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 21:41:40 -0500 Subject: [PATCH 094/358] test build job --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0a0d7ba9a9..f2db03fa44 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,6 +48,9 @@ jobs: pip install dnacentersdk ansible --version + # Change directory to dnacenter-ansible + cd /home/circleci/repo/dnacenter-ansible + # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" From 7f956c2720abfbdf8b6e4806f902bb7b8339c459 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 21:46:15 -0500 Subject: [PATCH 095/358] test build job --- .circleci/config.yml | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f2db03fa44..8e1afb3538 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -23,36 +23,11 @@ jobs: set -x echo "REPO_URL: $REPO_URL" env - - - run: - name: Custom Git Clone - command: git clone --depth=1 $REPO_URL - - - run: - name: Activate Virtual Environment, Install ansible and Build collection tarball - command: | - set -x - # Activate Virtual Environment - pyenv local ansible - export PYENV_ROOT="/home/circleci/.pyenv" - export PATH="$PYENV_ROOT/bin:$PATH" - export PATH="$PYENV_ROOT/shims/python3:$PATH" - export PATH="$PYENV_ROOT/shims/python:$PATH" - export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" - export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" - - # Install ansible, dnacentersdk - pip install --upgrade pip - pip install jinja2 PyYAML cryptography paramiko - pip install ansible - pip install dnacentersdk - ansible --version - - # Change directory to dnacenter-ansible - cd /home/circleci/repo/dnacenter-ansible - # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs - ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" + - checkout: + git: + depth: 1 + url: $REPO_URL workflows: testing: From 4869f1fd9c10638e71470cfe23f8ff0997a6c470 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 21:48:53 -0500 Subject: [PATCH 096/358] test build job --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8e1afb3538..99670dc393 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -23,12 +23,13 @@ jobs: set -x echo "REPO_URL: $REPO_URL" env - + - checkout: git: depth: 1 url: $REPO_URL + workflows: testing: jobs: From 77861199ad229c65f19380e9e30eab9a1a4459f2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 21:51:12 -0500 Subject: [PATCH 097/358] test build job --- .circleci/config.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 99670dc393..02a7a7e77a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,6 +29,33 @@ jobs: depth: 1 url: $REPO_URL + - run: + name: Activate Virtual Environment, Install ansible and Build collection tarball + command: | + set -x + # Activate Virtual Environment + pyenv local ansible + export PYENV_ROOT="/home/circleci/.pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" + export PATH="$PYENV_ROOT/shims/python3:$PATH" + export PATH="$PYENV_ROOT/shims/python:$PATH" + export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" + export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" + + # Install ansible, dnacentersdk + pip install --upgrade pip + pip install jinja2 PyYAML cryptography paramiko + pip install ansible + pip install dnacentersdk + ansible --version + + # Change directory to dnacenter-ansible + cd /home/circleci/repo/dnacenter-ansible + + # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs + ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" + + workflows: testing: From 06838edc1bc03652e719fe9d9bbf0dbe493a63fc Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 21:51:58 -0500 Subject: [PATCH 098/358] test build job --- .circleci/config.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 02a7a7e77a..b1564e051b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,9 +25,8 @@ jobs: env - checkout: - git: - depth: 1 - url: $REPO_URL + name: Custom Git Clone + command: git clone --depth=1 $REPO_URL - run: name: Activate Virtual Environment, Install ansible and Build collection tarball @@ -55,8 +54,6 @@ jobs: # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" - - workflows: testing: jobs: From b120a1020b12c886dfe9b0baf47b38a1d5e9a079 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 21:53:11 -0500 Subject: [PATCH 099/358] test build job --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b1564e051b..f2db03fa44 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,7 +24,7 @@ jobs: echo "REPO_URL: $REPO_URL" env - - checkout: + - run: name: Custom Git Clone command: git clone --depth=1 $REPO_URL From 6095ae7aed47ad8403248d523b250ff52cee38c3 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 21:54:26 -0500 Subject: [PATCH 100/358] test build job --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index f2db03fa44..fc3c523da7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -54,6 +54,7 @@ jobs: # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" + workflows: testing: jobs: From b074e620d41726ef4c0e91206625eedf58dec04b Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 21:57:40 -0500 Subject: [PATCH 101/358] test build job --- .circleci/config.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fc3c523da7..6118e3deea 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -52,8 +52,14 @@ jobs: cd /home/circleci/repo/dnacenter-ansible # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs - ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" + ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" + - run: + name: Remove Existing Directory + command: | + set -x + rm -rf ${HOME}/repo/dnacenter-ansible + rm -rf ${HOME}/.cache/v<< parameters.ansible_version >>/ workflows: testing: From d5c41617937afea8eedefe9347d506ba86641088 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 21:58:18 -0500 Subject: [PATCH 102/358] test build job --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6118e3deea..fa1f11a59a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -59,7 +59,7 @@ jobs: command: | set -x rm -rf ${HOME}/repo/dnacenter-ansible - rm -rf ${HOME}/.cache/v<< parameters.ansible_version >>/ + rm -rf ${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/ workflows: testing: From 0455c5f371ba93df64b50cbbd4d01d7cf0de3181 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 5 Feb 2024 21:59:31 -0500 Subject: [PATCH 103/358] test build job --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index fa1f11a59a..8c444a3a25 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -61,6 +61,7 @@ jobs: rm -rf ${HOME}/repo/dnacenter-ansible rm -rf ${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/ + workflows: testing: jobs: From cf7854910da97a6d0d5d4f31e3f049faff9aa4a1 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 6 Feb 2024 14:27:50 -0500 Subject: [PATCH 104/358] test build --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8c444a3a25..a192e3f758 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,5 @@ version: 2.1 - jobs: build: From d607046a9f00a1f0aa61ce340ee268e432f71cdc Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 6 Feb 2024 16:56:14 -0500 Subject: [PATCH 105/358] added sanity tests --- .circleci/config.yml | 126 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 121 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a192e3f758..df9bdebd6f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,8 +1,35 @@ version: 2.1 jobs: - build: - + + pre: + parameters: + ansible_cisco_dnac_version: + type: string + default: "6.9.0" + + machine: true + resource_class: rukapse/dnacenter-ansible + working_directory: ~/repo + + environment: + CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> + + steps: + - run: + name: Debug information + command: | + set -x + echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" + env + - run: + name: Remove existing directory and collection tarball + command: | + set -x + rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME + rm -rf ${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/ + + build: parameters: ansible_cisco_dnac_version: type: string @@ -17,7 +44,7 @@ jobs: steps: - run: - name: Debug Information + name: Debug information command: | set -x echo "REPO_URL: $REPO_URL" @@ -58,10 +85,99 @@ jobs: command: | set -x rm -rf ${HOME}/repo/dnacenter-ansible - rm -rf ${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/ + + sanity-tests: + parameters: + ansible_cisco_dnac_version: + type: string + default: "6.9.0" + + machine: true + resource_class: rukapse/dnacenter-ansible + working_directory: ~/repo + + environment: + REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> + + steps: + - run: + name: Debug information + command: | + set -x + echo "REPO_URL: $REPO_URL" + env + + - run: + name: Custom Git Clone + command: git clone --depth=1 $REPO_URL + + - run: + name: Activate Virtual Environment, Install ansible and Build collection tarball + command: | + set -x + # Activate Virtual Environment + pyenv local ansible + export PYENV_ROOT="/home/circleci/.pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" + export PATH="$PYENV_ROOT/shims/python3:$PATH" + export PATH="$PYENV_ROOT/shims/python:$PATH" + export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" + export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" + + export PATH="/home/circleci/.ansible/collections/:$PATH" + export PYTHONPATH="/home/circleci/.ansible/collections/:$PYTHONPATH" + + # Install ansible, dnacentersdk + pip install --upgrade pip + pip install jinja2 PyYAML cryptography paramiko + pip install ansible + pip install dnacentersdk + ansible --version + + environment: + PYTHONPATH: /home/circleci/.ansible/collections/:$PYTHONPATH + + - run: + name: Copy static files + command: | + + cp /home/circleci/static/credentials.yml /home/circleci/repo/dnacenter-ansible/playbooks/credentials.yml + cp /home/circleci/static/hosts /home/circleci/repo/dnacenter-ansible/playbooks/hosts + + - run: + name: Install the collection tarball + command: | + set -x + pyenv versions + python --version + ansible --version + + + ansible-galaxy collection install --force ${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs/*.tar.gz + + + - run: + name: Run sanity tests + command: | + export ANSIBLE_PERSISTENT_CONNECT_TIMEOUT=1000 + export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 + + cd /home/circleci/repo/dnacenter-ansible/playbooks + + ansible-playbook -i hosts site_workflow_manager.yml -vvvv + + + - run: + name: Remove Existing Directory + command: | + set -x + rm -rf ${HOME}/repo/dnacenter-ansible + workflows: testing: jobs: - - build \ No newline at end of file + - pre + - build + - sanity-tests \ No newline at end of file From 49000659e9eddbc8c3365f4c96ce36a1005cbf70 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 6 Feb 2024 16:58:38 -0500 Subject: [PATCH 106/358] added sanity tests --- .circleci/config.yml | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index df9bdebd6f..4f7fb58817 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,7 +10,6 @@ jobs: machine: true resource_class: rukapse/dnacenter-ansible - working_directory: ~/repo environment: CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> @@ -22,7 +21,7 @@ jobs: set -x echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" env - - run: + - run: name: Remove existing directory and collection tarball command: | set -x @@ -140,22 +139,19 @@ jobs: - run: name: Copy static files command: | - cp /home/circleci/static/credentials.yml /home/circleci/repo/dnacenter-ansible/playbooks/credentials.yml cp /home/circleci/static/hosts /home/circleci/repo/dnacenter-ansible/playbooks/hosts - run: - name: Install the collection tarball + name: Install the collection tarball command: | set -x pyenv versions python --version ansible --version - ansible-galaxy collection install --force ${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs/*.tar.gz - - run: name: Run sanity tests command: | @@ -166,18 +162,15 @@ jobs: ansible-playbook -i hosts site_workflow_manager.yml -vvvv - - run: name: Remove Existing Directory command: | set -x rm -rf ${HOME}/repo/dnacenter-ansible - - workflows: testing: jobs: - pre - build - - sanity-tests \ No newline at end of file + - sanity-tests From 9ff292bee2db1826ce4142e43155078ed9a99d10 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 6 Feb 2024 17:02:14 -0500 Subject: [PATCH 107/358] added sanity tests --- .circleci/config.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4f7fb58817..77af93a982 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -172,5 +172,9 @@ workflows: testing: jobs: - pre - - build - - sanity-tests + - build: + requires: + - pre + - sanity-tests: + requires: + - build From 25b6955121e62a1e5b951e86cedeb3f82501baa8 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 12:49:48 -0500 Subject: [PATCH 108/358] added sanity tests --- .circleci/config.yml | 53 +++++++++++++------ .../ccc_site_management/.travis.yml | 0 .../ccc_site_management/defaults/main.yml | 2 + .../ccc_site_management/meta/main.yml | 1 + .../ccc_site_management/tasks/main.yml | 20 +++++++ .../ccc_site_management/tests/test.yml | 50 +++++++++++++++++ .../ccc_site_management/vars/main.yml | 2 + 7 files changed, 111 insertions(+), 17 deletions(-) create mode 100644 tests/integration/ccc_site_management/.travis.yml create mode 100644 tests/integration/ccc_site_management/defaults/main.yml create mode 100644 tests/integration/ccc_site_management/meta/main.yml create mode 100644 tests/integration/ccc_site_management/tasks/main.yml create mode 100644 tests/integration/ccc_site_management/tests/test.yml create mode 100644 tests/integration/ccc_site_management/vars/main.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index 77af93a982..d7c639cdf0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -40,6 +40,7 @@ jobs: environment: REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> + CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> steps: - run: @@ -59,7 +60,7 @@ jobs: set -x # Activate Virtual Environment pyenv local ansible - export PYENV_ROOT="/home/circleci/.pyenv" + export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" export PATH="$PYENV_ROOT/shims/python3:$PATH" export PATH="$PYENV_ROOT/shims/python:$PATH" @@ -74,16 +75,16 @@ jobs: ansible --version # Change directory to dnacenter-ansible - cd /home/circleci/repo/dnacenter-ansible + cd $HOME/repo/dnacenter-ansible - # Build collection and store resulting tarball in directory /home/circleci/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs - ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" + # Build collection and store resulting tarball in directory $HOME/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs + ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" - run: name: Remove Existing Directory command: | set -x - rm -rf ${HOME}/repo/dnacenter-ansible + rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME sanity-tests: parameters: @@ -97,6 +98,7 @@ jobs: environment: REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> + CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> steps: - run: @@ -116,15 +118,15 @@ jobs: set -x # Activate Virtual Environment pyenv local ansible - export PYENV_ROOT="/home/circleci/.pyenv" + export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" export PATH="$PYENV_ROOT/shims/python3:$PATH" export PATH="$PYENV_ROOT/shims/python:$PATH" export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" - export PATH="/home/circleci/.ansible/collections/:$PATH" - export PYTHONPATH="/home/circleci/.ansible/collections/:$PYTHONPATH" + export PATH="$HOME/.ansible/collections/:$PATH" + export PYTHONPATH="$HOME/.ansible/collections/:$PYTHONPATH" # Install ansible, dnacentersdk pip install --upgrade pip @@ -134,13 +136,31 @@ jobs: ansible --version environment: - PYTHONPATH: /home/circleci/.ansible/collections/:$PYTHONPATH - + PYTHONPATH: $HOME/.ansible/collections/:$PYTHONPATH + + - run: + name: Create Roles File header + command: | + echo "---" > ccc_roles.yml + echo "- hosts: dnac_servers" >> ccc_roles.yml + echo " gather_facts: no" >> ccc_roles.yml + echo " connection: ansible.netcommon.httpapi" >> ccc_roles.yml + echo " " >> ccc_roles.yml + echo " tasks:" >> ccc_roles.yml + echo " " >> ccc_roles.yml + echo " vars:" >> ccc_roles.yml + echo " debug: false" >> ccc_roles.yml + echo " " >> ccc_roles.yml + echo " roles:" >> ccc_roles.yml + echo " - ccc_site_management" >> ccc_roles.yml + + cat ccc_roles.yaml + - run: name: Copy static files command: | - cp /home/circleci/static/credentials.yml /home/circleci/repo/dnacenter-ansible/playbooks/credentials.yml - cp /home/circleci/static/hosts /home/circleci/repo/dnacenter-ansible/playbooks/hosts + cp $STATIC_GROUP_VARS $GROUP_VARS + cp $STATIC_HOSTS $HOSTS - run: name: Install the collection tarball @@ -157,16 +177,15 @@ jobs: command: | export ANSIBLE_PERSISTENT_CONNECT_TIMEOUT=1000 export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 - - cd /home/circleci/repo/dnacenter-ansible/playbooks - - ansible-playbook -i hosts site_workflow_manager.yml -vvvv + export ANSIBLE_ROLES_PATH=$INTEGRATION_TESTS + ansible-playbook -i hosts ccc_roles.yml -vvvv - run: name: Remove Existing Directory command: | set -x - rm -rf ${HOME}/repo/dnacenter-ansible + rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME + workflows: testing: diff --git a/tests/integration/ccc_site_management/.travis.yml b/tests/integration/ccc_site_management/.travis.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/integration/ccc_site_management/defaults/main.yml b/tests/integration/ccc_site_management/defaults/main.yml new file mode 100644 index 0000000000..44e03fbe38 --- /dev/null +++ b/tests/integration/ccc_site_management/defaults/main.yml @@ -0,0 +1,2 @@ +--- +testcase: "{{ testcase }}" \ No newline at end of file diff --git a/tests/integration/ccc_site_management/meta/main.yml b/tests/integration/ccc_site_management/meta/main.yml new file mode 100644 index 0000000000..5514b6a40c --- /dev/null +++ b/tests/integration/ccc_site_management/meta/main.yml @@ -0,0 +1 @@ +dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_site_management/tasks/main.yml b/tests/integration/ccc_site_management/tasks/main.yml new file mode 100644 index 0000000000..be7eb2cd7f --- /dev/null +++ b/tests/integration/ccc_site_management/tasks/main.yml @@ -0,0 +1,20 @@ +--- +- name: collect site management test cases + find: + paths: "{{ role_path }}/tests" + patterns: "{{ testcase }}.yaml" + connection: local + register: ccc_cases + +- set_fact: + test_cases: + files: "{{ ccc_cases.files }}" + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test cases (connection=httpapi) + include: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run \ No newline at end of file diff --git a/tests/integration/ccc_site_management/tests/test.yml b/tests/integration/ccc_site_management/tests/test.yml new file mode 100644 index 0000000000..7e274be9b6 --- /dev/null +++ b/tests/integration/ccc_site_management/tests/test.yml @@ -0,0 +1,50 @@ +--- +- debug: msg="Starting site_management test" +- debug: msg="Role Path {{ role_path }}" + +############################################# +# CREATE SITE ## +############################################# + + +- name: Test creating area with valid parameters + cisco.dnac.site_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log: true + dnac_log_level: DEBUG + config_verify: true + state: merged + config: + - site: + area: + name: Abc + parent_name: 'Global' + type: area + register: result + +- name: Assert area creation success + assert: + that: + - result.changed == true + - result.response.status == "success" + - result.response.site.parentName == "Parent Name" + - "'created successfully' in result.msg" + fail_msg: "Area creation failed" + success_msg: "Area created successfully with valid parameters" + +############################################# +# IDEMPOTENCY CHECK ## +############################################# + + + +############################################## +## DELETE SITE ## +############################################## + diff --git a/tests/integration/ccc_site_management/vars/main.yml b/tests/integration/ccc_site_management/vars/main.yml new file mode 100644 index 0000000000..4eb771bf10 --- /dev/null +++ b/tests/integration/ccc_site_management/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for ccc_site_management From 0b37e95b0f1c00b0906ccf0b79c2c5e1af8b17f3 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 12:56:43 -0500 Subject: [PATCH 109/358] added sanity tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d7c639cdf0..a41873d512 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -141,7 +141,7 @@ jobs: - run: name: Create Roles File header command: | - echo "---" > ccc_roles.yml + echo "---" > $HOME/ccc_roles.yml echo "- hosts: dnac_servers" >> ccc_roles.yml echo " gather_facts: no" >> ccc_roles.yml echo " connection: ansible.netcommon.httpapi" >> ccc_roles.yml From 044d6fdcbf22cb0c16053bdf680350f42f16e638 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 12:58:19 -0500 Subject: [PATCH 110/358] added sanity tests --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a41873d512..c6e73aa9df 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -141,7 +141,8 @@ jobs: - run: name: Create Roles File header command: | - echo "---" > $HOME/ccc_roles.yml + touch ccc_roles.yml + echo "---" > ccc_roles.yml echo "- hosts: dnac_servers" >> ccc_roles.yml echo " gather_facts: no" >> ccc_roles.yml echo " connection: ansible.netcommon.httpapi" >> ccc_roles.yml From 67a4b7ec584de240ce0291e8c60a1b05e198a38e Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 13:00:09 -0500 Subject: [PATCH 111/358] added sanity tests --- .circleci/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c6e73aa9df..b650244fa5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -141,7 +141,6 @@ jobs: - run: name: Create Roles File header command: | - touch ccc_roles.yml echo "---" > ccc_roles.yml echo "- hosts: dnac_servers" >> ccc_roles.yml echo " gather_facts: no" >> ccc_roles.yml @@ -155,7 +154,7 @@ jobs: echo " roles:" >> ccc_roles.yml echo " - ccc_site_management" >> ccc_roles.yml - cat ccc_roles.yaml + cat ccc_roles.yml - run: name: Copy static files From 2d478e358262e90bb207ac2c1f5280df735a3d12 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 13:05:48 -0500 Subject: [PATCH 112/358] added sanity tests --- .circleci/config.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b650244fa5..0ccb62a057 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -159,8 +159,10 @@ jobs: - run: name: Copy static files command: | - cp $STATIC_GROUP_VARS $GROUP_VARS - cp $STATIC_HOSTS $HOSTS + echo "STATIC_GROUP_VARS: ${STATIC_GROUP_VARS}" + echo "STATIC_HOSTS: ${STATIC_HOSTS}" + cp ${STATIC_GROUP_VARS} ${GROUP_VARS} + cp ${STATIC_HOSTS} ${HOSTS} - run: name: Install the collection tarball From 01991292387cf9241f1a04750e6220d669141632 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 14:18:33 -0500 Subject: [PATCH 113/358] added sanity tests --- .circleci/config.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0ccb62a057..5361d795c6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -99,6 +99,10 @@ jobs: environment: REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> + STATIC_GROUP_VARS: << parameters.STATIC_GROUP_VARS + GROUP_VARS: << parameters.GROUP_VARS >> + STATIC_HOSTS: << parameters.STATIC_HOSTS + HOSTS: << parameters.HOSTS >> steps: - run: @@ -159,8 +163,10 @@ jobs: - run: name: Copy static files command: | - echo "STATIC_GROUP_VARS: ${STATIC_GROUP_VARS}" - echo "STATIC_HOSTS: ${STATIC_HOSTS}" + echo "STATIC_GROUP_VARS: $STATIC_GROUP_VARS" + echo "GROUP_VARS: $GROUP_VARS" + echo "STATIC_HOSTS: $STATIC_HOSTS" + echo "HOSTS: $HOSTS" cp ${STATIC_GROUP_VARS} ${GROUP_VARS} cp ${STATIC_HOSTS} ${HOSTS} From c7c7b74a9729ebf9835a66e643fee5846d66e9a8 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 14:20:31 -0500 Subject: [PATCH 114/358] added sanity tests --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5361d795c6..8d82eadbcd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -99,9 +99,9 @@ jobs: environment: REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> - STATIC_GROUP_VARS: << parameters.STATIC_GROUP_VARS + STATIC_GROUP_VARS: << parameters.STATIC_GROUP_VARS >> GROUP_VARS: << parameters.GROUP_VARS >> - STATIC_HOSTS: << parameters.STATIC_HOSTS + STATIC_HOSTS: << parameters.STATIC_HOSTS >> HOSTS: << parameters.HOSTS >> steps: From b0196109f1163ceadf7fd218efe38eb985ad14b4 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 14:38:04 -0500 Subject: [PATCH 115/358] added sanity tests --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8d82eadbcd..c4ff619752 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -99,10 +99,10 @@ jobs: environment: REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> - STATIC_GROUP_VARS: << parameters.STATIC_GROUP_VARS >> - GROUP_VARS: << parameters.GROUP_VARS >> - STATIC_HOSTS: << parameters.STATIC_HOSTS >> - HOSTS: << parameters.HOSTS >> + STATIC_GROUP_VARS: << pipeline.trigger_parameters.github_app.STATIC_GROUP_VARS >> + GROUP_VARS: << pipeline.trigger_parameters.github_app.GROUP_VARS >> + STATIC_HOSTS: << pipeline.trigger_parameters.github_app.STATIC_HOSTS >> + HOSTS: << pipeline.trigger_parameters.github_app.HOSTS >> steps: - run: From 562446263c0c3caed3b6a6ee4226c0848768ac48 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 14:41:10 -0500 Subject: [PATCH 116/358] added sanity tests --- .circleci/config.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c4ff619752..7d8bc5e1b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -99,10 +99,11 @@ jobs: environment: REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> - STATIC_GROUP_VARS: << pipeline.trigger_parameters.github_app.STATIC_GROUP_VARS >> - GROUP_VARS: << pipeline.trigger_parameters.github_app.GROUP_VARS >> - STATIC_HOSTS: << pipeline.trigger_parameters.github_app.STATIC_HOSTS >> - HOSTS: << pipeline.trigger_parameters.github_app.HOSTS >> + GROUP_VARS: $GROUP_VARS + HOSTS: $HOSTS + INTEGRATION_TESTS: $INTEGRATION_TESTS + STATIC_GROUP_VARS: $STATIC_GROUP_VARS + STATIC_HOSTS: $STATIC_HOSTS steps: - run: From 8e5affe43295b9912d973433e6b253a27a409ad2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 14:46:06 -0500 Subject: [PATCH 117/358] added sanity tests --- .circleci/config.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7d8bc5e1b1..6afd97a60b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -99,11 +99,6 @@ jobs: environment: REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> - GROUP_VARS: $GROUP_VARS - HOSTS: $HOSTS - INTEGRATION_TESTS: $INTEGRATION_TESTS - STATIC_GROUP_VARS: $STATIC_GROUP_VARS - STATIC_HOSTS: $STATIC_HOSTS steps: - run: From f99ffb9906234d90275a8a3b1d9e81069c8135a8 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 14:51:49 -0500 Subject: [PATCH 118/358] added sanity tests --- .circleci/config.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6afd97a60b..bf108d9b56 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -159,12 +159,8 @@ jobs: - run: name: Copy static files command: | - echo "STATIC_GROUP_VARS: $STATIC_GROUP_VARS" - echo "GROUP_VARS: $GROUP_VARS" - echo "STATIC_HOSTS: $STATIC_HOSTS" - echo "HOSTS: $HOSTS" - cp ${STATIC_GROUP_VARS} ${GROUP_VARS} - cp ${STATIC_HOSTS} ${HOSTS} + cp cp $HOME/static/group_vars/dnac_servers.yaml group_vars/dnac_servers.yaml + cp $HOME/static/hosts hosts - run: name: Install the collection tarball From b8c8e365a317bc8514e60b568b9e518cd66e1a4a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 14:54:15 -0500 Subject: [PATCH 119/358] added sanity tests --- .circleci/config.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bf108d9b56..8b34301ee2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -159,7 +159,7 @@ jobs: - run: name: Copy static files command: | - cp cp $HOME/static/group_vars/dnac_servers.yaml group_vars/dnac_servers.yaml + cp cp $HOME/static/group_vars/dnac_servers.yml group_vars/dnac_servers.yml cp $HOME/static/hosts hosts - run: @@ -178,6 +178,9 @@ jobs: export ANSIBLE_PERSISTENT_CONNECT_TIMEOUT=1000 export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 export ANSIBLE_ROLES_PATH=$INTEGRATION_TESTS + + env + ansible-playbook -i hosts ccc_roles.yml -vvvv - run: From 7276a841e2be6c9d0af88a812ffbd35dfa88e884 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 15:12:22 -0500 Subject: [PATCH 120/358] added sanity tests --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8b34301ee2..126387f2ee 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -159,8 +159,8 @@ jobs: - run: name: Copy static files command: | - cp cp $HOME/static/group_vars/dnac_servers.yml group_vars/dnac_servers.yml - cp $HOME/static/hosts hosts + cp cp ${HOME}/static/group_vars/dnac_servers.yml group_vars/dnac_servers.yml + cp ${HOME}/static/hosts hosts - run: name: Install the collection tarball @@ -180,7 +180,7 @@ jobs: export ANSIBLE_ROLES_PATH=$INTEGRATION_TESTS env - + ansible-playbook -i hosts ccc_roles.yml -vvvv - run: From 50580dee83f7a65e780cdda01776fec230f428a4 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 15:14:17 -0500 Subject: [PATCH 121/358] added sanity tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 126387f2ee..b49cf40cac 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -159,7 +159,7 @@ jobs: - run: name: Copy static files command: | - cp cp ${HOME}/static/group_vars/dnac_servers.yml group_vars/dnac_servers.yml + cp ${HOME}/static/group_vars/dnac_servers.yml group_vars/dnac_servers.yml cp ${HOME}/static/hosts hosts - run: From bcdd65d534f14f3dddf27c13ab249482d4e52e73 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 15:18:03 -0500 Subject: [PATCH 122/358] added sanity tests --- .circleci/config.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b49cf40cac..f47228b902 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -159,8 +159,9 @@ jobs: - run: name: Copy static files command: | - cp ${HOME}/static/group_vars/dnac_servers.yml group_vars/dnac_servers.yml - cp ${HOME}/static/hosts hosts + mkdir -p group_vars + cp "$STATIC_GROUP_VARS" "$GROUP_VARS" + cp "$STATIC_HOSTS" "$HOSTS" - run: name: Install the collection tarball From ccf0191e878492f74b183f6928088d197ed80815 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 15:20:12 -0500 Subject: [PATCH 123/358] added sanity tests --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f47228b902..f45a08c6a1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -159,9 +159,9 @@ jobs: - run: name: Copy static files command: | - mkdir -p group_vars - cp "$STATIC_GROUP_VARS" "$GROUP_VARS" - cp "$STATIC_HOSTS" "$HOSTS" + mkdir -p group_vars + cp ${HOME}/static/group_vars/dnac_servers.yml group_vars/dnac_servers.yml + cp ${HOME}/static/hosts hosts - run: name: Install the collection tarball From a6a2b8d40509485de6dc9c16f6193b79303378b5 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 15:21:03 -0500 Subject: [PATCH 124/358] added sanity tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f45a08c6a1..00c4ce5e82 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -159,7 +159,7 @@ jobs: - run: name: Copy static files command: | - mkdir -p group_vars + mkdir -p group_vars cp ${HOME}/static/group_vars/dnac_servers.yml group_vars/dnac_servers.yml cp ${HOME}/static/hosts hosts From b5b556609de0694ee9dfdac5b8136e9125b35a8f Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 15:23:44 -0500 Subject: [PATCH 125/358] added sanity tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 00c4ce5e82..5a30813287 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -178,7 +178,7 @@ jobs: command: | export ANSIBLE_PERSISTENT_CONNECT_TIMEOUT=1000 export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 - export ANSIBLE_ROLES_PATH=$INTEGRATION_TESTS + export ANSIBLE_ROLES_PATH=/home/circleci/repo/tests/integration/ env From 3cda06a04dac231760fcfd68d3c8ddedff1f477b Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 15:28:03 -0500 Subject: [PATCH 126/358] added sanity tests --- .circleci/config.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5a30813287..08c37050b3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -180,8 +180,6 @@ jobs: export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 export ANSIBLE_ROLES_PATH=/home/circleci/repo/tests/integration/ - env - ansible-playbook -i hosts ccc_roles.yml -vvvv - run: From 481cd815859c9c8a214c5ca799a415ac73155a81 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 15:37:32 -0500 Subject: [PATCH 127/358] added sanity tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 08c37050b3..ed3f59b9d0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -178,7 +178,7 @@ jobs: command: | export ANSIBLE_PERSISTENT_CONNECT_TIMEOUT=1000 export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 - export ANSIBLE_ROLES_PATH=/home/circleci/repo/tests/integration/ + export ANSIBLE_ROLES_PATH=/home/circleci/repo/tests/integration/ccc_site_management ansible-playbook -i hosts ccc_roles.yml -vvvv From e164515d911ad5e096cb7af964b52530c6030760 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 8 Feb 2024 15:53:21 -0500 Subject: [PATCH 128/358] added sanity tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ed3f59b9d0..08c37050b3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -178,7 +178,7 @@ jobs: command: | export ANSIBLE_PERSISTENT_CONNECT_TIMEOUT=1000 export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 - export ANSIBLE_ROLES_PATH=/home/circleci/repo/tests/integration/ccc_site_management + export ANSIBLE_ROLES_PATH=/home/circleci/repo/tests/integration/ ansible-playbook -i hosts ccc_roles.yml -vvvv From 67f1c5c7537accf52468f15b049c5cec545b2fb0 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 12 Feb 2024 15:46:19 -0500 Subject: [PATCH 129/358] added site management test cases --- .../ccc_site_management/defaults/main.yml | 2 +- .../ccc_site_management/tasks/main.yml | 29 +++-- .../ccc_site_management/tests/test.yml | 50 --------- .../tests/test_site_management.yml | 104 ++++++++++++++++++ 4 files changed, 127 insertions(+), 58 deletions(-) delete mode 100644 tests/integration/ccc_site_management/tests/test.yml create mode 100644 tests/integration/ccc_site_management/tests/test_site_management.yml diff --git a/tests/integration/ccc_site_management/defaults/main.yml b/tests/integration/ccc_site_management/defaults/main.yml index 44e03fbe38..55a93fc23d 100644 --- a/tests/integration/ccc_site_management/defaults/main.yml +++ b/tests/integration/ccc_site_management/defaults/main.yml @@ -1,2 +1,2 @@ --- -testcase: "{{ testcase }}" \ No newline at end of file +testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_site_management/tasks/main.yml b/tests/integration/ccc_site_management/tasks/main.yml index be7eb2cd7f..36c8954a15 100644 --- a/tests/integration/ccc_site_management/tasks/main.yml +++ b/tests/integration/ccc_site_management/tasks/main.yml @@ -1,20 +1,35 @@ ---- -- name: collect site management test cases +- name: collect ccc test cases find: paths: "{{ role_path }}/tests" - patterns: "{{ testcase }}.yaml" + patterns: "{{ testcase }}.yml" connection: local register: ccc_cases + tags: sanity + +- debug: + msg: "CCC Cases: {{ ccc_cases }}" - set_fact: test_cases: files: "{{ ccc_cases.files }}" + tags: sanity + +- debug: + msg: "Test Cases: {{ test_cases }}" - name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + tags: sanity + +- debug: + msg: "Test Items: {{ test_items }}" - name: run test cases (connection=httpapi) - include: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" + include_tasks: "{{ test_case_to_run }}" + loop: "{{ test_items }}" loop_control: - loop_var: test_case_to_run \ No newline at end of file + loop_var: test_case_to_run + tags: sanity + + diff --git a/tests/integration/ccc_site_management/tests/test.yml b/tests/integration/ccc_site_management/tests/test.yml deleted file mode 100644 index 7e274be9b6..0000000000 --- a/tests/integration/ccc_site_management/tests/test.yml +++ /dev/null @@ -1,50 +0,0 @@ ---- -- debug: msg="Starting site_management test" -- debug: msg="Role Path {{ role_path }}" - -############################################# -# CREATE SITE ## -############################################# - - -- name: Test creating area with valid parameters - cisco.dnac.site_workflow_manager: - dnac_host: "{{dnac_host}}" - dnac_username: "{{dnac_username}}" - dnac_password: "{{dnac_password}}" - dnac_verify: "{{dnac_verify}}" - dnac_port: "{{dnac_port}}" - dnac_version: "{{dnac_version}}" - dnac_debug: "{{dnac_debug}}" - dnac_log: true - dnac_log_level: DEBUG - config_verify: true - state: merged - config: - - site: - area: - name: Abc - parent_name: 'Global' - type: area - register: result - -- name: Assert area creation success - assert: - that: - - result.changed == true - - result.response.status == "success" - - result.response.site.parentName == "Parent Name" - - "'created successfully' in result.msg" - fail_msg: "Area creation failed" - success_msg: "Area created successfully with valid parameters" - -############################################# -# IDEMPOTENCY CHECK ## -############################################# - - - -############################################## -## DELETE SITE ## -############################################## - diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml new file mode 100644 index 0000000000..b6c2cef3dc --- /dev/null +++ b/tests/integration/ccc_site_management/tests/test_site_management.yml @@ -0,0 +1,104 @@ +--- +- debug: msg="Starting site management test" +- debug: msg="Role Path {{ role_path }}" + +############################################# +# CREATE SITE ## +############################################# + +- block: + + - name: Test creating area with valid parameters + cisco.dnac.site_workflow_manager: + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + config_verify: true + state: merged + config: + - site: + area: + name: Abc + parent_name: 'Global' + type: area + register: result_create_site + + - name: Assert area creation success + assert: + that: + - result_create_site.changed == true + - result_create_site.response.status == "SUCCESS" + - "'created successfully' in result_create_site.msg" + - result_create_site.response.bapiName == "Create Site" + +############################################# +# IDEMPOTENCY CHECK SITE ## +############################################# + +- block: + + - name: Test idempotency by creating area with valid parameters again + cisco.dnac.site_workflow_manager: + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + config_verify: true + state: merged + config: + - site: + area: + name: Abc + parent_name: 'Global' + type: area + register: result_idempotent + + - name: Assert idempotency of area creation + assert: + that: + - result_idempotent.changed == false + - "'does not need any update' in result_idempotent.msg" + +############################################# +# DELETE SITE ## +############################################# + +- block: + + - name: Test deleting area with valid parameters + cisco.dnac.site_workflow_manager: + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + config_verify: true + state: deleted + config: + - site: + area: + name: Abc + parent_name: 'Global' + type: area + register: result_delete_site + + - name: Assert deletion of area success + assert: + that: + - result_delete_site.changed == true + - "'deleted successfully' in result_delete_site.response" From 4ff4dfffd59105fa46ca9549c4296a162345dc74 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 12 Feb 2024 15:53:22 -0500 Subject: [PATCH 130/358] added sanity tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 08c37050b3..ead6b95040 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -152,7 +152,7 @@ jobs: echo " debug: false" >> ccc_roles.yml echo " " >> ccc_roles.yml echo " roles:" >> ccc_roles.yml - echo " - ccc_site_management" >> ccc_roles.yml + echo " - /home/circleci/repo/tests/integration/ccc_site_management" >> ccc_roles.yml cat ccc_roles.yml From 88f7ee73a210bdec31fdc65fadf61cebc72eb616 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 12 Feb 2024 16:04:08 -0500 Subject: [PATCH 131/358] added sanity tests --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ead6b95040..b84c3f8ff7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -52,7 +52,7 @@ jobs: - run: name: Custom Git Clone - command: git clone --depth=1 $REPO_URL + command: git clone --depth=1 -b circleci-setup $REPO_URL - run: name: Activate Virtual Environment, Install ansible and Build collection tarball @@ -110,7 +110,7 @@ jobs: - run: name: Custom Git Clone - command: git clone --depth=1 $REPO_URL + command: git clone --depth=1 -b circleci-setup $REPO_URL - run: name: Activate Virtual Environment, Install ansible and Build collection tarball @@ -152,7 +152,7 @@ jobs: echo " debug: false" >> ccc_roles.yml echo " " >> ccc_roles.yml echo " roles:" >> ccc_roles.yml - echo " - /home/circleci/repo/tests/integration/ccc_site_management" >> ccc_roles.yml + echo " - /home/circleci/repo/dnacenter-ansible/tests/integration/ccc_site_management" >> ccc_roles.yml cat ccc_roles.yml From dbe48952f8af9cb362061c696ea09f9ed8c1e352 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 12 Feb 2024 16:11:24 -0500 Subject: [PATCH 132/358] added sanity tests --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b84c3f8ff7..79878d84e7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -152,7 +152,7 @@ jobs: echo " debug: false" >> ccc_roles.yml echo " " >> ccc_roles.yml echo " roles:" >> ccc_roles.yml - echo " - /home/circleci/repo/dnacenter-ansible/tests/integration/ccc_site_management" >> ccc_roles.yml + echo " - ccc_site_management" >> ccc_roles.yml cat ccc_roles.yml @@ -178,7 +178,7 @@ jobs: command: | export ANSIBLE_PERSISTENT_CONNECT_TIMEOUT=1000 export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 - export ANSIBLE_ROLES_PATH=/home/circleci/repo/tests/integration/ + export ANSIBLE_ROLES_PATH=/home/circleci/repo/dnacenter-ansible/tests/integration ansible-playbook -i hosts ccc_roles.yml -vvvv From 1934a9bf96e8d20ac287816ce92cd8d06e2340a7 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 12 Feb 2024 16:18:02 -0500 Subject: [PATCH 133/358] added sanity tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 79878d84e7..06cde03f1e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -144,7 +144,7 @@ jobs: echo "---" > ccc_roles.yml echo "- hosts: dnac_servers" >> ccc_roles.yml echo " gather_facts: no" >> ccc_roles.yml - echo " connection: ansible.netcommon.httpapi" >> ccc_roles.yml + echo " connection: local" >> ccc_roles.yml echo " " >> ccc_roles.yml echo " tasks:" >> ccc_roles.yml echo " " >> ccc_roles.yml From fadef61fff3a68fe3bf3bd551c45c91ad5571bfc Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 12 Feb 2024 22:04:09 -0500 Subject: [PATCH 134/358] added scheduler for daily runs but commented for now --- .circleci/config.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 06cde03f1e..99e9595fb2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -190,6 +190,7 @@ jobs: workflows: + version: 2 testing: jobs: - pre @@ -199,3 +200,13 @@ workflows: - sanity-tests: requires: - build + # daily-scheduled: + # triggers: + # - schedule: + # cron: "0 0 * * *" + # filters: + # branches: + # only: + # - main + + From 58716ac4e477e6ee181c37d2c3d89cb41bc62974 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 12 Feb 2024 23:52:42 -0500 Subject: [PATCH 135/358] removed branch specific clone --- .circleci/config.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 99e9595fb2..26984c2b1f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -52,7 +52,7 @@ jobs: - run: name: Custom Git Clone - command: git clone --depth=1 -b circleci-setup $REPO_URL + command: git clone --depth=1 $REPO_URL - run: name: Activate Virtual Environment, Install ansible and Build collection tarball @@ -110,7 +110,7 @@ jobs: - run: name: Custom Git Clone - command: git clone --depth=1 -b circleci-setup $REPO_URL + command: git clone --depth=1 $REPO_URL - run: name: Activate Virtual Environment, Install ansible and Build collection tarball @@ -190,7 +190,6 @@ jobs: workflows: - version: 2 testing: jobs: - pre @@ -208,5 +207,3 @@ workflows: # branches: # only: # - main - - From c3f5728ec5258af22cc8ba86cc51028413e17a2f Mon Sep 17 00:00:00 2001 From: rukapse <89453872+rukapse@users.noreply.github.com> Date: Tue, 13 Feb 2024 00:04:26 -0500 Subject: [PATCH 136/358] Delete tests/integration/ccc_site_management/.travis.yml --- tests/integration/ccc_site_management/.travis.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/integration/ccc_site_management/.travis.yml diff --git a/tests/integration/ccc_site_management/.travis.yml b/tests/integration/ccc_site_management/.travis.yml deleted file mode 100644 index e69de29bb2..0000000000 From b5e25367f673f3659fd935da919f346a36405036 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 13 Feb 2024 00:27:56 -0500 Subject: [PATCH 137/358] sanity test bug fixes --- tests/integration/ccc_site_management/tasks/main.yml | 4 +--- .../ccc_site_management/tests/test_site_management.yml | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/integration/ccc_site_management/tasks/main.yml b/tests/integration/ccc_site_management/tasks/main.yml index 36c8954a15..0f2e3fe798 100644 --- a/tests/integration/ccc_site_management/tasks/main.yml +++ b/tests/integration/ccc_site_management/tasks/main.yml @@ -30,6 +30,4 @@ loop: "{{ test_items }}" loop_control: loop_var: test_case_to_run - tags: sanity - - + tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml index b6c2cef3dc..0d33b6d3bd 100644 --- a/tests/integration/ccc_site_management/tests/test_site_management.yml +++ b/tests/integration/ccc_site_management/tests/test_site_management.yml @@ -101,4 +101,4 @@ assert: that: - result_delete_site.changed == true - - "'deleted successfully' in result_delete_site.response" + - "'deleted successfully' in result_delete_site.response" \ No newline at end of file From d47678a3d827f9522966628fd5efd796bcbe78c7 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 14 Feb 2024 10:49:40 -0500 Subject: [PATCH 138/358] demo --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 26984c2b1f..c08d378daa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ jobs: steps: - run: - name: Debug information + name: Debug information for pre command: | set -x echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" From 2a765971f164f7d463a2866b2975e7a97d109f9c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 22 Feb 2024 09:17:08 -0500 Subject: [PATCH 139/358] modified site_test --- .../ccc_site_management/tasks/main.yml | 1 + .../tests/test_site_management.yml | 124 ++++++++---------- .../ccc_site_management/vars/main.yml | 2 - 3 files changed, 55 insertions(+), 72 deletions(-) delete mode 100644 tests/integration/ccc_site_management/vars/main.yml diff --git a/tests/integration/ccc_site_management/tasks/main.yml b/tests/integration/ccc_site_management/tasks/main.yml index 0f2e3fe798..09e0832ca2 100644 --- a/tests/integration/ccc_site_management/tasks/main.yml +++ b/tests/integration/ccc_site_management/tasks/main.yml @@ -1,3 +1,4 @@ +--- - name: collect ccc test cases find: paths: "{{ role_path }}/tests" diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml index 0d33b6d3bd..f24d60553f 100644 --- a/tests/integration/ccc_site_management/tests/test_site_management.yml +++ b/tests/integration/ccc_site_management/tests/test_site_management.yml @@ -2,103 +2,87 @@ - debug: msg="Starting site management test" - debug: msg="Role Path {{ role_path }}" -############################################# -# CREATE SITE ## -############################################# + - block: + - name: Load design_sites from ccc_site_management role and declare dnac vars + include_vars: + file: "{{ role_path }}/vars/vars_site_management.yml" + name: vars_map + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + + - debug: + msg: "{{ vars_map.delete_sites }}" + - - name: Test creating area with valid parameters +############################################# +# Clean Up # +############################################# + + - name: Clean up before test cisco.dnac.site_workflow_manager: - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG + <<: *dnac_login config_verify: true - state: merged + state: deleted config: - - site: - area: - name: Abc - parent_name: 'Global' - type: area - register: result_create_site - - - name: Assert area creation success - assert: - that: - - result_create_site.changed == true - - result_create_site.response.status == "SUCCESS" - - "'created successfully' in result_create_site.msg" - - result_create_site.response.bapiName == "Create Site" + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" ############################################# -# IDEMPOTENCY CHECK SITE ## +# CREATE SITES # ############################################# -- block: - - - name: Test idempotency by creating area with valid parameters again + - name: Create sites from design_sites config cisco.dnac.site_workflow_manager: - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG + <<: *dnac_login config_verify: true state: merged config: - - site: - area: - name: Abc - parent_name: 'Global' - type: area - register: result_idempotent + - "{{ item }}" + register: result_create_site + loop: "{{ vars_map.design_sites }}" + tags: merged - - name: Assert idempotency of area creation + - name: Assert area creation success for each site assert: that: - - result_idempotent.changed == false - - "'does not need any update' in result_idempotent.msg" + - item.changed == true + - item.response.status == "SUCCESS" + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined ############################################# -# DELETE SITE ## +# DELETE SITES # ############################################# -- block: - - name: Test deleting area with valid parameters + - name: Delete sites from design_sites config cisco.dnac.site_workflow_manager: - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG + <<: *dnac_login config_verify: true state: deleted config: - - site: - area: - name: Abc - parent_name: 'Global' - type: area + - "{{ item }}" register: result_delete_site + loop: "{{ vars_map.delete_sites }}" + tags: deleted - - name: Assert deletion of area success + - name: Assert deletion of area success for each site assert: that: - - result_delete_site.changed == true - - "'deleted successfully' in result_delete_site.response" \ No newline at end of file + - item.changed == true + - item.response.status == "SUCCESS" + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined diff --git a/tests/integration/ccc_site_management/vars/main.yml b/tests/integration/ccc_site_management/vars/main.yml deleted file mode 100644 index 4eb771bf10..0000000000 --- a/tests/integration/ccc_site_management/vars/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# vars file for ccc_site_management From 1645ef99e4c0a5e067898b445a0175d25c742f06 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 22 Feb 2024 09:30:51 -0500 Subject: [PATCH 140/358] modified vars for site tests --- .../vars/vars_site_management.yml | 408 ++++++++++++++++++ 1 file changed, 408 insertions(+) create mode 100644 tests/integration/ccc_site_management/vars/vars_site_management.yml diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml new file mode 100644 index 0000000000..ff891fb86b --- /dev/null +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -0,0 +1,408 @@ +--- +design_sites: + - site: + area: + name: USA + parent_name: Global + type: area + - site: + area: + name: India + parent_name: Global + type: area + - site: + area: + name: Mexico + parent_name: Global + type: area + - site: + area: + name: Canada + parent_name: Global + type: area + - site: + area: + name: SAN JOSE + parent_name: Global/USA + type: area + - site: + area: + name: RTP + parent_name: Global/USA + type: area + - site: + area: + name: BayAreaGuest + parent_name: Global/USA + type: area + - site: + area: + name: Bangalore + parent_name: Global/India + type: area + # - site: + # area: + # name: New York + # parent_name: Global/USA + # type: area + # - site: + # area: + # name: SAN-FRANCISCO + # parent_name: Global/USA + # type: area + # - site: + # area: + # name: BERKELEY + # parent_name: Global/USA + # type: area + - site: + building: + name: Mantri Square + parent_name: Global/India/Bangalore + address: Bengaluru, Karnataka, India + latitude: 12.969910 + longitude: 77.597960 + country: India + type: building + # - site: + # building: + # name: BLD10 + # parent_name: Global/USA/RTP + # address: Ev Chargers Bldg 10, 7200-10 Kit Creek Rd, Morrisville, North Carolina 27560, United States + # latitude: 35.85992111421487 + # longitude: -78.8829258991226 + # country: United States + # type: building + # - site: + # building: + # name: BLD11 + # parent_name: Global/USA/RTP + # address: Cisco Systems, 7200 Kit Creek Rd, Morrisville, North Carolina 27560, United States + # latitude: 35.86059627310624 + # longitude: -78.88105620286412 + # country: United States + # type: building + # - site: + # building: + # name: BLD12 + # parent_name: Global/USA/RTP + # address: Cisco Systems, 7200-12 Kit Creek Rd, Morrisville, North Carolina 27560, United States + # latitude: 35.8611847591779 + # longitude: -78.88217248318003 + # country: United States + # type: building + # - site: + # building: + # name: BLD23 + # parent_name: Global/USA/SAN JOSE + # address: McCarthy Blvd, San Jose, California 95131, United States + # latitude: 37.398188 + # longitude: -121.912974 + # country: United States + # type: building + # - site: + # building: + # name: BLD20 + # parent_name: Global/USA/SAN JOSE + # address: 725 Alder Drive, Milpitas, California 95035, United States + # latitude: 37.415947 + # longitude: -121.916327 + # country: United States + # type: building + # - site: + # building: + # name: BLD_GB + # parent_name: Global/USA/BayAreaGuest + # address: 725 Alder Drive, Milpitas, California 95035, United States + # latitude: 37.415947 + # longitude: -121.916327 + # country: United States + # type: building + # - site: + # building: + # name: BLDNYC + # parent_name: Global/USA/New York + # address: McCarthy Blvd, San Jose, California 95131, United States + # latitude: 37.398188 + # longitude: -121.912974 + # country: United States + # type: building + # - site: + # building: + # name: BLD_SF + # parent_name: Global/USA/SAN-FRANCISCO + # address: McCarthy Blvd, San Jose, California 95131, United States + # latitude: 37.398188 + # longitude: -121.912974 + # country: United States + # type: building + # - site: + # building: + # name: BLD_SF1 + # parent_name: Global/USA/SAN-FRANCISCO + # address: McCarthy Blvd, San Jose, California 95131, United States + # latitude: 37.398188 + # longitude: -121.912974 + # country: United States + # type: building + # - site: + # building: + # name: BLDBERK + # parent_name: Global/USA/BERKELEY + # address: 725 Alder Drive, Milpitas, California 95035, United States + # latitude: 37.415947 + # longitude: -121.916327 + # country: United States + # type: building + # - site: + # floor: + # name: BLD10_FLOOR1 + # parent_name: Global/USA/RTP/BLD10 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + # - site: + # floor: + # name: BLD10_FLOOR2 + # parent_name: Global/USA/RTP/BLD10 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 2 + # type: floor + # - site: + # floor: + # name: BLD10_FLOOR3 + # parent_name: Global/USA/RTP/BLD10 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 3 + # type: floor + # - site: + # floor: + # name: BLD11_FLOOR1 + # parent_name: Global/USA/RTP/BLD11 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + # - site: + # floor: + # name: BLD11_FLOOR2 + # parent_name: Global/USA/RTP/BLD11 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 2 + # type: floor + # - site: + # floor: + # name: BLD11_FLOOR3 + # parent_name: Global/USA/RTP/BLD11 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 3 + # type: floor + # - site: + # floor: + # name: BLD12_FLOOR1 + # parent_name: Global/USA/RTP/BLD12 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + # - site: + # floor: + # name: BLD12_FLOOR2 + # parent_name: Global/USA/RTP/BLD12 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 2 + # type: floor + # - site: + # floor: + # name: BLD12_FLOOR3 + # parent_name: Global/USA/RTP/BLD12 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 3 + # type: floor + # - site: + # floor: + # name: FLOOR1_LEVEL1 + # parent_name: Global/USA/SAN JOSE/BLD23 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + # - site: + # floor: + # name: FLOOR1_LEVEL2 + # parent_name: Global/USA/SAN JOSE/BLD23 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + # - site: + # floor: + # name: FLOOR1_LEVEL3 + # parent_name: Global/USA/SAN JOSE/BLD23 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + # - site: + # floor: + # name: FLOOR1_LEVEL4 + # parent_name: Global/USA/SAN JOSE/BLD23 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + # - site: + # floor: + # name: BLD20_FLOOR1 + # parent_name: Global/USA/SAN JOSE/BLD20 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + # - site: + # floor: + # name: BLD20_FLOOR2 + # parent_name: Global/USA/SAN JOSE/BLD20 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 2 + # type: floor + # - site: + # floor: + # name: FLOOR1 + # parent_name: Global/USA/New York/BLDNYC + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + # - site: + # floor: + # name: FLOOR2 + # parent_name: Global/USA/New York/BLDNYC + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 2 + # type: floor + # - site: + # floor: + # name: FLOOR1 + # parent_name: Global/USA/SAN-FRANCISCO/BLD_SF + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + # - site: + # floor: + # name: FLOOR2 + # parent_name: Global/USA/SAN-FRANCISCO/BLD_SF + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 2 + # type: floor + # - site: + # floor: + # name: FLOOR1 + # parent_name: Global/USA/SAN-FRANCISCO/BLD_SF1 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + # - site: + # floor: + # name: FLOOR2 + # parent_name: Global/USA/SAN-FRANCISCO/BLD_SF1 + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 2 + # type: floor + - site: + floor: + name: Floor1 + parent_name: Global/India/Bangalore/Mantri Square + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + # - site: + # floor: + # name: FLOOR1_LEVEL1 + # parent_name: Global/USA/BERKELEY/BLDBERK + # rf_model: Cubes And Walled Offices + # width: 100.00 + # length: 100.00 + # height: 10.00 + # floor_number: 1 + # type: floor + +delete_sites: + # - site: + # area: + # name: USA + # parent_name: Global + # type: area + - site: + area: + name: India + parent_name: Global + type: area + - site: + area: + name: Mexico + parent_name: Global + type: area + - site: + area: + name: Canada + parent_name: Global + type: area \ No newline at end of file From 817ae98439284b5879a60c12156c8d87155b4a2a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 22 Feb 2024 09:33:09 -0500 Subject: [PATCH 141/358] tests for device_credential module --- .../defaults/main.yml | 5 + .../meta/main.yml | 1 + .../tasks/main.yml | 34 +++ .../tests/test_assign_credentials.yml | 195 ++++++++++++++++++ .../test_device_credential_management.yml | 123 +++++++++++ .../vars/vars_assign_credentials.yml | 59 ++++++ .../vars/vars_credential_management.yml | 102 +++++++++ 7 files changed, 519 insertions(+) create mode 100644 tests/integration/ccc_device_credential_management/defaults/main.yml create mode 100644 tests/integration/ccc_device_credential_management/meta/main.yml create mode 100644 tests/integration/ccc_device_credential_management/tasks/main.yml create mode 100755 tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml create mode 100644 tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml create mode 100755 tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml create mode 100644 tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml diff --git a/tests/integration/ccc_device_credential_management/defaults/main.yml b/tests/integration/ccc_device_credential_management/defaults/main.yml new file mode 100644 index 0000000000..e453cb74ee --- /dev/null +++ b/tests/integration/ccc_device_credential_management/defaults/main.yml @@ -0,0 +1,5 @@ +--- +testcase: "*" + +debug: + msg: "{{ testcase }}" \ No newline at end of file diff --git a/tests/integration/ccc_device_credential_management/meta/main.yml b/tests/integration/ccc_device_credential_management/meta/main.yml new file mode 100644 index 0000000000..5514b6a40c --- /dev/null +++ b/tests/integration/ccc_device_credential_management/meta/main.yml @@ -0,0 +1 @@ +dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_device_credential_management/tasks/main.yml b/tests/integration/ccc_device_credential_management/tasks/main.yml new file mode 100644 index 0000000000..09e0832ca2 --- /dev/null +++ b/tests/integration/ccc_device_credential_management/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: collect ccc test cases + find: + paths: "{{ role_path }}/tests" + patterns: "{{ testcase }}.yml" + connection: local + register: ccc_cases + tags: sanity + +- debug: + msg: "CCC Cases: {{ ccc_cases }}" + +- set_fact: + test_cases: + files: "{{ ccc_cases.files }}" + tags: sanity + +- debug: + msg: "Test Cases: {{ test_cases }}" + +- name: set test_items + set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + tags: sanity + +- debug: + msg: "Test Items: {{ test_items }}" + +- name: run test cases (connection=httpapi) + include_tasks: "{{ test_case_to_run }}" + loop: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml new file mode 100755 index 0000000000..2e7de449be --- /dev/null +++ b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml @@ -0,0 +1,195 @@ +--- +- debug: msg="Starting device credential assign management test" +- debug: msg="Role Path {{ role_path }}" + +- block: + - name: Load device credentials from ccc_device_credential_management role and declare dnac vars + include_vars: + file: "{{ role_path }}/vars/vars_assign_credentials.yml" + name: vars_map + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + + - debug: + msg: "{{ vars_map.credentials_details }}" + - debug: + msg: "{{ vars_map.design_sites }}" + +############################################# +# Pre Tests Clean Up # +############################################# + - name: Clean up site before test + cisco.dnac.site_workflow_manager: + <<: *dnac_login + config_verify: true + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.design_sites }}" + + - name: Clean up device credentials before test + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config_verify: True + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + +############################################# +# CREATE SITE # +############################################# + + - name: Create sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + config_verify: true + state: merged + config: + - "{{ item }}" + register: result_create_site + loop: "{{ vars_map.design_sites }}" + tags: merged + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + + - name: Assert area creation success for each site + assert: + that: + - item.changed == true + - item.response.status == "SUCCESS" + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined + +############################################# +# Create Credentials # +############################################# + - name: Create Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config_verify: True + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: merged + register: result_create_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_credentials.results }}" + # when: result_create_credentials is defined + + - name: Assert Device Credential Creation + assert: + that: + - item.changed == true + - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_create_credentials.results }}" + when: result_create_credentials is defined + +############################################# +# Assign Credentials to site # +############################################# + - name: Assign Credentials to design_sites + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config_verify: True + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_assign }}" + tags: assign + register: result_assign_credentials + + - name: Debug item + debug: + var: item + loop: "{{ result_create_credentials.results }}" + when: result_assign_credentials is defined + + # - name: Assert Credentials to sites + # assert: + # that: + # - item.changed == true + # - item.response.status == "success" + # - "'assigned Successfully' in item.msg" + # loop: "{{ result_assign_credentials.results }}" + # when: result_assign_credentials is defined + + +############################################# +# DELETE SITE # +############################################# + + + - name: Delete site from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + config_verify: true + state: deleted + config: + - "{{ item }}" + register: result_delete_site + loop: "{{ vars_map.design_sites }}" + tags: deleted + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined + + - name: Assert deletion of area success for each site + assert: + that: + - item.changed == true + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined + +############################################# +# Delete Credentials # +############################################# + - name: Delete Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config_verify: True + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: deleted + register: result_delete_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_credentials.results }}" + # when: result_delete_credentials is defined + + - name: Assert Global Credential Deletion + assert: + that: + - item.changed == true + - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_delete_credentials.results }}" + when: result_delete_credentials is defined + diff --git a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml new file mode 100644 index 0000000000..35a3d400f2 --- /dev/null +++ b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml @@ -0,0 +1,123 @@ +--- +- debug: msg="Starting device credential management test" +- debug: msg="Role Path {{ role_path }}" + +- block: + - name: Load device credentials from ccc_device_credential_management role and declare dnac vars + include_vars: + file: "{{ role_path }}/vars/vars_credential_management.yml" + name: vars_map + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + + # - debug: + # msg: "{{ vars_map.credentials_details }}" + +############################################# +# Pre Tests Clean Up # +############################################# + - name: Clean up device credentials before test + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config_verify: True + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + + +############################################# +# Create Credentials # +############################################# + - name: Create Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config_verify: True + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: merged + register: result_create_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_credentials.results }}" + # when: result_create_credentials is defined + + - name: Assert Device Credential Creation + assert: + that: + - item.changed == true + - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_create_credentials.results }}" + when: result_create_credentials is defined + +############################################# +# Update Credentials # +############################################# + - name: Update Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config_verify: True + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_update }}" + tags: update + register: result_update_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_credentials.results }}" + # when: result_update_credentials is defined + + - name: Assert Global Credential Update + assert: + that: + - item.changed == true + - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_update_credentials.results }}" + when: result_update_credentials is defined + +############################################# +# Delete Credentials # +############################################# + - name: Delete Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config_verify: True + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: deleted + register: result_delete_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_credentials.results }}" + # when: result_delete_credentials is defined + + - name: Assert Global Credential Deletion + assert: + that: + - item.changed == true + - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_delete_credentials.results }}" + when: result_delete_credentials is defined diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml new file mode 100755 index 0000000000..26da0294b9 --- /dev/null +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -0,0 +1,59 @@ +--- +design_sites: + - site: + area: + name: TEST_SITE_DEVICE_CREDENTIALS + parent_name: 'Global' + type: area + +credentials_details: #Create multiple credentials for the same protocol + - global_credential_details: + cli_credential: + - description: CLIAssign + username: cli-A + password: "5!meh" + enable_password: "q4^t^" + snmp_v2c_read: + - description: SNMPv2cRead Test Assign + read_community: "j5aj#0z%" + snmp_v2c_write: + - description: SNMPv2cWrite Test Assign + write_community: "n2!y9k38" + snmp_v3: + - description: SNMPv3 Test Assign + auth_password: "hp!x6px&#@2xi5" + auth_type: SHA + snmp_mode: AUTHPRIV + privacy_password: "ai7tpci3j@*j5g" + privacy_type: AES128 + username: admin + https_read: + - description: httpsRead Test Assign + username: admin + password: "2!x85yvqz*7" + port: 443 + https_write: + - description: httpsWrite Test Assign + username: admin + password: "j@5wgm%s5g%" + port: 443 + +credentials_assign: + - assign_credentials_to_site: # Assign device credentials to sites + cli_credential: + description: CLIAssign + username: cli-A + snmp_v2c_read: + description: SNMPv2cRead Test Assign + snmp_v2c_write: + description: SNMPv2cWrite Test Assign + snmp_v3: + description: SNMPv3 Test Assign + https_read: + username: admin + description: httpsRead Test Assign + https_write: + username: admin + description: httpsWrite Test Assign + site_name: + - Global/TEST_SITE_DEVICE_CREDENTIALS \ No newline at end of file diff --git a/tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml b/tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml new file mode 100644 index 0000000000..8ac38544b4 --- /dev/null +++ b/tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml @@ -0,0 +1,102 @@ +--- +credentials_details: #Create multiple credentials for the same protocol + - global_credential_details: + cli_credential: + - description: CLI1 + username: cli-1 + password: "5!meh" + enable_password: "q4^t^" + - description: CLI2 + username: cli-2 + password: "sbs2@" + enable_password: "8b!rn" + - description: CLI3 + username: cli-3 + password: "9%2&g" + enable_password: "9%%4b" + snmp_v2c_read: + - description: SNMPv2cRead Test 1 + read_community: "j5aj#8z%" + - description: SNMPv2cRead Test 2 + read_community: "m!ivyd%4" + - description: SNMPv2cRead Test 3 + read_community: "8hzx4$xw" + snmp_v2c_write: + - description: SNMPv2cWrite Test 1 + write_community: "n2@k8k38" + - description: SNMPv2cWrite Test 2 + write_community: "@&*46me5" + - description: SNMPv2cWrite Test 3 + write_community: "q@s$hl2!" + snmp_v3: + - description: SNMPv3 Test 1 + auth_password: "hp!x6px&#@2xi5" + auth_type: SHA + snmp_mode: AUTHPRIV + privacy_password: "ai7tpci3j@*j5g" + privacy_type: AES128 + username: admin + - description: SNMPv3 Test 2 + auth_password: "pnf$b73g**@j99" + auth_type: SHA + snmp_mode: AUTHPRIV + privacy_password: "gadcr!w!up7" + privacy_type: AES128 + username: admin + - description: SNMPv3 Test 3 + auth_password: "fgn8v#rj#y6" + auth_type: SHA + snmp_mode: AUTHPRIV + privacy_password: "q#nk^u$oy58" + privacy_type: AES128 + username: admin + https_read: + - description: httpsRead Test 1 + username: admin + password: "2!x89yvzz*7" + port: 443 + - description: httpsRead Test 2 + username: admin + password: "67q!bsnm*#o" + port: 443 + - description: httpsRead Test 3 + username: admin + password: "97w!fwy85#b" + port: 443 + https_write: + - description: httpsWrite Test 1 + username: admin + password: "j@8wgm%s2z%" + port: 443 + +credentials_update: + - global_credential_details: + cli_credential: + - description: CLI1 + username: cli-1 + password: "r*55*z8d2%6" + enable_password: "3^p@9*84nen" + snmp_v2c_read: + - description: SNMPv2cRead Test 1 + read_community: "mwn&k&$g%8g" + snmpV2cWrite: + - description: SNMPv2cWrite Test 1 + write_community: "n&9c3csirhu" + snmpV3: + - description: SNMPv3 Test 1 + auth_password: "j$4@2%2wgrv6f3z" + auth_type: SHA + snmp_mode: AUTHNOPRIV + privacy_password: "muqzks@3y$fco#w" + privacy_type: AES192 + username: admin + https_read: + - description: httpsRead Test 1 + username: admin + password: "2xg%iqt&fu@d6mh" + port: 443 + https_write: + - description: httpsWrite Test 1 + username: admin + password: "*#s&n2r9x$s@i8@" + port: 443 \ No newline at end of file From 91a9c9e0b16c4fdef5b7b72e24cf517c7f00ee84 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 28 Feb 2024 15:30:59 -0500 Subject: [PATCH 142/358] added network_settings, discovery, inventory modules --- .../tests/test_assign_credentials.yml | 2 +- .../test_device_credential_management.yml | 2 +- .../defaults/main.yml | 2 + .../ccc_discovery_management/meta/main.yml | 1 + .../ccc_discovery_management/tasks/main.yml | 34 ++ .../tests/test_discovery_management.yml | 297 +++++++++++++++ .../vars/vars_delete_discoveries.yml | 14 + .../vars/vars_discovery_management.yml | 163 ++++++++ .../defaults/main.yml | 2 + .../ccc_inventory_management/meta/main.yml | 1 + .../ccc_inventory_management/tasks/main.yml | 34 ++ .../tests/test_inventory_management.yml | 358 ++++++++++++++++++ .../vars/vars_inventory_management.yml | 226 +++++++++++ .../defaults/main.yml | 2 + .../meta/main.yml | 1 + .../tasks/main.yml | 34 ++ .../tests/test.yml | 178 +++++++++ .../vars/main.yml | 7 + .../tests/test_site_management.yml | 25 +- 19 files changed, 1373 insertions(+), 10 deletions(-) create mode 100644 tests/integration/ccc_discovery_management/defaults/main.yml create mode 100644 tests/integration/ccc_discovery_management/meta/main.yml create mode 100644 tests/integration/ccc_discovery_management/tasks/main.yml create mode 100644 tests/integration/ccc_discovery_management/tests/test_discovery_management.yml create mode 100755 tests/integration/ccc_discovery_management/vars/vars_delete_discoveries.yml create mode 100644 tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml create mode 100644 tests/integration/ccc_inventory_management/defaults/main.yml create mode 100644 tests/integration/ccc_inventory_management/meta/main.yml create mode 100644 tests/integration/ccc_inventory_management/tasks/main.yml create mode 100644 tests/integration/ccc_inventory_management/tests/test_inventory_management.yml create mode 100644 tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml create mode 100644 tests/integration/ccc_network_settings_management/defaults/main.yml create mode 100644 tests/integration/ccc_network_settings_management/meta/main.yml create mode 100644 tests/integration/ccc_network_settings_management/tasks/main.yml create mode 100644 tests/integration/ccc_network_settings_management/tests/test.yml create mode 100644 tests/integration/ccc_network_settings_management/vars/main.yml diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml index 2e7de449be..81ed0928e5 100755 --- a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml @@ -3,7 +3,7 @@ - debug: msg="Role Path {{ role_path }}" - block: - - name: Load device credentials from ccc_device_credential_management role and declare dnac vars + - name: Load vars and declare dnac vars include_vars: file: "{{ role_path }}/vars/vars_assign_credentials.yml" name: vars_map diff --git a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml index 35a3d400f2..0982f50434 100644 --- a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml @@ -3,7 +3,7 @@ - debug: msg="Role Path {{ role_path }}" - block: - - name: Load device credentials from ccc_device_credential_management role and declare dnac vars + - name: Load vars and declare dnac vars include_vars: file: "{{ role_path }}/vars/vars_credential_management.yml" name: vars_map diff --git a/tests/integration/ccc_discovery_management/defaults/main.yml b/tests/integration/ccc_discovery_management/defaults/main.yml new file mode 100644 index 0000000000..55a93fc23d --- /dev/null +++ b/tests/integration/ccc_discovery_management/defaults/main.yml @@ -0,0 +1,2 @@ +--- +testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_discovery_management/meta/main.yml b/tests/integration/ccc_discovery_management/meta/main.yml new file mode 100644 index 0000000000..5514b6a40c --- /dev/null +++ b/tests/integration/ccc_discovery_management/meta/main.yml @@ -0,0 +1 @@ +dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_discovery_management/tasks/main.yml b/tests/integration/ccc_discovery_management/tasks/main.yml new file mode 100644 index 0000000000..09e0832ca2 --- /dev/null +++ b/tests/integration/ccc_discovery_management/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: collect ccc test cases + find: + paths: "{{ role_path }}/tests" + patterns: "{{ testcase }}.yml" + connection: local + register: ccc_cases + tags: sanity + +- debug: + msg: "CCC Cases: {{ ccc_cases }}" + +- set_fact: + test_cases: + files: "{{ ccc_cases.files }}" + tags: sanity + +- debug: + msg: "Test Cases: {{ test_cases }}" + +- name: set test_items + set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + tags: sanity + +- debug: + msg: "Test Items: {{ test_items }}" + +- name: run test cases (connection=httpapi) + include_tasks: "{{ test_case_to_run }}" + loop: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml new file mode 100644 index 0000000000..72382d49f5 --- /dev/null +++ b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml @@ -0,0 +1,297 @@ +--- +- debug: msg="Starting discovery management test" +- debug: msg="Role Path {{ role_path }}" + +- block: + - name: Load vars and declare dnac vars + include_vars: + file: "{{ role_path }}/vars/vars_discovery_management.yml" + name: vars_map + + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + + - name: Clean up vars + include_vars: + file: "{{ role_path }}/vars/vars_delete_discoveries.yml" + name: vars_map_delete + + - debug: + msg: "{{ vars_map.single_ip }}" + - debug: + msg: "{{ vars_map.ip_range }}" + - debug: + msg: "{{ vars_map.multi_range }}" + - debug: + msg: "{{ vars_map.cdp }}" + - debug: + msg: "{{ vars_map.lldp }}" + - debug: + msg: "{{ vars_map.cidr }}" + +############################################# +# Pre Tests Clean Up # +############################################# + - name: Delete all discovery + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + config_verify: True + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map_delete.delete_discoveries }}" + +############################################# +# Create Single IP Address Discovery # +############################################# + +# - name: Discover a single IP Address +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.single_ip }}" +# register: result_singleip_discovery + +# - name: Debug item +# debug: +# var: result_singleip_discovery + +# - name: Check single IP discovery creation +# assert: +# that: +# - result_singleip_discovery.changed == true +# - "'Discovery Created Successfully' in result_singleip_discovery.results | map(attribute='msg') | list" +# when: result_singleip_discovery is defined + +# ############################################# +# # Create Range IP Address Discovery # +# ############################################# + +# - name: Discover an IP Address Range +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.ip_range }}" +# register: result_ip_range_discovery + +# - name: Debug item +# debug: +# var: result_ip_range_discovery + +# - name: Check IP address range discovery creation +# assert: +# that: +# - result_ip_range_discovery.changed == true +# - "'Discovery Created Successfully' in result_ip_range_discovery.results | map(attribute='msg') | list" +# when: result_ip_range_discovery is defined + +# ############################################# +# # Create Multi Range IP Address Discovery # +# ############################################# + +# - name: Discover Multi IP Address Ranges +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.multi_range }}" +# register: result_multi_range_discovery + +# - name: Debug item +# debug: +# var: result_multi_range_discovery + +# - name: Check multi range IP address discovery creation +# assert: +# that: +# - result_multi_range_discovery.changed == true +# - "'Discovery Created Successfully' in result_multi_range_discovery.results | map(attribute='msg') | list" +# when: result_multi_range_discovery is defined + + +# ############################################# +# # Create Discovery using CDP # +# ############################################# + +# - name: Discover using CDP +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.cdp }}" +# register: result_cdp_discovery + +# - name: Debug item +# debug: +# var: result_cdp_discovery + +# - name: Check CDP discovery creation +# assert: +# that: +# - result_cdp_discovery.changed == true +# - "'Discovery Created Successfully' in result_cdp_discovery.results | map(attribute='msg') | list" +# when: result_cdp_discovery is defined + +# ############################################# +# # Create Discovery using LLDP # +# ############################################# + +# - name: Discover using LLDP +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.lldp }}" +# register: result_lldp_discovery + +# - name: Debug item +# debug: +# var: result_lldp_discovery + +# - name: Check LLDP discovery creation +# assert: +# that: +# - result_lldp_discovery.changed == true +# - "'Discovery Created Successfully' in result_lldp_discovery.results | map(attribute='msg') | list" +# when: result_lldp_discovery is defined + +# ############################################# +# # Create Discovery using CIDR # +# ############################################# + +# - name: Discover using CIDR +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.cidr }}" +# register: result_cidr_discovery + +# - name: Debug item +# debug: +# var: result_cidr_discovery + +# - name: Check CIDR discovery creation +# assert: +# that: +# - result_cidr_discovery.changed == true +# - "'Discovery Created Successfully' in result_cidr_discovery.results | map(attribute='msg') | list" +# when: result_cidr_discovery is defined + +# ############################################# +# # Create Multiple Discoveries # +# ############################################# + +# - name: Add new item with "preferred_mgmt_ip_method" +# set_fact: +# vars_map_preferred_mgmt: {} + +# - name: Add preferred_mgmt_ip_method to vars_map_preferred_mgmt +# set_fact: +# vars_map_preferred_mgmt: "{{ vars_map_preferred_mgmt | combine({item + '_preferred_mgmt': vars_map[item] | map('combine', {'preferred_mgmt_ip_method': 'UseLoopBack'}) | map('combine', {'discovery_name': vars_map[item][0]['discovery_name'] + ' - preferred_mgmt' }) | list}) }}" +# loop: "{{ vars_map.keys() }}" +# tags: multiple_discoveries + +# - name: Set vars_map_multiple +# set_fact: +# vars_map_multiple: "{{ vars_map | combine(vars_map_preferred_mgmt) }}" +# tags: multiple_discoveries + +# - name: Print the updated vars_map_multiple +# debug: +# var: vars_map_multiple +# tags: multiple_discoveries + +# - name: Create multiple Discoveries +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ vars_map_multiple[item][0] }}" +# with_items: "{{ vars_map_multiple }}" +# tags: multiple_discoveries +# register: result_multiple_discoveries + +# - name: Debug item +# debug: +# var: result_multiple_discoveries +# when: result_multiple_discoveries is defined + +# - name: Check if multiple discoveries were successfull +# assert: +# that: +# - item.changed == true +# - "'Discovery Created Successfully' in item.msg" +# loop: "{{ result_multiple_discoveries.results }}" +# when: result_multiple_discoveries is defined + +# ############################################# +# # Delete Discovery by name # +# ############################################# + +# - name: Delete all discovery +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map_delete.delete_discoveries }}" +# register: result_delete_discoveries + +# - name: Debug item +# debug: +# var: item +# loop: "{{ result_delete_discoveries.results }}" + +# - name: Check if discovery was successfully deleted +# assert: +# that: +# - item.changed == true +# - "'Successfully deleted discovery' in item.msg" +# loop: "{{ result_delete_discoveries.results }}" +# when: result_delete_discoveries is defined + +# ############################################ +# # Delete ALL Discovery # +# ############################################# + +# # - name: Delete all discovery +# # cisco.dnac.discovery_workflow_manager: +# # <<: *dnac_login +# # state: deleted +# # config_verify: True +# # config: +# # - delete_all: True +# # register: result_delete_all + +# # - name: Debug item +# # debug: +# # var: result_delete_all +# # when: result_delete_all is defined + + diff --git a/tests/integration/ccc_discovery_management/vars/vars_delete_discoveries.yml b/tests/integration/ccc_discovery_management/vars/vars_delete_discoveries.yml new file mode 100755 index 0000000000..c732b7d402 --- /dev/null +++ b/tests/integration/ccc_discovery_management/vars/vars_delete_discoveries.yml @@ -0,0 +1,14 @@ +--- +delete_discoveries: + - discovery_name: Single IP Discovery + - discovery_name: Single Range Discovery 1 + - discovery_name: Multi Range Discovery + - discovery_name: CDP Discovery + - discovery_name: LLDP Discovery + - discovery_name: CIDR Discovery + - discovery_name: Single IP Discovery - preferred_mgmt + - discovery_name: Single Range Discovery 1 - preferred_mgmt + - discovery_name: Multi Range Discovery - preferred_mgmt + - discovery_name: CDP Discovery - preferred_mgmt + - discovery_name: LLDP Discovery - preferred_mgmt + - discovery_name: CIDR Discovery - preferred_mgmt \ No newline at end of file diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml new file mode 100644 index 0000000000..791e2e3ff6 --- /dev/null +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -0,0 +1,163 @@ +--- +single_ip: + - discovery_name: Single IP Discovery + discovery_type: "SINGLE" + ip_address_list: + - 204.1.2.5 + protocol_order: ssh + discovery_specific_credentials: + cli_credentials_list: + - username: cisco + password: Cisco#123 + enable_password: Cisco#123 + http_read_credential: + username: string + password: Lablab#123 + port: 443 + secure: True + snmp_v2_read_credential: + desc: string + community: string + snmp_v2_write_credential: + desc: string + community: string + snmp_v3_credential: + username: v3Public2 + snmp_mode: AUTHPRIV + auth_type: SHA + auth_password: Lablab#1234 + privacy_type: AES256 + privacy_password: Lablab#1234 + global_cli_len: 3 + +ip_range: + - discovery_name: Single Range Discovery 1 + discovery_type: "RANGE" + ip_address_list: + - 204.1.2.1-204.1.2.5 + ip_filter_list: + - 204.1.2.3 + protocol_order: ssh + discovery_specific_credentials: + cli_credentials_list: + - username: cisco + password: Cisco#123 + enable_password: Cisco#123 + snmp_v3_credential: + username: v3Public2 + snmp_mode: AUTHPRIV + auth_type: SHA + auth_password: Lablab#1234 + privacy_type: AES256 + privacy_password: Lablab#1234 + + # Single IP Discovery an already existing discovery + # Test case - deleted and recreated when discovery with same name + - discovery_name: Single IP Discovery + discovery_type: "RANGE" + ip_address_list: + - 204.1.2.3 + protocol_order: ssh + discovery_specific_credentials: + cli_credentials_list: + - username: cisco + password: Cisco#123 + enable_password: Cisco#123 + snmp_v3_credential: + username: v3Phan + snmp_mode: AUTHPRIV + auth_type: SHA + auth_password: Cisco#123456789 + privacy_type: AES128 + privacy_password: Cisco#1234567890 + +multi_range: + - discovery_name: Multi Range Discovery + discovery_type: "MULTI RANGE" + ip_address_list: + - 204.1.2.1-204.1.2.5 + - 204.192.3.40 + - 204.192.4.200 + - 204.1.2.6 + - 204.1.2.7 + - 204.1.2.8 + - 204.1.2.9 + - 204.1.2.10 + - 204.1.2.11 + ip_filter_list: + - 204.1.2.3 + protocol_order: ssh + discovery_specific_credentials: + cli_credentials_list: + - username: cisco + password: Cisco#123 + enable_password: Cisco#123 + snmp_v3_credential: + username: v3Public2 + snmp_mode: AUTHPRIV + auth_type: SHA + auth_password: Lablab#1234 + privacy_type: AES256 + privacy_password: Lablab#1234 + +cdp: + - discovery_name: CDP Discovery + discovery_type: "CDP" + ip_address_list: + - 204.1.2.1 + cdp_level: 1 + protocol_order: ssh + discovery_specific_credentials: + cli_credentials_list: + - username: cisco + password: Cisco#123 + enable_password: Cisco#123 + snmp_v3_credential: + username: v3Public2 + snmp_mode: AUTHPRIV + auth_type: SHA + auth_password: Lablab#1234 + privacy_type: AES256 + privacy_password: Lablab#1234 + +lldp: + - discovery_name: LLDP Discovery + discovery_type: "LLDP" + ip_address_list: + - 204.1.2.1 + lldp_level: 16 + protocol_order: ssh + + discovery_specific_credentials: + cli_credentials_list: + - username: cisco + password: Cisco#123 + enable_password: Cisco#123 + snmp_v3_credential: + username: v3Public2 + snmp_mode: AUTHPRIV + auth_type: SHA + auth_password: Lablab#1234 + privacy_type: AES256 + privacy_password: Lablab#1234 + +cidr: + - discovery_name: CIDR Discovery + discovery_type: "CIDR" + ip_address_list: + - 204.1.2.0/24 + prefix_length: 30 + protocol_order: ssh + + discovery_specific_credentials: + cli_credentials_list: + - username: cisco + password: Cisco#123 + enable_password: Cisco#123 + snmp_v3_credential: + username: v3Public2 + snmp_mode: AUTHPRIV + auth_type: SHA + auth_password: Lablab#1234 + privacy_type: AES256 + privacy_password: Lablab#1234 diff --git a/tests/integration/ccc_inventory_management/defaults/main.yml b/tests/integration/ccc_inventory_management/defaults/main.yml new file mode 100644 index 0000000000..55a93fc23d --- /dev/null +++ b/tests/integration/ccc_inventory_management/defaults/main.yml @@ -0,0 +1,2 @@ +--- +testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_inventory_management/meta/main.yml b/tests/integration/ccc_inventory_management/meta/main.yml new file mode 100644 index 0000000000..5514b6a40c --- /dev/null +++ b/tests/integration/ccc_inventory_management/meta/main.yml @@ -0,0 +1 @@ +dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_inventory_management/tasks/main.yml b/tests/integration/ccc_inventory_management/tasks/main.yml new file mode 100644 index 0000000000..09e0832ca2 --- /dev/null +++ b/tests/integration/ccc_inventory_management/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: collect ccc test cases + find: + paths: "{{ role_path }}/tests" + patterns: "{{ testcase }}.yml" + connection: local + register: ccc_cases + tags: sanity + +- debug: + msg: "CCC Cases: {{ ccc_cases }}" + +- set_fact: + test_cases: + files: "{{ ccc_cases.files }}" + tags: sanity + +- debug: + msg: "Test Cases: {{ test_cases }}" + +- name: set test_items + set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + tags: sanity + +- debug: + msg: "Test Items: {{ test_items }}" + +- name: run test cases (connection=httpapi) + include_tasks: "{{ test_case_to_run }}" + loop: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml new file mode 100644 index 0000000000..c5c377302f --- /dev/null +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -0,0 +1,358 @@ +--- +- debug: msg="Starting inventory management test" +- debug: msg="Role Path {{ role_path }}" + +- block: + - name: Load design_sites from ccc_site_management role and declare dnac vars + include_vars: + file: "{{ role_path }}/vars/vars_inventory_management.yml" + name: vars_map + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + + # - debug: + # msg: "{{ vars_map.device_details }}" + # - debug: + # msg: "{{ vars_map.device_credential_updates }}" + # - debug: + # msg: "{{ vars_map.device_interface_updates }}" + # - debug: + # msg: "{{ vars_map.delete_devices }}" + +############################################# +# Clean Up # +############################################# + + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + - name: Debug item + debug: + var: item + loop: "{{ result_device_deleted.results }}" + when: result_device_deleted is defined + +############################################# +# Add Devices # +############################################# + + - name: Add new device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + config_verify: true + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_details }}" + register: result_add_device + + - name: Debug item + debug: + var: item + loop: "{{ result_add_device.results }}" + + - name: Assert device addition success + assert: + that: + - item.changed == true + - "'added to Cisco Catalyst Center' in item.msg" + loop: "{{ result_add_device.results }}" + when: result_add_device is defined + +############################################# +# Update Device Credential Details # +############################################# + + # - name: Update device details + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_credential_updates }}" + # register: result_update_device_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_credentials.results }}" + # when: result_update_device_credentials is defined + + # - name: Assert update + # assert: + # that: + # - item.changed == true + # loop: "{{ result_update_device_credentials.results }}" + # when: result_update_device_credentials is defined + +############################################# +# Update Device Interface Detials # +############################################# + + # - name: Update device interface details + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_interface_updates }}" + # register: result_update_device_interface + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + + # - name: Assert update + # assert: + # that: + # - item.changed == true + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + +############################################# +# Update Device Role Detials # +############################################# + + # - name: Update device role details + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_role_updates }}" + # register: result_update_device_role + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_role.results }}" + # when: result_update_device_role is defined + + # - name: Assert device role update + # assert: + # that: + # - result_update_device_role.changed == true + # - "'Device role was successfully updated' in item.response.progress" + # loop: "{{ result_update_device_role.results }}" + # when: result_update_device_role is defined + +############################################# +# Update Device Interface Description # +############################################# + + # - name: Update device interface description post changing role to non-access + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_int_update_post_rolechange }}" + # register: result_update_device_interface + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + + # - name: Assert update + # assert: + # that: + # - item.changed == true + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + +############################################# +# Resync Device # +############################################# + + # - name: Update device role details + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_resync }}" + # register: result_resync_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_resync_device.results }}" + # when: result_resync_device is defined + + # - name: Assert device resync + # assert: + # that: + # - result_resync_device.changed == true + # - "'Synced devices' in item.response.progress" + # loop: "{{ result_resync_device.results }}" + # when: result_resync_device is defined + +############################################# +# Create & Assign User Defined Field # +############################################# + + # - name: Create & Assign user defined field + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.create_assign_udf }}" + # register: result_create_assign_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_assign_udf.results }}" + # when: result_create_assign_udf is defined + + # - name: Assert user defined field creation and assignment + # assert: + # that: + # - item.changed == true + # loop: "{{ result_create_assign_udf.results }}" + # when: result_create_assign_udf is defined + +############################################# +# Update User Defined Field # +############################################# + + # - name: Updateuser defined field + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.update_udf }}" + # register: result_update_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_assign_udf.results }}" + # when: result_update_udf is defined + + # - name: Assert user defined field updated + # assert: + # that: + # - item.changed == true + # loop: "{{ result_update_udf.results }}" + # when: result_update_udf is defined + + +############################################# +# Delete User Defined Field # +############################################# + + # - name: Delete user defined field + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: deleted + # config: + # - "{{ item }}" + # loop: "{{ vars_map.delete_udf }}" + # register: result_delete_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_udf.results }}" + # when: result_delete_udf is defined + + # - name: Assert user defined field deletion + # assert: + # that: + # - result_delete_udf.changed == true + # - "'deleted successfully' in item.response.progress" + # loop: "{{ result_delete_udf.results }}" + # when: result_delete_udf is defined + + +############################################# +# Export Device Details # +############################################# + # - name: Export Device Details in a CSV file + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.export_device_details }}" + # register: result_export_details + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_export_details.results }}" + # when: result_export_details is defined + + # - name: Assert device details export + # assert: + # that: + # - item.changed == true + # loop: "{{ result_export_details.results }}" + # when: result_export_details is defined + +############################################# +# Export Device Credential Details # +############################################# + - name: Export Credential Device Details in a CSV file + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.export_credential_details }}" + register: result_export_credential_details + + - name: Debug item + debug: + var: item + loop: "{{ result_export_credential_details.results }}" + when: result_export_credential_details is defined + +# ############################################# +# # Delete Devices # +# ############################################# + +# - name: Delete device +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_devices }}" +# register: result_device_deleted + +# - name: Debug item +# debug: +# var: item +# loop: "{{ result_device_deleted.results }}" +# when: result_device_deleted is defined + +# - name: Assert device deletion success +# assert: +# that: +# - result_device_deleted.changed == true +# - "'successfully deleted from Cisco Catalyst Center' in result_device_deleted.msg" +# when: result_device_deleted is defined + diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml new file mode 100644 index 0000000000..36f7f7ee13 --- /dev/null +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -0,0 +1,226 @@ +--- +device_details: + # - type: "NETWORK_DEVICE" + # ip_address: ["204.1.2.5"] + # device_added: True + # # CLI Credentials + # username: "cisco" + # password: "Cisco#123" + # enable_password: "Cisco#123" + # # SNMP Credentials + # snmp_version: v3 + # snmp_username: "v3Public2" + # snmp_mode: "AUTHPRIV" + # snmp_auth_protocol: "SHA" + # snmp_auth_passphrase: "Lablab#1234" + # snmp_priv_protocol: "CISCOAES256" + # snmp_priv_passphrase: "Lablab#1234" + # #SNMP Retry and Timeout + # snmp_retry: 3 + # snmp_timeout: 5 + # #CLI Transport (ssh, Telnet) + # cli_transport: "ssh" + # netconf_port: 830 + + - type: "NETWORK_DEVICE" + ip_address: ["204.192.6.200"] + device_added: True + # CLI Credentials + username: "cisco" + password: "Cisco#123" + enable_password: "Cisco#123" + # HTTP Credentials + http_username: "wlcaccess" + http_password: "Lablab#123" + http_port: "443" + http_secure: False + # SNMP Credentials + snmp_version: v3 + snmp_username: "v3Public2" + snmp_mode: "AUTHPRIV" + snmp_auth_protocol: "SHA" + snmp_auth_passphrase: "Lablab#1234" + snmp_priv_protocol: "CISCOAES256" + snmp_priv_passphrase: "Lablab#1234" + #SNMP Retry and Timeout + snmp_retry: 3 + snmp_timeout: 5 + #CLI Transport (ssh, Telnet) + cli_transport: "ssh" + netconf_port: 830 + +device_credential_updates: + # Update CLI password + - type: "NETWORK_DEVICE" + ip_address: ["204.1.2.5"] + device_updated: True + credential_update: True + # CLI Credentials + password: "Cisco#1234" + + + # Update SNMP privacy type + - type: "NETWORK_DEVICE" + ip_address: ["204.1.2.5"] + device_updated: True + credential_update: True + # SNMP Credentials + snmp_priv_protocol: "AES192" + + + # Update SNMP username + - type: "NETWORK_DEVICE" + ip_address: ["204.1.2.5"] + device_updated: True + credential_update: True + # SNMP Credentials + snmp_username: "v3Public2-2" + + + # Update SNMP mode + - type: "NETWORK_DEVICE" + ip_address: ["204.1.2.5"] + device_updated: True + credential_update: True + # SNMP Credentials + snmp_version: v3 + snmp_mode: "NOAUTHNOPRIV" + + # Update cli_transport + - type: "NETWORK_DEVICE" + ip_address: ["204.1.2.5"] + device_updated: True + credential_update: True + #change cli_transport from ssh to telnet + cli_transport: telnet + + # Reverse changes + - type: "NETWORK_DEVICE" + ip_address: ["204.1.2.5"] + device_updated: True + credential_update: True + # CLI Credentials + username: "cisco" + password: "Cisco#123" + enable_password: "Cisco#123" + # SNMP Credentials + snmp_version: v3 + snmp_username: "v3Public2" + snmp_mode: "AUTHPRIV" + snmp_auth_protocol: "SHA" + snmp_auth_passphrase: "Lablab#1234" + snmp_priv_protocol: "CISCOAES256" + snmp_priv_passphrase: "Lablab#1234" + #CLI Transport (ssh, Telnet) + cli_transport: "ssh" + netconf_port: 830 + + +device_interface_updates: + # Update Interface Details + - ip_address: ["204.1.2.5"] + device_updated: True + # Interface details + update_interface_details: + interface_name: ["GigabitEthernet1/0/8"] + description: "Testing for updating interface details" + vlan_id: 23 + voice_vlan_id: 45 + admin_status: "UP" + + # # Update Interface Details + # - ip_address: ["204.1.2.5"] + # device_updated: True + # # Interface details + # update_interface_details: + # interface_name: ["GigabitEthernet1/0/11"] + # description: "Testing for updating interface details" + # admin_status: "UP" #not a paramter accepted by update_interface_details + # vlan_id: 23 + # voice_vlan_id: 45 + # deployment_mode: "Deploy" + + # Update Interface Details + # - ip_address: ["204.1.2.5"] + # device_updated: True + # # Interface details + # interface_name: ["GigabitEthernet1/0/11"] + # description: "Testing for updating interface details" + # admin_status: "UP" + # vlan_id: 23 + # voice_vlan_id: 45 + # deployment_mode: "Deploy" + +device_role_updates: + #Update role from access to core + - ip_address: ["204.1.2.5"] + device_updated: True + # Role details + update_device_role: + role: CORE + +device_int_update_post_rolechange: + # Update Interface description + - ip_address: ["204.1.2.5"] + device_updated: True + # Interface details + interface_name: ["GigabitEthernet1/0/23"] + description: "Testing for updating interface description post changing role" + + # - ip_address: ["204.1.2.5"] + # device_updated: True + # # Interface detail + # update_interface_details: + # interface_name: ["GigabitEthernet1/0/1"] + # description: "Testing for updating interface details" + +device_resync: + # Resync the device + - ip_address: ["204.1.2.5"] + device_resync: True + force_sync: False + +create_assign_udf: + - ip_address: ["204.1.2.5"] + add_user_defined_field: + - name: Test123 + description: "Added first udf for testing" + value: "value123" + - name: Test321 + description: "Added second udf for testing" + value: "value321" + +update_udf: + - ip_address: ["204.1.2.5"] + add_user_defined_field: + - name: Test123 + description: "modified first udf for testing" + value: "value124" + - name: Test321 + description: "modified second udf for testing" + value: "value421" + +delete_udf: + - ip_address: ["204.1.2.5"] + add_user_defined_field: + - name: "Test123" + + - ip_address: ["204.1.2.5"] + add_user_defined_field: + - name: "Test321" + +export_device_details: + - ip_address: ["204.1.2.5"] + export_device_list: + operation_enum: 1 + password: "Password123!" + +export_credential_details: + - ip_address: ["204.1.2.5"] + export_device_list: + operation_enum: "0" + password: "Password123$" + +delete_devices: + - ip_address: ["204.1.2.5", "204.192.6.200"] + clean_config: False \ No newline at end of file diff --git a/tests/integration/ccc_network_settings_management/defaults/main.yml b/tests/integration/ccc_network_settings_management/defaults/main.yml new file mode 100644 index 0000000000..55a93fc23d --- /dev/null +++ b/tests/integration/ccc_network_settings_management/defaults/main.yml @@ -0,0 +1,2 @@ +--- +testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_network_settings_management/meta/main.yml b/tests/integration/ccc_network_settings_management/meta/main.yml new file mode 100644 index 0000000000..5514b6a40c --- /dev/null +++ b/tests/integration/ccc_network_settings_management/meta/main.yml @@ -0,0 +1 @@ +dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_network_settings_management/tasks/main.yml b/tests/integration/ccc_network_settings_management/tasks/main.yml new file mode 100644 index 0000000000..09e0832ca2 --- /dev/null +++ b/tests/integration/ccc_network_settings_management/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: collect ccc test cases + find: + paths: "{{ role_path }}/tests" + patterns: "{{ testcase }}.yml" + connection: local + register: ccc_cases + tags: sanity + +- debug: + msg: "CCC Cases: {{ ccc_cases }}" + +- set_fact: + test_cases: + files: "{{ ccc_cases.files }}" + tags: sanity + +- debug: + msg: "Test Cases: {{ test_cases }}" + +- name: set test_items + set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + tags: sanity + +- debug: + msg: "Test Items: {{ test_items }}" + +- name: run test cases (connection=httpapi) + include_tasks: "{{ test_case_to_run }}" + loop: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_network_settings_management/tests/test.yml b/tests/integration/ccc_network_settings_management/tests/test.yml new file mode 100644 index 0000000000..d4dd989878 --- /dev/null +++ b/tests/integration/ccc_network_settings_management/tests/test.yml @@ -0,0 +1,178 @@ +--- +- debug: msg="Starting device credential management test" +- debug: msg="Role Path {{ role_path }}" + +- block: + - name: Load vars and declare dnac vars + include_vars: + file: "{{ role_path }}/vars/main.yml" + name: vars_map + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + + - debug: + msg: "{{ vars_map.design_sites }}" + - debug: + msg: "{{ vars_map. }}" + + +############################################# +# Pre Tests Clean Up # +############################################# + + - name: Clean up site before test + cisco.dnac.site_workflow_manager: + <<: *dnac_login + config_verify: true + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.design_sites }}" + + - name: Clean up before tests + cisco.dnac.site_workflow_manager: + <<: *dnac_login + config_verify: true + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map. }}" + + +############################################# +# CREATE SITE # +############################################# + + - name: Create sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + config_verify: true + state: merged + config: + - "{{ item }}" + register: result_create_site + loop: "{{ vars_map.design_sites }}" + tags: merged + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + + - name: Assert area creation success for each site + assert: + that: + - item.changed == true + - item.response.status == "SUCCESS" + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined + +############################################# +# UPDATE NETWORK SETTINGS # +############################################# + + +############################################# +# Create Global Pool # +############################################# + + - name: Create Global Pool + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config_verify: True + config: + - "{{ item }}" + with_list: "{{ vars_map. }}" + tags: merged + register: result_create_global_pool + + - name: Debug item + debug: + var: item + loop: "{{ result_create_global_pool.results }}" + when: result_create_global_pool is defined + + # - name: Assert Global Pool Creation + # assert: + # that: + # - item.changed == true + # - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" + # - item.response[0].globalCredential.Validation == "Success" + # loop: "{{ result_create_global_pool.results }}" + # when: result_create_global_pool is defined + +############################################# +# Update Global Pool # +############################################# + + - name: Update Global Pool + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config_verify: True + config: + - "{{ item }}" + with_list: "{{ vars_map. }}" + tags: update + register: result_update_global_pool + + - name: Debug item + debug: + var: item + loop: "{{ result_update_credentials.results }}" + when: result_update_credentials is defined + + # - name: Assert Global Credential Update + # assert: + # that: + # - item.changed == true + # - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" + # - item.response[0].globalCredential.Validation == "Success" + # loop: "{{ result_update_global_pool.results }}" + # when: result_update_global_pool is defined + +############################################# +# Delete Global Pool # +############################################# + + +############################################# +# DELETE SITE # +############################################# + + - name: Delete site from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + config_verify: true + state: deleted + config: + - "{{ item }}" + register: result_delete_site + loop: "{{ vars_map.design_sites }}" + tags: deleted + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined + + - name: Assert deletion of area success for each site + assert: + that: + - item.changed == true + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined diff --git a/tests/integration/ccc_network_settings_management/vars/main.yml b/tests/integration/ccc_network_settings_management/vars/main.yml new file mode 100644 index 0000000000..c1e2ff74b6 --- /dev/null +++ b/tests/integration/ccc_network_settings_management/vars/main.yml @@ -0,0 +1,7 @@ +--- +design_sites: + - site: + area: + name: TEST_NETWORK_SETTINGS + parent_name: 'Global' + type: area \ No newline at end of file diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml index f24d60553f..893d6a36af 100644 --- a/tests/integration/ccc_site_management/tests/test_site_management.yml +++ b/tests/integration/ccc_site_management/tests/test_site_management.yml @@ -3,9 +3,8 @@ - debug: msg="Role Path {{ role_path }}" - - block: - - name: Load design_sites from ccc_site_management role and declare dnac vars + - name: Load vars and declare dnac vars include_vars: file: "{{ role_path }}/vars/vars_site_management.yml" name: vars_map @@ -21,8 +20,8 @@ dnac_log: true dnac_log_level: DEBUG - - debug: - msg: "{{ vars_map.delete_sites }}" + # - debug: + # msg: "{{ vars_map.delete_sites }}" ############################################# @@ -49,9 +48,14 @@ state: merged config: - "{{ item }}" - register: result_create_site loop: "{{ vars_map.design_sites }}" - tags: merged + register: result_create_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined - name: Assert area creation success for each site assert: @@ -74,9 +78,14 @@ state: deleted config: - "{{ item }}" - register: result_delete_site loop: "{{ vars_map.delete_sites }}" - tags: deleted + register: result_delete_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined - name: Assert deletion of area success for each site assert: From 464b4df9426b6724a4a44fc53630fc5c2ff28ad9 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 11:22:28 -0500 Subject: [PATCH 143/358] site, discovery, intent, device_credentials IT --- .../tests/test_assign_credentials.yml | 28 +- .../test_device_credential_management.yml | 11 +- .../vars/vars_assign_credentials.yml | 4 +- .../vars/vars_credential_management.yml | 2 +- .../tests/test_discovery_management.yml | 504 ++++++------ .../vars/vars_discovery_management.yml | 12 +- ...s_delete_discoveries.yml => vars_misc.yml} | 0 .../tests/test_inventory_management.yml | 636 +++++++++------ .../vars/vars_inventory_management.yml | 186 +++-- .../tests/test_site_management.yml | 43 +- .../vars/vars_site_management.yml | 749 ++++++++++-------- 11 files changed, 1214 insertions(+), 961 deletions(-) rename tests/integration/ccc_discovery_management/vars/{vars_delete_discoveries.yml => vars_misc.yml} (100%) diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml index 81ed0928e5..e581833e9b 100755 --- a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml @@ -27,6 +27,7 @@ ############################################# # Pre Tests Clean Up # ############################################# + - name: Clean up site before test cisco.dnac.site_workflow_manager: <<: *dnac_login @@ -78,6 +79,7 @@ ############################################# # Create Credentials # ############################################# + - name: Create Credentials cisco.dnac.device_credential_workflow_manager: <<: *dnac_login @@ -107,6 +109,7 @@ ############################################# # Assign Credentials to site # ############################################# + - name: Assign Credentials to design_sites cisco.dnac.device_credential_workflow_manager: <<: *dnac_login @@ -118,27 +121,24 @@ tags: assign register: result_assign_credentials - - name: Debug item - debug: - var: item - loop: "{{ result_create_credentials.results }}" - when: result_assign_credentials is defined - - # - name: Assert Credentials to sites - # assert: - # that: - # - item.changed == true - # - item.response.status == "success" - # - "'assigned Successfully' in item.msg" + # - name: Debug item + # debug: + # var: item # loop: "{{ result_assign_credentials.results }}" # when: result_assign_credentials is defined + - name: Assert assign Credentials to sites + assert: + that: + - item.changed == true + - "'Device Credential Assigned to a site is Successfully' in item.response[0].assignCredential['Assign Credentials'].msg" + loop: "{{ result_assign_credentials.results }}" + when: result_assign_credentials is defined ############################################# # DELETE SITE # ############################################# - - name: Delete site from design_sites config cisco.dnac.site_workflow_manager: <<: *dnac_login @@ -167,6 +167,7 @@ ############################################# # Delete Credentials # ############################################# + - name: Delete Credentials cisco.dnac.device_credential_workflow_manager: <<: *dnac_login @@ -192,4 +193,3 @@ - item.response[0].globalCredential.Validation == "Success" loop: "{{ result_delete_credentials.results }}" when: result_delete_credentials is defined - diff --git a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml index 0982f50434..352838fe9e 100644 --- a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml @@ -21,10 +21,13 @@ # - debug: # msg: "{{ vars_map.credentials_details }}" + # - debug: + # msg: "{{ vars_map.credentials_update }}" ############################################# # Pre Tests Clean Up # ############################################# + - name: Clean up device credentials before test cisco.dnac.device_credential_workflow_manager: <<: *dnac_login @@ -34,10 +37,10 @@ - "{{ item }}" with_list: "{{ vars_map.credentials_details }}" - ############################################# # Create Credentials # ############################################# + - name: Create Credentials cisco.dnac.device_credential_workflow_manager: <<: *dnac_login @@ -67,6 +70,7 @@ ############################################# # Update Credentials # ############################################# + - name: Update Credentials cisco.dnac.device_credential_workflow_manager: <<: *dnac_login @@ -84,7 +88,7 @@ # loop: "{{ result_update_credentials.results }}" # when: result_update_credentials is defined - - name: Assert Global Credential Update + - name: Assert Device Credential Update assert: that: - item.changed == true @@ -96,6 +100,7 @@ ############################################# # Delete Credentials # ############################################# + - name: Delete Credentials cisco.dnac.device_credential_workflow_manager: <<: *dnac_login @@ -113,7 +118,7 @@ # loop: "{{ result_delete_credentials.results }}" # when: result_delete_credentials is defined - - name: Assert Global Credential Deletion + - name: Assert Device Credential Deletion assert: that: - item.changed == true diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index 26da0294b9..6ad1f9448d 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -6,7 +6,7 @@ design_sites: parent_name: 'Global' type: area -credentials_details: #Create multiple credentials for the same protocol +credentials_details: - global_credential_details: cli_credential: - description: CLIAssign @@ -56,4 +56,4 @@ credentials_assign: username: admin description: httpsWrite Test Assign site_name: - - Global/TEST_SITE_DEVICE_CREDENTIALS \ No newline at end of file + - Global/TEST_SITE_DEVICE_CREDENTIALS diff --git a/tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml b/tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml index 8ac38544b4..cd51dd1a85 100644 --- a/tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml @@ -99,4 +99,4 @@ credentials_update: - description: httpsWrite Test 1 username: admin password: "*#s&n2r9x$s@i8@" - port: 443 \ No newline at end of file + port: 443 diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml index 72382d49f5..76787f00da 100644 --- a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml @@ -22,26 +22,27 @@ - name: Clean up vars include_vars: - file: "{{ role_path }}/vars/vars_delete_discoveries.yml" + file: "{{ role_path }}/vars/vars_misc.yml" name: vars_map_delete - - debug: - msg: "{{ vars_map.single_ip }}" - - debug: - msg: "{{ vars_map.ip_range }}" - - debug: - msg: "{{ vars_map.multi_range }}" - - debug: - msg: "{{ vars_map.cdp }}" - - debug: - msg: "{{ vars_map.lldp }}" - - debug: - msg: "{{ vars_map.cidr }}" + # - debug: + # msg: "{{ vars_map.single_ip }}" + # - debug: + # msg: "{{ vars_map.ip_range }}" + # - debug: + # msg: "{{ vars_map.multi_range }}" + # - debug: + # msg: "{{ vars_map.cdp }}" + # - debug: + # msg: "{{ vars_map.lldp }}" + # - debug: + # msg: "{{ vars_map.cidr }}" ############################################# # Pre Tests Clean Up # ############################################# - - name: Delete all discovery + + - name: Delete discoveries before test cisco.dnac.discovery_workflow_manager: <<: *dnac_login config_verify: True @@ -54,244 +55,241 @@ # Create Single IP Address Discovery # ############################################# -# - name: Discover a single IP Address -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# config_verify: True -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.single_ip }}" -# register: result_singleip_discovery - -# - name: Debug item -# debug: -# var: result_singleip_discovery - -# - name: Check single IP discovery creation -# assert: -# that: -# - result_singleip_discovery.changed == true -# - "'Discovery Created Successfully' in result_singleip_discovery.results | map(attribute='msg') | list" -# when: result_singleip_discovery is defined - -# ############################################# -# # Create Range IP Address Discovery # -# ############################################# - -# - name: Discover an IP Address Range -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# config_verify: True -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.ip_range }}" -# register: result_ip_range_discovery - -# - name: Debug item -# debug: -# var: result_ip_range_discovery - -# - name: Check IP address range discovery creation -# assert: -# that: -# - result_ip_range_discovery.changed == true -# - "'Discovery Created Successfully' in result_ip_range_discovery.results | map(attribute='msg') | list" -# when: result_ip_range_discovery is defined - -# ############################################# -# # Create Multi Range IP Address Discovery # -# ############################################# - -# - name: Discover Multi IP Address Ranges -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# config_verify: True -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.multi_range }}" -# register: result_multi_range_discovery - -# - name: Debug item -# debug: -# var: result_multi_range_discovery - -# - name: Check multi range IP address discovery creation -# assert: -# that: -# - result_multi_range_discovery.changed == true -# - "'Discovery Created Successfully' in result_multi_range_discovery.results | map(attribute='msg') | list" -# when: result_multi_range_discovery is defined - - -# ############################################# -# # Create Discovery using CDP # -# ############################################# - -# - name: Discover using CDP -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# config_verify: True -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.cdp }}" -# register: result_cdp_discovery - -# - name: Debug item -# debug: -# var: result_cdp_discovery - -# - name: Check CDP discovery creation -# assert: -# that: -# - result_cdp_discovery.changed == true -# - "'Discovery Created Successfully' in result_cdp_discovery.results | map(attribute='msg') | list" -# when: result_cdp_discovery is defined - -# ############################################# -# # Create Discovery using LLDP # -# ############################################# - -# - name: Discover using LLDP -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# config_verify: True -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.lldp }}" -# register: result_lldp_discovery - -# - name: Debug item -# debug: -# var: result_lldp_discovery - -# - name: Check LLDP discovery creation -# assert: -# that: -# - result_lldp_discovery.changed == true -# - "'Discovery Created Successfully' in result_lldp_discovery.results | map(attribute='msg') | list" -# when: result_lldp_discovery is defined - -# ############################################# -# # Create Discovery using CIDR # -# ############################################# - -# - name: Discover using CIDR -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# config_verify: True -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.cidr }}" -# register: result_cidr_discovery - -# - name: Debug item -# debug: -# var: result_cidr_discovery - -# - name: Check CIDR discovery creation -# assert: -# that: -# - result_cidr_discovery.changed == true -# - "'Discovery Created Successfully' in result_cidr_discovery.results | map(attribute='msg') | list" -# when: result_cidr_discovery is defined - -# ############################################# -# # Create Multiple Discoveries # -# ############################################# - -# - name: Add new item with "preferred_mgmt_ip_method" -# set_fact: -# vars_map_preferred_mgmt: {} - -# - name: Add preferred_mgmt_ip_method to vars_map_preferred_mgmt -# set_fact: -# vars_map_preferred_mgmt: "{{ vars_map_preferred_mgmt | combine({item + '_preferred_mgmt': vars_map[item] | map('combine', {'preferred_mgmt_ip_method': 'UseLoopBack'}) | map('combine', {'discovery_name': vars_map[item][0]['discovery_name'] + ' - preferred_mgmt' }) | list}) }}" -# loop: "{{ vars_map.keys() }}" -# tags: multiple_discoveries - -# - name: Set vars_map_multiple -# set_fact: -# vars_map_multiple: "{{ vars_map | combine(vars_map_preferred_mgmt) }}" -# tags: multiple_discoveries - -# - name: Print the updated vars_map_multiple -# debug: -# var: vars_map_multiple -# tags: multiple_discoveries - -# - name: Create multiple Discoveries -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# config_verify: True -# state: merged -# config: -# - "{{ vars_map_multiple[item][0] }}" -# with_items: "{{ vars_map_multiple }}" -# tags: multiple_discoveries -# register: result_multiple_discoveries - -# - name: Debug item -# debug: -# var: result_multiple_discoveries -# when: result_multiple_discoveries is defined - -# - name: Check if multiple discoveries were successfull -# assert: -# that: -# - item.changed == true -# - "'Discovery Created Successfully' in item.msg" -# loop: "{{ result_multiple_discoveries.results }}" -# when: result_multiple_discoveries is defined - -# ############################################# -# # Delete Discovery by name # -# ############################################# - -# - name: Delete all discovery -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# config_verify: True -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map_delete.delete_discoveries }}" -# register: result_delete_discoveries - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_delete_discoveries.results }}" - -# - name: Check if discovery was successfully deleted -# assert: -# that: -# - item.changed == true -# - "'Successfully deleted discovery' in item.msg" -# loop: "{{ result_delete_discoveries.results }}" -# when: result_delete_discoveries is defined - -# ############################################ -# # Delete ALL Discovery # -# ############################################# - -# # - name: Delete all discovery -# # cisco.dnac.discovery_workflow_manager: -# # <<: *dnac_login -# # state: deleted -# # config_verify: True -# # config: -# # - delete_all: True -# # register: result_delete_all - -# # - name: Debug item -# # debug: -# # var: result_delete_all -# # when: result_delete_all is defined + - name: Discover a single IP Address + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + config_verify: True + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.single_ip }}" + register: result_singleip_discovery + + # - name: Debug item + # debug: + # var: result_singleip_discovery + + - name: Check single IP discovery creation + assert: + that: + - result_singleip_discovery.changed == true + - "'Discovery Created Successfully' in result_singleip_discovery.results | map(attribute='msg') | list" + when: result_singleip_discovery is defined + +############################################# +# Create Range IP Address Discovery # +############################################# + + - name: Discover an IP Address Range + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + config_verify: True + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.ip_range }}" + register: result_ip_range_discovery + + # - name: Debug item + # debug: + # var: result_ip_range_discovery + + - name: Check IP address range discovery creation + assert: + that: + - result_ip_range_discovery.changed == true + - "'Discovery Created Successfully' in result_ip_range_discovery.results | map(attribute='msg') | list" + when: result_ip_range_discovery is defined + +############################################# +# Create Multi Range IP Address Discovery # +############################################# + + - name: Discover Multi IP Address Ranges + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + config_verify: True + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.multi_range }}" + register: result_multi_range_discovery + + # - name: Debug item + # debug: + # var: result_multi_range_discovery + + - name: Check multi range IP address discovery creation + assert: + that: + - result_multi_range_discovery.changed == true + - "'Discovery Created Successfully' in result_multi_range_discovery.results | map(attribute='msg') | list" + when: result_multi_range_discovery is defined + +############################################# +# Create Discovery using CDP # +############################################# + + - name: Discover using CDP + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + config_verify: True + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.cdp }}" + register: result_cdp_discovery + + # - name: Debug item + # debug: + # var: result_cdp_discovery + + - name: Check CDP discovery creation + assert: + that: + - result_cdp_discovery.changed == true + - "'Discovery Created Successfully' in result_cdp_discovery.results | map(attribute='msg') | list" + when: result_cdp_discovery is defined + +############################################# +# Create Discovery using LLDP # +############################################# + + - name: Discover using LLDP + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + config_verify: True + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.lldp }}" + register: result_lldp_discovery + + # - name: Debug item + # debug: + # var: result_lldp_discovery + + - name: Check LLDP discovery creation + assert: + that: + - result_lldp_discovery.changed == true + - "'Discovery Created Successfully' in result_lldp_discovery.results | map(attribute='msg') | list" + when: result_lldp_discovery is defined + +############################################# +# Create Discovery using CIDR # +############################################# + + - name: Discover using CIDR + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + config_verify: True + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.cidr }}" + register: result_cidr_discovery + + # - name: Debug item + # debug: + # var: result_cidr_discovery + + - name: Check CIDR discovery creation + assert: + that: + - result_cidr_discovery.changed == true + - "'Discovery Created Successfully' in result_cidr_discovery.results | map(attribute='msg') | list" + when: result_cidr_discovery is defined + +############################################# +# Create Multiple Discoveries # +############################################# + + - name: Add new item with "preferred_mgmt_ip_method" + set_fact: + vars_map_preferred_mgmt: {} + + - name: Add preferred_mgmt_ip_method to vars_map_preferred_mgmt + set_fact: + vars_map_preferred_mgmt: "{{ vars_map_preferred_mgmt | combine({item + '_preferred_mgmt': vars_map[item] | map('combine', {'preferred_mgmt_ip_method': 'UseLoopBack'}) | map('combine', {'discovery_name': vars_map[item][0]['discovery_name'] + ' - preferred_mgmt' }) | list}) }}" + loop: "{{ vars_map.keys() }}" + tags: multiple_discoveries + + - name: Set vars_map_multiple + set_fact: + vars_map_multiple: "{{ vars_map | combine(vars_map_preferred_mgmt) }}" + tags: multiple_discoveries + + - name: Print the updated vars_map_multiple + debug: + var: vars_map_multiple + tags: multiple_discoveries + + - name: Create multiple Discoveries + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + config_verify: True + state: merged + config: + - "{{ vars_map_multiple[item][0] }}" + with_items: "{{ vars_map_multiple }}" + tags: multiple_discoveries + register: result_multiple_discoveries + + # - name: Debug item + # debug: + # var: result_multiple_discoveries + # when: result_multiple_discoveries is defined + + - name: Check if multiple discoveries were successfull + assert: + that: + - item.changed == true + - "'Discovery Created Successfully' in item.msg" + loop: "{{ result_multiple_discoveries.results }}" + when: result_multiple_discoveries is defined +############################################# +# Delete Discovery by name # +############################################# + - name: Delete all discovery + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + config_verify: True + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map_delete.delete_discoveries }}" + register: result_delete_discoveries + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_discoveries.results }}" + + - name: Check if discovery was successfully deleted + assert: + that: + - item.changed == true + - "'Successfully deleted discovery' in item.msg" + loop: "{{ result_delete_discoveries.results }}" + when: result_delete_discoveries is defined + +############################################ +# Delete ALL Discoveries # +############################################ + + # - name: Delete all discoveries that were created + # cisco.dnac.discovery_workflow_manager: + # <<: *dnac_login + # state: deleted + # config_verify: True + # config: + # - delete_all: True + # register: result_delete_all + + # - name: Debug item + # debug: + # var: result_delete_all + # when: result_delete_all is defined diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index 791e2e3ff6..98a9909a03 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -59,17 +59,7 @@ ip_range: - 204.1.2.3 protocol_order: ssh discovery_specific_credentials: - cli_credentials_list: - - username: cisco - password: Cisco#123 - enable_password: Cisco#123 - snmp_v3_credential: - username: v3Phan - snmp_mode: AUTHPRIV - auth_type: SHA - auth_password: Cisco#123456789 - privacy_type: AES128 - privacy_password: Cisco#1234567890 + global_cli_len: 3 multi_range: - discovery_name: Multi Range Discovery diff --git a/tests/integration/ccc_discovery_management/vars/vars_delete_discoveries.yml b/tests/integration/ccc_discovery_management/vars/vars_misc.yml similarity index 100% rename from tests/integration/ccc_discovery_management/vars/vars_delete_discoveries.yml rename to tests/integration/ccc_discovery_management/vars/vars_misc.yml diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index c5c377302f..33de4cbd0a 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -18,7 +18,8 @@ dnac_debug: "{{ dnac_debug }}" dnac_log: true dnac_log_level: DEBUG - + - debug: + msg: "{{ ansible_python_interpreter }}" # - debug: # msg: "{{ vars_map.device_details }}" # - debug: @@ -32,303 +33,413 @@ # Clean Up # ############################################# - - name: Delete device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_devices }}" - register: result_device_deleted +# - name: Delete device +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_devices }}" +# register: result_device_deleted - - name: Debug item - debug: - var: item - loop: "{{ result_device_deleted.results }}" - when: result_device_deleted is defined + # - name: Delete site + # cisco.dnac.site_workflow_manager: + # <<: *dnac_login + # config_verify: true + # state: deleted + # config: + # - "{{ item }}" + # loop: "{{ vars_map.delete_sites }}" + # register: result_delete_site -############################################# -# Add Devices # -############################################# +# ############################################# +# # Add Devices # +# ############################################# - - name: Add new device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - config_verify: true - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.device_details }}" - register: result_add_device +# - name: Add new device +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.device_details }}" +# register: result_add_device - - name: Debug item - debug: - var: item - loop: "{{ result_add_device.results }}" +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_add_device.results }}" - - name: Assert device addition success - assert: - that: - - item.changed == true - - "'added to Cisco Catalyst Center' in item.msg" - loop: "{{ result_add_device.results }}" - when: result_add_device is defined +# - name: Assert device addition success +# assert: +# that: +# - item.changed == true +# - "'added to Cisco Catalyst Center' in item.msg" +# loop: "{{ result_add_device.results }}" +# when: result_add_device is defined -############################################# -# Update Device Credential Details # -############################################# +# ############################################# +# # Update Device Credential Details # +# ############################################# - # - name: Update device details - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_credential_updates }}" - # register: result_update_device_credentials +# - name: Update device details +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.device_credential_updates }}" +# register: result_update_device_credentials - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_credentials.results }}" - # when: result_update_device_credentials is defined +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_update_device_credentials.results }}" +# # when: result_update_device_credentials is defined - # - name: Assert update - # assert: - # that: - # - item.changed == true - # loop: "{{ result_update_device_credentials.results }}" - # when: result_update_device_credentials is defined +# - name: Assert update +# assert: +# that: +# - item.changed == true +# loop: "{{ result_update_device_credentials.results }}" +# when: result_update_device_credentials is defined -############################################# -# Update Device Interface Detials # -############################################# +# ############################################# +# # Update Device Interface Detials # +# ############################################# - # - name: Update device interface details - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_interface_updates }}" - # register: result_update_device_interface +# # - name: Update device interface details +# # cisco.dnac.inventory_workflow_manager: +# # <<: *dnac_login +# # state: merged +# # config: +# # - "{{ item }}" +# # loop: "{{ vars_map.device_interface_updates }}" +# # register: result_update_device_interface + +# # # - name: Debug item +# # # debug: +# # # var: item +# # # loop: "{{ result_update_device_interface.results }}" +# # # when: result_update_device_interface is defined + +# # - name: Assert update +# # assert: +# # that: +# # - item.changed == true +# # loop: "{{ result_update_device_interface.results }}" +# # when: result_update_device_interface is defined - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined +# ############################################# +# # Update Device Role Detials # +# ############################################# - # - name: Assert update - # assert: - # that: - # - item.changed == true - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined +# - name: Update device role details +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.device_role_updates }}" +# register: result_update_device_role -############################################# -# Update Device Role Detials # -############################################# +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_update_device_role.results }}" +# # when: result_update_device_role is defined - # - name: Update device role details - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_role_updates }}" - # register: result_update_device_role +# - name: Assert device role update +# assert: +# that: +# - result_update_device_role.changed == true +# - "'Device role was successfully updated' in item.response.progress" +# loop: "{{ result_update_device_role.results }}" +# when: result_update_device_role is defined - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_role.results }}" - # when: result_update_device_role is defined +# ############################################# +# # Update Device Interface Description # +# ############################################# - # - name: Assert device role update - # assert: - # that: - # - result_update_device_role.changed == true - # - "'Device role was successfully updated' in item.response.progress" - # loop: "{{ result_update_device_role.results }}" - # when: result_update_device_role is defined +# # - name: Update device interface description post changing role to non-access +# # cisco.dnac.inventory_workflow_manager: +# # <<: *dnac_login +# # state: merged +# # config: +# # - "{{ item }}" +# # loop: "{{ vars_map.device_int_update_post_rolechange }}" +# # register: result_update_device_interface + +# # # - name: Debug item +# # # debug: +# # # var: item +# # # loop: "{{ result_update_device_interface.results }}" +# # # when: result_update_device_interface is defined + +# # - name: Assert update +# # assert: +# # that: +# # - item.changed == true +# # loop: "{{ result_update_device_interface.results }}" +# # when: result_update_device_interface is defined -############################################# -# Update Device Interface Description # -############################################# +# ############################################# +# # Resync Device # +# ############################################# - # - name: Update device interface description post changing role to non-access - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_int_update_post_rolechange }}" - # register: result_update_device_interface +# - name: Update device role details +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.device_resync }}" +# register: result_resync_device - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_resync_device.results }}" +# # when: result_resync_device is defined - # - name: Assert update - # assert: - # that: - # - item.changed == true - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined +# - name: Assert device resync +# assert: +# that: +# - result_resync_device.changed == true +# - "'Synced devices' in item.response.progress" +# loop: "{{ result_resync_device.results }}" +# when: result_resync_device is defined -############################################# -# Resync Device # -############################################# +# ############################################# +# # Create & Assign User Defined Field # +# ############################################# - # - name: Update device role details - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_resync }}" - # register: result_resync_device +# - name: Create & Assign user defined field +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.create_assign_udf }}" +# register: result_create_assign_udf - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_resync_device.results }}" - # when: result_resync_device is defined +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_create_assign_udf.results }}" +# # when: result_create_assign_udf is defined - # - name: Assert device resync - # assert: - # that: - # - result_resync_device.changed == true - # - "'Synced devices' in item.response.progress" - # loop: "{{ result_resync_device.results }}" - # when: result_resync_device is defined +# - name: Assert user defined field creation and assignment +# assert: +# that: +# - item.changed == true +# loop: "{{ result_create_assign_udf.results }}" +# when: result_create_assign_udf is defined -############################################# -# Create & Assign User Defined Field # -############################################# +# ############################################# +# # Update User Defined Field # +# ############################################# - # - name: Create & Assign user defined field - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.create_assign_udf }}" - # register: result_create_assign_udf +# - name: Updateuser defined field +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.update_udf }}" +# register: result_update_udf - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_assign_udf.results }}" - # when: result_create_assign_udf is defined +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_create_assign_udf.results }}" +# # when: result_update_udf is defined - # - name: Assert user defined field creation and assignment - # assert: - # that: - # - item.changed == true - # loop: "{{ result_create_assign_udf.results }}" - # when: result_create_assign_udf is defined +# - name: Assert user defined field updated +# assert: +# that: +# - item.changed == true +# loop: "{{ result_update_udf.results }}" +# when: result_update_udf is defined -############################################# -# Update User Defined Field # -############################################# - # - name: Updateuser defined field - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.update_udf }}" - # register: result_update_udf +# ############################################# +# # Delete User Defined Field # +# ############################################# - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_assign_udf.results }}" - # when: result_update_udf is defined +# - name: Delete user defined field +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_udf }}" +# register: result_delete_udf - # - name: Assert user defined field updated - # assert: - # that: - # - item.changed == true - # loop: "{{ result_update_udf.results }}" - # when: result_update_udf is defined +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_delete_udf.results }}" +# # when: result_delete_udf is defined +# - name: Assert user defined field deletion +# assert: +# that: +# - result_delete_udf.changed == true +# - "'deleted successfully' in item.response.progress" +# loop: "{{ result_delete_udf.results }}" +# when: result_delete_udf is defined -############################################# -# Delete User Defined Field # -############################################# - # - name: Delete user defined field - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: deleted - # config: - # - "{{ item }}" - # loop: "{{ vars_map.delete_udf }}" - # register: result_delete_udf +# ############################################# +# # Export Device Details # +# ############################################# - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_udf.results }}" - # when: result_delete_udf is defined +# - name: Export Device Details in a CSV file +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.export_device_details }}" +# register: result_export_details - # - name: Assert user defined field deletion - # assert: - # that: - # - result_delete_udf.changed == true - # - "'deleted successfully' in item.response.progress" - # loop: "{{ result_delete_udf.results }}" - # when: result_delete_udf is defined +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_export_details.results }}" +# # when: result_export_details is defined + +# - name: Assert device details export +# assert: +# that: +# - item.changed == true +# loop: "{{ result_export_details.results }}" +# when: result_export_details is defined + +# ############################################# +# # Export Device Credential Details # +# ############################################# + +# - name: Export Credential Device Details in a CSV file +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.export_credential_details }}" +# register: result_export_credential_details + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_export_credential_details.results }}" +# # when: result_export_credential_details is defined + +# - name: Assert device credential details export +# assert: +# that: +# - item.changed == true +# loop: "{{ result_export_credential_details.results }}" +# when: result_export_credential_details is defined ############################################# -# Export Device Details # +# CREATE SITE # ############################################# - # - name: Export Device Details in a CSV file - # cisco.dnac.inventory_workflow_manager: + + # - name: Create sites from design_sites config + # cisco.dnac.site_workflow_manager: # <<: *dnac_login + # config_verify: true # state: merged # config: - # - "{{ item }}" - # loop: "{{ vars_map.export_device_details }}" - # register: result_export_details + # - "{{ item }}" + # loop: "{{ vars_map.design_sites }}" + # register: result_create_site - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_export_details.results }}" - # when: result_export_details is defined + # # - name: Debug item + # # debug: + # # var: item + # # loop: "{{ result_create_site.results }}" + # # when: result_create_site is defined - # - name: Assert device details export + # - name: Assert area creation success for each site # assert: # that: # - item.changed == true - # loop: "{{ result_export_details.results }}" - # when: result_export_details is defined + # - item.response.status == "SUCCESS" + # - "'created successfully' in item.msg" + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + +# ############################################# +# # ASSOCIATE WIRED DEVICE TO SITE # +# ############################################# + +# - name: Assign wired device to site and then provision +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.associate_wired_device }}" +# register: result_associate_device + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_associate_device.results }}" +# # when: result_associate_device is defined + +# - name: Assert device credential details export +# assert: +# that: +# - item.changed == true +# loop: "{{ result_associate_device.results }}" +# when: result_associate_device is defined + ############################################# -# Export Device Credential Details # +# CREATE WIRELESS PROFILE # ############################################# - - name: Export Credential Device Details in a CSV file - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.export_credential_details }}" - register: result_export_credential_details + + - name: Create wireless profile + cisco.dnac.wireless_profile: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + profileDetails: + name: "ITest_wireless_profile" + sites: + - Global/ITest_Area/ITest_Building/ITest_Floor2 + ssidDetails: + - enableFabric: false + flexConnect: + enableFlexConnect: false + localToVlan: 0 + interfaceName: "etherenet1/1" + name: "itest_ssid" + policyProfileName: "itest_ssid_policy_profile" + wlanProfileName: "itest_ssid_wlan_profile" + register: result_create_wireless_profile - name: Debug item debug: - var: item - loop: "{{ result_export_credential_details.results }}" - when: result_export_credential_details is defined + var: result_create_wireless_profile + when: result_create_wireless_profile is defined + + +############################################# +# ASSOCIATE WIRELESS DEVICE TO SITE # +############################################# + # ############################################# # # Delete Devices # @@ -343,16 +454,43 @@ # loop: "{{ vars_map.delete_devices }}" # register: result_device_deleted -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_device_deleted.results }}" -# when: result_device_deleted is defined +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_device_deleted.results }}" +# # when: result_device_deleted is defined # - name: Assert device deletion success # assert: # that: # - result_device_deleted.changed == true -# - "'successfully deleted from Cisco Catalyst Center' in result_device_deleted.msg" # when: result_device_deleted is defined - + +# ############################################# +# # DELETE SITE # +# ############################################# + +# - name: Delete sites from design_sites config +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_sites }}" +# register: result_delete_site + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_delete_site.results }}" +# # when: result_delete_site is defined + +# - name: Assert deletion of area success for each site +# assert: +# that: +# - item.changed == true +# - "'deleted successfully' in item.response" +# loop: "{{ result_delete_site.results }}" +# when: result_delete_site is defined + diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 36f7f7ee13..05a7b3a671 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -1,29 +1,29 @@ --- device_details: - # - type: "NETWORK_DEVICE" - # ip_address: ["204.1.2.5"] - # device_added: True - # # CLI Credentials - # username: "cisco" - # password: "Cisco#123" - # enable_password: "Cisco#123" - # # SNMP Credentials - # snmp_version: v3 - # snmp_username: "v3Public2" - # snmp_mode: "AUTHPRIV" - # snmp_auth_protocol: "SHA" - # snmp_auth_passphrase: "Lablab#1234" - # snmp_priv_protocol: "CISCOAES256" - # snmp_priv_passphrase: "Lablab#1234" - # #SNMP Retry and Timeout - # snmp_retry: 3 - # snmp_timeout: 5 - # #CLI Transport (ssh, Telnet) - # cli_transport: "ssh" - # netconf_port: 830 + - type: "NETWORK_DEVICE" + ip_address_list: ["204.1.2.5"] + device_added: True + # CLI Credentials + username: "cisco" + password: "Cisco#123" + enable_password: "Cisco#123" + # SNMP Credentials + snmp_version: v3 + snmp_username: "v3Public2" + snmp_mode: "AUTHPRIV" + snmp_auth_protocol: "SHA" + snmp_auth_passphrase: "Lablab#1234" + snmp_priv_protocol: "CISCOAES256" + snmp_priv_passphrase: "Lablab#1234" + #SNMP Retry and Timeout + snmp_retry: 3 + snmp_timeout: 5 + #CLI Transport (ssh, Telnet) + cli_transport: "ssh" + netconf_port: 830 - type: "NETWORK_DEVICE" - ip_address: ["204.192.6.200"] + ip_address_list: ["204.192.6.200"] device_added: True # CLI Credentials username: "cisco" @@ -52,7 +52,7 @@ device_details: device_credential_updates: # Update CLI password - type: "NETWORK_DEVICE" - ip_address: ["204.1.2.5"] + ip_address_list: ["204.1.2.5", "204.192.6.200"] device_updated: True credential_update: True # CLI Credentials @@ -61,7 +61,7 @@ device_credential_updates: # Update SNMP privacy type - type: "NETWORK_DEVICE" - ip_address: ["204.1.2.5"] + ip_address_list: ["204.1.2.5", "204.192.6.200"] device_updated: True credential_update: True # SNMP Credentials @@ -70,7 +70,7 @@ device_credential_updates: # Update SNMP username - type: "NETWORK_DEVICE" - ip_address: ["204.1.2.5"] + ip_address_list: ["204.1.2.5", "204.192.6.200"] device_updated: True credential_update: True # SNMP Credentials @@ -79,7 +79,7 @@ device_credential_updates: # Update SNMP mode - type: "NETWORK_DEVICE" - ip_address: ["204.1.2.5"] + ip_address_list: ["204.1.2.5", "204.192.6.200"] device_updated: True credential_update: True # SNMP Credentials @@ -88,15 +88,24 @@ device_credential_updates: # Update cli_transport - type: "NETWORK_DEVICE" - ip_address: ["204.1.2.5"] + ip_address_list: ["204.1.2.5", "204.192.6.200"] device_updated: True credential_update: True #change cli_transport from ssh to telnet cli_transport: telnet + # SNMPv2 credentials + - type: "NETWORK_DEVICE" + ip_address_list: ["204.1.2.5", "204.192.6.200"] + device_updated: True + credential_update: True + snmp_version: v2 + snmp_ro_community: 'j5aj#0z%' + snmp_rw_community: 'j5aj#0z%' + # Reverse changes - type: "NETWORK_DEVICE" - ip_address: ["204.1.2.5"] + ip_address_list: ["204.1.2.5", "204.192.6.200"] device_updated: True credential_update: True # CLI Credentials @@ -118,7 +127,7 @@ device_credential_updates: device_interface_updates: # Update Interface Details - - ip_address: ["204.1.2.5"] + - ip_address_list: ["204.1.2.5", "204.192.6.200"] device_updated: True # Interface details update_interface_details: @@ -128,32 +137,9 @@ device_interface_updates: voice_vlan_id: 45 admin_status: "UP" - # # Update Interface Details - # - ip_address: ["204.1.2.5"] - # device_updated: True - # # Interface details - # update_interface_details: - # interface_name: ["GigabitEthernet1/0/11"] - # description: "Testing for updating interface details" - # admin_status: "UP" #not a paramter accepted by update_interface_details - # vlan_id: 23 - # voice_vlan_id: 45 - # deployment_mode: "Deploy" - - # Update Interface Details - # - ip_address: ["204.1.2.5"] - # device_updated: True - # # Interface details - # interface_name: ["GigabitEthernet1/0/11"] - # description: "Testing for updating interface details" - # admin_status: "UP" - # vlan_id: 23 - # voice_vlan_id: 45 - # deployment_mode: "Deploy" - device_role_updates: #Update role from access to core - - ip_address: ["204.1.2.5"] + - ip_address_list: ["204.1.2.5"] device_updated: True # Role details update_device_role: @@ -161,28 +147,22 @@ device_role_updates: device_int_update_post_rolechange: # Update Interface description - - ip_address: ["204.1.2.5"] + - ip_address_list: ["204.1.2.5"] device_updated: True # Interface details interface_name: ["GigabitEthernet1/0/23"] description: "Testing for updating interface description post changing role" - # - ip_address: ["204.1.2.5"] - # device_updated: True - # # Interface detail - # update_interface_details: - # interface_name: ["GigabitEthernet1/0/1"] - # description: "Testing for updating interface details" - device_resync: # Resync the device - - ip_address: ["204.1.2.5"] + - ip_address_list: ["204.1.2.5"] device_resync: True force_sync: False create_assign_udf: - - ip_address: ["204.1.2.5"] + - ip_address_list: ["204.1.2.5", "204.192.6.200"] add_user_defined_field: + # User defined fields - name: Test123 description: "Added first udf for testing" value: "value123" @@ -191,8 +171,9 @@ create_assign_udf: value: "value321" update_udf: - - ip_address: ["204.1.2.5"] + - ip_address_list: ["204.1.2.5", "204.192.6.200"] add_user_defined_field: + # User defined fields - name: Test123 description: "modified first udf for testing" value: "value124" @@ -201,26 +182,91 @@ update_udf: value: "value421" delete_udf: - - ip_address: ["204.1.2.5"] + # User defined fields + - ip_address_list: ["204.1.2.5", "204.192.6.200"] add_user_defined_field: - name: "Test123" - - - ip_address: ["204.1.2.5"] + - ip_address_list: ["204.1.2.5", "204.192.6.200"] add_user_defined_field: - name: "Test321" export_device_details: - - ip_address: ["204.1.2.5"] + - ip_address_list: ["204.1.2.5", "204.192.6.200"] export_device_list: operation_enum: 1 password: "Password123!" export_credential_details: - - ip_address: ["204.1.2.5"] + - ip_address_list: ["204.1.2.5", "204.192.6.200"] export_device_list: operation_enum: "0" password: "Password123$" +design_sites: + # Create site to associate device to + - site: + area: + name: ITest_Area + parent_name: Global + type: area + - site: + building: + name: ITest_Building + parent_name: Global/ITest_Area + address: Bengaluru, Karnataka, India + latitude: 12.969910 + longitude: 77.597960 + country: India + type: building + - site: + floor: + name: ITest_Floor1 + parent_name: Global/ITest_Area/ITest_Building + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: ITest_Floor2 + parent_name: Global/ITest_Area/ITest_Building + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 2 + type: floor + +associate_wired_device: + - provision_wired_device: + - device_ip: "204.1.2.5" + site_name: "Global/ITest_Area/ITest_Building/ITest_Floor1" + resync_retry_count: 200 + resync_interval: 2 + +associate_wireless_device: + - provision_wired_device: + - device_ip: "204.192.6.200" + site_name: "Global/ITest_Area/ITest_Building/ITest_Floor2" + dynamic_interfaces: + - interface_ip_address: 32.31.12.23 + interface_netmask_in_cidr: 26 + interface_gateway: "gateway_test" + lag_or_port_number: 33 + vlan_id: 78 + interface_name: "etherenet1/1" + resync_retry_count: 200 + resync_retry_interval: 2 + +delete_sites: + - site: + area: + name: ITest_Area + parent_name: Global + type: area + delete_devices: - - ip_address: ["204.1.2.5", "204.192.6.200"] + - ip_address_list: ["204.1.2.5"] clean_config: False \ No newline at end of file diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml index 893d6a36af..3365511376 100644 --- a/tests/integration/ccc_site_management/tests/test_site_management.yml +++ b/tests/integration/ccc_site_management/tests/test_site_management.yml @@ -2,7 +2,6 @@ - debug: msg="Starting site management test" - debug: msg="Role Path {{ role_path }}" - - block: - name: Load vars and declare dnac vars include_vars: @@ -20,10 +19,13 @@ dnac_log: true dnac_log_level: DEBUG + # - debug: + # msg: "{{ vars_map.design_sites }}" + # - debug: + # msg: "{{ vars_map.update_sites }}" # - debug: # msg: "{{ vars_map.delete_sites }}" - ############################################# # Clean Up # ############################################# @@ -41,7 +43,7 @@ # CREATE SITES # ############################################# - - name: Create sites from design_sites config + - name: Create sites cisco.dnac.site_workflow_manager: <<: *dnac_login config_verify: true @@ -61,17 +63,43 @@ assert: that: - item.changed == true - - item.response.status == "SUCCESS" - "'created successfully' in item.msg" loop: "{{ result_create_site.results }}" when: result_create_site is defined ############################################# -# DELETE SITES # +# UPDATE SITES # ############################################# + - name: Update sites + cisco.dnac.site_workflow_manager: + <<: *dnac_login + config_verify: true + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.update_sites }}" + register: result_update_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_site.results }}" + # when: result_update_site is defined + + - name: Assert area update success for each site + assert: + that: + - item.changed == true + - "'Updated Successfully' in item.msg" + loop: "{{ result_update_site.results }}" + when: result_update_site is defined + +############################################# +# DELETE SITES # +############################################# - - name: Delete sites from design_sites config + - name: Delete sites cisco.dnac.site_workflow_manager: <<: *dnac_login config_verify: true @@ -87,11 +115,10 @@ # loop: "{{ result_delete_site.results }}" # when: result_delete_site is defined - - name: Assert deletion of area success for each site + - name: Assert deletion success for each site assert: that: - item.changed == true - - item.response.status == "SUCCESS" - "'deleted successfully' in item.response" loop: "{{ result_delete_site.results }}" when: result_delete_site is defined diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index ff891fb86b..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -1,408 +1,457 @@ --- design_sites: + # USA-Test Site Hierarchy - site: area: - name: USA + name: USA-Test parent_name: Global type: area - site: area: - name: India - parent_name: Global + name: SAN JOSE + parent_name: Global/USA-Test type: area - site: area: - name: Mexico - parent_name: Global + name: RTP + parent_name: Global/USA-Test type: area - site: area: - name: Canada - parent_name: Global + name: BayAreaGuest + parent_name: Global/USA-Test type: area - site: area: - name: SAN JOSE - parent_name: Global/USA + name: New York + parent_name: Global/USA-Test type: area - site: area: - name: RTP - parent_name: Global/USA + name: SAN-FRANCISCO + parent_name: Global/USA-Test type: area - site: area: - name: BayAreaGuest - parent_name: Global/USA + name: BERKELEY + parent_name: Global/USA-Test + type: area + - site: + building: + name: BLD10 + parent_name: Global/USA-Test/RTP + address: Ev Chargers Bldg 10, 7200-10 Kit Creek Rd, Morrisville, North Carolina 27560, United States + latitude: 35.85992111421487 + longitude: -78.8829258991226 + country: United States + type: building + - site: + building: + name: BLD11 + parent_name: Global/USA-Test/RTP + address: Cisco Systems, 7200 Kit Creek Rd, Morrisville, North Carolina 27560, United States + latitude: 35.86059627310624 + longitude: -78.88105620286412 + country: United States + type: building + - site: + building: + name: BLD12 + parent_name: Global/USA-Test/RTP + address: Cisco Systems, 7200-12 Kit Creek Rd, Morrisville, North Carolina 27560, United States + latitude: 35.8611847591779 + longitude: -78.88217248318003 + country: United States + type: building + - site: + building: + name: BLD23 + parent_name: Global/USA-Test/SAN JOSE + address: McCarthy Blvd, San Jose, California 95131, United States + latitude: 37.398188 + longitude: -121.912974 + country: United States + type: building + - site: + building: + name: BLD20 + parent_name: Global/USA-Test/SAN JOSE + address: 725 Alder Drive, Milpitas, California 95035, United States + latitude: 37.415947 + longitude: -121.916327 + country: United States + type: building + - site: + building: + name: BLD_GB + parent_name: Global/USA-Test/BayAreaGuest + address: 725 Alder Drive, Milpitas, California 95035, United States + latitude: 37.415947 + longitude: -121.916327 + country: United States + type: building + - site: + building: + name: BLDNYC + parent_name: Global/USA-Test/New York + address: McCarthy Blvd, San Jose, California 95131, United States + latitude: 37.398188 + longitude: -121.912974 + country: United States + type: building + - site: + building: + name: BLD_SF + parent_name: Global/USA-Test/SAN-FRANCISCO + address: McCarthy Blvd, San Jose, California 95131, United States + latitude: 37.398188 + longitude: -121.912974 + country: United States + type: building + - site: + building: + name: BLD_SF1 + parent_name: Global/USA-Test/SAN-FRANCISCO + address: McCarthy Blvd, San Jose, California 95131, United States + latitude: 37.398188 + longitude: -121.912974 + country: United States + type: building + - site: + building: + name: BLDBERK + parent_name: Global/USA-Test/BERKELEY + address: 725 Alder Drive, Milpitas, California 95035, United States + latitude: 37.415947 + longitude: -121.916327 + country: United States + type: building + - site: + floor: + name: BLD10_FLOOR1 + parent_name: Global/USA-Test/RTP/BLD10 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: BLD10_FLOOR2 + parent_name: Global/USA-Test/RTP/BLD10 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 2 + type: floor + - site: + floor: + name: BLD10_FLOOR3 + parent_name: Global/USA-Test/RTP/BLD10 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 3 + type: floor + - site: + floor: + name: BLD11_FLOOR1 + parent_name: Global/USA-Test/RTP/BLD11 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: BLD11_FLOOR2 + parent_name: Global/USA-Test/RTP/BLD11 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 2 + type: floor + - site: + floor: + name: BLD11_FLOOR3 + parent_name: Global/USA-Test/RTP/BLD11 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 3 + type: floor + - site: + floor: + name: BLD12_FLOOR1 + parent_name: Global/USA-Test/RTP/BLD12 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: BLD12_FLOOR2 + parent_name: Global/USA-Test/RTP/BLD12 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 2 + type: floor + - site: + floor: + name: BLD12_FLOOR3 + parent_name: Global/USA-Test/RTP/BLD12 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 3 + type: floor + - site: + floor: + name: FLOOR1_LEVEL1 + parent_name: Global/USA-Test/SAN JOSE/BLD23 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: FLOOR1_LEVEL2 + parent_name: Global/USA-Test/SAN JOSE/BLD23 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: FLOOR1_LEVEL3 + parent_name: Global/USA-Test/SAN JOSE/BLD23 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: FLOOR1_LEVEL4 + parent_name: Global/USA-Test/SAN JOSE/BLD23 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: BLD20_FLOOR1 + parent_name: Global/USA-Test/SAN JOSE/BLD20 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: BLD20_FLOOR2 + parent_name: Global/USA-Test/SAN JOSE/BLD20 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 2 + type: floor + - site: + floor: + name: FLOOR1 + parent_name: Global/USA-Test/New York/BLDNYC + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: FLOOR2 + parent_name: Global/USA-Test/New York/BLDNYC + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 2 + type: floor + - site: + floor: + name: FLOOR1 + parent_name: Global/USA-Test/SAN-FRANCISCO/BLD_SF + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: FLOOR2 + parent_name: Global/USA-Test/SAN-FRANCISCO/BLD_SF + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 2 + type: floor + - site: + floor: + name: FLOOR1 + parent_name: Global/USA-Test/SAN-FRANCISCO/BLD_SF1 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + - site: + floor: + name: FLOOR2 + parent_name: Global/USA-Test/SAN-FRANCISCO/BLD_SF1 + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 2 + type: floor + - site: + floor: + name: FLOOR1_LEVEL1 + parent_name: Global/USA-Test/BERKELEY/BLDBERK + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + + #India-Test Site Hierarchy + - site: + area: + name: India-Test + parent_name: Global type: area - site: area: name: Bangalore - parent_name: Global/India + parent_name: Global/India-Test type: area - # - site: - # area: - # name: New York - # parent_name: Global/USA - # type: area - # - site: - # area: - # name: SAN-FRANCISCO - # parent_name: Global/USA - # type: area - # - site: - # area: - # name: BERKELEY - # parent_name: Global/USA - # type: area - site: building: name: Mantri Square - parent_name: Global/India/Bangalore + parent_name: Global/India-Test/Bangalore address: Bengaluru, Karnataka, India latitude: 12.969910 longitude: 77.597960 country: India type: building - # - site: - # building: - # name: BLD10 - # parent_name: Global/USA/RTP - # address: Ev Chargers Bldg 10, 7200-10 Kit Creek Rd, Morrisville, North Carolina 27560, United States - # latitude: 35.85992111421487 - # longitude: -78.8829258991226 - # country: United States - # type: building - # - site: - # building: - # name: BLD11 - # parent_name: Global/USA/RTP - # address: Cisco Systems, 7200 Kit Creek Rd, Morrisville, North Carolina 27560, United States - # latitude: 35.86059627310624 - # longitude: -78.88105620286412 - # country: United States - # type: building - # - site: - # building: - # name: BLD12 - # parent_name: Global/USA/RTP - # address: Cisco Systems, 7200-12 Kit Creek Rd, Morrisville, North Carolina 27560, United States - # latitude: 35.8611847591779 - # longitude: -78.88217248318003 - # country: United States - # type: building - # - site: - # building: - # name: BLD23 - # parent_name: Global/USA/SAN JOSE - # address: McCarthy Blvd, San Jose, California 95131, United States - # latitude: 37.398188 - # longitude: -121.912974 - # country: United States - # type: building - # - site: - # building: - # name: BLD20 - # parent_name: Global/USA/SAN JOSE - # address: 725 Alder Drive, Milpitas, California 95035, United States - # latitude: 37.415947 - # longitude: -121.916327 - # country: United States - # type: building - # - site: - # building: - # name: BLD_GB - # parent_name: Global/USA/BayAreaGuest - # address: 725 Alder Drive, Milpitas, California 95035, United States - # latitude: 37.415947 - # longitude: -121.916327 - # country: United States - # type: building - # - site: - # building: - # name: BLDNYC - # parent_name: Global/USA/New York - # address: McCarthy Blvd, San Jose, California 95131, United States - # latitude: 37.398188 - # longitude: -121.912974 - # country: United States - # type: building - # - site: - # building: - # name: BLD_SF - # parent_name: Global/USA/SAN-FRANCISCO - # address: McCarthy Blvd, San Jose, California 95131, United States - # latitude: 37.398188 - # longitude: -121.912974 - # country: United States - # type: building - # - site: - # building: - # name: BLD_SF1 - # parent_name: Global/USA/SAN-FRANCISCO - # address: McCarthy Blvd, San Jose, California 95131, United States - # latitude: 37.398188 - # longitude: -121.912974 - # country: United States - # type: building - # - site: - # building: - # name: BLDBERK - # parent_name: Global/USA/BERKELEY - # address: 725 Alder Drive, Milpitas, California 95035, United States - # latitude: 37.415947 - # longitude: -121.916327 - # country: United States - # type: building - # - site: - # floor: - # name: BLD10_FLOOR1 - # parent_name: Global/USA/RTP/BLD10 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor - # - site: - # floor: - # name: BLD10_FLOOR2 - # parent_name: Global/USA/RTP/BLD10 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 2 - # type: floor - # - site: - # floor: - # name: BLD10_FLOOR3 - # parent_name: Global/USA/RTP/BLD10 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 3 - # type: floor - # - site: - # floor: - # name: BLD11_FLOOR1 - # parent_name: Global/USA/RTP/BLD11 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor - # - site: - # floor: - # name: BLD11_FLOOR2 - # parent_name: Global/USA/RTP/BLD11 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 2 - # type: floor - # - site: - # floor: - # name: BLD11_FLOOR3 - # parent_name: Global/USA/RTP/BLD11 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 3 - # type: floor - # - site: - # floor: - # name: BLD12_FLOOR1 - # parent_name: Global/USA/RTP/BLD12 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor - # - site: - # floor: - # name: BLD12_FLOOR2 - # parent_name: Global/USA/RTP/BLD12 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 2 - # type: floor - # - site: - # floor: - # name: BLD12_FLOOR3 - # parent_name: Global/USA/RTP/BLD12 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 3 - # type: floor - # - site: - # floor: - # name: FLOOR1_LEVEL1 - # parent_name: Global/USA/SAN JOSE/BLD23 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor - # - site: - # floor: - # name: FLOOR1_LEVEL2 - # parent_name: Global/USA/SAN JOSE/BLD23 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor - # - site: - # floor: - # name: FLOOR1_LEVEL3 - # parent_name: Global/USA/SAN JOSE/BLD23 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor - # - site: - # floor: - # name: FLOOR1_LEVEL4 - # parent_name: Global/USA/SAN JOSE/BLD23 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor - # - site: - # floor: - # name: BLD20_FLOOR1 - # parent_name: Global/USA/SAN JOSE/BLD20 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor - # - site: - # floor: - # name: BLD20_FLOOR2 - # parent_name: Global/USA/SAN JOSE/BLD20 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 2 - # type: floor - # - site: - # floor: - # name: FLOOR1 - # parent_name: Global/USA/New York/BLDNYC - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor - # - site: - # floor: - # name: FLOOR2 - # parent_name: Global/USA/New York/BLDNYC - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 2 - # type: floor - # - site: - # floor: - # name: FLOOR1 - # parent_name: Global/USA/SAN-FRANCISCO/BLD_SF - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor - # - site: - # floor: - # name: FLOOR2 - # parent_name: Global/USA/SAN-FRANCISCO/BLD_SF - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 2 - # type: floor - # - site: - # floor: - # name: FLOOR1 - # parent_name: Global/USA/SAN-FRANCISCO/BLD_SF1 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor - # - site: - # floor: - # name: FLOOR2 - # parent_name: Global/USA/SAN-FRANCISCO/BLD_SF1 - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 2 - # type: floor - site: floor: name: Floor1 - parent_name: Global/India/Bangalore/Mantri Square + parent_name: Global/India-Test/Bangalore/Mantri Square rf_model: Cubes And Walled Offices width: 100.00 length: 100.00 height: 10.00 floor_number: 1 type: floor - # - site: - # floor: - # name: FLOOR1_LEVEL1 - # parent_name: Global/USA/BERKELEY/BLDBERK - # rf_model: Cubes And Walled Offices - # width: 100.00 - # length: 100.00 - # height: 10.00 - # floor_number: 1 - # type: floor + + #Mexico Site Hierarchy + - site: + area: + name: Mexico-Test + parent_name: Global + type: area + + #Canada Site Hierarchy + - site: + area: + name: Canada-Test + parent_name: Global + type: area + + +update_sites: + - site: + building: + name: BLD12 + parent_name: Global/USA-Test/RTP + address: Cisco Systems, 7200-12 Kit Creek Rd, Morrisville, North Carolina 27560, United States + latitude: 38.8611847591779 + longitude: 72.88217248318003 + country: United States + type: building + - site: + floor: + name: FLOOR1 + parent_name: Global/USA-Test/SAN-FRANCISCO/BLD_SF + rf_model: Cubes And Walled Offices + width: 200.00 + length: 200.00 + height: 20.00 + floor_number: 1 + type: floor + - site: + building: + name: Mantri Square + parent_name: Global/India-Test/Bangalore + address: Bengaluru, Karnataka, India + latitude: 18.969910 + longitude: 20.597960 + country: India + type: building + - site: + floor: + name: Floor1 + parent_name: Global/India-Test/Bangalore/Mantri Square + rf_model: Cubes And Walled Offices + width: 200.00 + length: 200.00 + height: 20.00 + floor_number: 1 + type: floor + delete_sites: - # - site: - # area: - # name: USA - # parent_name: Global - # type: area - site: area: - name: India + name: USA-Test parent_name: Global type: area - site: area: - name: Mexico + name: India-Test parent_name: Global type: area - site: area: - name: Canada + name: Mexico-Test parent_name: Global - type: area \ No newline at end of file + type: area + - site: + area: + name: Canada-Test + parent_name: Global + type: area From 239d132f68b402a3722283759c7d8185a78c9301 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 15:43:20 -0500 Subject: [PATCH 144/358] testing path filtering --- .circleci/config.yml | 103 ++- .../vars/vars_discovery_management.yml | 47 +- .../tests/test_inventory_management.yml | 807 +++++++++--------- .../vars/vars_inventory_management.yml | 98 +-- 4 files changed, 562 insertions(+), 493 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c08d378daa..0894fe5b85 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,5 +1,8 @@ version: 2.1 +orbs: + path-filtering: circleci/path-filtering@0.1.6 + jobs: pre: @@ -13,6 +16,7 @@ jobs: environment: CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> + CIRCLE_PROJECT_BRANCHNAME: << pipeline.trigger_parameters.github_app.branch >> steps: - run: @@ -20,6 +24,7 @@ jobs: command: | set -x echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" + echo "CIRCLE_PROJECT_BRANCHNAME: $CIRCLE_PROJECT_BRANCHNAME" env - run: name: Remove existing directory and collection tarball @@ -41,6 +46,7 @@ jobs: environment: REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> + CIRCLE_PROJECT_BRANCHNAME: << pipeline.trigger_parameters.github_app.branch >> steps: - run: @@ -52,7 +58,7 @@ jobs: - run: name: Custom Git Clone - command: git clone --depth=1 $REPO_URL + command: git clone --depth=1 -b $CIRCLE_PROJECT_BRANCHNAME $REPO_URL - run: name: Activate Virtual Environment, Install ansible and Build collection tarball @@ -70,6 +76,7 @@ jobs: # Install ansible, dnacentersdk pip install --upgrade pip pip install jinja2 PyYAML cryptography paramiko + pip install pyzipper pip install ansible pip install dnacentersdk ansible --version @@ -86,6 +93,25 @@ jobs: set -x rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME + addrole: + parameters: + modulename: + type: string + + working_directory: ~/repo + machine: true + resource_class: rukapse/dnacenter-ansible + + steps: + - checkout + + - run: + name: Adding role- << parameters.modulename >> + command: | + export MODULENAME="<< parameters.modulename >>" + echo " - $MODULENAME" >> ccc_roles.yaml + cat ccc_roles.yml + sanity-tests: parameters: ansible_cisco_dnac_version: @@ -99,6 +125,7 @@ jobs: environment: REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> + CIRCLE_PROJECT_BRANCHNAME: << pipeline.trigger_parameters.github_app.branch >> steps: - run: @@ -110,7 +137,7 @@ jobs: - run: name: Custom Git Clone - command: git clone --depth=1 $REPO_URL + command: git clone --depth=1 -b $CIRCLE_PROJECT_BRANCHNAME $REPO_URL - run: name: Activate Virtual Environment, Install ansible and Build collection tarball @@ -130,7 +157,8 @@ jobs: # Install ansible, dnacentersdk pip install --upgrade pip - pip install jinja2 PyYAML cryptography paramiko + pip install jinja2 PyYAML cryptography paramiko + pip install pyzipper pip install ansible pip install dnacentersdk ansible --version @@ -153,6 +181,9 @@ jobs: echo " " >> ccc_roles.yml echo " roles:" >> ccc_roles.yml echo " - ccc_site_management" >> ccc_roles.yml + echo " - ccc_device_credential_management" >> ccc_roles.yml + echo " - ccc_discovery_management" >> ccc_roles.yml + echo " - ccc_inventory_management" >> ccc_roles.yml cat ccc_roles.yml @@ -190,15 +221,79 @@ jobs: workflows: - testing: + pre: jobs: - pre + - build: requires: - pre + + - path-filtering/filter: + requires: + - build + base-revision: main + config-path: .circleci/config.yml + mapping: | + plugins/module_utils/.* run-all true + + plugins/modules/site_workflow_manager.py run-site true + plugins/modules/device_credential_workflow_manager.py run-devicecredential true + plugins/modules/discovery_workflow_manager.py run-discovery true + plugins/modules/inventory_workflow_manager.py run-inventory true + + tests/integration/ccc_site_management/.* run-site true + tests/integration/ccc_device_credential_management/.* run-devicecredential true + tests/integration/ccc_discovery_management/.* run-discovery true + tests/integration/ccc_inventory_management/.* run-inventory true + + site: + when: + or: + - << pipeline.parameters.run-all >> + - << pipeline.parameters.run-site >> + jobs: + - addrole: + modulename: + - ccc_site_management + + devicecredential: + when: + or: + - << pipeline.parameters.run-all >> + - << pipeline.parameters.run-devicecredential >> + jobs: + - addrole: + modulename: + - ccc_device_credential_management + + discovery: + when: + or: + - << pipeline.parameters.run-all >> + - << pipeline.parameters.run-discovery >> + jobs: + - addrole: + modulename: + - ccc_discovery_management + + inventory: + when: + or: + - << pipeline.parameters.run-all >> + - << pipeline.parameters.run-inventory >> + jobs: + - addrole: + modulename: + - ccc_inventory_management + + sanity-tests: + jobs: - sanity-tests: requires: - build + + # daily-scheduled: # triggers: # - schedule: diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index 98a9909a03..22786dad68 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -5,30 +5,13 @@ single_ip: ip_address_list: - 204.1.2.5 protocol_order: ssh - discovery_specific_credentials: - cli_credentials_list: - - username: cisco - password: Cisco#123 - enable_password: Cisco#123 - http_read_credential: - username: string - password: Lablab#123 - port: 443 - secure: True - snmp_v2_read_credential: - desc: string - community: string - snmp_v2_write_credential: - desc: string - community: string - snmp_v3_credential: - username: v3Public2 - snmp_mode: AUTHPRIV - auth_type: SHA - auth_password: Lablab#1234 - privacy_type: AES256 - privacy_password: Lablab#1234 - global_cli_len: 3 + # global_credentials: + # cli_credentials_list: + # - description: CLI + # username: cli + # snmp_v3_credential_list: + # - description: snmpV3 + # username: v3Public2 ip_range: - discovery_name: Single Range Discovery 1 @@ -43,6 +26,17 @@ ip_range: - username: cisco password: Cisco#123 enable_password: Cisco#123 + http_read_credential: + username: wlcaccess + password: Lablab#123 + port: 443 + secure: True + snmp_v2_read_credential: + desc: SNMPv2c Read + community: "j5aj#0z%" + snmp_v2_write_credential: + desc: SNMPv2c Write + community: "n2!y9k38" snmp_v3_credential: username: v3Public2 snmp_mode: AUTHPRIV @@ -50,6 +44,10 @@ ip_range: auth_password: Lablab#1234 privacy_type: AES256 privacy_password: Lablab#1234 + protocol_order: ssh + start_index: 1 + records_to_return: 1000 + snmp_version: v2 # Single IP Discovery an already existing discovery # Test case - deleted and recreated when discovery with same name @@ -58,7 +56,6 @@ ip_range: ip_address_list: - 204.1.2.3 protocol_order: ssh - discovery_specific_credentials: global_cli_len: 3 multi_range: diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index 33de4cbd0a..f7021d62f2 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -18,8 +18,7 @@ dnac_debug: "{{ dnac_debug }}" dnac_log: true dnac_log_level: DEBUG - - debug: - msg: "{{ ansible_python_interpreter }}" + # - debug: # msg: "{{ vars_map.device_details }}" # - debug: @@ -33,464 +32,450 @@ # Clean Up # ############################################# -# - name: Delete device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_devices }}" -# register: result_device_deleted - - # - name: Delete site - # cisco.dnac.site_workflow_manager: - # <<: *dnac_login - # config_verify: true - # state: deleted - # config: - # - "{{ item }}" - # loop: "{{ vars_map.delete_sites }}" - # register: result_delete_site + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + - name: Delete site + cisco.dnac.site_workflow_manager: + <<: *dnac_login + config_verify: true + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site # ############################################# # # Add Devices # # ############################################# -# - name: Add new device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# config_verify: true -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_details }}" -# register: result_add_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_add_device.results }}" - -# - name: Assert device addition success -# assert: -# that: -# - item.changed == true -# - "'added to Cisco Catalyst Center' in item.msg" -# loop: "{{ result_add_device.results }}" -# when: result_add_device is defined + - name: Add new device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + config_verify: true + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_details }}" + register: result_add_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_add_device.results }}" + + - name: Assert device addition success + assert: + that: + - item.changed == true + - "'added to Cisco Catalyst Center' in item.msg" + loop: "{{ result_add_device.results }}" + when: result_add_device is defined -# ############################################# -# # Update Device Credential Details # -# ############################################# +############################################# +# Update Device Credential Details # +############################################# -# - name: Update device details -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_credential_updates }}" -# register: result_update_device_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_device_credentials.results }}" -# # when: result_update_device_credentials is defined - -# - name: Assert update -# assert: -# that: -# - item.changed == true -# loop: "{{ result_update_device_credentials.results }}" -# when: result_update_device_credentials is defined + - name: Update device details + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_credential_updates }}" + register: result_update_device_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_credentials.results }}" + # when: result_update_device_credentials is defined + + - name: Assert update + assert: + that: + - item.changed == true + loop: "{{ result_update_device_credentials.results }}" + when: result_update_device_credentials is defined + +############################################ +# Update Device Interface Detials # +############################################# -# ############################################# -# # Update Device Interface Detials # -# ############################################# + # - name: Update device interface details + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_interface_updates }}" + # register: result_update_device_interface -# # - name: Update device interface details -# # cisco.dnac.inventory_workflow_manager: -# # <<: *dnac_login -# # state: merged -# # config: -# # - "{{ item }}" -# # loop: "{{ vars_map.device_interface_updates }}" -# # register: result_update_device_interface - -# # # - name: Debug item -# # # debug: -# # # var: item -# # # loop: "{{ result_update_device_interface.results }}" -# # # when: result_update_device_interface is defined - -# # - name: Assert update -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_update_device_interface.results }}" -# # when: result_update_device_interface is defined + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined -# ############################################# -# # Update Device Role Detials # -# ############################################# + # - name: Assert update + # assert: + # that: + # - item.changed == true + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined -# - name: Update device role details -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_role_updates }}" -# register: result_update_device_role - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_device_role.results }}" -# # when: result_update_device_role is defined - -# - name: Assert device role update -# assert: -# that: -# - result_update_device_role.changed == true -# - "'Device role was successfully updated' in item.response.progress" -# loop: "{{ result_update_device_role.results }}" -# when: result_update_device_role is defined +############################################# +# Update Device Role Detials # +############################################# -# ############################################# -# # Update Device Interface Description # -# ############################################# + # - name: Update device role details + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_role_updates }}" + # register: result_update_device_role -# # - name: Update device interface description post changing role to non-access -# # cisco.dnac.inventory_workflow_manager: -# # <<: *dnac_login -# # state: merged -# # config: -# # - "{{ item }}" -# # loop: "{{ vars_map.device_int_update_post_rolechange }}" -# # register: result_update_device_interface - -# # # - name: Debug item -# # # debug: -# # # var: item -# # # loop: "{{ result_update_device_interface.results }}" -# # # when: result_update_device_interface is defined - -# # - name: Assert update -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_update_device_interface.results }}" -# # when: result_update_device_interface is defined + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_role.results }}" + # when: result_update_device_role is defined -# ############################################# -# # Resync Device # -# ############################################# + # - name: Assert device role update + # assert: + # that: + # - result_update_device_role.changed == true + # - "'Device role was successfully updated' in item.response.progress" + # loop: "{{ result_update_device_role.results }}" + # when: result_update_device_role is defined -# - name: Update device role details -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_resync }}" -# register: result_resync_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_resync_device.results }}" -# # when: result_resync_device is defined - -# - name: Assert device resync -# assert: -# that: -# - result_resync_device.changed == true -# - "'Synced devices' in item.response.progress" -# loop: "{{ result_resync_device.results }}" -# when: result_resync_device is defined +############################################# +# Update Device Interface Description # +############################################# -# ############################################# -# # Create & Assign User Defined Field # -# ############################################# + # - name: Update device interface description post changing role to non-access + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_int_update_post_rolechange }}" + # register: result_update_device_interface -# - name: Create & Assign user defined field -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.create_assign_udf }}" -# register: result_create_assign_udf - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_assign_udf.results }}" -# # when: result_create_assign_udf is defined - -# - name: Assert user defined field creation and assignment -# assert: -# that: -# - item.changed == true -# loop: "{{ result_create_assign_udf.results }}" -# when: result_create_assign_udf is defined + # - name: Debug item + # desbug: + # var: item + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined -# ############################################# -# # Update User Defined Field # -# ############################################# + # - name: Assert update + # assert: + # that: + # - item.changed == true + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined -# - name: Updateuser defined field -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.update_udf }}" -# register: result_update_udf - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_assign_udf.results }}" -# # when: result_update_udf is defined - -# - name: Assert user defined field updated -# assert: -# that: -# - item.changed == true -# loop: "{{ result_update_udf.results }}" -# when: result_update_udf is defined +############################################# +# Resync Device # +############################################# + - name: Update device role details + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_resync }}" + register: result_resync_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_resync_device.results }}" + # when: result_resync_device is defined + + - name: Assert device resync + assert: + that: + - result_resync_device.changed == true + - "'Synced devices' in item.response.progress" + loop: "{{ result_resync_device.results }}" + when: result_resync_device is defined -# ############################################# -# # Delete User Defined Field # -# ############################################# +############################################# +# Create & Assign User Defined Field # +############################################# -# - name: Delete user defined field -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_udf }}" -# register: result_delete_udf - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_udf.results }}" -# # when: result_delete_udf is defined - -# - name: Assert user defined field deletion -# assert: -# that: -# - result_delete_udf.changed == true -# - "'deleted successfully' in item.response.progress" -# loop: "{{ result_delete_udf.results }}" -# when: result_delete_udf is defined + - name: Create & Assign user defined field + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.create_assign_udf }}" + register: result_create_assign_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_assign_udf.results }}" + # when: result_create_assign_udf is defined + + - name: Assert user defined field creation and assignment + assert: + that: + - item.changed == true + loop: "{{ result_create_assign_udf.results }}" + when: result_create_assign_udf is defined +############################################# +# Update User Defined Field # +############################################# -# ############################################# -# # Export Device Details # -# ############################################# + - name: Updateuser defined field + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.update_udf }}" + register: result_update_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_assign_udf.results }}" + # when: result_update_udf is defined + + - name: Assert user defined field updated + assert: + that: + - item.changed == true + loop: "{{ result_update_udf.results }}" + when: result_update_udf is defined -# - name: Export Device Details in a CSV file -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.export_device_details }}" -# register: result_export_details - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_export_details.results }}" -# # when: result_export_details is defined - -# - name: Assert device details export -# assert: -# that: -# - item.changed == true -# loop: "{{ result_export_details.results }}" -# when: result_export_details is defined -# ############################################# -# # Export Device Credential Details # -# ############################################# +############################################# +# Delete User Defined Field # +############################################# -# - name: Export Credential Device Details in a CSV file -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.export_credential_details }}" -# register: result_export_credential_details - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_export_credential_details.results }}" -# # when: result_export_credential_details is defined - -# - name: Assert device credential details export -# assert: -# that: -# - item.changed == true -# loop: "{{ result_export_credential_details.results }}" -# when: result_export_credential_details is defined + - name: Delete user defined field + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_udf }}" + register: result_delete_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_udf.results }}" + # when: result_delete_udf is defined + + - name: Assert user defined field deletion + assert: + that: + - result_delete_udf.changed == true + - "'deleted successfully' in item.response.progress" + loop: "{{ result_delete_udf.results }}" + when: result_delete_udf is defined ############################################# -# CREATE SITE # +# Export Device Details # ############################################# - # - name: Create sites from design_sites config - # cisco.dnac.site_workflow_manager: - # <<: *dnac_login - # config_verify: true - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.design_sites }}" - # register: result_create_site + - name: Export Device Details in a CSV file + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.export_device_details }}" + register: result_export_details + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_export_details.results }}" + # when: result_export_details is defined + + - name: Assert device details export + assert: + that: + - item.changed == true + loop: "{{ result_export_details.results }}" + when: result_export_details is defined - # # - name: Debug item - # # debug: - # # var: item - # # loop: "{{ result_create_site.results }}" - # # when: result_create_site is defined +############################################# +# Export Device Credential Details # +############################################# - # - name: Assert area creation success for each site - # assert: - # that: - # - item.changed == true - # - item.response.status == "SUCCESS" - # - "'created successfully' in item.msg" - # loop: "{{ result_create_site.results }}" - # when: result_create_site is defined + - name: Export Credential Device Details in a CSV file + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.export_credential_details }}" + register: result_export_credential_details + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_export_credential_details.results }}" + # when: result_export_credential_details is defined + + - name: Assert device credential details export + assert: + that: + - item.changed == true + loop: "{{ result_export_credential_details.results }}" + when: result_export_credential_details is defined -# ############################################# -# # ASSOCIATE WIRED DEVICE TO SITE # -# ############################################# -# - name: Assign wired device to site and then provision -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.associate_wired_device }}" -# register: result_associate_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_associate_device.results }}" -# # when: result_associate_device is defined - -# - name: Assert device credential details export -# assert: -# that: -# - item.changed == true -# loop: "{{ result_associate_device.results }}" -# when: result_associate_device is defined +############################################# +# CREATE SITE # +############################################# + + - name: Create sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + config_verify: true + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.design_sites }}" + register: result_create_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + - name: Assert area creation success for each site + assert: + that: + - item.changed == true + - item.response.status == "SUCCESS" + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined ############################################# -# CREATE WIRELESS PROFILE # +# ASSOCIATE WIRED DEVICE TO SITE # ############################################# - - name: Create wireless profile - cisco.dnac.wireless_profile: - dnac_host: "{{dnac_host}}" - dnac_username: "{{dnac_username}}" - dnac_password: "{{dnac_password}}" - dnac_verify: "{{dnac_verify}}" - dnac_port: "{{dnac_port}}" - dnac_version: "{{dnac_version}}" - dnac_debug: "{{dnac_debug}}" - state: present - profileDetails: - name: "ITest_wireless_profile" - sites: - - Global/ITest_Area/ITest_Building/ITest_Floor2 - ssidDetails: - - enableFabric: false - flexConnect: - enableFlexConnect: false - localToVlan: 0 - interfaceName: "etherenet1/1" - name: "itest_ssid" - policyProfileName: "itest_ssid_policy_profile" - wlanProfileName: "itest_ssid_wlan_profile" - register: result_create_wireless_profile - - - name: Debug item - debug: - var: result_create_wireless_profile - when: result_create_wireless_profile is defined + - name: Assign wired device to site and then provision + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.associate_wired_device }}" + register: result_associate_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_associate_device.results }}" + # when: result_associate_device is defined + + - name: Assert device credential details export + assert: + that: + - item.changed == true + loop: "{{ result_associate_device.results }}" + when: result_associate_device is defined ############################################# # ASSOCIATE WIRELESS DEVICE TO SITE # ############################################# + # - name: Assign wireless device to site and then provision + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.associate_wireless_device }}" + # register: result_associate_device -# ############################################# -# # Delete Devices # -# ############################################# + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_associate_device.results }}" + # when: result_associate_device is defined -# - name: Delete device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_devices }}" -# register: result_device_deleted - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_device_deleted.results }}" -# # when: result_device_deleted is defined - -# - name: Assert device deletion success -# assert: -# that: -# - result_device_deleted.changed == true -# when: result_device_deleted is defined + # - name: Assert device credential details export + # assert: + # that: + # - item.changed == true + # loop: "{{ result_associate_device.results }}" + # when: result_associate_device is defined -# ############################################# -# # DELETE SITE # -# ############################################# +############################################# +# Delete Devices # +############################################# + + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_device_deleted.results }}" + # when: result_device_deleted is defined + + - name: Assert device deletion success + assert: + that: + - result_device_deleted.changed == true + when: result_device_deleted is defined + +############################################# +# DELETE SITE # +############################################# -# - name: Delete sites from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# config_verify: true -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" -# register: result_delete_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_site.results }}" -# # when: result_delete_site is defined - -# - name: Assert deletion of area success for each site -# assert: -# that: -# - item.changed == true -# - "'deleted successfully' in item.response" -# loop: "{{ result_delete_site.results }}" -# when: result_delete_site is defined + - name: Delete sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + config_verify: true + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined + + - name: Assert deletion of area success for each site + assert: + that: + - item.changed == true + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 05a7b3a671..13c0aa5d57 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -22,37 +22,37 @@ device_details: cli_transport: "ssh" netconf_port: 830 - - type: "NETWORK_DEVICE" - ip_address_list: ["204.192.6.200"] - device_added: True - # CLI Credentials - username: "cisco" - password: "Cisco#123" - enable_password: "Cisco#123" - # HTTP Credentials - http_username: "wlcaccess" - http_password: "Lablab#123" - http_port: "443" - http_secure: False - # SNMP Credentials - snmp_version: v3 - snmp_username: "v3Public2" - snmp_mode: "AUTHPRIV" - snmp_auth_protocol: "SHA" - snmp_auth_passphrase: "Lablab#1234" - snmp_priv_protocol: "CISCOAES256" - snmp_priv_passphrase: "Lablab#1234" - #SNMP Retry and Timeout - snmp_retry: 3 - snmp_timeout: 5 - #CLI Transport (ssh, Telnet) - cli_transport: "ssh" - netconf_port: 830 + # - type: "NETWORK_DEVICE" + # ip_address_list: ["204.192.6.200"] + # device_added: True + # # CLI Credentials + # username: "cisco" + # password: "Cisco#123" + # enable_password: "Cisco#123" + # # HTTP Credentials + # http_username: "wlcaccess" + # http_password: "Lablab#123" + # http_port: "443" + # http_secure: False + # # SNMP Credentials + # snmp_version: v3 + # snmp_username: "v3Public2" + # snmp_mode: "AUTHPRIV" + # snmp_auth_protocol: "SHA" + # snmp_auth_passphrase: "Lablab#1234" + # snmp_priv_protocol: "AES256" + # snmp_priv_passphrase: "Lablab#1234" + # #SNMP Retry and Timeout + # snmp_retry: 3 + # snmp_timeout: 5 + # #CLI Transport (ssh, Telnet) + # cli_transport: "ssh"s + # netconf_port: 830 device_credential_updates: # Update CLI password - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5", "204.192.6.200"] + ip_address_list: ["204.1.2.5"] device_updated: True credential_update: True # CLI Credentials @@ -61,7 +61,7 @@ device_credential_updates: # Update SNMP privacy type - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5", "204.192.6.200"] + ip_address_list: ["204.1.2.5"] device_updated: True credential_update: True # SNMP Credentials @@ -70,7 +70,7 @@ device_credential_updates: # Update SNMP username - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5", "204.192.6.200"] + ip_address_list: ["204.1.2.5"] device_updated: True credential_update: True # SNMP Credentials @@ -79,7 +79,7 @@ device_credential_updates: # Update SNMP mode - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5", "204.192.6.200"] + ip_address_list: ["204.1.2.5"] device_updated: True credential_update: True # SNMP Credentials @@ -88,7 +88,7 @@ device_credential_updates: # Update cli_transport - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5", "204.192.6.200"] + ip_address_list: ["204.1.2.5"] device_updated: True credential_update: True #change cli_transport from ssh to telnet @@ -96,7 +96,7 @@ device_credential_updates: # SNMPv2 credentials - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5", "204.192.6.200"] + ip_address_list: ["204.1.2.5"] device_updated: True credential_update: True snmp_version: v2 @@ -105,7 +105,7 @@ device_credential_updates: # Reverse changes - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5", "204.192.6.200"] + ip_address_list: ["204.1.2.5"] device_updated: True credential_update: True # CLI Credentials @@ -141,9 +141,8 @@ device_role_updates: #Update role from access to core - ip_address_list: ["204.1.2.5"] device_updated: True - # Role details update_device_role: - role: CORE + role: ACCESS device_int_update_post_rolechange: # Update Interface description @@ -228,16 +227,7 @@ design_sites: height: 10.00 floor_number: 1 type: floor - - site: - floor: - name: ITest_Floor2 - parent_name: Global/ITest_Area/ITest_Building - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 2 - type: floor + associate_wired_device: - provision_wired_device: @@ -247,16 +237,17 @@ associate_wired_device: resync_interval: 2 associate_wireless_device: - - provision_wired_device: + - provision_wireless_device: - device_ip: "204.192.6.200" - site_name: "Global/ITest_Area/ITest_Building/ITest_Floor2" + site_name: "Global/ITest_Inventory_P_Area/ITest_Inventory_Building/ITest_Inventory_Floor1" + managed_ap_locations: ["Global/ITest_Inventory_P_Area/ITest_Inventory_Building/ITest_Inventory_Floor1", "Global/ITest_Inventory_S_Area/ITest_Inventory_Building/ITest_Inventory_Floor1"] dynamic_interfaces: - - interface_ip_address: 32.31.12.23 - interface_netmask_in_cidr: 26 - interface_gateway: "gateway_test" - lag_or_port_number: 33 - vlan_id: 78 - interface_name: "etherenet1/1" + - interface_ip_address: 23.23.21.12 + interface_netmask_in_cidr: 24 + interface_gateway: "gateway" + lag_or_port_number: 12 + vlan_id: 99 + interface_name: "management" resync_retry_count: 200 resync_retry_interval: 2 @@ -269,4 +260,5 @@ delete_sites: delete_devices: - ip_address_list: ["204.1.2.5"] + #ip_address_list: ["204.1.2.5", "204.192.6.200"] clean_config: False \ No newline at end of file From 8690e81b547196a1dac13c94bf90ba65566b1d1e Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 15:47:21 -0500 Subject: [PATCH 145/358] testing path filtering --- .circleci/config.yml | 34 +++++++++---------- .../vars/vars_site_management.yml | 1 - 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0894fe5b85..c046c706db 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -228,24 +228,24 @@ workflows: - build: requires: - pre - + - path-filtering/filter: - requires: - - build - base-revision: main - config-path: .circleci/config.yml - mapping: | - plugins/module_utils/.* run-all true - - plugins/modules/site_workflow_manager.py run-site true - plugins/modules/device_credential_workflow_manager.py run-devicecredential true - plugins/modules/discovery_workflow_manager.py run-discovery true - plugins/modules/inventory_workflow_manager.py run-inventory true - - tests/integration/ccc_site_management/.* run-site true - tests/integration/ccc_device_credential_management/.* run-devicecredential true - tests/integration/ccc_discovery_management/.* run-discovery true - tests/integration/ccc_inventory_management/.* run-inventory true + requires: + - build + base-revision: main + config-path: .circleci/config.yml + mapping: | + plugins/module_utils/.* run-all true + + plugins/modules/site_workflow_manager.py run-site true + plugins/modules/device_credential_workflow_manager.py run-devicecredential true + plugins/modules/discovery_workflow_manager.py run-discovery true + plugins/modules/inventory_workflow_manager.py run-inventory true + + tests/integration/ccc_site_management/.* run-site true + tests/integration/ccc_device_credential_management/.* run-devicecredential true + tests/integration/ccc_discovery_management/.* run-discovery true + tests/integration/ccc_inventory_management/.* run-inventory true site: when: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..179157040c 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,7 +433,6 @@ update_sites: floor_number: 1 type: floor - delete_sites: - site: area: From 900a37f0177b8d699a92f4d5ed7305c76608fae5 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 15:50:04 -0500 Subject: [PATCH 146/358] testing path filtering --- .circleci/config.yml | 19 ++++++++++++++++++- .../vars/vars_site_management.yml | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c046c706db..5c0d03db9f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,6 +3,23 @@ version: 2.1 orbs: path-filtering: circleci/path-filtering@0.1.6 +parameters: + run-all: + type: boolean + default: false + run-site: + type: boolean + default: true + run-devicecredential: + type: boolean + default: false + run-discovery: + type: boolean + default: false + run-inventory: + type: boolean + default: false + jobs: pre: @@ -228,7 +245,7 @@ workflows: - build: requires: - pre - + - path-filtering/filter: requires: - build diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 179157040c..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,6 +433,7 @@ update_sites: floor_number: 1 type: floor + delete_sites: - site: area: From 3c4c84c411ef86a3eacac4c4d0314f8c9f16d719 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 15:53:52 -0500 Subject: [PATCH 147/358] testing path filtering --- .circleci/config.yml | 12 ++++-------- .../vars/vars_site_management.yml | 1 - 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5c0d03db9f..5613397768 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -271,8 +271,7 @@ workflows: - << pipeline.parameters.run-site >> jobs: - addrole: - modulename: - - ccc_site_management + modulename: ccc_site_management devicecredential: when: @@ -281,8 +280,7 @@ workflows: - << pipeline.parameters.run-devicecredential >> jobs: - addrole: - modulename: - - ccc_device_credential_management + modulename: ccc_device_credential_management discovery: when: @@ -291,8 +289,7 @@ workflows: - << pipeline.parameters.run-discovery >> jobs: - addrole: - modulename: - - ccc_discovery_management + modulename: ccc_discovery_management inventory: when: @@ -301,8 +298,7 @@ workflows: - << pipeline.parameters.run-inventory >> jobs: - addrole: - modulename: - - ccc_inventory_management + modulename: ccc_inventory_management sanity-tests: jobs: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..179157040c 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,7 +433,6 @@ update_sites: floor_number: 1 type: floor - delete_sites: - site: area: From 59592ce6d0361aabf71bc0dc2d8a6ed066305853 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:03:19 -0500 Subject: [PATCH 148/358] testing path filtering --- .circleci/config.yml | 2 -- .../ccc_site_management/vars/vars_site_management.yml | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5613397768..393f5a1cd8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -303,8 +303,6 @@ workflows: sanity-tests: jobs: - sanity-tests: - requires: - - build # daily-scheduled: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 179157040c..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,6 +433,7 @@ update_sites: floor_number: 1 type: floor + delete_sites: - site: area: From 3e485d1a94c4a8691fb412f18416bd7487dd3015 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:04:06 -0500 Subject: [PATCH 149/358] testing path filtering --- .circleci/config.yml | 2 +- .../ccc_site_management/vars/vars_site_management.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 393f5a1cd8..155a5441b0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -302,7 +302,7 @@ workflows: sanity-tests: jobs: - - sanity-tests: + - sanity-tests # daily-scheduled: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..179157040c 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,7 +433,6 @@ update_sites: floor_number: 1 type: floor - delete_sites: - site: area: From a40c696b50e5b8197401431ecbcf162059d5a642 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:10:22 -0500 Subject: [PATCH 150/358] testing path filtering --- .circleci/config.yml | 15 ++++++++++++++- .../vars/vars_site_management.yml | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 155a5441b0..800d5c5af6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -120,7 +120,6 @@ jobs: resource_class: rukapse/dnacenter-ansible steps: - - checkout - run: name: Adding role- << parameters.modulename >> @@ -272,6 +271,8 @@ workflows: jobs: - addrole: modulename: ccc_site_management + requires: + - build devicecredential: when: @@ -281,6 +282,8 @@ workflows: jobs: - addrole: modulename: ccc_device_credential_management + requires: + - build discovery: when: @@ -290,6 +293,8 @@ workflows: jobs: - addrole: modulename: ccc_discovery_management + requires: + - build inventory: when: @@ -299,10 +304,18 @@ workflows: jobs: - addrole: modulename: ccc_inventory_management + requires: + - build sanity-tests: jobs: - sanity-tests + requires: + - build + - site + - devicecredential + - discovery + - inventory # daily-scheduled: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 179157040c..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,6 +433,7 @@ update_sites: floor_number: 1 type: floor + delete_sites: - site: area: From 35419122631783acfc169390e8b6f58bac95de55 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:14:37 -0500 Subject: [PATCH 151/358] testing path filtering --- .circleci/config.yml | 30 ++++++++++--------- .../vars/vars_site_management.yml | 1 - 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 800d5c5af6..96e643baca 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -271,8 +271,8 @@ workflows: jobs: - addrole: modulename: ccc_site_management - requires: - - build + requires: + - build devicecredential: when: @@ -282,8 +282,8 @@ workflows: jobs: - addrole: modulename: ccc_device_credential_management - requires: - - build + requires: + - build discovery: when: @@ -293,8 +293,8 @@ workflows: jobs: - addrole: modulename: ccc_discovery_management - requires: - - build + requires: + - build inventory: when: @@ -304,18 +304,20 @@ workflows: jobs: - addrole: modulename: ccc_inventory_management - requires: - - build + requires: + - build sanity-tests: + when: + always: true jobs: - sanity-tests - requires: - - build - - site - - devicecredential - - discovery - - inventory + requires: + - build + - site + - devicecredential + - discovery + - inventory # daily-scheduled: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..179157040c 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,7 +433,6 @@ update_sites: floor_number: 1 type: floor - delete_sites: - site: area: From 93638195367cad33590a4a315bb14d1dbc1cb885 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:16:56 -0500 Subject: [PATCH 152/358] testing path filtering --- .circleci/config.yml | 53 ++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 96e643baca..f609ad7595 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -240,28 +240,24 @@ workflows: pre: jobs: - pre - - build: requires: - pre - - path-filtering/filter: requires: - - build + - build base-revision: main config-path: .circleci/config.yml mapping: | - plugins/module_utils/.* run-all true - - plugins/modules/site_workflow_manager.py run-site true - plugins/modules/device_credential_workflow_manager.py run-devicecredential true - plugins/modules/discovery_workflow_manager.py run-discovery true - plugins/modules/inventory_workflow_manager.py run-inventory true - - tests/integration/ccc_site_management/.* run-site true - tests/integration/ccc_device_credential_management/.* run-devicecredential true - tests/integration/ccc_discovery_management/.* run-discovery true - tests/integration/ccc_inventory_management/.* run-inventory true + plugins/module_utils/.* run-all true + plugins/modules/site_workflow_manager.py run-site true + plugins/modules/device_credential_workflow_manager.py run-devicecredential true + plugins/modules/discovery_workflow_manager.py run-discovery true + plugins/modules/inventory_workflow_manager.py run-inventory true + tests/integration/ccc_site_management/.* run-site true + tests/integration/ccc_device_credential_management/.* run-devicecredential true + tests/integration/ccc_discovery_management/.* run-discovery true + tests/integration/ccc_inventory_management/.* run-inventory true site: when: @@ -271,8 +267,8 @@ workflows: jobs: - addrole: modulename: ccc_site_management - requires: - - build + requires: + - build devicecredential: when: @@ -282,8 +278,8 @@ workflows: jobs: - addrole: modulename: ccc_device_credential_management - requires: - - build + requires: + - site discovery: when: @@ -293,8 +289,8 @@ workflows: jobs: - addrole: modulename: ccc_discovery_management - requires: - - build + requires: + - devicecredential inventory: when: @@ -304,21 +300,20 @@ workflows: jobs: - addrole: modulename: ccc_inventory_management - requires: - - build + requires: + - discovery sanity-tests: when: always: true jobs: - sanity-tests - requires: - - build - - site - - devicecredential - - discovery - - inventory - + requires: + - build + - site + - devicecredential + - discovery + - inventory # daily-scheduled: # triggers: From a68f328e16f46df0a5e48f0bb7a6bb1957d6b30e Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:17:18 -0500 Subject: [PATCH 153/358] testing path filtering --- .circleci/config.yml | 1 + .../ccc_site_management/vars/vars_site_management.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index f609ad7595..850a3ff366 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -315,6 +315,7 @@ workflows: - discovery - inventory + # daily-scheduled: # triggers: # - schedule: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 179157040c..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,6 +433,7 @@ update_sites: floor_number: 1 type: floor + delete_sites: - site: area: From 719cecc661acac5a09a2fa625dd8c0974ca6cde8 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:24:43 -0500 Subject: [PATCH 154/358] testing path filtering --- .circleci/config.yml | 53 ++++++++++--------- .../vars/vars_site_management.yml | 1 - 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 850a3ff366..c6dddbb666 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -240,24 +240,28 @@ workflows: pre: jobs: - pre + - build: requires: - pre + - path-filtering/filter: requires: - - build + - build base-revision: main config-path: .circleci/config.yml mapping: | - plugins/module_utils/.* run-all true - plugins/modules/site_workflow_manager.py run-site true - plugins/modules/device_credential_workflow_manager.py run-devicecredential true - plugins/modules/discovery_workflow_manager.py run-discovery true - plugins/modules/inventory_workflow_manager.py run-inventory true - tests/integration/ccc_site_management/.* run-site true - tests/integration/ccc_device_credential_management/.* run-devicecredential true - tests/integration/ccc_discovery_management/.* run-discovery true - tests/integration/ccc_inventory_management/.* run-inventory true + plugins/module_utils/.* run-all true + + plugins/modules/site_workflow_manager.py run-site true + plugins/modules/device_credential_workflow_manager.py run-devicecredential true + plugins/modules/discovery_workflow_manager.py run-discovery true + plugins/modules/inventory_workflow_manager.py run-inventory true + + tests/integration/ccc_site_management/.* run-site true + tests/integration/ccc_device_credential_management/.* run-devicecredential true + tests/integration/ccc_discovery_management/.* run-discovery true + tests/integration/ccc_inventory_management/.* run-inventory true site: when: @@ -267,8 +271,8 @@ workflows: jobs: - addrole: modulename: ccc_site_management - requires: - - build + requires: + - build devicecredential: when: @@ -278,8 +282,8 @@ workflows: jobs: - addrole: modulename: ccc_device_credential_management - requires: - - site + requires: + - build discovery: when: @@ -289,8 +293,8 @@ workflows: jobs: - addrole: modulename: ccc_discovery_management - requires: - - devicecredential + requires: + - build inventory: when: @@ -300,20 +304,19 @@ workflows: jobs: - addrole: modulename: ccc_inventory_management - requires: - - discovery + requires: + - build sanity-tests: when: always: true jobs: - - sanity-tests - requires: - - build - - site - - devicecredential - - discovery - - inventory + - sanity-tests: + requires: + - site + - devicecredential + - discovery + - inventory # daily-scheduled: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..179157040c 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,7 +433,6 @@ update_sites: floor_number: 1 type: floor - delete_sites: - site: area: From 17472c4ae7cc1a84993ef1f0724f9c194bdf4194 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:33:47 -0500 Subject: [PATCH 155/358] testing path filtering --- .circleci/config.yml | 28 +++++++++---------- .../vars/vars_site_management.yml | 1 + 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c6dddbb666..70642c1976 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -271,8 +271,8 @@ workflows: jobs: - addrole: modulename: ccc_site_management - requires: - - build + requires: + - pre devicecredential: when: @@ -282,8 +282,8 @@ workflows: jobs: - addrole: modulename: ccc_device_credential_management - requires: - - build + requires: + - pre discovery: when: @@ -293,8 +293,8 @@ workflows: jobs: - addrole: modulename: ccc_discovery_management - requires: - - build + requires: + - pre inventory: when: @@ -304,19 +304,19 @@ workflows: jobs: - addrole: modulename: ccc_inventory_management - requires: - - build + requires: + - pre sanity-tests: when: always: true jobs: - - sanity-tests: - requires: - - site - - devicecredential - - discovery - - inventory + - sanity-tests + requires: + - site + - devicecredential + - discovery + - inventory # daily-scheduled: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 179157040c..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,6 +433,7 @@ update_sites: floor_number: 1 type: floor + delete_sites: - site: area: From 329ae00f8245cf33e45c3b20f021f93002b63e34 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:34:37 -0500 Subject: [PATCH 156/358] testing path filtering --- .circleci/config.yml | 2 +- .../ccc_site_management/vars/vars_site_management.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 70642c1976..caffba9170 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -311,7 +311,7 @@ workflows: when: always: true jobs: - - sanity-tests + - sanity-tests: requires: - site - devicecredential diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..179157040c 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,7 +433,6 @@ update_sites: floor_number: 1 type: floor - delete_sites: - site: area: From 05e91e191ec33db306e2223a2397bfe1bd675642 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:41:11 -0500 Subject: [PATCH 157/358] testing path filtering --- .circleci/config.yml | 26 +++++++++---------- .../vars/vars_site_management.yml | 1 + 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index caffba9170..7c5fb851fc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -271,8 +271,8 @@ workflows: jobs: - addrole: modulename: ccc_site_management - requires: - - pre + requires: + - build devicecredential: when: @@ -282,8 +282,8 @@ workflows: jobs: - addrole: modulename: ccc_device_credential_management - requires: - - pre + requires: + - build discovery: when: @@ -293,8 +293,8 @@ workflows: jobs: - addrole: modulename: ccc_discovery_management - requires: - - pre + requires: + - build inventory: when: @@ -304,19 +304,17 @@ workflows: jobs: - addrole: modulename: ccc_inventory_management - requires: - - pre + requires: + - build sanity-tests: when: always: true jobs: - - sanity-tests: - requires: - - site - - devicecredential - - discovery - - inventory + - sanity-tests + requires: + - build + - addrole # daily-scheduled: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 179157040c..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,6 +433,7 @@ update_sites: floor_number: 1 type: floor + delete_sites: - site: area: From 56a144da892f6fa124783d81e437e4099f4049ff Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:42:04 -0500 Subject: [PATCH 158/358] testing path filtering --- .circleci/config.yml | 2 +- .../ccc_site_management/vars/vars_site_management.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7c5fb851fc..652c389c20 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -311,7 +311,7 @@ workflows: when: always: true jobs: - - sanity-tests + - sanity-tests: requires: - build - addrole diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..179157040c 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,7 +433,6 @@ update_sites: floor_number: 1 type: floor - delete_sites: - site: area: From bef976261e71899ed298a7da6b055fba8d5f9c15 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:55:12 -0500 Subject: [PATCH 159/358] testing path filtering --- .circleci/config.yml | 97 ++++++------------- .../vars/vars_site_management.yml | 1 + 2 files changed, 31 insertions(+), 67 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 652c389c20..65547a812e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,22 +3,6 @@ version: 2.1 orbs: path-filtering: circleci/path-filtering@0.1.6 -parameters: - run-all: - type: boolean - default: false - run-site: - type: boolean - default: true - run-devicecredential: - type: boolean - default: false - run-discovery: - type: boolean - default: false - run-inventory: - type: boolean - default: false jobs: @@ -114,6 +98,21 @@ jobs: parameters: modulename: type: string + run-all: + type: boolean + default: false + run-site: + type: boolean + default: true + run-devicecredential: + type: boolean + default: false + run-discovery: + type: boolean + default: false + run-inventory: + type: boolean + default: false working_directory: ~/repo machine: true @@ -124,9 +123,19 @@ jobs: - run: name: Adding role- << parameters.modulename >> command: | - export MODULENAME="<< parameters.modulename >>" - echo " - $MODULENAME" >> ccc_roles.yaml - cat ccc_roles.yml + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-site }} == true ]]; then + export MODULENAME="ccc_site_management" + echo " - $MODULENAME" >> ccc_roles.yaml + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-devicecredential }} == true ]]; then + export MODULENAME="ccc_device_credential_management" + echo " - $MODULENAME" >> ccc_roles.yaml + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-discovery }} == true ]]; then + export MODULENAME="ccc_discovery_management" + echo " - $MODULENAME" >> ccc_roles.yaml + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-inventory }} == true ]]; then + export MODULENAME="ccc_inventory_management" + echo " - $MODULENAME" >> ccc_roles.yaml + sanity-tests: parameters: @@ -237,7 +246,7 @@ jobs: workflows: - pre: + testing: jobs: - pre @@ -247,7 +256,7 @@ workflows: - path-filtering/filter: requires: - - build + - build base-revision: main config-path: .circleci/config.yml mapping: | @@ -263,60 +272,14 @@ workflows: tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true - site: - when: - or: - - << pipeline.parameters.run-all >> - - << pipeline.parameters.run-site >> - jobs: - - addrole: - modulename: ccc_site_management - requires: - - build - - devicecredential: - when: - or: - - << pipeline.parameters.run-all >> - - << pipeline.parameters.run-devicecredential >> - jobs: - addrole: - modulename: ccc_device_credential_management requires: - build - discovery: - when: - or: - - << pipeline.parameters.run-all >> - - << pipeline.parameters.run-discovery >> - jobs: - - addrole: - modulename: ccc_discovery_management - requires: - - build - - inventory: - when: - or: - - << pipeline.parameters.run-all >> - - << pipeline.parameters.run-inventory >> - jobs: - - addrole: - modulename: ccc_inventory_management - requires: - - build - - sanity-tests: - when: - always: true - jobs: - sanity-tests: requires: - - build - addrole - # daily-scheduled: # triggers: # - schedule: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 179157040c..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,6 +433,7 @@ update_sites: floor_number: 1 type: floor + delete_sites: - site: area: From 951535b620f930ae85ba01028b370ad13484a1fd Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 16:58:10 -0500 Subject: [PATCH 160/358] testing path filtering --- .circleci/config.yml | 38 +++++++++---------- .../vars/vars_site_management.yml | 1 - 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 65547a812e..3f59938868 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,6 +3,24 @@ version: 2.1 orbs: path-filtering: circleci/path-filtering@0.1.6 +parameters: + modulename: + type: string + run-all: + type: boolean + default: false + run-site: + type: boolean + default: true + run-devicecredential: + type: boolean + default: false + run-discovery: + type: boolean + default: false + run-inventory: + type: boolean + default: false jobs: @@ -95,31 +113,11 @@ jobs: rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME addrole: - parameters: - modulename: - type: string - run-all: - type: boolean - default: false - run-site: - type: boolean - default: true - run-devicecredential: - type: boolean - default: false - run-discovery: - type: boolean - default: false - run-inventory: - type: boolean - default: false - working_directory: ~/repo machine: true resource_class: rukapse/dnacenter-ansible steps: - - run: name: Adding role- << parameters.modulename >> command: | diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..179157040c 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,7 +433,6 @@ update_sites: floor_number: 1 type: floor - delete_sites: - site: area: From d59151ad825c05ce7673c40f10686f19fe8ee41c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 17:13:01 -0500 Subject: [PATCH 161/358] testing path filtering --- .circleci/config.yml | 20 +++++++++++++------ .../vars/vars_site_management.yml | 1 + 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3f59938868..4a0e4af4bd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,8 +4,6 @@ orbs: path-filtering: circleci/path-filtering@0.1.6 parameters: - modulename: - type: string run-all: type: boolean default: false @@ -113,6 +111,10 @@ jobs: rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME addrole: + parameters: + modulename: + type: string + working_directory: ~/repo machine: true resource_class: rukapse/dnacenter-ansible @@ -121,18 +123,24 @@ jobs: - run: name: Adding role- << parameters.modulename >> command: | - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-site }} == true ]]; then + if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-site }} == true ]]; then export MODULENAME="ccc_site_management" echo " - $MODULENAME" >> ccc_roles.yaml - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-devicecredential }} == true ]]; then + fi + if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-devicecredential }} == true ]]; then export MODULENAME="ccc_device_credential_management" echo " - $MODULENAME" >> ccc_roles.yaml - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-discovery }} == true ]]; then + fi + if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-discovery }} == true ]]; then export MODULENAME="ccc_discovery_management" echo " - $MODULENAME" >> ccc_roles.yaml - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-inventory }} == true ]]; then + fi + if [[ ${{ pipeline.parameters.run-all }} == true || ${{ spipeline.parameters.run-inventory }} == true ]]; then export MODULENAME="ccc_inventory_management" echo " - $MODULENAME" >> ccc_roles.yaml + fi + + cat ccc_roles.yml sanity-tests: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 179157040c..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,6 +433,7 @@ update_sites: floor_number: 1 type: floor + delete_sites: - site: area: From 89e9748c6b7eaf0cd67ff6ff8ccd3d4330b6a1f2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 17:15:41 -0500 Subject: [PATCH 162/358] testing path filtering --- .circleci/config.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4a0e4af4bd..c0a41f8c01 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -111,9 +111,6 @@ jobs: rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME addrole: - parameters: - modulename: - type: string working_directory: ~/repo machine: true @@ -121,7 +118,7 @@ jobs: steps: - run: - name: Adding role- << parameters.modulename >> + name: Adding role command: | if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-site }} == true ]]; then export MODULENAME="ccc_site_management" From 5c11402e71b289b8a51cfc596251e70f052cde73 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 17:19:18 -0500 Subject: [PATCH 163/358] testing path filtering --- .circleci/config.yml | 63 +++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c0a41f8c01..9c9e26b599 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -110,35 +110,6 @@ jobs: set -x rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME - addrole: - - working_directory: ~/repo - machine: true - resource_class: rukapse/dnacenter-ansible - - steps: - - run: - name: Adding role - command: | - if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-site }} == true ]]; then - export MODULENAME="ccc_site_management" - echo " - $MODULENAME" >> ccc_roles.yaml - fi - if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-devicecredential }} == true ]]; then - export MODULENAME="ccc_device_credential_management" - echo " - $MODULENAME" >> ccc_roles.yaml - fi - if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-discovery }} == true ]]; then - export MODULENAME="ccc_discovery_management" - echo " - $MODULENAME" >> ccc_roles.yaml - fi - if [[ ${{ pipeline.parameters.run-all }} == true || ${{ spipeline.parameters.run-inventory }} == true ]]; then - export MODULENAME="ccc_inventory_management" - echo " - $MODULENAME" >> ccc_roles.yaml - fi - - cat ccc_roles.yml - sanity-tests: parameters: @@ -208,10 +179,28 @@ jobs: echo " debug: false" >> ccc_roles.yml echo " " >> ccc_roles.yml echo " roles:" >> ccc_roles.yml - echo " - ccc_site_management" >> ccc_roles.yml - echo " - ccc_device_credential_management" >> ccc_roles.yml - echo " - ccc_discovery_management" >> ccc_roles.yml - echo " - ccc_inventory_management" >> ccc_roles.yml + + cat ccc_roles.yml + + - run: + name: Adding role + command: | + if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-site }} == true ]]; then + export MODULENAME="ccc_site_management" + echo " - $MODULENAME" >> ccc_roles.yaml + fi + if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-devicecredential }} == true ]]; then + export MODULENAME="ccc_device_credential_management" + echo " - $MODULENAME" >> ccc_roles.yaml + fi + if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-discovery }} == true ]]; then + export MODULENAME="ccc_discovery_management" + echo " - $MODULENAME" >> ccc_roles.yaml + fi + if [[ ${{ pipeline.parameters.run-all }} == true || ${{ spipeline.parameters.run-inventory }} == true ]]; then + export MODULENAME="ccc_inventory_management" + echo " - $MODULENAME" >> ccc_roles.yaml + fi cat ccc_roles.yml @@ -249,7 +238,7 @@ jobs: workflows: - testing: + integration-testing: jobs: - pre @@ -275,13 +264,9 @@ workflows: tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true - - addrole: - requires: - - build - - sanity-tests: requires: - - addrole + - path-filtering/filter # daily-scheduled: # triggers: From 3246d1c5f4d3b09f12919bdebfca4d1a2ffeba78 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 17:25:34 -0500 Subject: [PATCH 164/358] testing path filtering --- .circleci/config.yml | 2 ++ .../ccc_site_management/vars/vars_site_management.yml | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9c9e26b599..81074971e9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,5 +1,7 @@ version: 2.1 +setup: true + orbs: path-filtering: circleci/path-filtering@0.1.6 diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..179157040c 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,7 +433,6 @@ update_sites: floor_number: 1 type: floor - delete_sites: - site: area: From e1a229941969a32125cedd1479e0a312d95ededb Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 17:33:38 -0500 Subject: [PATCH 165/358] testing path filtering --- .circleci/config.yml | 8 ++++---- .../ccc_site_management/vars/vars_site_management.yml | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 81074971e9..9920c9a3b4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -187,19 +187,19 @@ jobs: - run: name: Adding role command: | - if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-site }} == true ]]; then + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-site }} == true ]]; then export MODULENAME="ccc_site_management" echo " - $MODULENAME" >> ccc_roles.yaml fi - if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-devicecredential }} == true ]]; then + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-devicecredential }} == true ]]; then export MODULENAME="ccc_device_credential_management" echo " - $MODULENAME" >> ccc_roles.yaml fi - if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters.run-discovery }} == true ]]; then + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-discovery }} == true ]]; then export MODULENAME="ccc_discovery_management" echo " - $MODULENAME" >> ccc_roles.yaml fi - if [[ ${{ pipeline.parameters.run-all }} == true || ${{ spipeline.parameters.run-inventory }} == true ]]; then + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-inventory }} == true ]]; then export MODULENAME="ccc_inventory_management" echo " - $MODULENAME" >> ccc_roles.yaml fi diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 179157040c..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,6 +433,7 @@ update_sites: floor_number: 1 type: floor + delete_sites: - site: area: From 49aae6f97afa5809d513c642fc1743e712cb4466 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 19:37:14 -0500 Subject: [PATCH 166/358] testing path filtering --- .circleci/config.yml | 8 ++++---- .../ccc_site_management/vars/vars_site_management.yml | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9920c9a3b4..5dbd273bfa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -187,19 +187,19 @@ jobs: - run: name: Adding role command: | - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-site }} == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-site >> == true ]]; then export MODULENAME="ccc_site_management" echo " - $MODULENAME" >> ccc_roles.yaml fi - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-devicecredential }} == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-devicecredential >> == true ]]; then export MODULENAME="ccc_device_credential_management" echo " - $MODULENAME" >> ccc_roles.yaml fi - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-discovery }} == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-discovery >> == true ]]; then export MODULENAME="ccc_discovery_management" echo " - $MODULENAME" >> ccc_roles.yaml fi - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-inventory }} == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-inventory >> == true ]]; then export MODULENAME="ccc_inventory_management" echo " - $MODULENAME" >> ccc_roles.yaml fi diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..179157040c 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,7 +433,6 @@ update_sites: floor_number: 1 type: floor - delete_sites: - site: area: From c0c756ae7f86c459229164df935134586f03649a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 20:51:34 -0500 Subject: [PATCH 167/358] testing path filtering --- .circleci/config.yml | 8 ++++---- .../ccc_site_management/vars/vars_site_management.yml | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5dbd273bfa..079a4254d8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -187,19 +187,19 @@ jobs: - run: name: Adding role command: | - if [[ << parameters.run-all >> == true || << parameters.run-site >> == true ]]; then + if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-site >> == true ]]; then export MODULENAME="ccc_site_management" echo " - $MODULENAME" >> ccc_roles.yaml fi - if [[ << parameters.run-all >> == true || << parameters.run-devicecredential >> == true ]]; then + if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-devicecredential >> == true ]]; then export MODULENAME="ccc_device_credential_management" echo " - $MODULENAME" >> ccc_roles.yaml fi - if [[ << parameters.run-all >> == true || << parameters.run-discovery >> == true ]]; then + if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-discovery >> == true ]]; then export MODULENAME="ccc_discovery_management" echo " - $MODULENAME" >> ccc_roles.yaml fi - if [[ << parameters.run-all >> == true || << parameters.run-inventory >> == true ]]; then + if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-inventory >> == true ]]; then export MODULENAME="ccc_inventory_management" echo " - $MODULENAME" >> ccc_roles.yaml fi diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 179157040c..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,6 +433,7 @@ update_sites: floor_number: 1 type: floor + delete_sites: - site: area: From b2f9ce6204142eb64b7dc79a41a084ad990d2a61 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 21:02:06 -0500 Subject: [PATCH 168/358] testing path filtering --- .circleci/config.yml | 8 ++++---- .../ccc_site_management/vars/vars_site_management.yml | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 079a4254d8..dc8ce5ab8d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -189,19 +189,19 @@ jobs: command: | if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-site >> == true ]]; then export MODULENAME="ccc_site_management" - echo " - $MODULENAME" >> ccc_roles.yaml + echo " - $MODULENAME" >> ccc_roles.yml fi if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-devicecredential >> == true ]]; then export MODULENAME="ccc_device_credential_management" - echo " - $MODULENAME" >> ccc_roles.yaml + echo " - $MODULENAME" >> ccc_roles.yml fi if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-discovery >> == true ]]; then export MODULENAME="ccc_discovery_management" - echo " - $MODULENAME" >> ccc_roles.yaml + echo " - $MODULENAME" >> ccc_roles.yml fi if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-inventory >> == true ]]; then export MODULENAME="ccc_inventory_management" - echo " - $MODULENAME" >> ccc_roles.yaml + echo " - $MODULENAME" >> ccc_roles.yml fi cat ccc_roles.yml diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..179157040c 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,7 +433,6 @@ update_sites: floor_number: 1 type: floor - delete_sites: - site: area: From fc359bc60548d3cd47280360425f65859a3a93b0 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 21:13:53 -0500 Subject: [PATCH 169/358] testing integration tests --- .../ccc_site_management/vars/vars_site_management.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 179157040c..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -433,6 +433,7 @@ update_sites: floor_number: 1 type: floor + delete_sites: - site: area: From 7a5fc33857ed6eaf0d22c429cdb8d7d0c404ec87 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 21:23:50 -0500 Subject: [PATCH 170/358] Integration Tests --- .circleci/config.yml | 20 +++++++++---------- .../vars/vars_assign_credentials.yml | 2 ++ .../vars/vars_discovery_management.yml | 6 ++++++ .../vars/vars_inventory_management.yml | 14 +++++++++++++ 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index dc8ce5ab8d..6ca84e5096 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -241,16 +241,16 @@ jobs: workflows: integration-testing: - jobs: - - pre + # jobs: + # - pre - - build: - requires: - - pre + # - build: + # requires: + # - pre - path-filtering/filter: - requires: - - build + # requires: + # - build base-revision: main config-path: .circleci/config.yml mapping: | @@ -266,9 +266,9 @@ workflows: tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true - - sanity-tests: - requires: - - path-filtering/filter + # - sanity-tests: + # requires: + # - path-filtering/filter # daily-scheduled: # triggers: diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index 6ad1f9448d..ff19b97491 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -6,6 +6,7 @@ design_sites: parent_name: 'Global' type: area + credentials_details: - global_credential_details: cli_credential: @@ -38,6 +39,7 @@ credentials_details: password: "j@5wgm%s5g%" port: 443 + credentials_assign: - assign_credentials_to_site: # Assign device credentials to sites cli_credential: diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index 22786dad68..b64e9c0dc9 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -13,6 +13,8 @@ single_ip: # - description: snmpV3 # username: v3Public2 + + ip_range: - discovery_name: Single Range Discovery 1 discovery_type: "RANGE" @@ -58,6 +60,7 @@ ip_range: protocol_order: ssh global_cli_len: 3 + multi_range: - discovery_name: Multi Range Discovery discovery_type: "MULTI RANGE" @@ -87,6 +90,7 @@ multi_range: privacy_type: AES256 privacy_password: Lablab#1234 + cdp: - discovery_name: CDP Discovery discovery_type: "CDP" @@ -107,6 +111,7 @@ cdp: privacy_type: AES256 privacy_password: Lablab#1234 + lldp: - discovery_name: LLDP Discovery discovery_type: "LLDP" @@ -128,6 +133,7 @@ lldp: privacy_type: AES256 privacy_password: Lablab#1234 + cidr: - discovery_name: CIDR Discovery discovery_type: "CIDR" diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 13c0aa5d57..c38c2490bd 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -49,6 +49,8 @@ device_details: # cli_transport: "ssh"s # netconf_port: 830 + + device_credential_updates: # Update CLI password - type: "NETWORK_DEVICE" @@ -137,6 +139,7 @@ device_interface_updates: voice_vlan_id: 45 admin_status: "UP" + device_role_updates: #Update role from access to core - ip_address_list: ["204.1.2.5"] @@ -144,6 +147,7 @@ device_role_updates: update_device_role: role: ACCESS + device_int_update_post_rolechange: # Update Interface description - ip_address_list: ["204.1.2.5"] @@ -152,12 +156,14 @@ device_int_update_post_rolechange: interface_name: ["GigabitEthernet1/0/23"] description: "Testing for updating interface description post changing role" + device_resync: # Resync the device - ip_address_list: ["204.1.2.5"] device_resync: True force_sync: False + create_assign_udf: - ip_address_list: ["204.1.2.5", "204.192.6.200"] add_user_defined_field: @@ -169,6 +175,7 @@ create_assign_udf: description: "Added second udf for testing" value: "value321" + update_udf: - ip_address_list: ["204.1.2.5", "204.192.6.200"] add_user_defined_field: @@ -180,6 +187,7 @@ update_udf: description: "modified second udf for testing" value: "value421" + delete_udf: # User defined fields - ip_address_list: ["204.1.2.5", "204.192.6.200"] @@ -189,18 +197,21 @@ delete_udf: add_user_defined_field: - name: "Test321" + export_device_details: - ip_address_list: ["204.1.2.5", "204.192.6.200"] export_device_list: operation_enum: 1 password: "Password123!" + export_credential_details: - ip_address_list: ["204.1.2.5", "204.192.6.200"] export_device_list: operation_enum: "0" password: "Password123$" + design_sites: # Create site to associate device to - site: @@ -236,6 +247,7 @@ associate_wired_device: resync_retry_count: 200 resync_interval: 2 + associate_wireless_device: - provision_wireless_device: - device_ip: "204.192.6.200" @@ -251,6 +263,7 @@ associate_wireless_device: resync_retry_count: 200 resync_retry_interval: 2 + delete_sites: - site: area: @@ -258,6 +271,7 @@ delete_sites: parent_name: Global type: area + delete_devices: - ip_address_list: ["204.1.2.5"] #ip_address_list: ["204.1.2.5", "204.192.6.200"] From 3617ddec40c9d9a9f0124b2568ce9e16ec6d5247 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 21:26:44 -0500 Subject: [PATCH 171/358] Integration Tests --- .circleci/config.yml | 20 +++++++++---------- .../vars/vars_assign_credentials.yml | 1 + .../vars/vars_discovery_management.yml | 1 - .../vars/vars_inventory_management.yml | 2 +- .../vars/vars_site_management.yml | 1 + 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6ca84e5096..dc8ce5ab8d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -241,16 +241,16 @@ jobs: workflows: integration-testing: - # jobs: - # - pre + jobs: + - pre - # - build: - # requires: - # - pre + - build: + requires: + - pre - path-filtering/filter: - # requires: - # - build + requires: + - build base-revision: main config-path: .circleci/config.yml mapping: | @@ -266,9 +266,9 @@ workflows: tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true - # - sanity-tests: - # requires: - # - path-filtering/filter + - sanity-tests: + requires: + - path-filtering/filter # daily-scheduled: # triggers: diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index ff19b97491..1b6e5735cf 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -40,6 +40,7 @@ credentials_details: port: 443 + credentials_assign: - assign_credentials_to_site: # Assign device credentials to sites cli_credential: diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index b64e9c0dc9..2235d69f3e 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -14,7 +14,6 @@ single_ip: # username: v3Public2 - ip_range: - discovery_name: Single Range Discovery 1 discovery_type: "RANGE" diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index c38c2490bd..920a2230d8 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -50,7 +50,6 @@ device_details: # netconf_port: 830 - device_credential_updates: # Update CLI password - type: "NETWORK_DEVICE" @@ -127,6 +126,7 @@ device_credential_updates: netconf_port: 830 + device_interface_updates: # Update Interface Details - ip_address_list: ["204.1.2.5", "204.192.6.200"] diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..6989c9e864 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,6 +434,7 @@ update_sites: type: floor + delete_sites: - site: area: From ed5689d2be3488d6bed508ddcb963ddcbac97595 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 21:37:45 -0500 Subject: [PATCH 172/358] Integration Tests --- .../vars/vars_assign_credentials.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index 1b6e5735cf..ff19b97491 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -40,7 +40,6 @@ credentials_details: port: 443 - credentials_assign: - assign_credentials_to_site: # Assign device credentials to sites cli_credential: From e58e8bf9dc04af9c4eafb5febc5e7f9a3704891b Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 21:51:15 -0500 Subject: [PATCH 173/358] Integration tests --- .circleci/config.yml | 13 ++++++++++--- .../vars/vars_assign_credentials.yml | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index dc8ce5ab8d..e5f4f40a5f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -265,10 +265,17 @@ workflows: tests/integration/ccc_device_credential_management/.* run-devicecredential true tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true + + - sanity-tests: + parameters: + run-all: << pipeline.parameters.run-all >> + run-site: << pipeline.parameters.run-site >> + run-devicecredential: << pipeline.parameters.run-devicecredential >> + run-discovery: << pipeline.parameters.run-discovery >> + run-inventory: << pipeline.parameters.run-inventory >> + requires: + - path-filtering/filter - - sanity-tests: - requires: - - path-filtering/filter # daily-scheduled: # triggers: diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index ff19b97491..a1f4b9c886 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -7,6 +7,7 @@ design_sites: type: area + credentials_details: - global_credential_details: cli_credential: From 00e7a9c39d824d9754d1ec0c650ca51cff9997c3 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 21:52:19 -0500 Subject: [PATCH 174/358] Integration tests --- .circleci/config.yml | 18 +++++++++--------- .../vars/vars_assign_credentials.yml | 1 - 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e5f4f40a5f..a0080cd2fa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -266,15 +266,15 @@ workflows: tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true - - sanity-tests: - parameters: - run-all: << pipeline.parameters.run-all >> - run-site: << pipeline.parameters.run-site >> - run-devicecredential: << pipeline.parameters.run-devicecredential >> - run-discovery: << pipeline.parameters.run-discovery >> - run-inventory: << pipeline.parameters.run-inventory >> - requires: - - path-filtering/filter + - sanity-tests: + parameters: + run-all: << pipeline.parameters.run-all >> + run-site: << pipeline.parameters.run-site >> + run-devicecredential: << pipeline.parameters.run-devicecredential >> + run-discovery: << pipeline.parameters.run-discovery >> + run-inventory: << pipeline.parameters.run-inventory >> + requires: + - path-filtering/filter # daily-scheduled: diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index a1f4b9c886..ff19b97491 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -7,7 +7,6 @@ design_sites: type: area - credentials_details: - global_credential_details: cli_credential: From 8b9e34b5d8a8a4e268b9ba06d947845496318777 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 21:56:50 -0500 Subject: [PATCH 175/358] Integration tests --- .circleci/config.yml | 25 ++++++++----------- .../vars/vars_assign_credentials.yml | 1 + 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a0080cd2fa..1aba4046d0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -134,6 +134,11 @@ jobs: command: | set -x echo "REPO_URL: $REPO_URL" + echo "run-all: << pipeline.parameters.run-all >>" + echo "run-site: << pipeline.parameters.run-site >>" + echo "run-devicecredential: << pipeline.parameters.run-devicecredential >>" + echo "run-discovery: << pipeline.parameters.run-discovery >>" + echo "run-inventory: << pipeline.parameters.run-inventory >>" env - run: @@ -188,20 +193,16 @@ jobs: name: Adding role command: | if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-site >> == true ]]; then - export MODULENAME="ccc_site_management" - echo " - $MODULENAME" >> ccc_roles.yml + echo " - ccc_site_management" >> ccc_roles.yml fi if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-devicecredential >> == true ]]; then - export MODULENAME="ccc_device_credential_management" - echo " - $MODULENAME" >> ccc_roles.yml + echo " - ccc_device_credential_management" >> ccc_roles.yml fi if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-discovery >> == true ]]; then - export MODULENAME="ccc_discovery_management" - echo " - $MODULENAME" >> ccc_roles.yml + echo " - ccc_discovery_management" >> ccc_roles.yml fi if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-inventory >> == true ]]; then - export MODULENAME="ccc_inventory_management" - echo " - $MODULENAME" >> ccc_roles.yml + echo " - ccc_inventory_management" >> ccc_roles.yml fi cat ccc_roles.yml @@ -265,14 +266,8 @@ workflows: tests/integration/ccc_device_credential_management/.* run-devicecredential true tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true - + - sanity-tests: - parameters: - run-all: << pipeline.parameters.run-all >> - run-site: << pipeline.parameters.run-site >> - run-devicecredential: << pipeline.parameters.run-devicecredential >> - run-discovery: << pipeline.parameters.run-discovery >> - run-inventory: << pipeline.parameters.run-inventory >> requires: - path-filtering/filter diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index ff19b97491..a1f4b9c886 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -7,6 +7,7 @@ design_sites: type: area + credentials_details: - global_credential_details: cli_credential: From cf1c731706848c355b1982478b717013416d460b Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 22:59:54 -0500 Subject: [PATCH 176/358] integration tests --- .circleci/config.yml | 190 ++++++++++++------ .../vars/vars_assign_credentials.yml | 1 - 2 files changed, 129 insertions(+), 62 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1aba4046d0..60061a3c7c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,12 +6,15 @@ orbs: path-filtering: circleci/path-filtering@0.1.6 parameters: + run-setup: + type: boolean + default: true run-all: type: boolean default: false run-site: type: boolean - default: true + default: false run-devicecredential: type: boolean default: false @@ -42,6 +45,7 @@ jobs: name: Debug information for pre command: | set -x + echo "REPO_URL: $REPO_URL" echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" echo "CIRCLE_PROJECT_BRANCHNAME: $CIRCLE_PROJECT_BRANCHNAME" env @@ -73,12 +77,38 @@ jobs: command: | set -x echo "REPO_URL: $REPO_URL" + echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" + echo "CIRCLE_PROJECT_BRANCHNAME: $CIRCLE_PROJECT_BRANCHNAME" env - run: name: Custom Git Clone command: git clone --depth=1 -b $CIRCLE_PROJECT_BRANCHNAME $REPO_URL + - run: + name: Create Roles File header + command: | + echo "---" > ccc_roles.yml + echo "- hosts: dnac_servers" >> ccc_roles.yml + echo " gather_facts: no" >> ccc_roles.yml + echo " connection: local" >> ccc_roles.yml + echo " " >> ccc_roles.yml + echo " tasks:" >> ccc_roles.yml + echo " " >> ccc_roles.yml + echo " vars:" >> ccc_roles.yml + echo " debug: false" >> ccc_roles.yml + echo " " >> ccc_roles.yml + echo " roles:" >> ccc_roles.yml + + cat ccc_roles.yml + + - run: + name: Copy static files + command: | + mkdir -p group_vars + cp ${HOME}/static/group_vars/dnac_servers.yml group_vars/dnac_servers.yml + cp ${HOME}/static/hosts hosts + - run: name: Activate Virtual Environment, Install ansible and Build collection tarball command: | @@ -112,6 +142,22 @@ jobs: set -x rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME + addrole: + parameters: + modulename: + type: string + + machine: true + resource_class: rukapse/dnacenter-ansible + working_directory: ~/repo + + steps: + - run: + name: Adding role - << parameters.modulename >> + command: | + export MODULENAME="<< parameters.modulename >>" + echo " - $MODULENAME" >> ccc_roles.yaml + cat ccc_roles.yml sanity-tests: parameters: @@ -134,11 +180,8 @@ jobs: command: | set -x echo "REPO_URL: $REPO_URL" - echo "run-all: << pipeline.parameters.run-all >>" - echo "run-site: << pipeline.parameters.run-site >>" - echo "run-devicecredential: << pipeline.parameters.run-devicecredential >>" - echo "run-discovery: << pipeline.parameters.run-discovery >>" - echo "run-inventory: << pipeline.parameters.run-inventory >>" + echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" + echo "CIRCLE_PROJECT_BRANCHNAME: $CIRCLE_PROJECT_BRANCHNAME" env - run: @@ -172,48 +215,6 @@ jobs: environment: PYTHONPATH: $HOME/.ansible/collections/:$PYTHONPATH - - run: - name: Create Roles File header - command: | - echo "---" > ccc_roles.yml - echo "- hosts: dnac_servers" >> ccc_roles.yml - echo " gather_facts: no" >> ccc_roles.yml - echo " connection: local" >> ccc_roles.yml - echo " " >> ccc_roles.yml - echo " tasks:" >> ccc_roles.yml - echo " " >> ccc_roles.yml - echo " vars:" >> ccc_roles.yml - echo " debug: false" >> ccc_roles.yml - echo " " >> ccc_roles.yml - echo " roles:" >> ccc_roles.yml - - cat ccc_roles.yml - - - run: - name: Adding role - command: | - if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-site >> == true ]]; then - echo " - ccc_site_management" >> ccc_roles.yml - fi - if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-devicecredential >> == true ]]; then - echo " - ccc_device_credential_management" >> ccc_roles.yml - fi - if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-discovery >> == true ]]; then - echo " - ccc_discovery_management" >> ccc_roles.yml - fi - if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-inventory >> == true ]]; then - echo " - ccc_inventory_management" >> ccc_roles.yml - fi - - cat ccc_roles.yml - - - run: - name: Copy static files - command: | - mkdir -p group_vars - cp ${HOME}/static/group_vars/dnac_servers.yml group_vars/dnac_servers.yml - cp ${HOME}/static/hosts hosts - - run: name: Install the collection tarball command: | @@ -241,35 +242,102 @@ jobs: workflows: - integration-testing: + pre-testing: + when: << pipeline.parameters.run-setup >> jobs: - pre - build: + matrix: + parameters: + ansible_cisco_dnac_version: + - "6.9.0" requires: - pre - path-filtering/filter: + # filters: + # branches: + # ignore: develop requires: - build base-revision: main config-path: .circleci/config.yml mapping: | - plugins/module_utils/.* run-all true - - plugins/modules/site_workflow_manager.py run-site true - plugins/modules/device_credential_workflow_manager.py run-devicecredential true - plugins/modules/discovery_workflow_manager.py run-discovery true - plugins/modules/inventory_workflow_manager.py run-inventory true + .* run-setup false + plugins/.* run-any true + tests/integration/.* run-any true + plugins/module_utils/.* run-all true + + plugins/modules/site_workflow_manager.py run-site true + plugins/modules/device_credential_workflow_manager.py run-devicecredential true + plugins/modules/discovery_workflow_manager.py run-discovery true + plugins/modules/inventory_workflow_manager.py run-inventory true + + tests/integration/ccc_site_management/.* run-site true + tests/integration/ccc_device_credential_management/.* run-devicecredential true + tests/integration/ccc_discovery_management/.* run-discovery true + tests/integration/ccc_inventory_management/.* run-inventory true + + site: + when: + or: + - << pipeline.parameters.run-all >> + - << pipeline.parameters.run-site >> + jobs: + - addrole: + matrix: + parameters: + modulename: + - ccc_site_management + + + devicecredential: + when: + or: + - << pipeline.parameters.run-all >> + - << pipeline.parameters.run-devicecredential >> + jobs: + - addrole: + matrix: + parameters: + modulename: + - ccc_device_credential_management + + discovery: + when: + or: + - << pipeline.parameters.run-all >> + - << pipeline.parameters.run-discovery >> + jobs: + - addrole: + matrix: + parameters: + modulename: + - ccc_discovery_management + + inventory: + when: + or: + - << pipeline.parameters.run-all >> + - << pipeline.parameters.run-inventory >> + jobs: + - addrole: + matrix: + parameters: + modulename: + - ccc_inventory_management - tests/integration/ccc_site_management/.* run-site true - tests/integration/ccc_device_credential_management/.* run-devicecredential true - tests/integration/ccc_discovery_management/.* run-discovery true - tests/integration/ccc_inventory_management/.* run-inventory true + sanity: + when: << pipeline.parameters.run-any >> + jobs: - sanity-tests: - requires: - - path-filtering/filter + matrix: + parameters: + ansible_cisco_dnac_version: + - "6.9.0" + # daily-scheduled: diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index a1f4b9c886..ff19b97491 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -7,7 +7,6 @@ design_sites: type: area - credentials_details: - global_credential_details: cli_credential: From d13ef92115dd8c0e99a25b00cedb157ce6b3feb9 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 23:02:10 -0500 Subject: [PATCH 177/358] integration tests --- .circleci/config.yml | 3 +++ .../vars/vars_assign_credentials.yml | 1 + 2 files changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 60061a3c7c..ca8f18e984 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,6 +9,9 @@ parameters: run-setup: type: boolean default: true + run-any: + type: boolean + default: false run-all: type: boolean default: false diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index ff19b97491..a1f4b9c886 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -7,6 +7,7 @@ design_sites: type: area + credentials_details: - global_credential_details: cli_credential: From d95ec16646289d0823e6069c6bfff9c30c7f4c82 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 23:05:35 -0500 Subject: [PATCH 178/358] integration tests --- .circleci/config.yml | 2 +- .../vars/vars_assign_credentials.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ca8f18e984..844a84ed25 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,6 @@ version: 2.1 -setup: true +setup: << pipeline.parameters.run-setup >> orbs: path-filtering: circleci/path-filtering@0.1.6 diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index a1f4b9c886..ff19b97491 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -7,7 +7,6 @@ design_sites: type: area - credentials_details: - global_credential_details: cli_credential: From 4d29c86ad3ed605796df8ce8b8f4302313e178d3 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 23:07:45 -0500 Subject: [PATCH 179/358] integration tests --- .circleci/config.yml | 5 ++--- .../vars/vars_assign_credentials.yml | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 844a84ed25..fad0c9c841 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -268,8 +268,7 @@ workflows: config-path: .circleci/config.yml mapping: | .* run-setup false - plugins/.* run-any true - tests/integration/.* run-any true + plugins/module_utils/.* run-all true plugins/modules/site_workflow_manager.py run-site true @@ -333,7 +332,7 @@ workflows: sanity: - when: << pipeline.parameters.run-any >> + #when: << pipeline.parameters.run-any >> jobs: - sanity-tests: matrix: diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index ff19b97491..a1f4b9c886 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -7,6 +7,7 @@ design_sites: type: area + credentials_details: - global_credential_details: cli_credential: From 29272b52c572071878ceb3f00c3b53889eeea4a8 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 23:40:58 -0500 Subject: [PATCH 180/358] integraiton tests --- .circleci/config.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fad0c9c841..36dd7c03f1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,7 +14,7 @@ parameters: default: false run-all: type: boolean - default: false + default: true run-site: type: boolean default: false @@ -267,19 +267,19 @@ workflows: base-revision: main config-path: .circleci/config.yml mapping: | - .* run-setup false + # .* run-setup false - plugins/module_utils/.* run-all true + # plugins/module_utils/.* run-all true - plugins/modules/site_workflow_manager.py run-site true - plugins/modules/device_credential_workflow_manager.py run-devicecredential true - plugins/modules/discovery_workflow_manager.py run-discovery true - plugins/modules/inventory_workflow_manager.py run-inventory true + # plugins/modules/site_workflow_manager.py run-site true + # plugins/modules/device_credential_workflow_manager.py run-devicecredential true + # plugins/modules/discovery_workflow_manager.py run-discovery true + # plugins/modules/inventory_workflow_manager.py run-inventory true - tests/integration/ccc_site_management/.* run-site true - tests/integration/ccc_device_credential_management/.* run-devicecredential true - tests/integration/ccc_discovery_management/.* run-discovery true - tests/integration/ccc_inventory_management/.* run-inventory true + # tests/integration/ccc_site_management/.* run-site true + # tests/integration/ccc_device_credential_management/.* run-devicecredential true + # tests/integration/ccc_discovery_management/.* run-discovery true + # tests/integration/ccc_inventory_management/.* run-inventory true site: when: From a4ebde02a8140c470323c6af574214496045fe65 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 4 Mar 2024 23:57:15 -0500 Subject: [PATCH 181/358] integraiton tests --- .circleci/config.yml | 92 ++++++++++---------------------------------- 1 file changed, 20 insertions(+), 72 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 36dd7c03f1..2a3986a287 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -146,9 +146,6 @@ jobs: rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME addrole: - parameters: - modulename: - type: string machine: true resource_class: rukapse/dnacenter-ansible @@ -156,10 +153,21 @@ jobs: steps: - run: - name: Adding role - << parameters.modulename >> + name: Adding roles based on parameters command: | - export MODULENAME="<< parameters.modulename >>" - echo " - $MODULENAME" >> ccc_roles.yaml + roles_map=( + ["run-site"]="ccc_site_management" + ["run-devicecredential"]="ccc_device_credential_management" + ["run-discovery"]="ccc_discovery_management" + ["run-inventory"]="ccc_inventory_management" + ) + + for param in "${!roles_map[@]}"; do + if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters[$param] >> == true ]]; then + echo " - ${roles_map[$param]}" >> ccc_roles.yml + fi + done + cat ccc_roles.yml sanity-tests: @@ -267,81 +275,21 @@ workflows: base-revision: main config-path: .circleci/config.yml mapping: | - # .* run-setup false - - # plugins/module_utils/.* run-all true - - # plugins/modules/site_workflow_manager.py run-site true - # plugins/modules/device_credential_workflow_manager.py run-devicecredential true - # plugins/modules/discovery_workflow_manager.py run-discovery true - # plugins/modules/inventory_workflow_manager.py run-inventory true + - # tests/integration/ccc_site_management/.* run-site true - # tests/integration/ccc_device_credential_management/.* run-devicecredential true - # tests/integration/ccc_discovery_management/.* run-discovery true - # tests/integration/ccc_inventory_management/.* run-inventory true - - site: - when: - or: - - << pipeline.parameters.run-all >> - - << pipeline.parameters.run-site >> - jobs: - addrole: - matrix: - parameters: - modulename: - - ccc_site_management - - - devicecredential: - when: - or: - - << pipeline.parameters.run-all >> - - << pipeline.parameters.run-devicecredential >> - jobs: - - addrole: - matrix: - parameters: - modulename: - - ccc_device_credential_management - - discovery: - when: - or: - - << pipeline.parameters.run-all >> - - << pipeline.parameters.run-discovery >> - jobs: - - addrole: - matrix: - parameters: - modulename: - - ccc_discovery_management - - inventory: - when: - or: - - << pipeline.parameters.run-all >> - - << pipeline.parameters.run-inventory >> - jobs: - - addrole: - matrix: - parameters: - modulename: - - ccc_inventory_management - - - sanity: - #when: << pipeline.parameters.run-any >> - jobs: + requires: + - path-filtering/filter + - sanity-tests: + requires: + - addrole matrix: parameters: ansible_cisco_dnac_version: - "6.9.0" - # daily-scheduled: # triggers: # - schedule: From de9aae049054f4173f0732aa3940c19b5ec32df2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 00:00:29 -0500 Subject: [PATCH 182/358] integraiton tests --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2a3986a287..5607ef5eba 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -145,6 +145,7 @@ jobs: set -x rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME + addrole: machine: true @@ -163,7 +164,7 @@ jobs: ) for param in "${!roles_map[@]}"; do - if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters[$param] >> == true ]]; then + if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters[$param] }} == true ]]; then echo " - ${roles_map[$param]}" >> ccc_roles.yml fi done From 4d91c4874477757f30237f3bbe83aefee3bd111f Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 00:03:51 -0500 Subject: [PATCH 183/358] integraiton tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5607ef5eba..9f14264e5a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -276,7 +276,7 @@ workflows: base-revision: main config-path: .circleci/config.yml mapping: | - + .* run-setup false - addrole: requires: From 82550bf06a6f7131ad4d23e7884a971bc8b98e44 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 00:14:59 -0500 Subject: [PATCH 184/358] integraiton tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9f14264e5a..b352c78fae 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -164,7 +164,7 @@ jobs: ) for param in "${!roles_map[@]}"; do - if [[ ${{ pipeline.parameters.run-all }} == true || ${{ pipeline.parameters[$param] }} == true ]]; then + if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters[$param] >> == true ]]; then echo " - ${roles_map[$param]}" >> ccc_roles.yml fi done From cc7354e8c7177b2ee6bf8b8dd9a2ecbed31b07b4 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 17:51:18 -0500 Subject: [PATCH 185/358] Integration tests --- .../vars/vars_discovery_management.yml | 14 +++--- .../tests/test_inventory_management.yml | 50 +++++++++---------- .../vars/vars_inventory_management.yml | 2 +- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index 2235d69f3e..577a50e0f1 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -5,13 +5,13 @@ single_ip: ip_address_list: - 204.1.2.5 protocol_order: ssh - # global_credentials: - # cli_credentials_list: - # - description: CLI - # username: cli - # snmp_v3_credential_list: - # - description: snmpV3 - # username: v3Public2 + global_credentials: + cli_credentials_list: + - description: CLI + username: cli + snmp_v3_credential_list: + - description: snmpV3 + username: v3Public2 ip_range: diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index f7021d62f2..7ab0eb118a 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -51,9 +51,9 @@ loop: "{{ vars_map.delete_sites }}" register: result_delete_site -# ############################################# -# # Add Devices # -# ############################################# +############################################# +# Add Devices # +############################################# - name: Add new device cisco.dnac.inventory_workflow_manager: @@ -134,28 +134,28 @@ # Update Device Role Detials # ############################################# - # - name: Update device role details - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_role_updates }}" - # register: result_update_device_role + - name: Update device role details + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_role_updates }}" + register: result_update_device_role - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_role.results }}" - # when: result_update_device_role is defined + - name: Debug item + debug: + var: item + loop: "{{ result_update_device_role.results }}" + when: result_update_device_role is defined - # - name: Assert device role update - # assert: - # that: - # - result_update_device_role.changed == true - # - "'Device role was successfully updated' in item.response.progress" - # loop: "{{ result_update_device_role.results }}" - # when: result_update_device_role is defined + - name: Assert device role update + assert: + that: + - result_update_device_role.changed == true + - "'Device role was successfully updated' in item.response.progress" + loop: "{{ result_update_device_role.results }}" + when: result_update_device_role is defined ############################################# # Update Device Interface Description # @@ -187,7 +187,7 @@ # Resync Device # ############################################# - - name: Update device role details + - name: Resync Device cisco.dnac.inventory_workflow_manager: <<: *dnac_login state: merged @@ -240,7 +240,7 @@ # Update User Defined Field # ############################################# - - name: Updateuser defined field + - name: Update user defined field cisco.dnac.inventory_workflow_manager: <<: *dnac_login state: merged diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 920a2230d8..fa412f471a 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -145,7 +145,7 @@ device_role_updates: - ip_address_list: ["204.1.2.5"] device_updated: True update_device_role: - role: ACCESS + role: CORE device_int_update_post_rolechange: From f273fb612ab0804bedc80c5df246d5a8c1a40322 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 18:40:43 -0500 Subject: [PATCH 186/358] integration tests --- .../tests/test_inventory_management.yml | 11 +++++++++-- .../vars/vars_inventory_management.yml | 14 +++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index 7ab0eb118a..8b8ceb8c3e 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -108,6 +108,10 @@ # Update Device Interface Detials # ############################################# + # - name: Pause for 60 seconds before updating interfaces + # pause: + # seconds: 60 + # - name: Update device interface details # cisco.dnac.inventory_workflow_manager: # <<: *dnac_login @@ -161,6 +165,10 @@ # Update Device Interface Description # ############################################# + # - name: Pause for 60 seconds before updating interfaces + # pause: + # seconds: 60 + # - name: Update device interface description post changing role to non-access # cisco.dnac.inventory_workflow_manager: # <<: *dnac_login @@ -171,7 +179,7 @@ # register: result_update_device_interface # - name: Debug item - # desbug: + # debug: # var: item # loop: "{{ result_update_device_interface.results }}" # when: result_update_device_interface is defined @@ -478,4 +486,3 @@ - "'deleted successfully' in item.response" loop: "{{ result_delete_site.results }}" when: result_delete_site is defined - diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index fa412f471a..6a192fdcbf 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -129,7 +129,7 @@ device_credential_updates: device_interface_updates: # Update Interface Details - - ip_address_list: ["204.1.2.5", "204.192.6.200"] + - ip_address_list: ["204.1.2.5"] device_updated: True # Interface details update_interface_details: @@ -165,7 +165,7 @@ device_resync: create_assign_udf: - - ip_address_list: ["204.1.2.5", "204.192.6.200"] + - ip_address_list: ["204.1.2.5"] add_user_defined_field: # User defined fields - name: Test123 @@ -177,7 +177,7 @@ create_assign_udf: update_udf: - - ip_address_list: ["204.1.2.5", "204.192.6.200"] + - ip_address_list: ["204.1.2.5"] add_user_defined_field: # User defined fields - name: Test123 @@ -190,23 +190,23 @@ update_udf: delete_udf: # User defined fields - - ip_address_list: ["204.1.2.5", "204.192.6.200"] + - ip_address_list: ["204.1.2.5"] add_user_defined_field: - name: "Test123" - - ip_address_list: ["204.1.2.5", "204.192.6.200"] + - ip_address_list: ["204.1.2.5"] add_user_defined_field: - name: "Test321" export_device_details: - - ip_address_list: ["204.1.2.5", "204.192.6.200"] + - ip_address_list: ["204.1.2.5"] export_device_list: operation_enum: 1 password: "Password123!" export_credential_details: - - ip_address_list: ["204.1.2.5", "204.192.6.200"] + - ip_address_list: ["204.1.2.5"] export_device_list: operation_enum: "0" password: "Password123$" From 43d8a5d8c691dcb639c9c2b8dae2fd9cb7dca881 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 18:48:22 -0500 Subject: [PATCH 187/358] path filtering tests --- .circleci/config.yml | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b352c78fae..6cbb2ddfe3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -156,18 +156,21 @@ jobs: - run: name: Adding roles based on parameters command: | - roles_map=( - ["run-site"]="ccc_site_management" - ["run-devicecredential"]="ccc_device_credential_management" - ["run-discovery"]="ccc_discovery_management" - ["run-inventory"]="ccc_inventory_management" - ) - - for param in "${!roles_map[@]}"; do - if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters[$param] >> == true ]]; then - echo " - ${roles_map[$param]}" >> ccc_roles.yml - fi - done + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-site }} == true ]]; then + echo " - ccc_site_management" >> ccc_roles.yaml + fi + + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-devicecredential }} == true ]]; then + echo " - ccc_device_credential_management" >> ccc_roles.yaml + fi + + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-discovery }} == true ]]; then + echo " - ccc_discovery_management" >> ccc_roles.yaml + fi + + if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-inventory }} == true ]]; then + echo " - ccc_inventory_management" >> ccc_roles.yaml + fi cat ccc_roles.yml From 551a7b8e301e076862fee3bb8804393ec58b5252 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 19:10:13 -0500 Subject: [PATCH 188/358] integration tests --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6cbb2ddfe3..1ed83242d4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -156,19 +156,19 @@ jobs: - run: name: Adding roles based on parameters command: | - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-site }} == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-site >> == true ]]; then echo " - ccc_site_management" >> ccc_roles.yaml fi - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-devicecredential }} == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-devicecredential >> == true ]]; then echo " - ccc_device_credential_management" >> ccc_roles.yaml fi - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-discovery }} == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-discovery >> == true ]]; then echo " - ccc_discovery_management" >> ccc_roles.yaml fi - if [[ ${{ parameters.run-all }} == true || ${{ parameters.run-inventory }} == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-inventory >> == true ]]; then echo " - ccc_inventory_management" >> ccc_roles.yaml fi From 10e2f72291e7e801aa515d3030186fbb03c1d00a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 19:11:39 -0500 Subject: [PATCH 189/358] integration tests --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1ed83242d4..2ece69aea4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -156,19 +156,19 @@ jobs: - run: name: Adding roles based on parameters command: | - if [[ << parameters.run-all >> == true || << parameters.run-site >> == true ]]; then + if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-site >> == true ]]; then echo " - ccc_site_management" >> ccc_roles.yaml fi - if [[ << parameters.run-all >> == true || << parameters.run-devicecredential >> == true ]]; then + if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-devicecredential >> == true ]]; then echo " - ccc_device_credential_management" >> ccc_roles.yaml fi - if [[ << parameters.run-all >> == true || << parameters.run-discovery >> == true ]]; then + if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-discovery >> == true ]]; then echo " - ccc_discovery_management" >> ccc_roles.yaml fi - if [[ << parameters.run-all >> == true || << parameters.run-inventory >> == true ]]; then + if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-inventory >> == true ]]; then echo " - ccc_inventory_management" >> ccc_roles.yaml fi From 99d1970b2a60f945e0f82b4b59b5690d9bfdef38 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 19:15:46 -0500 Subject: [PATCH 190/358] integration tests --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2ece69aea4..4cba16d55c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -157,19 +157,19 @@ jobs: name: Adding roles based on parameters command: | if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-site >> == true ]]; then - echo " - ccc_site_management" >> ccc_roles.yaml + echo " - ccc_site_management" >> ccc_roles.yml fi if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-devicecredential >> == true ]]; then - echo " - ccc_device_credential_management" >> ccc_roles.yaml + echo " - ccc_device_credential_management" >> ccc_roles.yml fi if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-discovery >> == true ]]; then - echo " - ccc_discovery_management" >> ccc_roles.yaml + echo " - ccc_discovery_management" >> ccc_roles.yml fi if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-inventory >> == true ]]; then - echo " - ccc_inventory_management" >> ccc_roles.yaml + echo " - ccc_inventory_management" >> ccc_roles.yml fi cat ccc_roles.yml From 669dbeec439b5275ab28728b964f72fa76d252a3 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 20:11:25 -0500 Subject: [PATCH 191/358] integration tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4cba16d55c..bf65bf0593 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -247,7 +247,7 @@ jobs: export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 export ANSIBLE_ROLES_PATH=/home/circleci/repo/dnacenter-ansible/tests/integration - ansible-playbook -i hosts ccc_roles.yml -vvvv + ansible-playbook -i hosts ccc_roles.yml - run: name: Remove Existing Directory From a052b998e2292fe39ae1afb98032388e326ed647 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 21:26:07 -0500 Subject: [PATCH 192/358] testing path filtering --- .circleci/config.yml | 21 ++++++++++++------- .../vars/vars_site_management.yml | 1 - 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bf65bf0593..57d32f28f3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,12 +9,9 @@ parameters: run-setup: type: boolean default: true - run-any: - type: boolean - default: false run-all: type: boolean - default: true + default: false run-site: type: boolean default: false @@ -247,7 +244,7 @@ jobs: export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 export ANSIBLE_ROLES_PATH=/home/circleci/repo/dnacenter-ansible/tests/integration - ansible-playbook -i hosts ccc_roles.yml + ansible-playbook -q -i hosts ccc_roles.yml - run: name: Remove Existing Directory @@ -257,7 +254,7 @@ jobs: workflows: - pre-testing: + integration-testing: when: << pipeline.parameters.run-setup >> jobs: - pre @@ -279,7 +276,17 @@ workflows: base-revision: main config-path: .circleci/config.yml mapping: | - .* run-setup false + plugins/module_utils/.* run-all true + + plugins/modules/site_workflow_manager.py run-site true + plugins/modules/device_credential_workflow_manager.py run-devicecredential true + plugins/modules/discovery_workflow_manager.py run-discovery true + plugins/modules/inventory_workflow_manager.py run-inventory + + tests/integration/ccc_site_management/.* run-site true + tests/integration/ccc_device_credential_management/.* run-devicecredential true + tests/integration/ccc_discovery_management/.* run-discovery true + tests/integration/ccc_inventory_management/.* run-inventory true - addrole: requires: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 6989c9e864..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,7 +434,6 @@ update_sites: type: floor - delete_sites: - site: area: From 8f9b231e79eff52a7fd97f7bd01ce79986e4a98e Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 21:30:49 -0500 Subject: [PATCH 193/358] testing path filtering --- .circleci/config.yml | 2 +- .../ccc_site_management/vars/vars_site_management.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 57d32f28f3..71a0b1e42e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -281,7 +281,7 @@ workflows: plugins/modules/site_workflow_manager.py run-site true plugins/modules/device_credential_workflow_manager.py run-devicecredential true plugins/modules/discovery_workflow_manager.py run-discovery true - plugins/modules/inventory_workflow_manager.py run-inventory + plugins/modules/inventory_workflow_manager.py run-inventory true tests/integration/ccc_site_management/.* run-site true tests/integration/ccc_device_credential_management/.* run-devicecredential true diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..6989c9e864 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,6 +434,7 @@ update_sites: type: floor + delete_sites: - site: area: From 98a6254a9e31ace493af325ca60d6223e4f17fc6 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 21:42:34 -0500 Subject: [PATCH 194/358] testing path filtering --- .circleci/config.yml | 4 ++-- .../ccc_site_management/vars/vars_site_management.yml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 71a0b1e42e..76d2c37d1c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -244,7 +244,7 @@ jobs: export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 export ANSIBLE_ROLES_PATH=/home/circleci/repo/dnacenter-ansible/tests/integration - ansible-playbook -q -i hosts ccc_roles.yml + ansible-playbook -i hosts ccc_roles.yml - run: name: Remove Existing Directory @@ -283,7 +283,7 @@ workflows: plugins/modules/discovery_workflow_manager.py run-discovery true plugins/modules/inventory_workflow_manager.py run-inventory true - tests/integration/ccc_site_management/.* run-site true + tests/integration/ccc_site_management/.* << pipeline.parameters.run-site >> true tests/integration/ccc_device_credential_management/.* run-devicecredential true tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 6989c9e864..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,7 +434,6 @@ update_sites: type: floor - delete_sites: - site: area: From a29ca173e0172e0d47c57138e8e3dbfba3be1491 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 5 Mar 2024 22:13:01 -0500 Subject: [PATCH 195/358] testing path filtering --- .circleci/config.yml | 2 +- .../ccc_site_management/vars/vars_site_management.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 76d2c37d1c..0723017405 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -283,7 +283,7 @@ workflows: plugins/modules/discovery_workflow_manager.py run-discovery true plugins/modules/inventory_workflow_manager.py run-inventory true - tests/integration/ccc_site_management/.* << pipeline.parameters.run-site >> true + tests/integration/ccc_site_management/vars/vars_site_management.yml run-site true tests/integration/ccc_device_credential_management/.* run-devicecredential true tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..6989c9e864 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,6 +434,7 @@ update_sites: type: floor + delete_sites: - site: area: From 7a5b1589e4c892c1a914df0ed25eb37042d636f7 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 11:09:19 -0500 Subject: [PATCH 196/358] integration tests --- .circleci/config.yml | 17 +- .../tests/test_assign_credentials.yml | 338 +++---- .../test_device_credential_management.yml | 204 ++-- .../tests/test_discovery_management.yml | 510 +++++----- .../tests/test_inventory_management.yml | 916 +++++++++--------- .../tests/test_site_management.yml | 192 ++-- 6 files changed, 1094 insertions(+), 1083 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0723017405..2d88ad4ce7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,6 +9,9 @@ parameters: run-setup: type: boolean default: true + run-any: + type: boolean + default: false run-all: type: boolean default: false @@ -255,11 +258,12 @@ jobs: workflows: integration-testing: - when: << pipeline.parameters.run-setup >> jobs: - - pre + - pre: + when: << pipeline.parameters.run_setup >> - build: + when: << pipeline.parameters.run_setup >> matrix: parameters: ansible_cisco_dnac_version: @@ -268,6 +272,7 @@ workflows: - pre - path-filtering/filter: + when: << pipeline.parameters.run_setup >> # filters: # branches: # ignore: develop @@ -276,6 +281,11 @@ workflows: base-revision: main config-path: .circleci/config.yml mapping: | + .* run-setup false + + plugins/.* run-any true + tests/integration/.* run-any true + plugins/module_utils/.* run-all true plugins/modules/site_workflow_manager.py run-site true @@ -283,7 +293,7 @@ workflows: plugins/modules/discovery_workflow_manager.py run-discovery true plugins/modules/inventory_workflow_manager.py run-inventory true - tests/integration/ccc_site_management/vars/vars_site_management.yml run-site true + tests/integration/ccc_site_management/.* run-site true tests/integration/ccc_device_credential_management/.* run-devicecredential true tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true @@ -293,6 +303,7 @@ workflows: - path-filtering/filter - sanity-tests: + when: << pipeline.parameters.run_any >> requires: - addrole matrix: diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml index e581833e9b..69c325c0f7 100755 --- a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml @@ -24,172 +24,172 @@ - debug: msg: "{{ vars_map.design_sites }}" -############################################# -# Pre Tests Clean Up # -############################################# - - - name: Clean up site before test - cisco.dnac.site_workflow_manager: - <<: *dnac_login - config_verify: true - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.design_sites }}" - - - name: Clean up device credentials before test - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: deleted - config_verify: True - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - -############################################# -# CREATE SITE # -############################################# - - - name: Create sites from design_sites config - cisco.dnac.site_workflow_manager: - <<: *dnac_login - config_verify: true - state: merged - config: - - "{{ item }}" - register: result_create_site - loop: "{{ vars_map.design_sites }}" - tags: merged - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_site.results }}" - # when: result_create_site is defined - - - name: Assert area creation success for each site - assert: - that: - - item.changed == true - - item.response.status == "SUCCESS" - - "'created successfully' in item.msg" - loop: "{{ result_create_site.results }}" - when: result_create_site is defined - -############################################# -# Create Credentials # -############################################# - - - name: Create Credentials - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: merged - config_verify: True - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - tags: merged - register: result_create_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_credentials.results }}" - # when: result_create_credentials is defined - - - name: Assert Device Credential Creation - assert: - that: - - item.changed == true - - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" - - item.response[0].globalCredential.Validation == "Success" - loop: "{{ result_create_credentials.results }}" - when: result_create_credentials is defined - -############################################# -# Assign Credentials to site # -############################################# - - - name: Assign Credentials to design_sites - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: merged - config_verify: True - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_assign }}" - tags: assign - register: result_assign_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_assign_credentials.results }}" - # when: result_assign_credentials is defined - - - name: Assert assign Credentials to sites - assert: - that: - - item.changed == true - - "'Device Credential Assigned to a site is Successfully' in item.response[0].assignCredential['Assign Credentials'].msg" - loop: "{{ result_assign_credentials.results }}" - when: result_assign_credentials is defined - -############################################# -# DELETE SITE # -############################################# - - - name: Delete site from design_sites config - cisco.dnac.site_workflow_manager: - <<: *dnac_login - config_verify: true - state: deleted - config: - - "{{ item }}" - register: result_delete_site - loop: "{{ vars_map.design_sites }}" - tags: deleted - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_site.results }}" - # when: result_delete_site is defined - - - name: Assert deletion of area success for each site - assert: - that: - - item.changed == true - - "'deleted successfully' in item.response" - loop: "{{ result_delete_site.results }}" - when: result_delete_site is defined - -############################################# -# Delete Credentials # -############################################# - - - name: Delete Credentials - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: deleted - config_verify: True - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - tags: deleted - register: result_delete_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_credentials.results }}" - # when: result_delete_credentials is defined - - - name: Assert Global Credential Deletion - assert: - that: - - item.changed == true - - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" - - item.response[0].globalCredential.Validation == "Success" - loop: "{{ result_delete_credentials.results }}" - when: result_delete_credentials is defined +# ############################################# +# # Pre Tests Clean Up # +# ############################################# + +# - name: Clean up site before test +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.design_sites }}" + +# - name: Clean up device credentials before test +# cisco.dnac.device_credential_workflow_manager: +# <<: *dnac_login +# state: deleted +# config_verify: True +# config: +# - "{{ item }}" +# with_list: "{{ vars_map.credentials_details }}" + +# ############################################# +# # CREATE SITE # +# ############################################# + +# - name: Create sites from design_sites config +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: merged +# config: +# - "{{ item }}" +# register: result_create_site +# loop: "{{ vars_map.design_sites }}" +# tags: merged + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_create_site.results }}" +# # when: result_create_site is defined + +# - name: Assert area creation success for each site +# assert: +# that: +# - item.changed == true +# - item.response.status == "SUCCESS" +# - "'created successfully' in item.msg" +# loop: "{{ result_create_site.results }}" +# when: result_create_site is defined + +# ############################################# +# # Create Credentials # +# ############################################# + +# - name: Create Credentials +# cisco.dnac.device_credential_workflow_manager: +# <<: *dnac_login +# state: merged +# config_verify: True +# config: +# - "{{ item }}" +# with_list: "{{ vars_map.credentials_details }}" +# tags: merged +# register: result_create_credentials + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_create_credentials.results }}" +# # when: result_create_credentials is defined + +# - name: Assert Device Credential Creation +# assert: +# that: +# - item.changed == true +# - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" +# - item.response[0].globalCredential.Validation == "Success" +# loop: "{{ result_create_credentials.results }}" +# when: result_create_credentials is defined + +# ############################################# +# # Assign Credentials to site # +# ############################################# + +# - name: Assign Credentials to design_sites +# cisco.dnac.device_credential_workflow_manager: +# <<: *dnac_login +# state: merged +# config_verify: True +# config: +# - "{{ item }}" +# with_list: "{{ vars_map.credentials_assign }}" +# tags: assign +# register: result_assign_credentials + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_assign_credentials.results }}" +# # when: result_assign_credentials is defined + +# - name: Assert assign Credentials to sites +# assert: +# that: +# - item.changed == true +# - "'Device Credential Assigned to a site is Successfully' in item.response[0].assignCredential['Assign Credentials'].msg" +# loop: "{{ result_assign_credentials.results }}" +# when: result_assign_credentials is defined + +# ############################################# +# # DELETE SITE # +# ############################################# + +# - name: Delete site from design_sites config +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: deleted +# config: +# - "{{ item }}" +# register: result_delete_site +# loop: "{{ vars_map.design_sites }}" +# tags: deleted + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_delete_site.results }}" +# # when: result_delete_site is defined + +# - name: Assert deletion of area success for each site +# assert: +# that: +# - item.changed == true +# - "'deleted successfully' in item.response" +# loop: "{{ result_delete_site.results }}" +# when: result_delete_site is defined + +# ############################################# +# # Delete Credentials # +# ############################################# + +# - name: Delete Credentials +# cisco.dnac.device_credential_workflow_manager: +# <<: *dnac_login +# state: deleted +# config_verify: True +# config: +# - "{{ item }}" +# with_list: "{{ vars_map.credentials_details }}" +# tags: deleted +# register: result_delete_credentials + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_delete_credentials.results }}" +# # when: result_delete_credentials is defined + +# - name: Assert Global Credential Deletion +# assert: +# that: +# - item.changed == true +# - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" +# - item.response[0].globalCredential.Validation == "Success" +# loop: "{{ result_delete_credentials.results }}" +# when: result_delete_credentials is defined diff --git a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml index 352838fe9e..5c8a8fe06f 100644 --- a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml @@ -24,105 +24,105 @@ # - debug: # msg: "{{ vars_map.credentials_update }}" -############################################# -# Pre Tests Clean Up # -############################################# - - - name: Clean up device credentials before test - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: deleted - config_verify: True - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - -############################################# -# Create Credentials # -############################################# - - - name: Create Credentials - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: merged - config_verify: True - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - tags: merged - register: result_create_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_credentials.results }}" - # when: result_create_credentials is defined - - - name: Assert Device Credential Creation - assert: - that: - - item.changed == true - - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" - - item.response[0].globalCredential.Validation == "Success" - loop: "{{ result_create_credentials.results }}" - when: result_create_credentials is defined - -############################################# -# Update Credentials # -############################################# - - - name: Update Credentials - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: merged - config_verify: True - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_update }}" - tags: update - register: result_update_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_credentials.results }}" - # when: result_update_credentials is defined - - - name: Assert Device Credential Update - assert: - that: - - item.changed == true - - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" - - item.response[0].globalCredential.Validation == "Success" - loop: "{{ result_update_credentials.results }}" - when: result_update_credentials is defined - -############################################# -# Delete Credentials # -############################################# - - - name: Delete Credentials - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: deleted - config_verify: True - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - tags: deleted - register: result_delete_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_credentials.results }}" - # when: result_delete_credentials is defined - - - name: Assert Device Credential Deletion - assert: - that: - - item.changed == true - - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" - - item.response[0].globalCredential.Validation == "Success" - loop: "{{ result_delete_credentials.results }}" - when: result_delete_credentials is defined +# ############################################# +# # Pre Tests Clean Up # +# ############################################# + +# - name: Clean up device credentials before test +# cisco.dnac.device_credential_workflow_manager: +# <<: *dnac_login +# state: deleted +# config_verify: True +# config: +# - "{{ item }}" +# with_list: "{{ vars_map.credentials_details }}" + +# ############################################# +# # Create Credentials # +# ############################################# + +# - name: Create Credentials +# cisco.dnac.device_credential_workflow_manager: +# <<: *dnac_login +# state: merged +# config_verify: True +# config: +# - "{{ item }}" +# with_list: "{{ vars_map.credentials_details }}" +# tags: merged +# register: result_create_credentials + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_create_credentials.results }}" +# # when: result_create_credentials is defined + +# - name: Assert Device Credential Creation +# assert: +# that: +# - item.changed == true +# - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" +# - item.response[0].globalCredential.Validation == "Success" +# loop: "{{ result_create_credentials.results }}" +# when: result_create_credentials is defined + +# ############################################# +# # Update Credentials # +# ############################################# + +# - name: Update Credentials +# cisco.dnac.device_credential_workflow_manager: +# <<: *dnac_login +# state: merged +# config_verify: True +# config: +# - "{{ item }}" +# with_list: "{{ vars_map.credentials_update }}" +# tags: update +# register: result_update_credentials + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_update_credentials.results }}" +# # when: result_update_credentials is defined + +# - name: Assert Device Credential Update +# assert: +# that: +# - item.changed == true +# - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" +# - item.response[0].globalCredential.Validation == "Success" +# loop: "{{ result_update_credentials.results }}" +# when: result_update_credentials is defined + +# ############################################# +# # Delete Credentials # +# ############################################# + +# - name: Delete Credentials +# cisco.dnac.device_credential_workflow_manager: +# <<: *dnac_login +# state: deleted +# config_verify: True +# config: +# - "{{ item }}" +# with_list: "{{ vars_map.credentials_details }}" +# tags: deleted +# register: result_delete_credentials + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_delete_credentials.results }}" +# # when: result_delete_credentials is defined + +# - name: Assert Device Credential Deletion +# assert: +# that: +# - item.changed == true +# - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" +# - item.response[0].globalCredential.Validation == "Success" +# loop: "{{ result_delete_credentials.results }}" +# when: result_delete_credentials is defined diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml index 76787f00da..904128a7a4 100644 --- a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml @@ -38,258 +38,258 @@ # - debug: # msg: "{{ vars_map.cidr }}" -############################################# -# Pre Tests Clean Up # -############################################# - - - name: Delete discoveries before test - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - config_verify: True - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map_delete.delete_discoveries }}" - -############################################# -# Create Single IP Address Discovery # -############################################# - - - name: Discover a single IP Address - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - config_verify: True - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.single_ip }}" - register: result_singleip_discovery - - # - name: Debug item - # debug: - # var: result_singleip_discovery - - - name: Check single IP discovery creation - assert: - that: - - result_singleip_discovery.changed == true - - "'Discovery Created Successfully' in result_singleip_discovery.results | map(attribute='msg') | list" - when: result_singleip_discovery is defined - -############################################# -# Create Range IP Address Discovery # -############################################# - - - name: Discover an IP Address Range - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - config_verify: True - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.ip_range }}" - register: result_ip_range_discovery - - # - name: Debug item - # debug: - # var: result_ip_range_discovery - - - name: Check IP address range discovery creation - assert: - that: - - result_ip_range_discovery.changed == true - - "'Discovery Created Successfully' in result_ip_range_discovery.results | map(attribute='msg') | list" - when: result_ip_range_discovery is defined - -############################################# -# Create Multi Range IP Address Discovery # -############################################# - - - name: Discover Multi IP Address Ranges - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - config_verify: True - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.multi_range }}" - register: result_multi_range_discovery - - # - name: Debug item - # debug: - # var: result_multi_range_discovery - - - name: Check multi range IP address discovery creation - assert: - that: - - result_multi_range_discovery.changed == true - - "'Discovery Created Successfully' in result_multi_range_discovery.results | map(attribute='msg') | list" - when: result_multi_range_discovery is defined - -############################################# -# Create Discovery using CDP # -############################################# - - - name: Discover using CDP - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - config_verify: True - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.cdp }}" - register: result_cdp_discovery - - # - name: Debug item - # debug: - # var: result_cdp_discovery - - - name: Check CDP discovery creation - assert: - that: - - result_cdp_discovery.changed == true - - "'Discovery Created Successfully' in result_cdp_discovery.results | map(attribute='msg') | list" - when: result_cdp_discovery is defined - -############################################# -# Create Discovery using LLDP # -############################################# - - - name: Discover using LLDP - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - config_verify: True - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.lldp }}" - register: result_lldp_discovery - - # - name: Debug item - # debug: - # var: result_lldp_discovery - - - name: Check LLDP discovery creation - assert: - that: - - result_lldp_discovery.changed == true - - "'Discovery Created Successfully' in result_lldp_discovery.results | map(attribute='msg') | list" - when: result_lldp_discovery is defined - -############################################# -# Create Discovery using CIDR # -############################################# - - - name: Discover using CIDR - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - config_verify: True - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.cidr }}" - register: result_cidr_discovery - - # - name: Debug item - # debug: - # var: result_cidr_discovery - - - name: Check CIDR discovery creation - assert: - that: - - result_cidr_discovery.changed == true - - "'Discovery Created Successfully' in result_cidr_discovery.results | map(attribute='msg') | list" - when: result_cidr_discovery is defined - -############################################# -# Create Multiple Discoveries # -############################################# - - - name: Add new item with "preferred_mgmt_ip_method" - set_fact: - vars_map_preferred_mgmt: {} - - - name: Add preferred_mgmt_ip_method to vars_map_preferred_mgmt - set_fact: - vars_map_preferred_mgmt: "{{ vars_map_preferred_mgmt | combine({item + '_preferred_mgmt': vars_map[item] | map('combine', {'preferred_mgmt_ip_method': 'UseLoopBack'}) | map('combine', {'discovery_name': vars_map[item][0]['discovery_name'] + ' - preferred_mgmt' }) | list}) }}" - loop: "{{ vars_map.keys() }}" - tags: multiple_discoveries - - - name: Set vars_map_multiple - set_fact: - vars_map_multiple: "{{ vars_map | combine(vars_map_preferred_mgmt) }}" - tags: multiple_discoveries - - - name: Print the updated vars_map_multiple - debug: - var: vars_map_multiple - tags: multiple_discoveries - - - name: Create multiple Discoveries - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - config_verify: True - state: merged - config: - - "{{ vars_map_multiple[item][0] }}" - with_items: "{{ vars_map_multiple }}" - tags: multiple_discoveries - register: result_multiple_discoveries - - # - name: Debug item - # debug: - # var: result_multiple_discoveries - # when: result_multiple_discoveries is defined - - - name: Check if multiple discoveries were successfull - assert: - that: - - item.changed == true - - "'Discovery Created Successfully' in item.msg" - loop: "{{ result_multiple_discoveries.results }}" - when: result_multiple_discoveries is defined - -############################################# -# Delete Discovery by name # -############################################# - - - name: Delete all discovery - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - config_verify: True - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map_delete.delete_discoveries }}" - register: result_delete_discoveries - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_discoveries.results }}" - - - name: Check if discovery was successfully deleted - assert: - that: - - item.changed == true - - "'Successfully deleted discovery' in item.msg" - loop: "{{ result_delete_discoveries.results }}" - when: result_delete_discoveries is defined - -############################################ -# Delete ALL Discoveries # -############################################ - - # - name: Delete all discoveries that were created - # cisco.dnac.discovery_workflow_manager: - # <<: *dnac_login - # state: deleted - # config_verify: True - # config: - # - delete_all: True - # register: result_delete_all - - # - name: Debug item - # debug: - # var: result_delete_all - # when: result_delete_all is defined +# ############################################# +# # Pre Tests Clean Up # +# ############################################# + +# - name: Delete discoveries before test +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map_delete.delete_discoveries }}" + +# ############################################# +# # Create Single IP Address Discovery # +# ############################################# + +# - name: Discover a single IP Address +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.single_ip }}" +# register: result_singleip_discovery + +# # - name: Debug item +# # debug: +# # var: result_singleip_discovery + +# - name: Check single IP discovery creation +# assert: +# that: +# - result_singleip_discovery.changed == true +# - "'Discovery Created Successfully' in result_singleip_discovery.results | map(attribute='msg') | list" +# when: result_singleip_discovery is defined + +# ############################################# +# # Create Range IP Address Discovery # +# ############################################# + +# - name: Discover an IP Address Range +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.ip_range }}" +# register: result_ip_range_discovery + +# # - name: Debug item +# # debug: +# # var: result_ip_range_discovery + +# - name: Check IP address range discovery creation +# assert: +# that: +# - result_ip_range_discovery.changed == true +# - "'Discovery Created Successfully' in result_ip_range_discovery.results | map(attribute='msg') | list" +# when: result_ip_range_discovery is defined + +# ############################################# +# # Create Multi Range IP Address Discovery # +# ############################################# + +# - name: Discover Multi IP Address Ranges +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.multi_range }}" +# register: result_multi_range_discovery + +# # - name: Debug item +# # debug: +# # var: result_multi_range_discovery + +# - name: Check multi range IP address discovery creation +# assert: +# that: +# - result_multi_range_discovery.changed == true +# - "'Discovery Created Successfully' in result_multi_range_discovery.results | map(attribute='msg') | list" +# when: result_multi_range_discovery is defined + +# ############################################# +# # Create Discovery using CDP # +# ############################################# + +# - name: Discover using CDP +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.cdp }}" +# register: result_cdp_discovery + +# # - name: Debug item +# # debug: +# # var: result_cdp_discovery + +# - name: Check CDP discovery creation +# assert: +# that: +# - result_cdp_discovery.changed == true +# - "'Discovery Created Successfully' in result_cdp_discovery.results | map(attribute='msg') | list" +# when: result_cdp_discovery is defined + +# ############################################# +# # Create Discovery using LLDP # +# ############################################# + +# - name: Discover using LLDP +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.lldp }}" +# register: result_lldp_discovery + +# # - name: Debug item +# # debug: +# # var: result_lldp_discovery + +# - name: Check LLDP discovery creation +# assert: +# that: +# - result_lldp_discovery.changed == true +# - "'Discovery Created Successfully' in result_lldp_discovery.results | map(attribute='msg') | list" +# when: result_lldp_discovery is defined + +# ############################################# +# # Create Discovery using CIDR # +# ############################################# + +# - name: Discover using CIDR +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.cidr }}" +# register: result_cidr_discovery + +# # - name: Debug item +# # debug: +# # var: result_cidr_discovery + +# - name: Check CIDR discovery creation +# assert: +# that: +# - result_cidr_discovery.changed == true +# - "'Discovery Created Successfully' in result_cidr_discovery.results | map(attribute='msg') | list" +# when: result_cidr_discovery is defined + +# ############################################# +# # Create Multiple Discoveries # +# ############################################# + +# - name: Add new item with "preferred_mgmt_ip_method" +# set_fact: +# vars_map_preferred_mgmt: {} + +# - name: Add preferred_mgmt_ip_method to vars_map_preferred_mgmt +# set_fact: +# vars_map_preferred_mgmt: "{{ vars_map_preferred_mgmt | combine({item + '_preferred_mgmt': vars_map[item] | map('combine', {'preferred_mgmt_ip_method': 'UseLoopBack'}) | map('combine', {'discovery_name': vars_map[item][0]['discovery_name'] + ' - preferred_mgmt' }) | list}) }}" +# loop: "{{ vars_map.keys() }}" +# tags: multiple_discoveries + +# - name: Set vars_map_multiple +# set_fact: +# vars_map_multiple: "{{ vars_map | combine(vars_map_preferred_mgmt) }}" +# tags: multiple_discoveries + +# - name: Print the updated vars_map_multiple +# debug: +# var: vars_map_multiple +# tags: multiple_discoveries + +# - name: Create multiple Discoveries +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: merged +# config: +# - "{{ vars_map_multiple[item][0] }}" +# with_items: "{{ vars_map_multiple }}" +# tags: multiple_discoveries +# register: result_multiple_discoveries + +# # - name: Debug item +# # debug: +# # var: result_multiple_discoveries +# # when: result_multiple_discoveries is defined + +# - name: Check if multiple discoveries were successfull +# assert: +# that: +# - item.changed == true +# - "'Discovery Created Successfully' in item.msg" +# loop: "{{ result_multiple_discoveries.results }}" +# when: result_multiple_discoveries is defined + +# ############################################# +# # Delete Discovery by name # +# ############################################# + +# - name: Delete all discovery +# cisco.dnac.discovery_workflow_manager: +# <<: *dnac_login +# config_verify: True +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map_delete.delete_discoveries }}" +# register: result_delete_discoveries + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_delete_discoveries.results }}" + +# - name: Check if discovery was successfully deleted +# assert: +# that: +# - item.changed == true +# - "'Successfully deleted discovery' in item.msg" +# loop: "{{ result_delete_discoveries.results }}" +# when: result_delete_discoveries is defined + +# ############################################ +# # Delete ALL Discoveries # +# ############################################ + +# # - name: Delete all discoveries that were created +# # cisco.dnac.discovery_workflow_manager: +# # <<: *dnac_login +# # state: deleted +# # config_verify: True +# # config: +# # - delete_all: True +# # register: result_delete_all + +# # - name: Debug item +# # debug: +# # var: result_delete_all +# # when: result_delete_all is defined diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index 8b8ceb8c3e..3c170cc0bc 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -28,461 +28,461 @@ # - debug: # msg: "{{ vars_map.delete_devices }}" -############################################# -# Clean Up # -############################################# - - - name: Delete device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_devices }}" - register: result_device_deleted - - - name: Delete site - cisco.dnac.site_workflow_manager: - <<: *dnac_login - config_verify: true - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_sites }}" - register: result_delete_site - -############################################# -# Add Devices # -############################################# - - - name: Add new device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - config_verify: true - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.device_details }}" - register: result_add_device - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_add_device.results }}" - - - name: Assert device addition success - assert: - that: - - item.changed == true - - "'added to Cisco Catalyst Center' in item.msg" - loop: "{{ result_add_device.results }}" - when: result_add_device is defined - -############################################# -# Update Device Credential Details # -############################################# - - - name: Update device details - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.device_credential_updates }}" - register: result_update_device_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_credentials.results }}" - # when: result_update_device_credentials is defined - - - name: Assert update - assert: - that: - - item.changed == true - loop: "{{ result_update_device_credentials.results }}" - when: result_update_device_credentials is defined - -############################################ -# Update Device Interface Detials # -############################################# - - # - name: Pause for 60 seconds before updating interfaces - # pause: - # seconds: 60 - - # - name: Update device interface details - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_interface_updates }}" - # register: result_update_device_interface - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined - - # - name: Assert update - # assert: - # that: - # - item.changed == true - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined - -############################################# -# Update Device Role Detials # -############################################# - - - name: Update device role details - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.device_role_updates }}" - register: result_update_device_role - - - name: Debug item - debug: - var: item - loop: "{{ result_update_device_role.results }}" - when: result_update_device_role is defined - - - name: Assert device role update - assert: - that: - - result_update_device_role.changed == true - - "'Device role was successfully updated' in item.response.progress" - loop: "{{ result_update_device_role.results }}" - when: result_update_device_role is defined - -############################################# -# Update Device Interface Description # -############################################# - - # - name: Pause for 60 seconds before updating interfaces - # pause: - # seconds: 60 - - # - name: Update device interface description post changing role to non-access - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_int_update_post_rolechange }}" - # register: result_update_device_interface - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined - - # - name: Assert update - # assert: - # that: - # - item.changed == true - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined - -############################################# -# Resync Device # -############################################# - - - name: Resync Device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.device_resync }}" - register: result_resync_device - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_resync_device.results }}" - # when: result_resync_device is defined - - - name: Assert device resync - assert: - that: - - result_resync_device.changed == true - - "'Synced devices' in item.response.progress" - loop: "{{ result_resync_device.results }}" - when: result_resync_device is defined - -############################################# -# Create & Assign User Defined Field # -############################################# - - - name: Create & Assign user defined field - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.create_assign_udf }}" - register: result_create_assign_udf - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_assign_udf.results }}" - # when: result_create_assign_udf is defined - - - name: Assert user defined field creation and assignment - assert: - that: - - item.changed == true - loop: "{{ result_create_assign_udf.results }}" - when: result_create_assign_udf is defined - -############################################# -# Update User Defined Field # -############################################# - - - name: Update user defined field - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.update_udf }}" - register: result_update_udf - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_assign_udf.results }}" - # when: result_update_udf is defined - - - name: Assert user defined field updated - assert: - that: - - item.changed == true - loop: "{{ result_update_udf.results }}" - when: result_update_udf is defined - - -############################################# -# Delete User Defined Field # -############################################# - - - name: Delete user defined field - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_udf }}" - register: result_delete_udf - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_udf.results }}" - # when: result_delete_udf is defined - - - name: Assert user defined field deletion - assert: - that: - - result_delete_udf.changed == true - - "'deleted successfully' in item.response.progress" - loop: "{{ result_delete_udf.results }}" - when: result_delete_udf is defined - - -############################################# -# Export Device Details # -############################################# - - - name: Export Device Details in a CSV file - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.export_device_details }}" - register: result_export_details - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_export_details.results }}" - # when: result_export_details is defined - - - name: Assert device details export - assert: - that: - - item.changed == true - loop: "{{ result_export_details.results }}" - when: result_export_details is defined - -############################################# -# Export Device Credential Details # -############################################# - - - name: Export Credential Device Details in a CSV file - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.export_credential_details }}" - register: result_export_credential_details - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_export_credential_details.results }}" - # when: result_export_credential_details is defined - - - name: Assert device credential details export - assert: - that: - - item.changed == true - loop: "{{ result_export_credential_details.results }}" - when: result_export_credential_details is defined - - -############################################# -# CREATE SITE # -############################################# - - - name: Create sites from design_sites config - cisco.dnac.site_workflow_manager: - <<: *dnac_login - config_verify: true - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.design_sites }}" - register: result_create_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_site.results }}" - # when: result_create_site is defined - - - name: Assert area creation success for each site - assert: - that: - - item.changed == true - - item.response.status == "SUCCESS" - - "'created successfully' in item.msg" - loop: "{{ result_create_site.results }}" - when: result_create_site is defined - -############################################# -# ASSOCIATE WIRED DEVICE TO SITE # -############################################# - - - name: Assign wired device to site and then provision - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.associate_wired_device }}" - register: result_associate_device - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_associate_device.results }}" - # when: result_associate_device is defined - - - name: Assert device credential details export - assert: - that: - - item.changed == true - loop: "{{ result_associate_device.results }}" - when: result_associate_device is defined - - -############################################# -# ASSOCIATE WIRELESS DEVICE TO SITE # -############################################# - - # - name: Assign wireless device to site and then provision - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.associate_wireless_device }}" - # register: result_associate_device - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_associate_device.results }}" - # when: result_associate_device is defined - - # - name: Assert device credential details export - # assert: - # that: - # - item.changed == true - # loop: "{{ result_associate_device.results }}" - # when: result_associate_device is defined - -############################################# -# Delete Devices # -############################################# - - - name: Delete device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_devices }}" - register: result_device_deleted - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_device_deleted.results }}" - # when: result_device_deleted is defined - - - name: Assert device deletion success - assert: - that: - - result_device_deleted.changed == true - when: result_device_deleted is defined - -############################################# -# DELETE SITE # -############################################# - - - name: Delete sites from design_sites config - cisco.dnac.site_workflow_manager: - <<: *dnac_login - config_verify: true - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_sites }}" - register: result_delete_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_site.results }}" - # when: result_delete_site is defined - - - name: Assert deletion of area success for each site - assert: - that: - - item.changed == true - - "'deleted successfully' in item.response" - loop: "{{ result_delete_site.results }}" - when: result_delete_site is defined +# ############################################# +# # Clean Up # +# ############################################# + +# - name: Delete device +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_devices }}" +# register: result_device_deleted + +# - name: Delete site +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_sites }}" +# register: result_delete_site + +# ############################################# +# # Add Devices # +# ############################################# + +# - name: Add new device +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.device_details }}" +# register: result_add_device + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_add_device.results }}" + +# - name: Assert device addition success +# assert: +# that: +# - item.changed == true +# - "'added to Cisco Catalyst Center' in item.msg" +# loop: "{{ result_add_device.results }}" +# when: result_add_device is defined + +# ############################################# +# # Update Device Credential Details # +# ############################################# + +# - name: Update device details +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.device_credential_updates }}" +# register: result_update_device_credentials + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_update_device_credentials.results }}" +# # when: result_update_device_credentials is defined + +# - name: Assert update +# assert: +# that: +# - item.changed == true +# loop: "{{ result_update_device_credentials.results }}" +# when: result_update_device_credentials is defined + +# ############################################ +# # Update Device Interface Detials # +# ############################################# + +# # - name: Pause for 60 seconds before updating interfaces +# # pause: +# # seconds: 60 + +# # - name: Update device interface details +# # cisco.dnac.inventory_workflow_manager: +# # <<: *dnac_login +# # state: merged +# # config: +# # - "{{ item }}" +# # loop: "{{ vars_map.device_interface_updates }}" +# # register: result_update_device_interface + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_update_device_interface.results }}" +# # when: result_update_device_interface is defined + +# # - name: Assert update +# # assert: +# # that: +# # - item.changed == true +# # loop: "{{ result_update_device_interface.results }}" +# # when: result_update_device_interface is defined + +# ############################################# +# # Update Device Role Detials # +# ############################################# + +# - name: Update device role details +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.device_role_updates }}" +# register: result_update_device_role + +# - name: Debug item +# debug: +# var: item +# loop: "{{ result_update_device_role.results }}" +# when: result_update_device_role is defined + +# - name: Assert device role update +# assert: +# that: +# - result_update_device_role.changed == true +# - "'Device role was successfully updated' in item.response.progress" +# loop: "{{ result_update_device_role.results }}" +# when: result_update_device_role is defined + +# ############################################# +# # Update Device Interface Description # +# ############################################# + +# # - name: Pause for 60 seconds before updating interfaces +# # pause: +# # seconds: 60 + +# # - name: Update device interface description post changing role to non-access +# # cisco.dnac.inventory_workflow_manager: +# # <<: *dnac_login +# # state: merged +# # config: +# # - "{{ item }}" +# # loop: "{{ vars_map.device_int_update_post_rolechange }}" +# # register: result_update_device_interface + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_update_device_interface.results }}" +# # when: result_update_device_interface is defined + +# # - name: Assert update +# # assert: +# # that: +# # - item.changed == true +# # loop: "{{ result_update_device_interface.results }}" +# # when: result_update_device_interface is defined + +# ############################################# +# # Resync Device # +# ############################################# + +# - name: Resync Device +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.device_resync }}" +# register: result_resync_device + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_resync_device.results }}" +# # when: result_resync_device is defined + +# - name: Assert device resync +# assert: +# that: +# - result_resync_device.changed == true +# - "'Synced devices' in item.response.progress" +# loop: "{{ result_resync_device.results }}" +# when: result_resync_device is defined + +# ############################################# +# # Create & Assign User Defined Field # +# ############################################# + +# - name: Create & Assign user defined field +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.create_assign_udf }}" +# register: result_create_assign_udf + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_create_assign_udf.results }}" +# # when: result_create_assign_udf is defined + +# - name: Assert user defined field creation and assignment +# assert: +# that: +# - item.changed == true +# loop: "{{ result_create_assign_udf.results }}" +# when: result_create_assign_udf is defined + +# ############################################# +# # Update User Defined Field # +# ############################################# + +# - name: Update user defined field +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.update_udf }}" +# register: result_update_udf + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_create_assign_udf.results }}" +# # when: result_update_udf is defined + +# - name: Assert user defined field updated +# assert: +# that: +# - item.changed == true +# loop: "{{ result_update_udf.results }}" +# when: result_update_udf is defined + + +# ############################################# +# # Delete User Defined Field # +# ############################################# + +# - name: Delete user defined field +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_udf }}" +# register: result_delete_udf + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_delete_udf.results }}" +# # when: result_delete_udf is defined + +# - name: Assert user defined field deletion +# assert: +# that: +# - result_delete_udf.changed == true +# - "'deleted successfully' in item.response.progress" +# loop: "{{ result_delete_udf.results }}" +# when: result_delete_udf is defined + + +# ############################################# +# # Export Device Details # +# ############################################# + +# - name: Export Device Details in a CSV file +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.export_device_details }}" +# register: result_export_details + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_export_details.results }}" +# # when: result_export_details is defined + +# - name: Assert device details export +# assert: +# that: +# - item.changed == true +# loop: "{{ result_export_details.results }}" +# when: result_export_details is defined + +# ############################################# +# # Export Device Credential Details # +# ############################################# + +# - name: Export Credential Device Details in a CSV file +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.export_credential_details }}" +# register: result_export_credential_details + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_export_credential_details.results }}" +# # when: result_export_credential_details is defined + +# - name: Assert device credential details export +# assert: +# that: +# - item.changed == true +# loop: "{{ result_export_credential_details.results }}" +# when: result_export_credential_details is defined + + +# ############################################# +# # CREATE SITE # +# ############################################# + +# - name: Create sites from design_sites config +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.design_sites }}" +# register: result_create_site + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_create_site.results }}" +# # when: result_create_site is defined + +# - name: Assert area creation success for each site +# assert: +# that: +# - item.changed == true +# - item.response.status == "SUCCESS" +# - "'created successfully' in item.msg" +# loop: "{{ result_create_site.results }}" +# when: result_create_site is defined + +# ############################################# +# # ASSOCIATE WIRED DEVICE TO SITE # +# ############################################# + +# - name: Assign wired device to site and then provision +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.associate_wired_device }}" +# register: result_associate_device + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_associate_device.results }}" +# # when: result_associate_device is defined + +# - name: Assert device credential details export +# assert: +# that: +# - item.changed == true +# loop: "{{ result_associate_device.results }}" +# when: result_associate_device is defined + + +# ############################################# +# # ASSOCIATE WIRELESS DEVICE TO SITE # +# ############################################# + +# # - name: Assign wireless device to site and then provision +# # cisco.dnac.inventory_workflow_manager: +# # <<: *dnac_login +# # state: merged +# # config: +# # - "{{ item }}" +# # loop: "{{ vars_map.associate_wireless_device }}" +# # register: result_associate_device + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_associate_device.results }}" +# # when: result_associate_device is defined + +# # - name: Assert device credential details export +# # assert: +# # that: +# # - item.changed == true +# # loop: "{{ result_associate_device.results }}" +# # when: result_associate_device is defined + +# ############################################# +# # Delete Devices # +# ############################################# + +# - name: Delete device +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_devices }}" +# register: result_device_deleted + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_device_deleted.results }}" +# # when: result_device_deleted is defined + +# - name: Assert device deletion success +# assert: +# that: +# - result_device_deleted.changed == true +# when: result_device_deleted is defined + +# ############################################# +# # DELETE SITE # +# ############################################# + +# - name: Delete sites from design_sites config +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_sites }}" +# register: result_delete_site + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_delete_site.results }}" +# # when: result_delete_site is defined + +# - name: Assert deletion of area success for each site +# assert: +# that: +# - item.changed == true +# - "'deleted successfully' in item.response" +# loop: "{{ result_delete_site.results }}" +# when: result_delete_site is defined diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml index 3365511376..330104b95d 100644 --- a/tests/integration/ccc_site_management/tests/test_site_management.yml +++ b/tests/integration/ccc_site_management/tests/test_site_management.yml @@ -26,99 +26,99 @@ # - debug: # msg: "{{ vars_map.delete_sites }}" -############################################# -# Clean Up # -############################################# - - - name: Clean up before test - cisco.dnac.site_workflow_manager: - <<: *dnac_login - config_verify: true - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_sites }}" - -############################################# -# CREATE SITES # -############################################# - - - name: Create sites - cisco.dnac.site_workflow_manager: - <<: *dnac_login - config_verify: true - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.design_sites }}" - register: result_create_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_site.results }}" - # when: result_create_site is defined - - - name: Assert area creation success for each site - assert: - that: - - item.changed == true - - "'created successfully' in item.msg" - loop: "{{ result_create_site.results }}" - when: result_create_site is defined - -############################################# -# UPDATE SITES # -############################################# - - - name: Update sites - cisco.dnac.site_workflow_manager: - <<: *dnac_login - config_verify: true - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.update_sites }}" - register: result_update_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_site.results }}" - # when: result_update_site is defined - - - name: Assert area update success for each site - assert: - that: - - item.changed == true - - "'Updated Successfully' in item.msg" - loop: "{{ result_update_site.results }}" - when: result_update_site is defined - -############################################# -# DELETE SITES # -############################################# - - - name: Delete sites - cisco.dnac.site_workflow_manager: - <<: *dnac_login - config_verify: true - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_sites }}" - register: result_delete_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_site.results }}" - # when: result_delete_site is defined - - - name: Assert deletion success for each site - assert: - that: - - item.changed == true - - "'deleted successfully' in item.response" - loop: "{{ result_delete_site.results }}" - when: result_delete_site is defined +# ############################################# +# # Clean Up # +# ############################################# + +# - name: Clean up before test +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_sites }}" + +# ############################################# +# # CREATE SITES # +# ############################################# + +# - name: Create sites +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.design_sites }}" +# register: result_create_site + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_create_site.results }}" +# # when: result_create_site is defined + +# - name: Assert area creation success for each site +# assert: +# that: +# - item.changed == true +# - "'created successfully' in item.msg" +# loop: "{{ result_create_site.results }}" +# when: result_create_site is defined + +# ############################################# +# # UPDATE SITES # +# ############################################# + +# - name: Update sites +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.update_sites }}" +# register: result_update_site + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_update_site.results }}" +# # when: result_update_site is defined + +# - name: Assert area update success for each site +# assert: +# that: +# - item.changed == true +# - "'Updated Successfully' in item.msg" +# loop: "{{ result_update_site.results }}" +# when: result_update_site is defined + +# ############################################# +# # DELETE SITES # +# ############################################# + +# - name: Delete sites +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# config_verify: true +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_sites }}" +# register: result_delete_site + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_delete_site.results }}" +# # when: result_delete_site is defined + +# - name: Assert deletion success for each site +# assert: +# that: +# - item.changed == true +# - "'deleted successfully' in item.response" +# loop: "{{ result_delete_site.results }}" +# when: result_delete_site is defined From 6ccde047523846c6e9720e8ba74d1b6e97d7d5c4 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 11:11:52 -0500 Subject: [PATCH 197/358] path filtering testing --- .circleci/config.yml | 8 ++++---- .../ccc_site_management/vars/vars_site_management.yml | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2d88ad4ce7..deb33350e5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -260,10 +260,10 @@ workflows: integration-testing: jobs: - pre: - when: << pipeline.parameters.run_setup >> + when: << pipeline.parameters.run-setup >> - build: - when: << pipeline.parameters.run_setup >> + when: << pipeline.parameters.run-setup >> matrix: parameters: ansible_cisco_dnac_version: @@ -272,7 +272,7 @@ workflows: - pre - path-filtering/filter: - when: << pipeline.parameters.run_setup >> + when: << pipeline.parameters.run-setup >> # filters: # branches: # ignore: develop @@ -303,7 +303,7 @@ workflows: - path-filtering/filter - sanity-tests: - when: << pipeline.parameters.run_any >> + when: << pipeline.parameters.run-any >> requires: - addrole matrix: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 6989c9e864..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,7 +434,6 @@ update_sites: type: floor - delete_sites: - site: area: From 54a995384a7eb19c84c62eeee0f312528e5b26e6 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 11:35:54 -0500 Subject: [PATCH 198/358] path filtering testing --- .circleci/config.yml | 17 ++++++----------- .../vars/vars_site_management.yml | 1 + 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index deb33350e5..f052507472 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -257,13 +257,12 @@ jobs: workflows: - integration-testing: + pre-testing: + when: << pipeline.parameters.run-setup >> jobs: - pre: - when: << pipeline.parameters.run-setup >> - build: - when: << pipeline.parameters.run-setup >> matrix: parameters: ansible_cisco_dnac_version: @@ -272,10 +271,6 @@ workflows: - pre - path-filtering/filter: - when: << pipeline.parameters.run-setup >> - # filters: - # branches: - # ignore: develop requires: - build base-revision: main @@ -301,11 +296,11 @@ workflows: - addrole: requires: - path-filtering/filter - + + integration-tests: + when: << pipeline.parameters.run-any >> + jobs: - sanity-tests: - when: << pipeline.parameters.run-any >> - requires: - - addrole matrix: parameters: ansible_cisco_dnac_version: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..6989c9e864 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,6 +434,7 @@ update_sites: type: floor + delete_sites: - site: area: From 1962b967f5b1c295bd4345acb54b6b631ff41d7f Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 11:37:25 -0500 Subject: [PATCH 199/358] path filtering testing --- .circleci/config.yml | 2 +- .../ccc_site_management/vars/vars_site_management.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f052507472..1dc5cf49b3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -260,7 +260,7 @@ workflows: pre-testing: when: << pipeline.parameters.run-setup >> jobs: - - pre: + - pre - build: matrix: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 6989c9e864..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,7 +434,6 @@ update_sites: type: floor - delete_sites: - site: area: From 5754c42847df5dddfefb3542a27c37c3884679fe Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 11:40:58 -0500 Subject: [PATCH 200/358] path filtering tests --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1dc5cf49b3..2290cb4776 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -297,6 +297,7 @@ workflows: requires: - path-filtering/filter + integration-tests: when: << pipeline.parameters.run-any >> jobs: From da1e6fe47400e7195aa3320cad3fe1c348d4a33c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 13:04:36 -0500 Subject: [PATCH 201/358] path filtering changes --- .circleci/config.yml | 48 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2290cb4776..a2da98129b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -147,6 +147,28 @@ jobs: addrole: + parameters: + run-setup: + type: boolean + default: true + run-any: + type: boolean + default: false + run-all: + type: boolean + default: false + run-site: + type: boolean + default: false + run-devicecredential: + type: boolean + default: false + run-discovery: + type: boolean + default: false + run-inventory: + type: boolean + default: false machine: true resource_class: rukapse/dnacenter-ansible @@ -156,19 +178,19 @@ jobs: - run: name: Adding roles based on parameters command: | - if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-site >> == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-site >> == true ]]; then echo " - ccc_site_management" >> ccc_roles.yml fi - if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-devicecredential >> == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-devicecredential >> == true ]]; then echo " - ccc_device_credential_management" >> ccc_roles.yml fi - if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-discovery >> == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-discovery >> == true ]]; then echo " - ccc_discovery_management" >> ccc_roles.yml fi - if [[ << pipeline.parameters.run-all >> == true || << pipeline.parameters.run-inventory >> == true ]]; then + if [[ << parameters.run-all >> == true || << parameters.run-inventory >> == true ]]; then echo " - ccc_inventory_management" >> ccc_roles.yml fi @@ -278,6 +300,9 @@ workflows: mapping: | .* run-setup false + .circleci/.* run-any false + .circleci/.* run-all false + plugins/.* run-any true tests/integration/.* run-any true @@ -294,6 +319,21 @@ workflows: tests/integration/ccc_inventory_management/.* run-inventory true - addrole: + matrix: + parameters: + run-all: + - << pipeline.parameters.run-all >> + run-any: + - << pipeline.parameters.run-any >> + run-site: + - << pipeline.parameters.run-site >> + run-devicecredential: + - << pipeline.parameters.run-devicecredential >> + run-discovery: + - << pipeline.parameters.run-discovery >> + run-inventory: + - << pipeline.parameters.run-inventory >> + requires: - path-filtering/filter From ea0d5cc6f381dfcfb8c74a3294135c4cfbead572 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 15:42:50 -0500 Subject: [PATCH 202/358] path mapping tests --- .circleci/config.yml | 123 ++++++++---------- .../vars/vars_inventory_management.yml | 2 +- 2 files changed, 56 insertions(+), 69 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a2da98129b..d0b5e78b67 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,6 +27,9 @@ parameters: run-inventory: type: boolean default: false + run-tests: + type: boolean + default: false jobs: @@ -145,56 +148,58 @@ jobs: set -x rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME - addrole: - parameters: - run-setup: - type: boolean - default: true - run-any: - type: boolean - default: false - run-all: - type: boolean - default: false - run-site: - type: boolean - default: false - run-devicecredential: - type: boolean - default: false - run-discovery: - type: boolean - default: false - run-inventory: - type: boolean - default: false + parameters: + modulename: + type: string machine: true resource_class: rukapse/dnacenter-ansible working_directory: ~/repo steps: - - run: - name: Adding roles based on parameters - command: | - if [[ << parameters.run-all >> == true || << parameters.run-site >> == true ]]; then - echo " - ccc_site_management" >> ccc_roles.yml - fi - - if [[ << parameters.run-all >> == true || << parameters.run-devicecredential >> == true ]]; then - echo " - ccc_device_credential_management" >> ccc_roles.yml - fi - - if [[ << parameters.run-all >> == true || << parameters.run-discovery >> == true ]]; then - echo " - ccc_discovery_management" >> ccc_roles.yml - fi - - if [[ << parameters.run-all >> == true || << parameters.run-inventory >> == true ]]; then - echo " - ccc_inventory_management" >> ccc_roles.yml - fi - - cat ccc_roles.yml + - when: + condition: << pipeline.parameters.run-site >> + steps: + - run: + command: | + echo " - $ccc_site_management" >> ccc_roles.yml + cat ccc_roles.yml + + - when: + condition: << pipeline.parameters.run-devicecredential >> + steps: + - run: + command: | + echo " - $ccc_device_credential_management" >> ccc_roles.yml + cat ccc_roles.yml + + - when: + condition: << pipeline.parameters.run-discovery >> + steps: + - run: + command: | + echo " - $ccc_discovery_management" >> ccc_roles.yml + cat ccc_roles.yml + + - when: + condition: << pipeline.parameters.run-inventory >> + steps: + - run: + command: | + echo " - $ccc_inventory_management" >> ccc_roles.yml + cat ccc_roles.yml + + - when: + condition: << pipeline.parameters.run-all >> + steps: + - run: + command: | + echo " - $ccc_site_management" >> ccc_roles.yml + echo " - $ccc_device_credential_management" >> ccc_roles.yml + echo " - $ccc_discovery_management" >> ccc_roles.yml + echo " - $ccc_inventory_management" >> ccc_roles.yml + cat ccc_roles.yml sanity-tests: parameters: @@ -300,9 +305,6 @@ workflows: mapping: | .* run-setup false - .circleci/.* run-any false - .circleci/.* run-all false - plugins/.* run-any true tests/integration/.* run-any true @@ -318,30 +320,15 @@ workflows: tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true - - addrole: - matrix: - parameters: - run-all: - - << pipeline.parameters.run-all >> - run-any: - - << pipeline.parameters.run-any >> - run-site: - - << pipeline.parameters.run-site >> - run-devicecredential: - - << pipeline.parameters.run-devicecredential >> - run-discovery: - - << pipeline.parameters.run-discovery >> - run-inventory: - - << pipeline.parameters.run-inventory >> - - requires: - - path-filtering/filter - - - integration-tests: - when: << pipeline.parameters.run-any >> + integration-testing: + when: + - equal: [ true, << pipeline.parameters.run-any >> ] jobs: + - addrole + - sanity-tests: + requires: + - addrole matrix: parameters: ansible_cisco_dnac_version: diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 6a192fdcbf..824565d0c1 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -145,7 +145,7 @@ device_role_updates: - ip_address_list: ["204.1.2.5"] device_updated: True update_device_role: - role: CORE + role: ACCESS device_int_update_post_rolechange: From a9eb06c1369d7ef030a3690fd7a6a7de8363db0d Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 15:46:18 -0500 Subject: [PATCH 203/358] path mapping tests --- .circleci/config.yml | 15 +++++---------- .../vars/vars_site_management.yml | 1 + 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d0b5e78b67..a148174a98 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -158,40 +158,35 @@ jobs: working_directory: ~/repo steps: - - when: - condition: << pipeline.parameters.run-site >> + - when: << pipeline.parameters.run-site >> steps: - run: command: | echo " - $ccc_site_management" >> ccc_roles.yml cat ccc_roles.yml - - when: - condition: << pipeline.parameters.run-devicecredential >> + - when: << pipeline.parameters.run-devicecredential >> steps: - run: command: | echo " - $ccc_device_credential_management" >> ccc_roles.yml cat ccc_roles.yml - - when: - condition: << pipeline.parameters.run-discovery >> + - when: << pipeline.parameters.run-discovery >> steps: - run: command: | echo " - $ccc_discovery_management" >> ccc_roles.yml cat ccc_roles.yml - - when: - condition: << pipeline.parameters.run-inventory >> + - when: << pipeline.parameters.run-inventory >> steps: - run: command: | echo " - $ccc_inventory_management" >> ccc_roles.yml cat ccc_roles.yml - - when: - condition: << pipeline.parameters.run-all >> + - when: << pipeline.parameters.run-all >> steps: - run: command: | diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..6989c9e864 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,6 +434,7 @@ update_sites: type: floor + delete_sites: - site: area: From 2401b2e80d149e5ed7e6a7d47d4b86c19939f1ba Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 15:51:02 -0500 Subject: [PATCH 204/358] path mapping tests --- .circleci/config.yml | 17 +++++++++++------ .../vars/vars_site_management.yml | 1 - 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a148174a98..f496839bae 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -158,36 +158,41 @@ jobs: working_directory: ~/repo steps: - - when: << pipeline.parameters.run-site >> + - when: + condition: << pipeline.parameters.run-site >> steps: - run: command: | echo " - $ccc_site_management" >> ccc_roles.yml cat ccc_roles.yml - - when: << pipeline.parameters.run-devicecredential >> + - when: + condition: << pipeline.parameters.run-devicecredential >> steps: - run: command: | echo " - $ccc_device_credential_management" >> ccc_roles.yml cat ccc_roles.yml - - when: << pipeline.parameters.run-discovery >> + - when: + condition: << pipeline.parameters.run-discovery >> steps: - run: command: | echo " - $ccc_discovery_management" >> ccc_roles.yml cat ccc_roles.yml - - when: << pipeline.parameters.run-inventory >> + - when: + condition: << pipeline.parameters.run-inventory >> steps: - run: command: | echo " - $ccc_inventory_management" >> ccc_roles.yml cat ccc_roles.yml - - when: << pipeline.parameters.run-all >> - steps: + - when: + condition: << pipeline.parameters.run-all >> + steps: - run: command: | echo " - $ccc_site_management" >> ccc_roles.yml diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 6989c9e864..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,7 +434,6 @@ update_sites: type: floor - delete_sites: - site: area: From e480c726233ad8522a0e45d41144b6ac21e4be8c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 15:52:44 -0500 Subject: [PATCH 205/358] path mapping tests --- .circleci/config.yml | 3 +-- .../ccc_site_management/vars/vars_site_management.yml | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f496839bae..4df1bb4fbc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -321,8 +321,7 @@ workflows: tests/integration/ccc_inventory_management/.* run-inventory true integration-testing: - when: - - equal: [ true, << pipeline.parameters.run-any >> ] + when: << pipeline.parameters.run-any >> jobs: - addrole diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..6989c9e864 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,6 +434,7 @@ update_sites: type: floor + delete_sites: - site: area: From 27a545225776957c4e6197218334d7a1f82e540f Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 15:53:30 -0500 Subject: [PATCH 206/358] path mapping tests --- .circleci/config.yml | 4 ---- .../ccc_site_management/vars/vars_site_management.yml | 1 - 2 files changed, 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4df1bb4fbc..d3aadc14e0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -149,10 +149,6 @@ jobs: rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME addrole: - parameters: - modulename: - type: string - machine: true resource_class: rukapse/dnacenter-ansible working_directory: ~/repo diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 6989c9e864..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,7 +434,6 @@ update_sites: type: floor - delete_sites: - site: area: From 3ffd5a3f494ab5c4892c00727ee89acd27eaa1a3 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 16:02:05 -0500 Subject: [PATCH 207/358] path mapping tests --- .circleci/config.yml | 8 ++++---- .../ccc_site_management/vars/vars_site_management.yml | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d3aadc14e0..36b2f155f1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -159,7 +159,7 @@ jobs: steps: - run: command: | - echo " - $ccc_site_management" >> ccc_roles.yml + echo " - ccc_site_management" >> ccc_roles.yml cat ccc_roles.yml - when: @@ -167,7 +167,7 @@ jobs: steps: - run: command: | - echo " - $ccc_device_credential_management" >> ccc_roles.yml + echo " - ccc_device_credential_management" >> ccc_roles.yml cat ccc_roles.yml - when: @@ -175,7 +175,7 @@ jobs: steps: - run: command: | - echo " - $ccc_discovery_management" >> ccc_roles.yml + echo " - ccc_discovery_management" >> ccc_roles.yml cat ccc_roles.yml - when: @@ -183,7 +183,7 @@ jobs: steps: - run: command: | - echo " - $ccc_inventory_management" >> ccc_roles.yml + echo " - ccc_inventory_management" >> ccc_roles.yml cat ccc_roles.yml - when: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..6989c9e864 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,6 +434,7 @@ update_sites: type: floor + delete_sites: - site: area: From 0ba36ab7f36c99f4a2302453338c6b7f9f6c4d23 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 16:05:10 -0500 Subject: [PATCH 208/358] path mapping tests --- .circleci/config.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 36b2f155f1..c160403757 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -306,16 +306,6 @@ workflows: plugins/module_utils/.* run-all true - plugins/modules/site_workflow_manager.py run-site true - plugins/modules/device_credential_workflow_manager.py run-devicecredential true - plugins/modules/discovery_workflow_manager.py run-discovery true - plugins/modules/inventory_workflow_manager.py run-inventory true - - tests/integration/ccc_site_management/.* run-site true - tests/integration/ccc_device_credential_management/.* run-devicecredential true - tests/integration/ccc_discovery_management/.* run-discovery true - tests/integration/ccc_inventory_management/.* run-inventory true - integration-testing: when: << pipeline.parameters.run-any >> jobs: From 9c2ef75c66c258421d97b3d6e0099f593d015cbf Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 16:30:24 -0500 Subject: [PATCH 209/358] path mapping tests --- .circleci/config.yml | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c160403757..17afff0d0c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -160,7 +160,6 @@ jobs: - run: command: | echo " - ccc_site_management" >> ccc_roles.yml - cat ccc_roles.yml - when: condition: << pipeline.parameters.run-devicecredential >> @@ -168,7 +167,6 @@ jobs: - run: command: | echo " - ccc_device_credential_management" >> ccc_roles.yml - cat ccc_roles.yml - when: condition: << pipeline.parameters.run-discovery >> @@ -176,7 +174,6 @@ jobs: - run: command: | echo " - ccc_discovery_management" >> ccc_roles.yml - cat ccc_roles.yml - when: condition: << pipeline.parameters.run-inventory >> @@ -184,7 +181,6 @@ jobs: - run: command: | echo " - ccc_inventory_management" >> ccc_roles.yml - cat ccc_roles.yml - when: condition: << pipeline.parameters.run-all >> @@ -195,7 +191,9 @@ jobs: echo " - $ccc_device_credential_management" >> ccc_roles.yml echo " - $ccc_discovery_management" >> ccc_roles.yml echo " - $ccc_inventory_management" >> ccc_roles.yml - cat ccc_roles.yml + + - run: + command: cat ccc_roles.yml sanity-tests: parameters: @@ -301,11 +299,6 @@ workflows: mapping: | .* run-setup false - plugins/.* run-any true - tests/integration/.* run-any true - - plugins/module_utils/.* run-all true - integration-testing: when: << pipeline.parameters.run-any >> jobs: From 97890d71fd990b38ae6313f61fc30455bd346b0e Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 16:32:59 -0500 Subject: [PATCH 210/358] path mapping tests --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 17afff0d0c..5263ec1582 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -298,6 +298,8 @@ workflows: config-path: .circleci/config.yml mapping: | .* run-setup false + + plugins/.* run-any true integration-testing: when: << pipeline.parameters.run-any >> From 377b35746f2f88e282290dc883f967ece7e04fdf Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 16:53:34 -0500 Subject: [PATCH 211/358] path filtering --- .circleci/config.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5263ec1582..9d8179b54a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -294,12 +294,25 @@ workflows: - path-filtering/filter: requires: - build - base-revision: main + base-revision: circleci-setup config-path: .circleci/config.yml mapping: | .* run-setup false - + plugins/.* run-any true + tests/integration/.* run-any true + + plugins/module_utils/.* run-all true + + plugins/modules/site_workflow_manager.py run-site true + plugins/modules/device_credential_workflow_manager.py run-devicecredential true + plugins/modules/discovery_workflow_manager.py run-discovery true + plugins/modules/inventory_workflow_manager.py run-inventory true + + tests/integration/ccc_site_management/.* run-site true + tests/integration/ccc_device_credential_management/.* run-devicecredential true + tests/integration/ccc_discovery_management/.* run-discovery true + tests/integration/ccc_inventory_management/.* run-inventory true integration-testing: when: << pipeline.parameters.run-any >> From e1d57e1b3c60e484d3cc9509be7fbb9f9f68bdad Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 16:55:43 -0500 Subject: [PATCH 212/358] final testing --- .../ccc_site_management/vars/vars_site_management.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 6989c9e864..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,7 +434,6 @@ update_sites: type: floor - delete_sites: - site: area: From 83e1d002761725b872d2f7b5c573c150bb95dce6 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 17:18:30 -0500 Subject: [PATCH 213/358] testing scheduled workflow --- .circleci/config.yml | 64 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9d8179b54a..df7c464ae9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -187,14 +187,30 @@ jobs: steps: - run: command: | - echo " - $ccc_site_management" >> ccc_roles.yml - echo " - $ccc_device_credential_management" >> ccc_roles.yml - echo " - $ccc_discovery_management" >> ccc_roles.yml - echo " - $ccc_inventory_management" >> ccc_roles.yml + echo " - ccc_site_management" >> ccc_roles.yml + echo " - ccc_device_credential_management" >> ccc_roles.yml + echo " - ccc_discovery_management" >> ccc_roles.yml + echo " - ccc_inventory_management" >> ccc_roles.yml - run: command: cat ccc_roles.yml + add-all-roles: + machine: true + resource_class: rukapse/dnacenter-ansible + working_directory: ~/repo + + steps: + - run: + name: Debug information + command: | + echo " - ccc_site_management" >> ccc_roles.yml + echo " - ccc_device_credential_management" >> ccc_roles.yml + echo " - ccc_discovery_management" >> ccc_roles.yml + echo " - ccc_inventory_management" >> ccc_roles.yml + cat ccc_roles.yml + + sanity-tests: parameters: ansible_cisco_dnac_version: @@ -277,7 +293,7 @@ jobs: rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME -workflows: +workflows: pre-testing: when: << pipeline.parameters.run-setup >> jobs: @@ -327,12 +343,34 @@ workflows: ansible_cisco_dnac_version: - "6.9.0" + scheduled-testing: + triggers: + - schedule: + cron: "0 0 * * *" + filters: + branches: + only: + - circleci-setup + jobs: + - pre + + - build: + matrix: + parameters: + ansible_cisco_dnac_version: + - "6.9.0" + requires: + - pre + + - add-all-roles: + requires: + - build + + - sanity-tests: + requires: + - addrole + matrix: + parameters: + ansible_cisco_dnac_version: + - "6.9.0" - # daily-scheduled: - # triggers: - # - schedule: - # cron: "0 0 * * *" - # filters: - # branches: - # only: - # - main From 40719efdd4a16aa7c4ea74992ae62a962159cc8e Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 17:34:22 -0500 Subject: [PATCH 214/358] testing scheduled workflow --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index df7c464ae9..dc73f9cf00 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -368,7 +368,7 @@ workflows: - sanity-tests: requires: - - addrole + - add-all-roles matrix: parameters: ansible_cisco_dnac_version: From 7f32d77d95f4ad3d3400acde308bd3c1986fa6b6 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 6 Mar 2024 18:39:27 -0500 Subject: [PATCH 215/358] testing scheduled workflow --- .circleci/config.yml | 59 ++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index dc73f9cf00..abc18b389f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -343,34 +343,35 @@ workflows: ansible_cisco_dnac_version: - "6.9.0" - scheduled-testing: - triggers: - - schedule: - cron: "0 0 * * *" - filters: - branches: - only: - - circleci-setup - jobs: - - pre - - - build: - matrix: - parameters: - ansible_cisco_dnac_version: - - "6.9.0" - requires: - - pre - - add-all-roles: - requires: - - build - - - sanity-tests: - requires: - - add-all-roles - matrix: - parameters: - ansible_cisco_dnac_version: - - "6.9.0" + # scheduled-testing: + # triggers: + # - schedule: + # cron: "0 0 * * *" + # filters: + # branches: + # only: + # - circleci-setup + # jobs: + # - pre + + # - build: + # matrix: + # parameters: + # ansible_cisco_dnac_version: + # - "6.9.0" + # requires: + # - pre + + # - add-all-roles: + # requires: + # - build + + # - sanity-tests: + # requires: + # - add-all-roles + # matrix: + # parameters: + # ansible_cisco_dnac_version: + # - "6.9.0" From 0e111e9d20f818cd4b83f9384111750ce3adb6e6 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 11 Mar 2024 21:16:26 -0400 Subject: [PATCH 216/358] scheduler added --- .circleci/config.yml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index abc18b389f..cc3d66750d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -295,6 +295,13 @@ jobs: workflows: pre-testing: + triggers: + - schedule: + cron: "0 0 * * *" + filters: + branches: + only: + - circleci-setup when: << pipeline.parameters.run-setup >> jobs: - pre @@ -332,8 +339,9 @@ workflows: integration-testing: when: << pipeline.parameters.run-any >> - jobs: - - addrole + jobs: + - <<# if scheduled-build >>add-all-roles<< else >>addrole<< /if >> + # - addrole - sanity-tests: requires: @@ -344,14 +352,7 @@ workflows: - "6.9.0" - # scheduled-testing: - # triggers: - # - schedule: - # cron: "0 0 * * *" - # filters: - # branches: - # only: - # - circleci-setup + # jobs: # - pre From 7de082261cc9bac43a9c998c9aee2a6a7d8cbcef Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 11 Mar 2024 21:18:54 -0400 Subject: [PATCH 217/358] scheduler added --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cc3d66750d..cef2613a5f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -340,7 +340,7 @@ workflows: integration-testing: when: << pipeline.parameters.run-any >> jobs: - - <<# if scheduled-build >>add-all-roles<< else >>addrole<< /if >> + - <<\<<# if scheduled-build >>add-all-roles<< else >>addrole<< /if >> # - addrole - sanity-tests: From 497a64b246f2c3ea7f2e968862bb6483ed50f339 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 11 Mar 2024 21:39:21 -0400 Subject: [PATCH 218/358] scheduler added --- .circleci/config.yml | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cef2613a5f..0f05b581ca 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -183,7 +183,11 @@ jobs: echo " - ccc_inventory_management" >> ccc_roles.yml - when: - condition: << pipeline.parameters.run-all >> + condition: + or: + - << pipeline.parameters.run-all >> + - equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] + steps: - run: command: | @@ -195,20 +199,20 @@ jobs: - run: command: cat ccc_roles.yml - add-all-roles: - machine: true - resource_class: rukapse/dnacenter-ansible - working_directory: ~/repo + # add-all-roles: + # machine: true + # resource_class: rukapse/dnacenter-ansible + # working_directory: ~/repo - steps: - - run: - name: Debug information - command: | - echo " - ccc_site_management" >> ccc_roles.yml - echo " - ccc_device_credential_management" >> ccc_roles.yml - echo " - ccc_discovery_management" >> ccc_roles.yml - echo " - ccc_inventory_management" >> ccc_roles.yml - cat ccc_roles.yml + # steps: + # - run: + # name: Debug information + # command: | + # echo " - ccc_site_management" >> ccc_roles.yml + # echo " - ccc_device_credential_management" >> ccc_roles.yml + # echo " - ccc_discovery_management" >> ccc_roles.yml + # echo " - ccc_inventory_management" >> ccc_roles.yml + # cat ccc_roles.yml sanity-tests: @@ -340,8 +344,7 @@ workflows: integration-testing: when: << pipeline.parameters.run-any >> jobs: - - <<\<<# if scheduled-build >>add-all-roles<< else >>addrole<< /if >> - # - addrole + - addrole - sanity-tests: requires: From 1ec316f48ccb5dfc70c50a4ead1c846ecf9215a2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 11 Mar 2024 21:43:56 -0400 Subject: [PATCH 219/358] scheduler added --- .circleci/config.yml | 94 ++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0f05b581ca..0047c13e52 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -183,11 +183,10 @@ jobs: echo " - ccc_inventory_management" >> ccc_roles.yml - when: - condition: - or: - - << pipeline.parameters.run-all >> - - equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] - + condition: << pipeline.parameters.run-all >> + # or: + # - << pipeline.parameters.run-all >> + # - equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] steps: - run: command: | @@ -199,20 +198,20 @@ jobs: - run: command: cat ccc_roles.yml - # add-all-roles: - # machine: true - # resource_class: rukapse/dnacenter-ansible - # working_directory: ~/repo + add-all-roles: + machine: true + resource_class: rukapse/dnacenter-ansible + working_directory: ~/repo - # steps: - # - run: - # name: Debug information - # command: | - # echo " - ccc_site_management" >> ccc_roles.yml - # echo " - ccc_device_credential_management" >> ccc_roles.yml - # echo " - ccc_discovery_management" >> ccc_roles.yml - # echo " - ccc_inventory_management" >> ccc_roles.yml - # cat ccc_roles.yml + steps: + - run: + name: Debug information + command: | + echo " - ccc_site_management" >> ccc_roles.yml + echo " - ccc_device_credential_management" >> ccc_roles.yml + echo " - ccc_discovery_management" >> ccc_roles.yml + echo " - ccc_inventory_management" >> ccc_roles.yml + cat ccc_roles.yml sanity-tests: @@ -299,13 +298,6 @@ jobs: workflows: pre-testing: - triggers: - - schedule: - cron: "0 0 * * *" - filters: - branches: - only: - - circleci-setup when: << pipeline.parameters.run-setup >> jobs: - pre @@ -354,28 +346,34 @@ workflows: ansible_cisco_dnac_version: - "6.9.0" + scheduled_testing: + triggers: + - schedule: + cron: "0 0 * * *" + filters: + branches: + only: + - circleci-setup + jobs: + - pre + + - build: + matrix: + parameters: + ansible_cisco_dnac_version: + - "6.9.0" + requires: + - pre + + - add-all-roles: + requires: + - build - - # jobs: - # - pre - - # - build: - # matrix: - # parameters: - # ansible_cisco_dnac_version: - # - "6.9.0" - # requires: - # - pre - - # - add-all-roles: - # requires: - # - build - - # - sanity-tests: - # requires: - # - add-all-roles - # matrix: - # parameters: - # ansible_cisco_dnac_version: - # - "6.9.0" + - sanity-tests: + requires: + - add-all-roles + matrix: + parameters: + ansible_cisco_dnac_version: + - "6.9.0" From f34c1eb4b4e9fbce98e935a59a551b81a2ed1910 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 11 Mar 2024 21:47:43 -0400 Subject: [PATCH 220/358] scheduler added --- .circleci/config.yml | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0047c13e52..f42c47293c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,9 +9,9 @@ parameters: run-setup: type: boolean default: true - run-any: - type: boolean - default: false + # run-any: + # type: boolean + # default: false run-all: type: boolean default: false @@ -317,10 +317,7 @@ workflows: config-path: .circleci/config.yml mapping: | .* run-setup false - - plugins/.* run-any true - tests/integration/.* run-any true - + plugins/module_utils/.* run-all true plugins/modules/site_workflow_manager.py run-site true @@ -333,10 +330,9 @@ workflows: tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true - integration-testing: - when: << pipeline.parameters.run-any >> - jobs: - - addrole + - addrole: + requires: + - path-filtering/filter - sanity-tests: requires: @@ -346,6 +342,19 @@ workflows: ansible_cisco_dnac_version: - "6.9.0" + # integration-testing: + # when: << pipeline.parameters.run-any >> + # jobs: + # - addrole + + # - sanity-tests: + # requires: + # - addrole + # matrix: + # parameters: + # ansible_cisco_dnac_version: + # - "6.9.0" + scheduled_testing: triggers: - schedule: From 9ccf7b22e132753cc7a1026461d8b6c68599cd51 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 11 Mar 2024 21:49:41 -0400 Subject: [PATCH 221/358] scheduler added --- .circleci/config.yml | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f42c47293c..5d125c82f6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -317,7 +317,7 @@ workflows: config-path: .circleci/config.yml mapping: | .* run-setup false - + plugins/module_utils/.* run-all true plugins/modules/site_workflow_manager.py run-site true @@ -342,19 +342,6 @@ workflows: ansible_cisco_dnac_version: - "6.9.0" - # integration-testing: - # when: << pipeline.parameters.run-any >> - # jobs: - # - addrole - - # - sanity-tests: - # requires: - # - addrole - # matrix: - # parameters: - # ansible_cisco_dnac_version: - # - "6.9.0" - scheduled_testing: triggers: - schedule: From aa7efbe04825ee58d0863ce825626c96ff5b1811 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 11 Mar 2024 21:50:32 -0400 Subject: [PATCH 222/358] scheduler added --- .circleci/config.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5d125c82f6..d38c770b3e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -342,34 +342,4 @@ workflows: ansible_cisco_dnac_version: - "6.9.0" - scheduled_testing: - triggers: - - schedule: - cron: "0 0 * * *" - filters: - branches: - only: - - circleci-setup - jobs: - - pre - - - build: - matrix: - parameters: - ansible_cisco_dnac_version: - - "6.9.0" - requires: - - pre - - - add-all-roles: - requires: - - build - - - sanity-tests: - requires: - - add-all-roles - matrix: - parameters: - ansible_cisco_dnac_version: - - "6.9.0" From b22399cef6a6c57d5af3d31433ea23a29a80507a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 11 Mar 2024 21:53:20 -0400 Subject: [PATCH 223/358] test --- .../ccc_site_management/tests/test_site_management.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml index 330104b95d..62f2114416 100644 --- a/tests/integration/ccc_site_management/tests/test_site_management.yml +++ b/tests/integration/ccc_site_management/tests/test_site_management.yml @@ -18,6 +18,7 @@ dnac_debug: "{{ dnac_debug }}" dnac_log: true dnac_log_level: DEBUG + config_verify: true # - debug: # msg: "{{ vars_map.design_sites }}" @@ -33,7 +34,6 @@ # - name: Clean up before test # cisco.dnac.site_workflow_manager: # <<: *dnac_login -# config_verify: true # state: deleted # config: # - "{{ item }}" @@ -46,7 +46,6 @@ # - name: Create sites # cisco.dnac.site_workflow_manager: # <<: *dnac_login -# config_verify: true # state: merged # config: # - "{{ item }}" @@ -74,7 +73,6 @@ # - name: Update sites # cisco.dnac.site_workflow_manager: # <<: *dnac_login -# config_verify: true # state: merged # config: # - "{{ item }}" @@ -102,7 +100,6 @@ # - name: Delete sites # cisco.dnac.site_workflow_manager: # <<: *dnac_login -# config_verify: true # state: deleted # config: # - "{{ item }}" From a939802fb922f58ba3939f73f395e545497f0cc3 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 11 Mar 2024 21:57:18 -0400 Subject: [PATCH 224/358] test --- .circleci/config.yml | 52 +++++++++++++++---- .../vars/vars_site_management.yml | 1 + 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d38c770b3e..abc18b389f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,9 +9,9 @@ parameters: run-setup: type: boolean default: true - # run-any: - # type: boolean - # default: false + run-any: + type: boolean + default: false run-all: type: boolean default: false @@ -183,10 +183,7 @@ jobs: echo " - ccc_inventory_management" >> ccc_roles.yml - when: - condition: << pipeline.parameters.run-all >> - # or: - # - << pipeline.parameters.run-all >> - # - equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] + condition: << pipeline.parameters.run-all >> steps: - run: command: | @@ -318,6 +315,9 @@ workflows: mapping: | .* run-setup false + plugins/.* run-any true + tests/integration/.* run-any true + plugins/module_utils/.* run-all true plugins/modules/site_workflow_manager.py run-site true @@ -330,9 +330,10 @@ workflows: tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true - - addrole: - requires: - - path-filtering/filter + integration-testing: + when: << pipeline.parameters.run-any >> + jobs: + - addrole - sanity-tests: requires: @@ -343,3 +344,34 @@ workflows: - "6.9.0" + # scheduled-testing: + # triggers: + # - schedule: + # cron: "0 0 * * *" + # filters: + # branches: + # only: + # - circleci-setup + # jobs: + # - pre + + # - build: + # matrix: + # parameters: + # ansible_cisco_dnac_version: + # - "6.9.0" + # requires: + # - pre + + # - add-all-roles: + # requires: + # - build + + # - sanity-tests: + # requires: + # - add-all-roles + # matrix: + # parameters: + # ansible_cisco_dnac_version: + # - "6.9.0" + diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..6989c9e864 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,6 +434,7 @@ update_sites: type: floor + delete_sites: - site: area: From ffcedb6c94bb01928ff50fb77452127676cb519f Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 11 Mar 2024 23:43:08 -0400 Subject: [PATCH 225/358] test --- .circleci/config.yml | 64 +++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index abc18b389f..93f0e288bc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -294,6 +294,39 @@ jobs: workflows: + + scheduled-testing: + triggers: + - schedule: + cron: "0 0 * * *" + filters: + branches: + only: + - circleci-setup + jobs: + - pre + + - build: + matrix: + parameters: + ansible_cisco_dnac_version: + - "6.9.0" + requires: + - pre + + - add-all-roles: + requires: + - build + + - sanity-tests: + requires: + - add-all-roles + matrix: + parameters: + ansible_cisco_dnac_version: + - "6.9.0" + + pre-testing: when: << pipeline.parameters.run-setup >> jobs: @@ -344,34 +377,3 @@ workflows: - "6.9.0" - # scheduled-testing: - # triggers: - # - schedule: - # cron: "0 0 * * *" - # filters: - # branches: - # only: - # - circleci-setup - # jobs: - # - pre - - # - build: - # matrix: - # parameters: - # ansible_cisco_dnac_version: - # - "6.9.0" - # requires: - # - pre - - # - add-all-roles: - # requires: - # - build - - # - sanity-tests: - # requires: - # - add-all-roles - # matrix: - # parameters: - # ansible_cisco_dnac_version: - # - "6.9.0" - From 8bdc44bbe2bc6f6d0b094c5b7f1c022d0e530fc3 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 13 Mar 2024 16:54:10 -0400 Subject: [PATCH 226/358] tests --- .circleci/config.yml | 64 ++++--------------- .../tests/test_assign_credentials.yml | 8 +-- .../test_device_credential_management.yml | 5 +- .../tests/test_discovery_management.yml | 11 +--- .../tests/test.yml | 7 +- 5 files changed, 16 insertions(+), 79 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 93f0e288bc..15d7afc1fe 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,7 +27,7 @@ parameters: run-inventory: type: boolean default: false - run-tests: + run-swim: type: boolean default: false @@ -182,6 +182,13 @@ jobs: command: | echo " - ccc_inventory_management" >> ccc_roles.yml + - when: + condition: << pipeline.parameters.run-swim >> + steps: + - run: + command: | + echo " - ccc_swim_management" >> ccc_roles.yml + - when: condition: << pipeline.parameters.run-all >> steps: @@ -191,26 +198,11 @@ jobs: echo " - ccc_device_credential_management" >> ccc_roles.yml echo " - ccc_discovery_management" >> ccc_roles.yml echo " - ccc_inventory_management" >> ccc_roles.yml + echo " - ccc_swim_management" >> ccc_roles.yml - run: command: cat ccc_roles.yml - add-all-roles: - machine: true - resource_class: rukapse/dnacenter-ansible - working_directory: ~/repo - - steps: - - run: - name: Debug information - command: | - echo " - ccc_site_management" >> ccc_roles.yml - echo " - ccc_device_credential_management" >> ccc_roles.yml - echo " - ccc_discovery_management" >> ccc_roles.yml - echo " - ccc_inventory_management" >> ccc_roles.yml - cat ccc_roles.yml - - sanity-tests: parameters: ansible_cisco_dnac_version: @@ -294,39 +286,7 @@ jobs: workflows: - - scheduled-testing: - triggers: - - schedule: - cron: "0 0 * * *" - filters: - branches: - only: - - circleci-setup - jobs: - - pre - - - build: - matrix: - parameters: - ansible_cisco_dnac_version: - - "6.9.0" - requires: - - pre - - - add-all-roles: - requires: - - build - - - sanity-tests: - requires: - - add-all-roles - matrix: - parameters: - ansible_cisco_dnac_version: - - "6.9.0" - - + pre-testing: when: << pipeline.parameters.run-setup >> jobs: @@ -357,11 +317,13 @@ workflows: plugins/modules/device_credential_workflow_manager.py run-devicecredential true plugins/modules/discovery_workflow_manager.py run-discovery true plugins/modules/inventory_workflow_manager.py run-inventory true + plugins/modules/swim_workflow_manager.py run-swim true tests/integration/ccc_site_management/.* run-site true tests/integration/ccc_device_credential_management/.* run-devicecredential true tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true + tests/integration/ccc_swim_management/.* run-swim true integration-testing: when: << pipeline.parameters.run-any >> @@ -375,5 +337,3 @@ workflows: parameters: ansible_cisco_dnac_version: - "6.9.0" - - diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml index 69c325c0f7..498ab204f4 100755 --- a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml @@ -18,6 +18,7 @@ dnac_debug: "{{ dnac_debug }}" dnac_log: true dnac_log_level: DEBUG + config_verify: true - debug: msg: "{{ vars_map.credentials_details }}" @@ -31,7 +32,6 @@ # - name: Clean up site before test # cisco.dnac.site_workflow_manager: # <<: *dnac_login -# config_verify: true # state: deleted # config: # - "{{ item }}" @@ -41,7 +41,6 @@ # cisco.dnac.device_credential_workflow_manager: # <<: *dnac_login # state: deleted -# config_verify: True # config: # - "{{ item }}" # with_list: "{{ vars_map.credentials_details }}" @@ -53,7 +52,6 @@ # - name: Create sites from design_sites config # cisco.dnac.site_workflow_manager: # <<: *dnac_login -# config_verify: true # state: merged # config: # - "{{ item }}" @@ -84,7 +82,6 @@ # cisco.dnac.device_credential_workflow_manager: # <<: *dnac_login # state: merged -# config_verify: True # config: # - "{{ item }}" # with_list: "{{ vars_map.credentials_details }}" @@ -114,7 +111,6 @@ # cisco.dnac.device_credential_workflow_manager: # <<: *dnac_login # state: merged -# config_verify: True # config: # - "{{ item }}" # with_list: "{{ vars_map.credentials_assign }}" @@ -142,7 +138,6 @@ # - name: Delete site from design_sites config # cisco.dnac.site_workflow_manager: # <<: *dnac_login -# config_verify: true # state: deleted # config: # - "{{ item }}" @@ -172,7 +167,6 @@ # cisco.dnac.device_credential_workflow_manager: # <<: *dnac_login # state: deleted -# config_verify: True # config: # - "{{ item }}" # with_list: "{{ vars_map.credentials_details }}" diff --git a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml index 5c8a8fe06f..f593ebb51c 100644 --- a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml @@ -18,6 +18,7 @@ dnac_debug: "{{ dnac_debug }}" dnac_log: true dnac_log_level: DEBUG + config_verify: true # - debug: # msg: "{{ vars_map.credentials_details }}" @@ -32,7 +33,6 @@ # cisco.dnac.device_credential_workflow_manager: # <<: *dnac_login # state: deleted -# config_verify: True # config: # - "{{ item }}" # with_list: "{{ vars_map.credentials_details }}" @@ -45,7 +45,6 @@ # cisco.dnac.device_credential_workflow_manager: # <<: *dnac_login # state: merged -# config_verify: True # config: # - "{{ item }}" # with_list: "{{ vars_map.credentials_details }}" @@ -75,7 +74,6 @@ # cisco.dnac.device_credential_workflow_manager: # <<: *dnac_login # state: merged -# config_verify: True # config: # - "{{ item }}" # with_list: "{{ vars_map.credentials_update }}" @@ -105,7 +103,6 @@ # cisco.dnac.device_credential_workflow_manager: # <<: *dnac_login # state: deleted -# config_verify: True # config: # - "{{ item }}" # with_list: "{{ vars_map.credentials_details }}" diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml index 904128a7a4..bb358ffff6 100644 --- a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml @@ -19,6 +19,7 @@ dnac_debug: "{{ dnac_debug }}" dnac_log: true dnac_log_level: DEBUG + config_verify: True - name: Clean up vars include_vars: @@ -45,7 +46,6 @@ # - name: Delete discoveries before test # cisco.dnac.discovery_workflow_manager: # <<: *dnac_login -# config_verify: True # state: deleted # config: # - "{{ item }}" @@ -58,7 +58,6 @@ # - name: Discover a single IP Address # cisco.dnac.discovery_workflow_manager: # <<: *dnac_login -# config_verify: True # state: merged # config: # - "{{ item }}" @@ -83,7 +82,6 @@ # - name: Discover an IP Address Range # cisco.dnac.discovery_workflow_manager: # <<: *dnac_login -# config_verify: True # state: merged # config: # - "{{ item }}" @@ -108,7 +106,6 @@ # - name: Discover Multi IP Address Ranges # cisco.dnac.discovery_workflow_manager: # <<: *dnac_login -# config_verify: True # state: merged # config: # - "{{ item }}" @@ -133,7 +130,6 @@ # - name: Discover using CDP # cisco.dnac.discovery_workflow_manager: # <<: *dnac_login -# config_verify: True # state: merged # config: # - "{{ item }}" @@ -158,7 +154,6 @@ # - name: Discover using LLDP # cisco.dnac.discovery_workflow_manager: # <<: *dnac_login -# config_verify: True # state: merged # config: # - "{{ item }}" @@ -183,7 +178,6 @@ # - name: Discover using CIDR # cisco.dnac.discovery_workflow_manager: # <<: *dnac_login -# config_verify: True # state: merged # config: # - "{{ item }}" @@ -228,7 +222,6 @@ # - name: Create multiple Discoveries # cisco.dnac.discovery_workflow_manager: # <<: *dnac_login -# config_verify: True # state: merged # config: # - "{{ vars_map_multiple[item][0] }}" @@ -256,7 +249,6 @@ # - name: Delete all discovery # cisco.dnac.discovery_workflow_manager: # <<: *dnac_login -# config_verify: True # state: deleted # config: # - "{{ item }}" @@ -284,7 +276,6 @@ # # cisco.dnac.discovery_workflow_manager: # # <<: *dnac_login # # state: deleted -# # config_verify: True # # config: # # - delete_all: True # # register: result_delete_all diff --git a/tests/integration/ccc_network_settings_management/tests/test.yml b/tests/integration/ccc_network_settings_management/tests/test.yml index d4dd989878..3fc28a2608 100644 --- a/tests/integration/ccc_network_settings_management/tests/test.yml +++ b/tests/integration/ccc_network_settings_management/tests/test.yml @@ -18,6 +18,7 @@ dnac_debug: "{{ dnac_debug }}" dnac_log: true dnac_log_level: DEBUG + config_verify: true - debug: msg: "{{ vars_map.design_sites }}" @@ -32,7 +33,6 @@ - name: Clean up site before test cisco.dnac.site_workflow_manager: <<: *dnac_login - config_verify: true state: deleted config: - "{{ item }}" @@ -41,7 +41,6 @@ - name: Clean up before tests cisco.dnac.site_workflow_manager: <<: *dnac_login - config_verify: true state: deleted config: - "{{ item }}" @@ -55,7 +54,6 @@ - name: Create sites from design_sites config cisco.dnac.site_workflow_manager: <<: *dnac_login - config_verify: true state: merged config: - "{{ item }}" @@ -91,7 +89,6 @@ cisco.dnac.device_credential_workflow_manager: <<: *dnac_login state: merged - config_verify: True config: - "{{ item }}" with_list: "{{ vars_map. }}" @@ -121,7 +118,6 @@ cisco.dnac.device_credential_workflow_manager: <<: *dnac_login state: merged - config_verify: True config: - "{{ item }}" with_list: "{{ vars_map. }}" @@ -155,7 +151,6 @@ - name: Delete site from design_sites config cisco.dnac.site_workflow_manager: <<: *dnac_login - config_verify: true state: deleted config: - "{{ item }}" From 42db7d79dc15a2f5c4ab346e2447af7120be3f8a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 13 Mar 2024 17:01:20 -0400 Subject: [PATCH 227/358] added pnp and network settings --- .../tests/test_inventory_management.yml | 11 +- .../tests/test.yml | 173 ---------- .../test_network_settings_management.yml | 173 ++++++++++ .../vars/main.yml | 7 - .../vars_network_setttings_management.yml | 0 .../ccc_pnp_management/defaults/main.yml | 2 + .../ccc_pnp_management/meta/main.yml | 1 + .../ccc_pnp_management/tasks/main.yml | 34 ++ .../tests/test_pnp_management.yml | 1 + .../vars/vars_pnp_management.yml | 2 + .../ccc_swim_management/defaults/main.yml | 2 + .../ccc_swim_management/meta/main.yml | 1 + .../ccc_swim_management/tasks/main.yml | 34 ++ .../tests/test_swim_management.yml | 305 ++++++++++++++++++ .../vars/vars_swim_management.yml | 172 ++++++++++ 15 files changed, 731 insertions(+), 187 deletions(-) delete mode 100644 tests/integration/ccc_network_settings_management/tests/test.yml create mode 100644 tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml delete mode 100644 tests/integration/ccc_network_settings_management/vars/main.yml create mode 100644 tests/integration/ccc_network_settings_management/vars/vars_network_setttings_management.yml create mode 100644 tests/integration/ccc_pnp_management/defaults/main.yml create mode 100644 tests/integration/ccc_pnp_management/meta/main.yml create mode 100644 tests/integration/ccc_pnp_management/tasks/main.yml create mode 100644 tests/integration/ccc_pnp_management/tests/test_pnp_management.yml create mode 100644 tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml create mode 100644 tests/integration/ccc_swim_management/defaults/main.yml create mode 100644 tests/integration/ccc_swim_management/meta/main.yml create mode 100644 tests/integration/ccc_swim_management/tasks/main.yml create mode 100644 tests/integration/ccc_swim_management/tests/test_swim_management.yml create mode 100644 tests/integration/ccc_swim_management/vars/vars_swim_management.yml diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index 3c170cc0bc..d5e66346f8 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -3,7 +3,7 @@ - debug: msg="Role Path {{ role_path }}" - block: - - name: Load design_sites from ccc_site_management role and declare dnac vars + - name: Load vars and declare dnac vars include_vars: file: "{{ role_path }}/vars/vars_inventory_management.yml" name: vars_map @@ -18,6 +18,7 @@ dnac_debug: "{{ dnac_debug }}" dnac_log: true dnac_log_level: DEBUG + config_verify: true # - debug: # msg: "{{ vars_map.device_details }}" @@ -44,7 +45,6 @@ # - name: Delete site # cisco.dnac.site_workflow_manager: # <<: *dnac_login -# config_verify: true # state: deleted # config: # - "{{ item }}" @@ -58,7 +58,6 @@ # - name: Add new device # cisco.dnac.inventory_workflow_manager: # <<: *dnac_login -# config_verify: true # state: merged # config: # - "{{ item }}" @@ -359,7 +358,6 @@ # - name: Create sites from design_sites config # cisco.dnac.site_workflow_manager: # <<: *dnac_login -# config_verify: true # state: merged # config: # - "{{ item }}" @@ -400,7 +398,7 @@ # # loop: "{{ result_associate_device.results }}" # # when: result_associate_device is defined -# - name: Assert device credential details export +# - name: Assert Assign wired device to site and then provision # assert: # that: # - item.changed == true @@ -427,7 +425,7 @@ # # loop: "{{ result_associate_device.results }}" # # when: result_associate_device is defined -# # - name: Assert device credential details export +# # - name: Assert Assign wireless device to site and then provision # # assert: # # that: # # - item.changed == true @@ -466,7 +464,6 @@ # - name: Delete sites from design_sites config # cisco.dnac.site_workflow_manager: # <<: *dnac_login -# config_verify: true # state: deleted # config: # - "{{ item }}" diff --git a/tests/integration/ccc_network_settings_management/tests/test.yml b/tests/integration/ccc_network_settings_management/tests/test.yml deleted file mode 100644 index 3fc28a2608..0000000000 --- a/tests/integration/ccc_network_settings_management/tests/test.yml +++ /dev/null @@ -1,173 +0,0 @@ ---- -- debug: msg="Starting device credential management test" -- debug: msg="Role Path {{ role_path }}" - -- block: - - name: Load vars and declare dnac vars - include_vars: - file: "{{ role_path }}/vars/main.yml" - name: vars_map - vars: - dnac_login: &dnac_login - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG - config_verify: true - - - debug: - msg: "{{ vars_map.design_sites }}" - - debug: - msg: "{{ vars_map. }}" - - -############################################# -# Pre Tests Clean Up # -############################################# - - - name: Clean up site before test - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.design_sites }}" - - - name: Clean up before tests - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map. }}" - - -############################################# -# CREATE SITE # -############################################# - - - name: Create sites from design_sites config - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - register: result_create_site - loop: "{{ vars_map.design_sites }}" - tags: merged - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_site.results }}" - # when: result_create_site is defined - - - name: Assert area creation success for each site - assert: - that: - - item.changed == true - - item.response.status == "SUCCESS" - - "'created successfully' in item.msg" - loop: "{{ result_create_site.results }}" - when: result_create_site is defined - -############################################# -# UPDATE NETWORK SETTINGS # -############################################# - - -############################################# -# Create Global Pool # -############################################# - - - name: Create Global Pool - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - with_list: "{{ vars_map. }}" - tags: merged - register: result_create_global_pool - - - name: Debug item - debug: - var: item - loop: "{{ result_create_global_pool.results }}" - when: result_create_global_pool is defined - - # - name: Assert Global Pool Creation - # assert: - # that: - # - item.changed == true - # - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" - # - item.response[0].globalCredential.Validation == "Success" - # loop: "{{ result_create_global_pool.results }}" - # when: result_create_global_pool is defined - -############################################# -# Update Global Pool # -############################################# - - - name: Update Global Pool - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - with_list: "{{ vars_map. }}" - tags: update - register: result_update_global_pool - - - name: Debug item - debug: - var: item - loop: "{{ result_update_credentials.results }}" - when: result_update_credentials is defined - - # - name: Assert Global Credential Update - # assert: - # that: - # - item.changed == true - # - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" - # - item.response[0].globalCredential.Validation == "Success" - # loop: "{{ result_update_global_pool.results }}" - # when: result_update_global_pool is defined - -############################################# -# Delete Global Pool # -############################################# - - -############################################# -# DELETE SITE # -############################################# - - - name: Delete site from design_sites config - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - register: result_delete_site - loop: "{{ vars_map.design_sites }}" - tags: deleted - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_site.results }}" - # when: result_delete_site is defined - - - name: Assert deletion of area success for each site - assert: - that: - - item.changed == true - - "'deleted successfully' in item.response" - loop: "{{ result_delete_site.results }}" - when: result_delete_site is defined diff --git a/tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml b/tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml new file mode 100644 index 0000000000..9b329a8aab --- /dev/null +++ b/tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml @@ -0,0 +1,173 @@ +--- +- debug: msg="Starting device credential management test" +- debug: msg="Role Path {{ role_path }}" + +- block: + - name: Load vars and declare dnac vars + include_vars: + file: "{{ role_path }}/vars/main.yml" + name: vars_map + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + config_verify: true + + - debug: + msg: "{{ vars_map.design_sites }}" + - debug: + msg: "{{ vars_map. }}" + + +# ############################################# +# # Pre Tests Clean Up # +# ############################################# + +# - name: Clean up site before test +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.design_sites }}" + +# - name: Clean up before tests +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map. }}" + + +# ############################################# +# # CREATE SITE # +# ############################################# + +# - name: Create sites from design_sites config +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# register: result_create_site +# loop: "{{ vars_map.design_sites }}" +# tags: merged + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_create_site.results }}" +# # when: result_create_site is defined + +# - name: Assert area creation success for each site +# assert: +# that: +# - item.changed == true +# - item.response.status == "SUCCESS" +# - "'created successfully' in item.msg" +# loop: "{{ result_create_site.results }}" +# when: result_create_site is defined + +# ############################################# +# # UPDATE NETWORK SETTINGS # +# ############################################# + + +# ############################################# +# # Create Global Pool # +# ############################################# + +# - name: Create Global Pool +# cisco.dnac.device_credential_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# with_list: "{{ vars_map. }}" +# tags: merged +# register: result_create_global_pool + +# - name: Debug item +# debug: +# var: item +# loop: "{{ result_create_global_pool.results }}" +# when: result_create_global_pool is defined + +# # - name: Assert Global Pool Creation +# # assert: +# # that: +# # - item.changed == true +# # - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" +# # - item.response[0].globalCredential.Validation == "Success" +# # loop: "{{ result_create_global_pool.results }}" +# # when: result_create_global_pool is defined + +# ############################################# +# # Update Global Pool # +# ############################################# + +# - name: Update Global Pool +# cisco.dnac.device_credential_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# with_list: "{{ vars_map. }}" +# tags: update +# register: result_update_global_pool + +# - name: Debug item +# debug: +# var: item +# loop: "{{ result_update_credentials.results }}" +# when: result_update_credentials is defined + +# # - name: Assert Global Credential Update +# # assert: +# # that: +# # - item.changed == true +# # - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" +# # - item.response[0].globalCredential.Validation == "Success" +# # loop: "{{ result_update_global_pool.results }}" +# # when: result_update_global_pool is defined + +# ############################################# +# # Delete Global Pool # +# ############################################# + + +# ############################################# +# # DELETE SITE # +# ############################################# + +# - name: Delete site from design_sites config +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# register: result_delete_site +# loop: "{{ vars_map.design_sites }}" +# tags: deleted + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_delete_site.results }}" +# # when: result_delete_site is defined + +# - name: Assert deletion of area success for each site +# assert: +# that: +# - item.changed == true +# - "'deleted successfully' in item.response" +# loop: "{{ result_delete_site.results }}" +# when: result_delete_site is defined diff --git a/tests/integration/ccc_network_settings_management/vars/main.yml b/tests/integration/ccc_network_settings_management/vars/main.yml deleted file mode 100644 index c1e2ff74b6..0000000000 --- a/tests/integration/ccc_network_settings_management/vars/main.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -design_sites: - - site: - area: - name: TEST_NETWORK_SETTINGS - parent_name: 'Global' - type: area \ No newline at end of file diff --git a/tests/integration/ccc_network_settings_management/vars/vars_network_setttings_management.yml b/tests/integration/ccc_network_settings_management/vars/vars_network_setttings_management.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/integration/ccc_pnp_management/defaults/main.yml b/tests/integration/ccc_pnp_management/defaults/main.yml new file mode 100644 index 0000000000..55a93fc23d --- /dev/null +++ b/tests/integration/ccc_pnp_management/defaults/main.yml @@ -0,0 +1,2 @@ +--- +testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_pnp_management/meta/main.yml b/tests/integration/ccc_pnp_management/meta/main.yml new file mode 100644 index 0000000000..5514b6a40c --- /dev/null +++ b/tests/integration/ccc_pnp_management/meta/main.yml @@ -0,0 +1 @@ +dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_pnp_management/tasks/main.yml b/tests/integration/ccc_pnp_management/tasks/main.yml new file mode 100644 index 0000000000..09e0832ca2 --- /dev/null +++ b/tests/integration/ccc_pnp_management/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: collect ccc test cases + find: + paths: "{{ role_path }}/tests" + patterns: "{{ testcase }}.yml" + connection: local + register: ccc_cases + tags: sanity + +- debug: + msg: "CCC Cases: {{ ccc_cases }}" + +- set_fact: + test_cases: + files: "{{ ccc_cases.files }}" + tags: sanity + +- debug: + msg: "Test Cases: {{ test_cases }}" + +- name: set test_items + set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + tags: sanity + +- debug: + msg: "Test Items: {{ test_items }}" + +- name: run test cases (connection=httpapi) + include_tasks: "{{ test_case_to_run }}" + loop: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml new file mode 100644 index 0000000000..ed97d539c0 --- /dev/null +++ b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml @@ -0,0 +1 @@ +--- diff --git a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml new file mode 100644 index 0000000000..678fdcb00c --- /dev/null +++ b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml @@ -0,0 +1,2 @@ +--- +# vars file for ccc_pnp_management diff --git a/tests/integration/ccc_swim_management/defaults/main.yml b/tests/integration/ccc_swim_management/defaults/main.yml new file mode 100644 index 0000000000..55a93fc23d --- /dev/null +++ b/tests/integration/ccc_swim_management/defaults/main.yml @@ -0,0 +1,2 @@ +--- +testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_swim_management/meta/main.yml b/tests/integration/ccc_swim_management/meta/main.yml new file mode 100644 index 0000000000..5514b6a40c --- /dev/null +++ b/tests/integration/ccc_swim_management/meta/main.yml @@ -0,0 +1 @@ +dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_swim_management/tasks/main.yml b/tests/integration/ccc_swim_management/tasks/main.yml new file mode 100644 index 0000000000..09e0832ca2 --- /dev/null +++ b/tests/integration/ccc_swim_management/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: collect ccc test cases + find: + paths: "{{ role_path }}/tests" + patterns: "{{ testcase }}.yml" + connection: local + register: ccc_cases + tags: sanity + +- debug: + msg: "CCC Cases: {{ ccc_cases }}" + +- set_fact: + test_cases: + files: "{{ ccc_cases.files }}" + tags: sanity + +- debug: + msg: "Test Cases: {{ test_cases }}" + +- name: set test_items + set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + tags: sanity + +- debug: + msg: "Test Items: {{ test_items }}" + +- name: run test cases (connection=httpapi) + include_tasks: "{{ test_case_to_run }}" + loop: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml new file mode 100644 index 0000000000..7106432a92 --- /dev/null +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -0,0 +1,305 @@ +--- +- debug: msg="Starting swim management test" +- debug: msg="Role Path {{ role_path }}" + +- block: + - name: Load vars and declare dnac vars + include_vars: + file: "{{ role_path }}/vars/vars_swim_management.yml" + name: vars_map + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + + # - debug: + # msg: "{{ vars_map. }}" + # - debug: + # msg: "{{ vars_map. }}" + # - debug: + # msg: "{{ vars_map. }}" + +############################################# +# Clean Up # +############################################# + +# - name: Delete device +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_devices }}" +# register: result_device_deleted + +# - name: Delete site +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_sites }}" +# register: result_delete_site + +# ############################################# +# # CREATE SITE # +# ############################################# + +# - name: Create sites +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.design_sites }}" +# register: result_create_site + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_create_site.results }}" +# # when: result_create_site is defined + +# - name: Assert area creation success for each site +# assert: +# that: +# - item.changed == true +# - "'created successfully' in item.msg" +# loop: "{{ result_create_site.results }}" +# when: result_create_site is defined + +# ############################################# +# # Add Devices # +# ############################################# + +# - name: Add new device +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.device_details }}" +# register: result_add_device + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_add_device.results }}" + +# - name: Assert device addition success +# assert: +# that: +# - item.changed == true +# - "'added to Cisco Catalyst Center' in item.msg" +# loop: "{{ result_add_device.results }}" +# when: result_add_device is defined + +# ############################################# +# # ASSOCIATE WIRED DEVICE TO SITE # +# ############################################# + +# - name: Assign wired device to site and then provision +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.associate_wired_device }}" +# register: result_associate_device + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_associate_device.results }}" +# # when: result_associate_device is defined + +# - name: Assert Assign wired device to site and then provision +# assert: +# that: +# - item.changed == true +# loop: "{{ result_associate_device.results }}" +# when: result_associate_device is defined + + +# ############################################# +# # IMPORT IMAGE # +# ############################################# + +# - name: SWIM task - import +# cisco.dnac.swim_workflow_manager: +# <<: *dnac_login +# config: +# - "{{ item }}" +# loop: "{{ vars_map.image_details }}" +# register: result_import_image + +# - name: Debug item +# debug: +# var: item +# loop: "{{ result_import_image.results }}" + +# # - name: Assert import images +# # assert: +# # that: +# # - item.changed == true +# # - '"imported successfully" in item.msg' +# # loop: "{{ result_import_image.results }}" +# # when: result_import_image is defined + +# ############################################# +# # TAG IMAGE # +# ############################################# + +# - name: SWIM task - tag +# cisco.dnac.swim_workflow_manager: +# <<: *dnac_login +# config: +# - "{{ item }}" +# loop: "{{ vars_map.image_golden_tagging_details}}" +# register: result_tag_image + +# - name: Debug item +# debug: +# var: item +# loop: "{{ result_tag_image.results }}" + +# - name: Assert tag images +# assert: +# that: +# - item.changed == true +# - '"Tagging image" in item.msg' +# loop: "{{ result_tag_image.results }}" +# when: result_tag_image is defined + +# ############################################# +# # DISTRIBUTE # +# ############################################# + +# - name: SWIM task - distribute stack +# cisco.dnac.swim_workflow_manager: +# <<: *dnac_login +# config: +# - "{{ item }}" +# loop: "{{ vars_map.image_distributation_details }}" +# register: result_distribute_stack + +# - name: Debug item +# debug: +# var: item +# loop: "{{ result_distribute_stack.results }}" + +# # - name: Assert distribution +# # assert: +# # that: +# # - item.changed == true +# # loop: "{{ result_distribute_stack.results }}" +# # when: result_distribute_stack is defined + +# ############################################# +# # ACTIVATE IMAGE # +# ############################################# + +# - name: SWIM task - activate +# cisco.dnac.swim_workflow_manager: +# <<: *dnac_login +# config: +# - "{{ item }}" +# loop: "{{ vars_map.image_activation_details }}" +# register: result_activate_image + +# - name: Debug item +# debug: +# var: item +# loop: "{{ result_activate_image.results }}" + +# # - name: Assert image activation +# # assert: +# # that: +# # - item.changed == true +# # loop: "{{ result_activate_image.results }}" +# # when: result_activate_image is defined + +# ############################################# +# # UNTAG IMAGE # +# ############################################# + +# - name: SWIM task - untag +# cisco.dnac.swim_workflow_manager: +# <<: *dnac_login +# config: +# - "{{ item }}" +# loop: "{{ vars_map.image_golden_untagging_details }}" +# register: result_untag_image + +# - name: Debug item +# debug: +# var: item +# loop: "{{ result_untag_image.results }}" + +# - name: Assert untag images +# assert: +# that: +# - item.changed == true +# - '"Untagging of image" in item.msg' +# - '"successful" in item.msg' +# loop: "{{ result_untag_image.results }}" +# when: result_untag_image is defined + +# ############################################# +# # Delete Devices # +# ############################################# + +# - name: Delete device +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_devices }}" +# register: result_device_deleted + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_device_deleted.results }}" +# # when: result_device_deleted is defined + +# - name: Assert device deletion success +# assert: +# that: +# - result_device_deleted.changed == true +# when: result_device_deleted is defined + +# ############################################# +# # DELETE SITE # +# ############################################# + +# - name: Delete sites from design_sites config +# cisco.dnac.site_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_sites }}" +# register: result_delete_site + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_delete_site.results }}" +# # when: result_delete_site is defined + +# - name: Assert deletion of area success for each site +# assert: +# that: +# - item.changed == true +# - "'deleted successfully' in item.response" +# loop: "{{ result_delete_site.results }}" +# when: result_delete_site is defined diff --git a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml new file mode 100644 index 0000000000..0b956c1d7d --- /dev/null +++ b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml @@ -0,0 +1,172 @@ +--- +image_details: + - import_image_details: + type: "remote" + url_details: + payload: + - source_url: http://172.21.236.183/swim/V1712_2_CCO/cat9k_iosxe.17.12.02.SPA.bin + third_party: False + - import_image_details: + type: "remote" + url_details: + payload: + - source_url: http://10.197.156.28/stda/abimishr/cat9k_iosxe.17.12.01.SPA.bin + third_party: False + + +image_golden_tagging_details: + - tagging_details: + image_name: "cat9k_iosxe.17.12.01.SPA.bin" + site_name: "Global/ITest_Swim_Area/ITest_Swim_Building/ITest_Swim_Floor1" + device_role: "DISTRIBUTION" + device_image_family_name: "Cisco Catalyst 9300 Switch" + tagging: True + +image_distributation_details: + - image_distribution_details: + image_name: "cat9k_lite_iosxe.17.12.01.SPA.bin" + site_name: "Global/ITest_Swim_Area/ITest_Swim_Building/ITest_Swim_Floor1" + device_role: "DISTRIBUTION" + device_family_name: "Switches and Hubs" + device_series_name: "Cisco Catalyst 9300 Series Switches" + +image_activation_details: + - image_activation_details: + image_name: "cat9k_iosxe.17.12.02.SPA.bin" + site_name: "Global/ITest_Swim_Area/ITest_Swim_Building/ITest_Swim_Floor1" + device_role: "DISTRIBUTION" + device_family_name: "Switches and Hubs" + device_series_name: "Cisco Catalyst 9300 Series Switches" + scehdule_validate: False + distribute_if_needed: True + +image_golden_untagging_details: + - tagging_details: + image_name: "cat9k_iosxe.17.12.01.SPA.bin" + site_name: "Global/ITest_Swim_Area/ITest_Swim_Building/ITest_Swim_Floor1" + device_role: "DISTRIBUTION" + device_image_family_name: "Cisco Catalyst 9300 Switch" + tagging: False + +design_sites: + # Create site to associate device to + - site: + area: + name: ITest_Swim_Area + parent_name: Global + type: area + - site: + building: + name: ITest_Swim_Building + parent_name: Global/ITest_Swim_Area + address: Bengaluru, Karnataka, India + latitude: 12.969910 + longitude: 77.597960 + country: India + type: building + - site: + floor: + name: ITest_Swim_Floor1 + parent_name: Global/ITest_Swim_Area/ITest_Swim_Building + rf_model: Cubes And Walled Offices + width: 100.00 + length: 100.00 + height: 10.00 + floor_number: 1 + type: floor + + +device_details: + - type: "NETWORK_DEVICE" + ip_address_list: ["204.1.2.3"] + device_added: True + # CLI Credentials + username: "cisco" + password: "Cisco#123" + enable_password: "Cisco#123" + # SNMP Credentials + snmp_version: v3 + snmp_username: "v3Public2" + snmp_mode: "AUTHPRIV" + snmp_auth_protocol: "SHA" + snmp_auth_passphrase: "Lablab#1234" + snmp_priv_protocol: "CISCOAES256" + snmp_priv_passphrase: "Lablab#1234" + #SNMP Retry and Timeout + snmp_retry: 3 + snmp_timeout: 5 + #CLI Transport (ssh, Telnet) + cli_transport: "ssh" + netconf_port: 830 + + +associate_wired_device: + - provision_wired_device: + - device_ip: "204.1.2.3" + site_name: "Global/ITest_Swim_Area/ITest_Swim_Building/ITest_Swim_Floor1" + resync_retry_count: 200 + resync_interval: 2 + + +delete_sites: + - site: + area: + name: ITest_Swim_Area + parent_name: Global + type: area + + +delete_devices: + - ip_address_list: ["204.1.2.3"] + #ip_address_list: ["204.1.2.5", "204.192.6.200"] + clean_config: False + + + +#http://172.21.236.183/swim/V1712_2_CCO/cat9k_iosxe.17.12.02.SPA.bin +#device_family_name: "Switches and Hubs" +#IMAGE FAMILY NAME "Cisco Catalyst 9300 Switch" +#device_series_name = +# + + +# --- +# image_details: +# - type: "remote" +# url_details: +# payload: +# - source_url: "http://172.21.236.183/swim/V1712_2_CCO/cat9k_iosxe.17.12.02.SPA.bin" +# is_third_party: false +# device_role: "ACCESS" +# image_name: cat9k_iosxe.17.12.02.SPA.bin +# # device_family_name: "Wireless Controller" +# device_family_name: "Switches and Hubs" + +# # device_type: "Cisco Catalyst 9800-40 Wireless Controller" +# device_image_family_name: "Cisco Catalyst 9300 Switch" +# site_name: "Global/USA/San Francisco/BGL_18" +# # site_name: "" +# # device_serial_number: "FJC2327U0S2" +# # Device with IP - 204.192.3.40 +# # device_serial_number: "FJC2721271T" +# # Device with IP - 204.192.3.40 + + +# # - type: "local" +# # local_image_details: +# # file_path: "/Users/abmahesh/Downloads/cat9k_iosxe.17.12.01.SPA.bin" +# # is_third_party: false +# # device_role: "ACCESS" +# # device_family_name: "Cisco Catalyst 9300 Switch" +# # device_serial_number: "FJC271924K0" +# # site_name: "Global/USA/San Francisco/BGL_18" + + +# # - type: "url" +# # urlDetails: +# # payload: +# # - sourceURL: "http://10.104.118.10/swim/17.12/C9800-SW-iosxe-wlc.BLD_POLARIS_DEV_LATEST_20230402_072041_V17_12_0_8.SSA.bin" +# # isThirdParty: false +# # device_role: "ALL" +# # device_family_name: "Cisco Catalyst 9800-40 Wireless Controller" +# # device_serial_number: "FOX2639PAY7" \ No newline at end of file From d900377fd075877bc599a07e1d7c1ca4bf81da87 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 13 Mar 2024 17:04:29 -0400 Subject: [PATCH 228/358] added pnp and network settings --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 15d7afc1fe..923ebb154a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -303,7 +303,7 @@ workflows: - path-filtering/filter: requires: - build - base-revision: circleci-setup + base-revision: main config-path: .circleci/config.yml mapping: | .* run-setup false From e3848d93f76382c1b280e674a30d7c2ce5d63b01 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 26 Mar 2024 00:48:08 -0400 Subject: [PATCH 229/358] pnp ITs --- .circleci/config.yml | 14 ++ .../tests/test_pnp_management.yml | 226 ++++++++++++++++++ .../vars/vars_pnp_management.yml | 62 ++++- 3 files changed, 301 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 923ebb154a..44c43788e8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -30,6 +30,9 @@ parameters: run-swim: type: boolean default: false + run-pnp: + type: boolean + default: false jobs: @@ -189,6 +192,14 @@ jobs: command: | echo " - ccc_swim_management" >> ccc_roles.yml + - when: + condition: << pipeline.parameters.run-pnp >> + steps: + - run: + command: | + echo " - ccc_pnp_management" >> ccc_roles.yml + + - when: condition: << pipeline.parameters.run-all >> steps: @@ -199,6 +210,7 @@ jobs: echo " - ccc_discovery_management" >> ccc_roles.yml echo " - ccc_inventory_management" >> ccc_roles.yml echo " - ccc_swim_management" >> ccc_roles.yml + echo " - ccc_pnp_management" >> ccc_roles.yml - run: command: cat ccc_roles.yml @@ -318,12 +330,14 @@ workflows: plugins/modules/discovery_workflow_manager.py run-discovery true plugins/modules/inventory_workflow_manager.py run-inventory true plugins/modules/swim_workflow_manager.py run-swim true + plugins/modules/pnp_workflow_manager.py run-swim true tests/integration/ccc_site_management/.* run-site true tests/integration/ccc_device_credential_management/.* run-devicecredential true tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true tests/integration/ccc_swim_management/.* run-swim true + tests/integration/ccc_pnp_management/.* run-swim true integration-testing: when: << pipeline.parameters.run-any >> diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml index ed97d539c0..fbb923d623 100644 --- a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml @@ -1 +1,227 @@ --- +- debug: msg="Starting pnp management test" +- debug: msg="Role Path {{ role_path }}" + +- block: + - name: Load vars and declare dnac vars + include_vars: + file: "{{ role_path }}/vars/vars_pnp_management.yml" + name: vars_map + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + config_verify: true + + + # - debug: + # msg: "{{ vars_map.device_details }}" + + +############################################# +# Clean Up # +############################################# + + # - name: Delete PnP devices + # cisco.dnac.pnp_workflow_manager: + # <<: *dnac_login + # state: deleted + # config: + # - "{{ item }}" + # loop: "{{ vars_map.pnp_delete.delete }}" + + # - name: Delete PnP devices + # cisco.dnac.pnp_workflow_manager: + # <<: *dnac_login + # state: deleted + # config: + # - "{{ item }}" + # loop: "{{ vars_map.bulk.add }}" + +############################################# +# Add device but not Claim PNP Device # +############################################# + + # - name: Adding devices but not claiming + # cisco.dnac.pnp_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.pnp_delete.add }}" + # register: result_add_device + + # - name: Debug Adding devices but not claiming + # debug: + # var: item + # loop: "{{ result_add_device.results }}" + # when: result_add_device is defined + + # - name: Assert adding devices but not claiming + # assert: + # that: + # - item.changed == true + # - "'Only Device Added Successfully' in item.msg" + # loop: "{{ result_add_device.results }}" + # when: result_add_device is defined + +############################################# +# Delete Unclaimed Devices # +############################################# + + # - name: Delete PnP devices + # cisco.dnac.pnp_workflow_manager: + # <<: *dnac_login + # state: deleted + # config: + # - "{{ item }}" + # loop: "{{ vars_map.pnp_delete.delete }}" + # register: result_delete_device + + # - name: Debug delete unclaimed devices + # debug: + # var: item + # loop: "{{ result_delete_device.results }}" + # when: result_delete_device is defined + + # - name: Assert deletion of unclaimed PnP devices + # assert: + # that: + # - item.changed == true + # - "'Deleted Successfully' in item.msg" + # loop: "{{ result_delete_device.results }}" + # when: result_delete_device is defined + + +############################################# +# Bulk Add device but not Claim PNP Device # +############################################# + + # - name: Bulk Adding devices but not claiming + # cisco.dnac.pnp_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.bulk.add }}" + # register: result_add_device + + # - name: Debug Bulk Adding devices but not claiming + # debug: + # var: item + # loop: "{{ result_add_device.results }}" + # when: result_add_device is defined + + # - name: Assert bulk adding devices but not claiming + # assert: + # that: + # - item.changed == true + # - "'imported successfully' in item.msg" + # loop: "{{ result_add_device.results }}" + # when: result_add_device is defined + +############################################# +# Bulk Delete Unclaimed Devices # +############################################# + + # - name: Delete Bulk Unclaimed PnP devices + # cisco.dnac.pnp_workflow_manager: + # <<: *dnac_login + # state: deleted + # config: + # - "{{ item }}" + # loop: "{{ vars_map.bulk.add }}" + # register: result_delete_device + + # - name: Debug Bulk delete unclaimed devices + # debug: + # var: item + # loop: "{{ result_delete_device.results }}" + # when: result_delete_device is defined + + # - name: Assert Bulk deletion of unclaimed PnP devices + # assert: + # that: + # - item.changed == true + # - "'Deleted Successfully' in item.msg" + # loop: "{{ result_delete_device.results }}" + + +############################################# +# Add and Claim PNP Device # +############################################# + + - name: Add and Claim PnP devices + cisco.dnac.pnp_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.pnp_claim.cat9k }}" + tags: claim_cat9k + + - name: Debug Adding ad claiming devices but not claiming + debug: + var: item + loop: "{{ result_add_device.results }}" + when: result_add_device is defined + +############################################# +# Delete Claimed Devices # +############################################# + + # - name: Delete PnP devices + # cisco.dnac.pnp_workflow_manager: + # <<: *dnac_login + # state: deleted + # config: + # - "{{ item }}" + # loop: "{{ vars_map.pnp_claim.delete-cat9k }}" + # register: result_delete_device + + # - name: Debug delete unclaimed devices + # debug: + # var: item + # loop: "{{ result_delete_device.results }}" + # when: result_delete_device is defined + + # - name: Assert deletion of unclaimed PnP devices + # assert: + # that: + # - item.changed == true + # - "'Deleted Successfully' in item.msg" + # loop: "{{ result_delete_device.results }}" + # when: result_delete_device is defined + + +# ############################################# +# # Delete Devices # +# ############################################# + +# - name: Delete device +# cisco.dnac.inventory_workflow_manager: +# <<: *dnac_login +# state: deleted +# config: +# - "{{ item }}" +# loop: "{{ vars_map.delete_devices }}" +# register: result_device_deleted + +# # - name: Debug item +# # debug: +# # var: item +# # loop: "{{ result_device_deleted.results }}" +# # when: result_device_deleted is defined + +# - name: Assert device deletion success +# assert: +# that: +# - result_device_deleted.changed == true +# when: result_device_deleted is defined diff --git a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml index 678fdcb00c..247edd940e 100644 --- a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml @@ -1,2 +1,62 @@ --- -# vars file for ccc_pnp_management +pnp_delete: + add: + - device_info: + - serial_number: FJC2721271T + hostname: SJ-EN-9300 + state: Unclaimed + pid: C9300-48T + + delete: + - device_info: + - serial_number: FJC2721271T + hostname: SJ-EN-9300 + state: Unclaimed + pid: C9300-48T + +pnp_claim: + cat9k: + - site_name: Global/ITest_PnP_Area/ITest_PnP_Building + project_name: Onboarding Configuration + template_name: "Ansible_PNP_Switch" + template_details: + hostname: SJ-EN-9300 + interface: TwoGigabitEthernet1/0/2 + image_name: cat9k_iosxe.17.12.02.SPA.bin + device_info: + - serial_number: FJC2721271T + hostname: SJ-EN-9300 + state: Unclaimed + pid: C9300-48T + + delete-cat9k: + - device_info: + - serial_number: FJC2721271T + hostname: SJ-EN-9300 + state: Unclaimed + pid: C9300-48T + +bulk: + add: + - device_info: + - serial_number: FOX2639PAYD + hostname: SJ-EWLC-1 + state: Unclaimed + pid: C9800-40-K9 + - serial_number: FJC271924D9 + hostname: SJ-EN-9300 + state: Unclaimed + pid: C9300-48UXM + - serial_number: FJC271925Q1 + hostname: NY-EN-9300 + state: Unclaimed + pid: C9300-48UXM + - serial_number: FJC2402A0TX + hostname: SF-BN-ISR + state: Unclaimed + pid: ISR4451-X/K9 + + +delete_devices: + - ip_address_list: ["204.1.2.1"] + clean_config: False From 42eb3a63a6fcf3749848dc25d050299279a09af8 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 26 Mar 2024 00:56:54 -0400 Subject: [PATCH 230/358] swim changes --- .../ccc_swim_management/vars/vars_swim_management.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml index 0b956c1d7d..04198145ef 100644 --- a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml +++ b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml @@ -121,8 +121,6 @@ delete_devices: #ip_address_list: ["204.1.2.5", "204.192.6.200"] clean_config: False - - #http://172.21.236.183/swim/V1712_2_CCO/cat9k_iosxe.17.12.02.SPA.bin #device_family_name: "Switches and Hubs" #IMAGE FAMILY NAME "Cisco Catalyst 9300 Switch" From 52739d10f39d0985da84044762d0dd367ab280a6 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 26 Mar 2024 01:19:41 -0400 Subject: [PATCH 231/358] final testing --- .../tests/test_assign_credentials.yml | 324 +++---- .../test_device_credential_management.yml | 196 ++-- .../vars/vars_assign_credentials.yml | 1 - .../tests/test_discovery_management.yml | 490 +++++----- .../tests/test_inventory_management.yml | 908 +++++++++--------- .../vars/vars_inventory_management.yml | 2 +- .../defaults/main.yml | 2 - .../meta/main.yml | 1 - .../tasks/main.yml | 34 - .../test_network_settings_management.yml | 173 ---- .../vars_network_setttings_management.yml | 0 .../ccc_pnp_management/defaults/main.yml | 2 - .../ccc_pnp_management/meta/main.yml | 1 - .../ccc_pnp_management/tasks/main.yml | 34 - .../tests/test_pnp_management.yml | 1 - .../vars/vars_pnp_management.yml | 2 - .../tests/test_site_management.yml | 184 ++-- .../vars/vars_site_management.yml | 1 - .../tests/test_swim_management.yml | 546 +++++------ .../vars/vars_swim_management.yml | 51 +- 20 files changed, 1326 insertions(+), 1627 deletions(-) delete mode 100644 tests/integration/ccc_network_settings_management/defaults/main.yml delete mode 100644 tests/integration/ccc_network_settings_management/meta/main.yml delete mode 100644 tests/integration/ccc_network_settings_management/tasks/main.yml delete mode 100644 tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml delete mode 100644 tests/integration/ccc_network_settings_management/vars/vars_network_setttings_management.yml delete mode 100644 tests/integration/ccc_pnp_management/defaults/main.yml delete mode 100644 tests/integration/ccc_pnp_management/meta/main.yml delete mode 100644 tests/integration/ccc_pnp_management/tasks/main.yml delete mode 100644 tests/integration/ccc_pnp_management/tests/test_pnp_management.yml delete mode 100644 tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml index 498ab204f4..3e76d3dae9 100755 --- a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml @@ -25,165 +25,165 @@ - debug: msg: "{{ vars_map.design_sites }}" -# ############################################# -# # Pre Tests Clean Up # -# ############################################# - -# - name: Clean up site before test -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.design_sites }}" - -# - name: Clean up device credentials before test -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" - -# ############################################# -# # CREATE SITE # -# ############################################# - -# - name: Create sites from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# register: result_create_site -# loop: "{{ vars_map.design_sites }}" -# tags: merged - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_site.results }}" -# # when: result_create_site is defined - -# - name: Assert area creation success for each site -# assert: -# that: -# - item.changed == true -# - item.response.status == "SUCCESS" -# - "'created successfully' in item.msg" -# loop: "{{ result_create_site.results }}" -# when: result_create_site is defined - -# ############################################# -# # Create Credentials # -# ############################################# - -# - name: Create Credentials -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" -# tags: merged -# register: result_create_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_credentials.results }}" -# # when: result_create_credentials is defined - -# - name: Assert Device Credential Creation -# assert: -# that: -# - item.changed == true -# - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" -# - item.response[0].globalCredential.Validation == "Success" -# loop: "{{ result_create_credentials.results }}" -# when: result_create_credentials is defined - -# ############################################# -# # Assign Credentials to site # -# ############################################# - -# - name: Assign Credentials to design_sites -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_assign }}" -# tags: assign -# register: result_assign_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_assign_credentials.results }}" -# # when: result_assign_credentials is defined - -# - name: Assert assign Credentials to sites -# assert: -# that: -# - item.changed == true -# - "'Device Credential Assigned to a site is Successfully' in item.response[0].assignCredential['Assign Credentials'].msg" -# loop: "{{ result_assign_credentials.results }}" -# when: result_assign_credentials is defined - -# ############################################# -# # DELETE SITE # -# ############################################# - -# - name: Delete site from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# register: result_delete_site -# loop: "{{ vars_map.design_sites }}" -# tags: deleted - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_site.results }}" -# # when: result_delete_site is defined - -# - name: Assert deletion of area success for each site -# assert: -# that: -# - item.changed == true -# - "'deleted successfully' in item.response" -# loop: "{{ result_delete_site.results }}" -# when: result_delete_site is defined - -# ############################################# -# # Delete Credentials # -# ############################################# - -# - name: Delete Credentials -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" -# tags: deleted -# register: result_delete_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_credentials.results }}" -# # when: result_delete_credentials is defined - -# - name: Assert Global Credential Deletion -# assert: -# that: -# - item.changed == true -# - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" -# - item.response[0].globalCredential.Validation == "Success" -# loop: "{{ result_delete_credentials.results }}" -# when: result_delete_credentials is defined +############################################# +# Pre Tests Clean Up # +############################################# + + - name: Clean up site before test + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.design_sites }}" + + - name: Clean up device credentials before test + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + +############################################# +# CREATE SITE # +############################################# + + - name: Create sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + register: result_create_site + loop: "{{ vars_map.design_sites }}" + tags: merged + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + + - name: Assert area creation success for each site + assert: + that: + - item.changed == true + - item.response.status == "SUCCESS" + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined + +############################################# +# Create Credentials # +############################################# + + - name: Create Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: merged + register: result_create_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_credentials.results }}" + # when: result_create_credentials is defined + + - name: Assert Device Credential Creation + assert: + that: + - item.changed == true + - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_create_credentials.results }}" + when: result_create_credentials is defined + +############################################# +# Assign Credentials to site # +############################################# + + - name: Assign Credentials to design_sites + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_assign }}" + tags: assign + register: result_assign_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_assign_credentials.results }}" + # when: result_assign_credentials is defined + + - name: Assert assign Credentials to sites + assert: + that: + - item.changed == true + - "'Device Credential Assigned to a site is Successfully' in item.response[0].assignCredential['Assign Credentials'].msg" + loop: "{{ result_assign_credentials.results }}" + when: result_assign_credentials is defined + +############################################# +# DELETE SITE # +############################################# + + - name: Delete site from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + register: result_delete_site + loop: "{{ vars_map.design_sites }}" + tags: deleted + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined + + - name: Assert deletion of area success for each site + assert: + that: + - item.changed == true + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined + +############################################# +# Delete Credentials # +############################################# + + - name: Delete Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: deleted + register: result_delete_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_credentials.results }}" + # when: result_delete_credentials is defined + + - name: Assert Global Credential Deletion + assert: + that: + - item.changed == true + - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_delete_credentials.results }}" + when: result_delete_credentials is defined diff --git a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml index f593ebb51c..f4f9af6f3e 100644 --- a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml @@ -25,101 +25,101 @@ # - debug: # msg: "{{ vars_map.credentials_update }}" -# ############################################# -# # Pre Tests Clean Up # -# ############################################# - -# - name: Clean up device credentials before test -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" - -# ############################################# -# # Create Credentials # -# ############################################# - -# - name: Create Credentials -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" -# tags: merged -# register: result_create_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_credentials.results }}" -# # when: result_create_credentials is defined - -# - name: Assert Device Credential Creation -# assert: -# that: -# - item.changed == true -# - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" -# - item.response[0].globalCredential.Validation == "Success" -# loop: "{{ result_create_credentials.results }}" -# when: result_create_credentials is defined - -# ############################################# -# # Update Credentials # -# ############################################# - -# - name: Update Credentials -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_update }}" -# tags: update -# register: result_update_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_credentials.results }}" -# # when: result_update_credentials is defined - -# - name: Assert Device Credential Update -# assert: -# that: -# - item.changed == true -# - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" -# - item.response[0].globalCredential.Validation == "Success" -# loop: "{{ result_update_credentials.results }}" -# when: result_update_credentials is defined - -# ############################################# -# # Delete Credentials # -# ############################################# - -# - name: Delete Credentials -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" -# tags: deleted -# register: result_delete_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_credentials.results }}" -# # when: result_delete_credentials is defined - -# - name: Assert Device Credential Deletion -# assert: -# that: -# - item.changed == true -# - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" -# - item.response[0].globalCredential.Validation == "Success" -# loop: "{{ result_delete_credentials.results }}" -# when: result_delete_credentials is defined +############################################# +# Pre Tests Clean Up # +############################################# + + - name: Clean up device credentials before test + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + +############################################# +# Create Credentials # +############################################# + + - name: Create Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: merged + register: result_create_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_credentials.results }}" + # when: result_create_credentials is defined + + - name: Assert Device Credential Creation + assert: + that: + - item.changed == true + - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_create_credentials.results }}" + when: result_create_credentials is defined + +############################################# +# Update Credentials # +############################################# + + - name: Update Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_update }}" + tags: update + register: result_update_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_credentials.results }}" + # when: result_update_credentials is defined + + - name: Assert Device Credential Update + assert: + that: + - item.changed == true + - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_update_credentials.results }}" + when: result_update_credentials is defined + +############################################# +# Delete Credentials # +############################################# + + - name: Delete Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: deleted + register: result_delete_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_credentials.results }}" + # when: result_delete_credentials is defined + + - name: Assert Device Credential Deletion + assert: + that: + - item.changed == true + - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_delete_credentials.results }}" + when: result_delete_credentials is defined diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index a1f4b9c886..ff19b97491 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -7,7 +7,6 @@ design_sites: type: area - credentials_details: - global_credential_details: cli_credential: diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml index bb358ffff6..2663f741ac 100644 --- a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml @@ -39,248 +39,248 @@ # - debug: # msg: "{{ vars_map.cidr }}" -# ############################################# -# # Pre Tests Clean Up # -# ############################################# - -# - name: Delete discoveries before test -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map_delete.delete_discoveries }}" - -# ############################################# -# # Create Single IP Address Discovery # -# ############################################# - -# - name: Discover a single IP Address -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.single_ip }}" -# register: result_singleip_discovery - -# # - name: Debug item -# # debug: -# # var: result_singleip_discovery - -# - name: Check single IP discovery creation -# assert: -# that: -# - result_singleip_discovery.changed == true -# - "'Discovery Created Successfully' in result_singleip_discovery.results | map(attribute='msg') | list" -# when: result_singleip_discovery is defined - -# ############################################# -# # Create Range IP Address Discovery # -# ############################################# - -# - name: Discover an IP Address Range -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.ip_range }}" -# register: result_ip_range_discovery - -# # - name: Debug item -# # debug: -# # var: result_ip_range_discovery - -# - name: Check IP address range discovery creation -# assert: -# that: -# - result_ip_range_discovery.changed == true -# - "'Discovery Created Successfully' in result_ip_range_discovery.results | map(attribute='msg') | list" -# when: result_ip_range_discovery is defined - -# ############################################# -# # Create Multi Range IP Address Discovery # -# ############################################# - -# - name: Discover Multi IP Address Ranges -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.multi_range }}" -# register: result_multi_range_discovery - -# # - name: Debug item -# # debug: -# # var: result_multi_range_discovery - -# - name: Check multi range IP address discovery creation -# assert: -# that: -# - result_multi_range_discovery.changed == true -# - "'Discovery Created Successfully' in result_multi_range_discovery.results | map(attribute='msg') | list" -# when: result_multi_range_discovery is defined - -# ############################################# -# # Create Discovery using CDP # -# ############################################# - -# - name: Discover using CDP -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.cdp }}" -# register: result_cdp_discovery - -# # - name: Debug item -# # debug: -# # var: result_cdp_discovery - -# - name: Check CDP discovery creation -# assert: -# that: -# - result_cdp_discovery.changed == true -# - "'Discovery Created Successfully' in result_cdp_discovery.results | map(attribute='msg') | list" -# when: result_cdp_discovery is defined - -# ############################################# -# # Create Discovery using LLDP # -# ############################################# - -# - name: Discover using LLDP -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.lldp }}" -# register: result_lldp_discovery - -# # - name: Debug item -# # debug: -# # var: result_lldp_discovery - -# - name: Check LLDP discovery creation -# assert: -# that: -# - result_lldp_discovery.changed == true -# - "'Discovery Created Successfully' in result_lldp_discovery.results | map(attribute='msg') | list" -# when: result_lldp_discovery is defined - -# ############################################# -# # Create Discovery using CIDR # -# ############################################# - -# - name: Discover using CIDR -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.cidr }}" -# register: result_cidr_discovery - -# # - name: Debug item -# # debug: -# # var: result_cidr_discovery - -# - name: Check CIDR discovery creation -# assert: -# that: -# - result_cidr_discovery.changed == true -# - "'Discovery Created Successfully' in result_cidr_discovery.results | map(attribute='msg') | list" -# when: result_cidr_discovery is defined - -# ############################################# -# # Create Multiple Discoveries # -# ############################################# - -# - name: Add new item with "preferred_mgmt_ip_method" -# set_fact: -# vars_map_preferred_mgmt: {} - -# - name: Add preferred_mgmt_ip_method to vars_map_preferred_mgmt -# set_fact: -# vars_map_preferred_mgmt: "{{ vars_map_preferred_mgmt | combine({item + '_preferred_mgmt': vars_map[item] | map('combine', {'preferred_mgmt_ip_method': 'UseLoopBack'}) | map('combine', {'discovery_name': vars_map[item][0]['discovery_name'] + ' - preferred_mgmt' }) | list}) }}" -# loop: "{{ vars_map.keys() }}" -# tags: multiple_discoveries - -# - name: Set vars_map_multiple -# set_fact: -# vars_map_multiple: "{{ vars_map | combine(vars_map_preferred_mgmt) }}" -# tags: multiple_discoveries - -# - name: Print the updated vars_map_multiple -# debug: -# var: vars_map_multiple -# tags: multiple_discoveries - -# - name: Create multiple Discoveries -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ vars_map_multiple[item][0] }}" -# with_items: "{{ vars_map_multiple }}" -# tags: multiple_discoveries -# register: result_multiple_discoveries - -# # - name: Debug item -# # debug: -# # var: result_multiple_discoveries -# # when: result_multiple_discoveries is defined - -# - name: Check if multiple discoveries were successfull -# assert: -# that: -# - item.changed == true -# - "'Discovery Created Successfully' in item.msg" -# loop: "{{ result_multiple_discoveries.results }}" -# when: result_multiple_discoveries is defined - -# ############################################# -# # Delete Discovery by name # -# ############################################# - -# - name: Delete all discovery -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map_delete.delete_discoveries }}" -# register: result_delete_discoveries - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_discoveries.results }}" - -# - name: Check if discovery was successfully deleted -# assert: -# that: -# - item.changed == true -# - "'Successfully deleted discovery' in item.msg" -# loop: "{{ result_delete_discoveries.results }}" -# when: result_delete_discoveries is defined - -# ############################################ -# # Delete ALL Discoveries # -# ############################################ - -# # - name: Delete all discoveries that were created -# # cisco.dnac.discovery_workflow_manager: -# # <<: *dnac_login -# # state: deleted -# # config: -# # - delete_all: True -# # register: result_delete_all - -# # - name: Debug item -# # debug: -# # var: result_delete_all -# # when: result_delete_all is defined +############################################# +# Pre Tests Clean Up # +############################################# + + - name: Delete discoveries before test + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map_delete.delete_discoveries }}" + +############################################# +# Create Single IP Address Discovery # +############################################# + + - name: Discover a single IP Address + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.single_ip }}" + register: result_singleip_discovery + + # - name: Debug item + # debug: + # var: result_singleip_discovery + + - name: Check single IP discovery creation + assert: + that: + - result_singleip_discovery.changed == true + - "'Discovery Created Successfully' in result_singleip_discovery.results | map(attribute='msg') | list" + when: result_singleip_discovery is defined + +############################################# +# Create Range IP Address Discovery # +############################################# + + - name: Discover an IP Address Range + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.ip_range }}" + register: result_ip_range_discovery + + # - name: Debug item + # debug: + # var: result_ip_range_discovery + + - name: Check IP address range discovery creation + assert: + that: + - result_ip_range_discovery.changed == true + - "'Discovery Created Successfully' in result_ip_range_discovery.results | map(attribute='msg') | list" + when: result_ip_range_discovery is defined + +############################################# +# Create Multi Range IP Address Discovery # +############################################# + + - name: Discover Multi IP Address Ranges + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.multi_range }}" + register: result_multi_range_discovery + + # - name: Debug item + # debug: + # var: result_multi_range_discovery + + - name: Check multi range IP address discovery creation + assert: + that: + - result_multi_range_discovery.changed == true + - "'Discovery Created Successfully' in result_multi_range_discovery.results | map(attribute='msg') | list" + when: result_multi_range_discovery is defined + +############################################# +# Create Discovery using CDP # +############################################# + + - name: Discover using CDP + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.cdp }}" + register: result_cdp_discovery + + # - name: Debug item + # debug: + # var: result_cdp_discovery + + - name: Check CDP discovery creation + assert: + that: + - result_cdp_discovery.changed == true + - "'Discovery Created Successfully' in result_cdp_discovery.results | map(attribute='msg') | list" + when: result_cdp_discovery is defined + +############################################# +# Create Discovery using LLDP # +############################################# + + - name: Discover using LLDP + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.lldp }}" + register: result_lldp_discovery + + # - name: Debug item + # debug: + # var: result_lldp_discovery + + - name: Check LLDP discovery creation + assert: + that: + - result_lldp_discovery.changed == true + - "'Discovery Created Successfully' in result_lldp_discovery.results | map(attribute='msg') | list" + when: result_lldp_discovery is defined + +############################################# +# Create Discovery using CIDR # +############################################# + + - name: Discover using CIDR + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.cidr }}" + register: result_cidr_discovery + + # - name: Debug item + # debug: + # var: result_cidr_discovery + + - name: Check CIDR discovery creation + assert: + that: + - result_cidr_discovery.changed == true + - "'Discovery Created Successfully' in result_cidr_discovery.results | map(attribute='msg') | list" + when: result_cidr_discovery is defined + +############################################# +# Create Multiple Discoveries # +############################################# + + - name: Add new item with "preferred_mgmt_ip_method" + set_fact: + vars_map_preferred_mgmt: {} + + - name: Add preferred_mgmt_ip_method to vars_map_preferred_mgmt + set_fact: + vars_map_preferred_mgmt: "{{ vars_map_preferred_mgmt | combine({item + '_preferred_mgmt': vars_map[item] | map('combine', {'preferred_mgmt_ip_method': 'UseLoopBack'}) | map('combine', {'discovery_name': vars_map[item][0]['discovery_name'] + ' - preferred_mgmt' }) | list}) }}" + loop: "{{ vars_map.keys() }}" + tags: multiple_discoveries + + - name: Set vars_map_multiple + set_fact: + vars_map_multiple: "{{ vars_map | combine(vars_map_preferred_mgmt) }}" + tags: multiple_discoveries + + - name: Print the updated vars_map_multiple + debug: + var: vars_map_multiple + tags: multiple_discoveries + + - name: Create multiple Discoveries + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ vars_map_multiple[item][0] }}" + with_items: "{{ vars_map_multiple }}" + tags: multiple_discoveries + register: result_multiple_discoveries + + # - name: Debug item + # debug: + # var: result_multiple_discoveries + # when: result_multiple_discoveries is defined + + - name: Check if multiple discoveries were successfull + assert: + that: + - item.changed == true + - "'Discovery Created Successfully' in item.msg" + loop: "{{ result_multiple_discoveries.results }}" + when: result_multiple_discoveries is defined + +############################################# +# Delete Discovery by name # +############################################# + + - name: Delete all discovery + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map_delete.delete_discoveries }}" + register: result_delete_discoveries + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_discoveries.results }}" + + - name: Check if discovery was successfully deleted + assert: + that: + - item.changed == true + - "'Successfully deleted discovery' in item.msg" + loop: "{{ result_delete_discoveries.results }}" + when: result_delete_discoveries is defined + +############################################ +# Delete ALL Discoveries # +############################################ + + # - name: Delete all discoveries that were created + # cisco.dnac.discovery_workflow_manager: + # <<: *dnac_login + # state: deleted + # config: + # - delete_all: True + # register: result_delete_all + + # - name: Debug item + # debug: + # var: result_delete_all + # when: result_delete_all is defined diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index d5e66346f8..9eaf332e12 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -29,457 +29,457 @@ # - debug: # msg: "{{ vars_map.delete_devices }}" -# ############################################# -# # Clean Up # -# ############################################# - -# - name: Delete device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_devices }}" -# register: result_device_deleted - -# - name: Delete site -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" -# register: result_delete_site - -# ############################################# -# # Add Devices # -# ############################################# - -# - name: Add new device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_details }}" -# register: result_add_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_add_device.results }}" - -# - name: Assert device addition success -# assert: -# that: -# - item.changed == true -# - "'added to Cisco Catalyst Center' in item.msg" -# loop: "{{ result_add_device.results }}" -# when: result_add_device is defined - -# ############################################# -# # Update Device Credential Details # -# ############################################# - -# - name: Update device details -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_credential_updates }}" -# register: result_update_device_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_device_credentials.results }}" -# # when: result_update_device_credentials is defined - -# - name: Assert update -# assert: -# that: -# - item.changed == true -# loop: "{{ result_update_device_credentials.results }}" -# when: result_update_device_credentials is defined - -# ############################################ -# # Update Device Interface Detials # -# ############################################# - -# # - name: Pause for 60 seconds before updating interfaces -# # pause: -# # seconds: 60 - -# # - name: Update device interface details -# # cisco.dnac.inventory_workflow_manager: -# # <<: *dnac_login -# # state: merged -# # config: -# # - "{{ item }}" -# # loop: "{{ vars_map.device_interface_updates }}" -# # register: result_update_device_interface - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_device_interface.results }}" -# # when: result_update_device_interface is defined - -# # - name: Assert update -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_update_device_interface.results }}" -# # when: result_update_device_interface is defined - -# ############################################# -# # Update Device Role Detials # -# ############################################# - -# - name: Update device role details -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_role_updates }}" -# register: result_update_device_role - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_update_device_role.results }}" -# when: result_update_device_role is defined - -# - name: Assert device role update -# assert: -# that: -# - result_update_device_role.changed == true -# - "'Device role was successfully updated' in item.response.progress" -# loop: "{{ result_update_device_role.results }}" -# when: result_update_device_role is defined - -# ############################################# -# # Update Device Interface Description # -# ############################################# - -# # - name: Pause for 60 seconds before updating interfaces -# # pause: -# # seconds: 60 - -# # - name: Update device interface description post changing role to non-access -# # cisco.dnac.inventory_workflow_manager: -# # <<: *dnac_login -# # state: merged -# # config: -# # - "{{ item }}" -# # loop: "{{ vars_map.device_int_update_post_rolechange }}" -# # register: result_update_device_interface - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_device_interface.results }}" -# # when: result_update_device_interface is defined - -# # - name: Assert update -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_update_device_interface.results }}" -# # when: result_update_device_interface is defined - -# ############################################# -# # Resync Device # -# ############################################# - -# - name: Resync Device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_resync }}" -# register: result_resync_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_resync_device.results }}" -# # when: result_resync_device is defined - -# - name: Assert device resync -# assert: -# that: -# - result_resync_device.changed == true -# - "'Synced devices' in item.response.progress" -# loop: "{{ result_resync_device.results }}" -# when: result_resync_device is defined - -# ############################################# -# # Create & Assign User Defined Field # -# ############################################# - -# - name: Create & Assign user defined field -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.create_assign_udf }}" -# register: result_create_assign_udf - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_assign_udf.results }}" -# # when: result_create_assign_udf is defined - -# - name: Assert user defined field creation and assignment -# assert: -# that: -# - item.changed == true -# loop: "{{ result_create_assign_udf.results }}" -# when: result_create_assign_udf is defined - -# ############################################# -# # Update User Defined Field # -# ############################################# - -# - name: Update user defined field -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.update_udf }}" -# register: result_update_udf - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_assign_udf.results }}" -# # when: result_update_udf is defined - -# - name: Assert user defined field updated -# assert: -# that: -# - item.changed == true -# loop: "{{ result_update_udf.results }}" -# when: result_update_udf is defined - - -# ############################################# -# # Delete User Defined Field # -# ############################################# - -# - name: Delete user defined field -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_udf }}" -# register: result_delete_udf - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_udf.results }}" -# # when: result_delete_udf is defined - -# - name: Assert user defined field deletion -# assert: -# that: -# - result_delete_udf.changed == true -# - "'deleted successfully' in item.response.progress" -# loop: "{{ result_delete_udf.results }}" -# when: result_delete_udf is defined - - -# ############################################# -# # Export Device Details # -# ############################################# - -# - name: Export Device Details in a CSV file -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.export_device_details }}" -# register: result_export_details - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_export_details.results }}" -# # when: result_export_details is defined - -# - name: Assert device details export -# assert: -# that: -# - item.changed == true -# loop: "{{ result_export_details.results }}" -# when: result_export_details is defined - -# ############################################# -# # Export Device Credential Details # -# ############################################# - -# - name: Export Credential Device Details in a CSV file -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.export_credential_details }}" -# register: result_export_credential_details - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_export_credential_details.results }}" -# # when: result_export_credential_details is defined - -# - name: Assert device credential details export -# assert: -# that: -# - item.changed == true -# loop: "{{ result_export_credential_details.results }}" -# when: result_export_credential_details is defined - - -# ############################################# -# # CREATE SITE # -# ############################################# - -# - name: Create sites from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.design_sites }}" -# register: result_create_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_site.results }}" -# # when: result_create_site is defined - -# - name: Assert area creation success for each site -# assert: -# that: -# - item.changed == true -# - item.response.status == "SUCCESS" -# - "'created successfully' in item.msg" -# loop: "{{ result_create_site.results }}" -# when: result_create_site is defined - -# ############################################# -# # ASSOCIATE WIRED DEVICE TO SITE # -# ############################################# - -# - name: Assign wired device to site and then provision -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.associate_wired_device }}" -# register: result_associate_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_associate_device.results }}" -# # when: result_associate_device is defined - -# - name: Assert Assign wired device to site and then provision -# assert: -# that: -# - item.changed == true -# loop: "{{ result_associate_device.results }}" -# when: result_associate_device is defined - - -# ############################################# -# # ASSOCIATE WIRELESS DEVICE TO SITE # -# ############################################# - -# # - name: Assign wireless device to site and then provision -# # cisco.dnac.inventory_workflow_manager: -# # <<: *dnac_login -# # state: merged -# # config: -# # - "{{ item }}" -# # loop: "{{ vars_map.associate_wireless_device }}" -# # register: result_associate_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_associate_device.results }}" -# # when: result_associate_device is defined - -# # - name: Assert Assign wireless device to site and then provision -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_associate_device.results }}" -# # when: result_associate_device is defined - -# ############################################# -# # Delete Devices # -# ############################################# - -# - name: Delete device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_devices }}" -# register: result_device_deleted - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_device_deleted.results }}" -# # when: result_device_deleted is defined - -# - name: Assert device deletion success -# assert: -# that: -# - result_device_deleted.changed == true -# when: result_device_deleted is defined - -# ############################################# -# # DELETE SITE # -# ############################################# - -# - name: Delete sites from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" -# register: result_delete_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_site.results }}" -# # when: result_delete_site is defined - -# - name: Assert deletion of area success for each site -# assert: -# that: -# - item.changed == true -# - "'deleted successfully' in item.response" -# loop: "{{ result_delete_site.results }}" -# when: result_delete_site is defined +############################################# +# Clean Up # +############################################# + + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + - name: Delete site + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site + +############################################# +# Add Devices # +############################################# + + - name: Add new device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_details }}" + register: result_add_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_add_device.results }}" + + - name: Assert device addition success + assert: + that: + - item.changed == true + - "'added to Cisco Catalyst Center' in item.msg" + loop: "{{ result_add_device.results }}" + when: result_add_device is defined + +############################################# +# Update Device Credential Details # +############################################# + + - name: Update device details + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_credential_updates }}" + register: result_update_device_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_credentials.results }}" + # when: result_update_device_credentials is defined + + - name: Assert update + assert: + that: + - item.changed == true + loop: "{{ result_update_device_credentials.results }}" + when: result_update_device_credentials is defined + +############################################ +# Update Device Interface Detials # +############################################# + + # - name: Pause for 60 seconds before updating interfaces + # pause: + # seconds: 60 + + # - name: Update device interface details + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_interface_updates }}" + # register: result_update_device_interface + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + + # - name: Assert update + # assert: + # that: + # - item.changed == true + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + +############################################# +# Update Device Role Detials # +############################################# + + - name: Update device role details + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_role_updates }}" + register: result_update_device_role + + - name: Debug item + debug: + var: item + loop: "{{ result_update_device_role.results }}" + when: result_update_device_role is defined + + - name: Assert device role update + assert: + that: + - result_update_device_role.changed == true + - "'Device role was successfully updated' in item.response.progress" + loop: "{{ result_update_device_role.results }}" + when: result_update_device_role is defined + +############################################# +# Update Device Interface Description # +############################################# + + # - name: Pause for 60 seconds before updating interfaces + # pause: + # seconds: 60 + + # - name: Update device interface description post changing role to non-access + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_int_update_post_rolechange }}" + # register: result_update_device_interface + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + + # - name: Assert update + # assert: + # that: + # - item.changed == true + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + +############################################# +# Resync Device # +############################################# + + - name: Resync Device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_resync }}" + register: result_resync_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_resync_device.results }}" + # when: result_resync_device is defined + + - name: Assert device resync + assert: + that: + - result_resync_device.changed == true + - "'Synced devices' in item.response.progress" + loop: "{{ result_resync_device.results }}" + when: result_resync_device is defined + +############################################# +# Create & Assign User Defined Field # +############################################# + + - name: Create & Assign user defined field + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.create_assign_udf }}" + register: result_create_assign_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_assign_udf.results }}" + # when: result_create_assign_udf is defined + + - name: Assert user defined field creation and assignment + assert: + that: + - item.changed == true + loop: "{{ result_create_assign_udf.results }}" + when: result_create_assign_udf is defined + +############################################# +# Update User Defined Field # +############################################# + + - name: Update user defined field + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.update_udf }}" + register: result_update_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_assign_udf.results }}" + # when: result_update_udf is defined + + - name: Assert user defined field updated + assert: + that: + - item.changed == true + loop: "{{ result_update_udf.results }}" + when: result_update_udf is defined + + +############################################# +# Delete User Defined Field # +############################################# + + - name: Delete user defined field + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_udf }}" + register: result_delete_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_udf.results }}" + # when: result_delete_udf is defined + + - name: Assert user defined field deletion + assert: + that: + - result_delete_udf.changed == true + - "'deleted successfully' in item.response.progress" + loop: "{{ result_delete_udf.results }}" + when: result_delete_udf is defined + + +############################################# +# Export Device Details # +############################################# + + - name: Export Device Details in a CSV file + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.export_device_details }}" + register: result_export_details + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_export_details.results }}" + # when: result_export_details is defined + + - name: Assert device details export + assert: + that: + - item.changed == true + loop: "{{ result_export_details.results }}" + when: result_export_details is defined + +############################################# +# Export Device Credential Details # +############################################# + + - name: Export Credential Device Details in a CSV file + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.export_credential_details }}" + register: result_export_credential_details + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_export_credential_details.results }}" + # when: result_export_credential_details is defined + + - name: Assert device credential details export + assert: + that: + - item.changed == true + loop: "{{ result_export_credential_details.results }}" + when: result_export_credential_details is defined + + +############################################# +# CREATE SITE # +############################################# + + - name: Create sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.design_sites }}" + register: result_create_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + + - name: Assert area creation success for each site + assert: + that: + - item.changed == true + - item.response.status == "SUCCESS" + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined + +############################################# +# ASSOCIATE WIRED DEVICE TO SITE # +############################################# + + - name: Assign wired device to site and then provision + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.associate_wired_device }}" + register: result_associate_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_associate_device.results }}" + # when: result_associate_device is defined + + - name: Assert Assign wired device to site and then provision + assert: + that: + - item.changed == true + loop: "{{ result_associate_device.results }}" + when: result_associate_device is defined + + +############################################# +# ASSOCIATE WIRELESS DEVICE TO SITE # +############################################# + + # - name: Assign wireless device to site and then provision + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.associate_wireless_device }}" + # register: result_associate_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_associate_device.results }}" + # when: result_associate_device is defined + + # - name: Assert Assign wireless device to site and then provision + # assert: + # that: + # - item.changed == true + # loop: "{{ result_associate_device.results }}" + # when: result_associate_device is defined + +############################################# +# Delete Devices # +############################################# + + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_device_deleted.results }}" + # when: result_device_deleted is defined + + - name: Assert device deletion success + assert: + that: + - result_device_deleted.changed == true + when: result_device_deleted is defined + +############################################# +# DELETE SITE # +############################################# + + - name: Delete sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined + + - name: Assert deletion of area success for each site + assert: + that: + - item.changed == true + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 824565d0c1..81affd1938 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -275,4 +275,4 @@ delete_sites: delete_devices: - ip_address_list: ["204.1.2.5"] #ip_address_list: ["204.1.2.5", "204.192.6.200"] - clean_config: False \ No newline at end of file + clean_config: False diff --git a/tests/integration/ccc_network_settings_management/defaults/main.yml b/tests/integration/ccc_network_settings_management/defaults/main.yml deleted file mode 100644 index 55a93fc23d..0000000000 --- a/tests/integration/ccc_network_settings_management/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_network_settings_management/meta/main.yml b/tests/integration/ccc_network_settings_management/meta/main.yml deleted file mode 100644 index 5514b6a40c..0000000000 --- a/tests/integration/ccc_network_settings_management/meta/main.yml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_network_settings_management/tasks/main.yml b/tests/integration/ccc_network_settings_management/tasks/main.yml deleted file mode 100644 index 09e0832ca2..0000000000 --- a/tests/integration/ccc_network_settings_management/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: collect ccc test cases - find: - paths: "{{ role_path }}/tests" - patterns: "{{ testcase }}.yml" - connection: local - register: ccc_cases - tags: sanity - -- debug: - msg: "CCC Cases: {{ ccc_cases }}" - -- set_fact: - test_cases: - files: "{{ ccc_cases.files }}" - tags: sanity - -- debug: - msg: "Test Cases: {{ test_cases }}" - -- name: set test_items - set_fact: - test_items: "{{ test_cases.files | map(attribute='path') | list }}" - tags: sanity - -- debug: - msg: "Test Items: {{ test_items }}" - -- name: run test cases (connection=httpapi) - include_tasks: "{{ test_case_to_run }}" - loop: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml b/tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml deleted file mode 100644 index 9b329a8aab..0000000000 --- a/tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml +++ /dev/null @@ -1,173 +0,0 @@ ---- -- debug: msg="Starting device credential management test" -- debug: msg="Role Path {{ role_path }}" - -- block: - - name: Load vars and declare dnac vars - include_vars: - file: "{{ role_path }}/vars/main.yml" - name: vars_map - vars: - dnac_login: &dnac_login - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG - config_verify: true - - - debug: - msg: "{{ vars_map.design_sites }}" - - debug: - msg: "{{ vars_map. }}" - - -# ############################################# -# # Pre Tests Clean Up # -# ############################################# - -# - name: Clean up site before test -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.design_sites }}" - -# - name: Clean up before tests -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map. }}" - - -# ############################################# -# # CREATE SITE # -# ############################################# - -# - name: Create sites from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# register: result_create_site -# loop: "{{ vars_map.design_sites }}" -# tags: merged - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_site.results }}" -# # when: result_create_site is defined - -# - name: Assert area creation success for each site -# assert: -# that: -# - item.changed == true -# - item.response.status == "SUCCESS" -# - "'created successfully' in item.msg" -# loop: "{{ result_create_site.results }}" -# when: result_create_site is defined - -# ############################################# -# # UPDATE NETWORK SETTINGS # -# ############################################# - - -# ############################################# -# # Create Global Pool # -# ############################################# - -# - name: Create Global Pool -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map. }}" -# tags: merged -# register: result_create_global_pool - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_create_global_pool.results }}" -# when: result_create_global_pool is defined - -# # - name: Assert Global Pool Creation -# # assert: -# # that: -# # - item.changed == true -# # - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" -# # - item.response[0].globalCredential.Validation == "Success" -# # loop: "{{ result_create_global_pool.results }}" -# # when: result_create_global_pool is defined - -# ############################################# -# # Update Global Pool # -# ############################################# - -# - name: Update Global Pool -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map. }}" -# tags: update -# register: result_update_global_pool - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_update_credentials.results }}" -# when: result_update_credentials is defined - -# # - name: Assert Global Credential Update -# # assert: -# # that: -# # - item.changed == true -# # - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" -# # - item.response[0].globalCredential.Validation == "Success" -# # loop: "{{ result_update_global_pool.results }}" -# # when: result_update_global_pool is defined - -# ############################################# -# # Delete Global Pool # -# ############################################# - - -# ############################################# -# # DELETE SITE # -# ############################################# - -# - name: Delete site from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# register: result_delete_site -# loop: "{{ vars_map.design_sites }}" -# tags: deleted - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_site.results }}" -# # when: result_delete_site is defined - -# - name: Assert deletion of area success for each site -# assert: -# that: -# - item.changed == true -# - "'deleted successfully' in item.response" -# loop: "{{ result_delete_site.results }}" -# when: result_delete_site is defined diff --git a/tests/integration/ccc_network_settings_management/vars/vars_network_setttings_management.yml b/tests/integration/ccc_network_settings_management/vars/vars_network_setttings_management.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/integration/ccc_pnp_management/defaults/main.yml b/tests/integration/ccc_pnp_management/defaults/main.yml deleted file mode 100644 index 55a93fc23d..0000000000 --- a/tests/integration/ccc_pnp_management/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_pnp_management/meta/main.yml b/tests/integration/ccc_pnp_management/meta/main.yml deleted file mode 100644 index 5514b6a40c..0000000000 --- a/tests/integration/ccc_pnp_management/meta/main.yml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_pnp_management/tasks/main.yml b/tests/integration/ccc_pnp_management/tasks/main.yml deleted file mode 100644 index 09e0832ca2..0000000000 --- a/tests/integration/ccc_pnp_management/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: collect ccc test cases - find: - paths: "{{ role_path }}/tests" - patterns: "{{ testcase }}.yml" - connection: local - register: ccc_cases - tags: sanity - -- debug: - msg: "CCC Cases: {{ ccc_cases }}" - -- set_fact: - test_cases: - files: "{{ ccc_cases.files }}" - tags: sanity - -- debug: - msg: "Test Cases: {{ test_cases }}" - -- name: set test_items - set_fact: - test_items: "{{ test_cases.files | map(attribute='path') | list }}" - tags: sanity - -- debug: - msg: "Test Items: {{ test_items }}" - -- name: run test cases (connection=httpapi) - include_tasks: "{{ test_case_to_run }}" - loop: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml deleted file mode 100644 index ed97d539c0..0000000000 --- a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml deleted file mode 100644 index 678fdcb00c..0000000000 --- a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# vars file for ccc_pnp_management diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml index 62f2114416..6f703e4e70 100644 --- a/tests/integration/ccc_site_management/tests/test_site_management.yml +++ b/tests/integration/ccc_site_management/tests/test_site_management.yml @@ -27,95 +27,95 @@ # - debug: # msg: "{{ vars_map.delete_sites }}" -# ############################################# -# # Clean Up # -# ############################################# - -# - name: Clean up before test -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" - -# ############################################# -# # CREATE SITES # -# ############################################# - -# - name: Create sites -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.design_sites }}" -# register: result_create_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_site.results }}" -# # when: result_create_site is defined - -# - name: Assert area creation success for each site -# assert: -# that: -# - item.changed == true -# - "'created successfully' in item.msg" -# loop: "{{ result_create_site.results }}" -# when: result_create_site is defined - -# ############################################# -# # UPDATE SITES # -# ############################################# - -# - name: Update sites -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.update_sites }}" -# register: result_update_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_site.results }}" -# # when: result_update_site is defined - -# - name: Assert area update success for each site -# assert: -# that: -# - item.changed == true -# - "'Updated Successfully' in item.msg" -# loop: "{{ result_update_site.results }}" -# when: result_update_site is defined - -# ############################################# -# # DELETE SITES # -# ############################################# - -# - name: Delete sites -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" -# register: result_delete_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_site.results }}" -# # when: result_delete_site is defined - -# - name: Assert deletion success for each site -# assert: -# that: -# - item.changed == true -# - "'deleted successfully' in item.response" -# loop: "{{ result_delete_site.results }}" -# when: result_delete_site is defined +############################################# +# Clean Up # +############################################# + + - name: Clean up before test + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + +############################################# +# CREATE SITES # +############################################# + + - name: Create sites + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.design_sites }}" + register: result_create_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + + - name: Assert area creation success for each site + assert: + that: + - item.changed == true + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined + +############################################# +# UPDATE SITES # +############################################# + + - name: Update sites + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.update_sites }}" + register: result_update_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_site.results }}" + # when: result_update_site is defined + + - name: Assert area update success for each site + assert: + that: + - item.changed == true + - "'Updated Successfully' in item.msg" + loop: "{{ result_update_site.results }}" + when: result_update_site is defined + +############################################# +# DELETE SITES # +############################################# + + - name: Delete sites + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined + + - name: Assert deletion success for each site + assert: + that: + - item.changed == true + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 6989c9e864..4d66c9a628 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -434,7 +434,6 @@ update_sites: type: floor - delete_sites: - site: area: diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml index 7106432a92..6d36c3629d 100644 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -30,276 +30,276 @@ # Clean Up # ############################################# -# - name: Delete device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_devices }}" -# register: result_device_deleted - -# - name: Delete site -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" -# register: result_delete_site - -# ############################################# -# # CREATE SITE # -# ############################################# - -# - name: Create sites -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.design_sites }}" -# register: result_create_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_site.results }}" -# # when: result_create_site is defined - -# - name: Assert area creation success for each site -# assert: -# that: -# - item.changed == true -# - "'created successfully' in item.msg" -# loop: "{{ result_create_site.results }}" -# when: result_create_site is defined - -# ############################################# -# # Add Devices # -# ############################################# - -# - name: Add new device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_details }}" -# register: result_add_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_add_device.results }}" - -# - name: Assert device addition success -# assert: -# that: -# - item.changed == true -# - "'added to Cisco Catalyst Center' in item.msg" -# loop: "{{ result_add_device.results }}" -# when: result_add_device is defined - -# ############################################# -# # ASSOCIATE WIRED DEVICE TO SITE # -# ############################################# - -# - name: Assign wired device to site and then provision -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.associate_wired_device }}" -# register: result_associate_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_associate_device.results }}" -# # when: result_associate_device is defined - -# - name: Assert Assign wired device to site and then provision -# assert: -# that: -# - item.changed == true -# loop: "{{ result_associate_device.results }}" -# when: result_associate_device is defined - - -# ############################################# -# # IMPORT IMAGE # -# ############################################# - -# - name: SWIM task - import -# cisco.dnac.swim_workflow_manager: -# <<: *dnac_login -# config: -# - "{{ item }}" -# loop: "{{ vars_map.image_details }}" -# register: result_import_image - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_import_image.results }}" - -# # - name: Assert import images -# # assert: -# # that: -# # - item.changed == true -# # - '"imported successfully" in item.msg' -# # loop: "{{ result_import_image.results }}" -# # when: result_import_image is defined - -# ############################################# -# # TAG IMAGE # -# ############################################# - -# - name: SWIM task - tag -# cisco.dnac.swim_workflow_manager: -# <<: *dnac_login -# config: -# - "{{ item }}" -# loop: "{{ vars_map.image_golden_tagging_details}}" -# register: result_tag_image - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_tag_image.results }}" - -# - name: Assert tag images -# assert: -# that: -# - item.changed == true -# - '"Tagging image" in item.msg' -# loop: "{{ result_tag_image.results }}" -# when: result_tag_image is defined - -# ############################################# -# # DISTRIBUTE # -# ############################################# - -# - name: SWIM task - distribute stack -# cisco.dnac.swim_workflow_manager: -# <<: *dnac_login -# config: -# - "{{ item }}" -# loop: "{{ vars_map.image_distributation_details }}" -# register: result_distribute_stack - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_distribute_stack.results }}" - -# # - name: Assert distribution -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_distribute_stack.results }}" -# # when: result_distribute_stack is defined - -# ############################################# -# # ACTIVATE IMAGE # -# ############################################# - -# - name: SWIM task - activate -# cisco.dnac.swim_workflow_manager: -# <<: *dnac_login -# config: -# - "{{ item }}" -# loop: "{{ vars_map.image_activation_details }}" -# register: result_activate_image - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_activate_image.results }}" - -# # - name: Assert image activation -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_activate_image.results }}" -# # when: result_activate_image is defined - -# ############################################# -# # UNTAG IMAGE # -# ############################################# - -# - name: SWIM task - untag -# cisco.dnac.swim_workflow_manager: -# <<: *dnac_login -# config: -# - "{{ item }}" -# loop: "{{ vars_map.image_golden_untagging_details }}" -# register: result_untag_image - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_untag_image.results }}" - -# - name: Assert untag images -# assert: -# that: -# - item.changed == true -# - '"Untagging of image" in item.msg' -# - '"successful" in item.msg' -# loop: "{{ result_untag_image.results }}" -# when: result_untag_image is defined - -# ############################################# -# # Delete Devices # -# ############################################# - -# - name: Delete device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_devices }}" -# register: result_device_deleted - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_device_deleted.results }}" -# # when: result_device_deleted is defined - -# - name: Assert device deletion success -# assert: -# that: -# - result_device_deleted.changed == true -# when: result_device_deleted is defined - -# ############################################# -# # DELETE SITE # -# ############################################# - -# - name: Delete sites from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" -# register: result_delete_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_site.results }}" -# # when: result_delete_site is defined - -# - name: Assert deletion of area success for each site -# assert: -# that: -# - item.changed == true -# - "'deleted successfully' in item.response" -# loop: "{{ result_delete_site.results }}" -# when: result_delete_site is defined + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + - name: Delete site + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site + +############################################# +# CREATE SITE # +############################################# + + - name: Create sites + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.design_sites }}" + register: result_create_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + + - name: Assert area creation success for each site + assert: + that: + - item.changed == true + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined + +############################################# +# Add Devices # +############################################# + + - name: Add new device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_details }}" + register: result_add_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_add_device.results }}" + + - name: Assert device addition success + assert: + that: + - item.changed == true + - "'added to Cisco Catalyst Center' in item.msg" + loop: "{{ result_add_device.results }}" + when: result_add_device is defined + +############################################# +# ASSOCIATE WIRED DEVICE TO SITE # +############################################# + + - name: Assign wired device to site and then provision + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.associate_wired_device }}" + register: result_associate_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_associate_device.results }}" + # when: result_associate_device is defined + + - name: Assert Assign wired device to site and then provision + assert: + that: + - item.changed == true + loop: "{{ result_associate_device.results }}" + when: result_associate_device is defined + + +############################################# +# IMPORT IMAGE # +############################################# + + - name: SWIM task - import + cisco.dnac.swim_workflow_manager: + <<: *dnac_login + config: + - "{{ item }}" + loop: "{{ vars_map.image_details }}" + register: result_import_image + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_import_image.results }}" + + - name: Assert import images + assert: + that: + - item.changed == true + - '"imported successfully" in item.msg' + loop: "{{ result_import_image.results }}" + when: result_import_image is defined + +############################################# +# TAG IMAGE # +############################################# + + - name: SWIM task - tag + cisco.dnac.swim_workflow_manager: + <<: *dnac_login + config: + - "{{ item }}" + loop: "{{ vars_map.image_golden_tagging_details}}" + register: result_tag_image + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_tag_image.results }}" + + - name: Assert tag images + assert: + that: + - item.changed == true + - '"Tagging image" in item.msg' + loop: "{{ result_tag_image.results }}" + when: result_tag_image is defined + +############################################# +# DISTRIBUTE # +############################################# + + - name: SWIM task - distribute stack + cisco.dnac.swim_workflow_manager: + <<: *dnac_login + config: + - "{{ item }}" + loop: "{{ vars_map.image_distributation_details }}" + register: result_distribute_stack + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_distribute_stack.results }}" + + - name: Assert distribution + assert: + that: + - item.changed == true + loop: "{{ result_distribute_stack.results }}" + when: result_distribute_stack is defined + +############################################# +# ACTIVATE IMAGE # +############################################# + + - name: SWIM task - activate + cisco.dnac.swim_workflow_manager: + <<: *dnac_login + config: + - "{{ item }}" + loop: "{{ vars_map.image_activation_details }}" + register: result_activate_image + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_activate_image.results }}" + + - name: Assert image activation + assert: + that: + - item.changed == true + loop: "{{ result_activate_image.results }}" + when: result_activate_image is defined + +############################################# +# UNTAG IMAGE # +############################################# + + - name: SWIM task - untag + cisco.dnac.swim_workflow_manager: + <<: *dnac_login + config: + - "{{ item }}" + loop: "{{ vars_map.image_golden_untagging_details }}" + register: result_untag_image + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_untag_image.results }}" + + - name: Assert untag images + assert: + that: + - item.changed == true + - '"Untagging of image" in item.msg' + - '"successful" in item.msg' + loop: "{{ result_untag_image.results }}" + when: result_untag_image is defined + +############################################# +# Delete Devices # +############################################# + + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_device_deleted.results }}" + # when: result_device_deleted is defined + + - name: Assert device deletion success + assert: + that: + - result_device_deleted.changed == true + when: result_device_deleted is defined + +############################################# +# DELETE SITE # +############################################# + + - name: Delete sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined + + - name: Assert deletion of area success for each site + assert: + that: + - item.changed == true + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined diff --git a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml index 0b956c1d7d..440ba7077f 100644 --- a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml +++ b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml @@ -48,6 +48,7 @@ image_golden_untagging_details: device_image_family_name: "Cisco Catalyst 9300 Switch" tagging: False + design_sites: # Create site to associate device to - site: @@ -120,53 +121,3 @@ delete_devices: - ip_address_list: ["204.1.2.3"] #ip_address_list: ["204.1.2.5", "204.192.6.200"] clean_config: False - - - -#http://172.21.236.183/swim/V1712_2_CCO/cat9k_iosxe.17.12.02.SPA.bin -#device_family_name: "Switches and Hubs" -#IMAGE FAMILY NAME "Cisco Catalyst 9300 Switch" -#device_series_name = -# - - -# --- -# image_details: -# - type: "remote" -# url_details: -# payload: -# - source_url: "http://172.21.236.183/swim/V1712_2_CCO/cat9k_iosxe.17.12.02.SPA.bin" -# is_third_party: false -# device_role: "ACCESS" -# image_name: cat9k_iosxe.17.12.02.SPA.bin -# # device_family_name: "Wireless Controller" -# device_family_name: "Switches and Hubs" - -# # device_type: "Cisco Catalyst 9800-40 Wireless Controller" -# device_image_family_name: "Cisco Catalyst 9300 Switch" -# site_name: "Global/USA/San Francisco/BGL_18" -# # site_name: "" -# # device_serial_number: "FJC2327U0S2" -# # Device with IP - 204.192.3.40 -# # device_serial_number: "FJC2721271T" -# # Device with IP - 204.192.3.40 - - -# # - type: "local" -# # local_image_details: -# # file_path: "/Users/abmahesh/Downloads/cat9k_iosxe.17.12.01.SPA.bin" -# # is_third_party: false -# # device_role: "ACCESS" -# # device_family_name: "Cisco Catalyst 9300 Switch" -# # device_serial_number: "FJC271924K0" -# # site_name: "Global/USA/San Francisco/BGL_18" - - -# # - type: "url" -# # urlDetails: -# # payload: -# # - sourceURL: "http://10.104.118.10/swim/17.12/C9800-SW-iosxe-wlc.BLD_POLARIS_DEV_LATEST_20230402_072041_V17_12_0_8.SSA.bin" -# # isThirdParty: false -# # device_role: "ALL" -# # device_family_name: "Cisco Catalyst 9800-40 Wireless Controller" -# # device_serial_number: "FOX2639PAY7" \ No newline at end of file From 48ba99f045f5aa272446bfc4b7f06c598a28af9d Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 26 Mar 2024 15:07:53 -0400 Subject: [PATCH 232/358] clean up --- .../vars/vars_assign_credentials.yml | 2 +- .../vars/vars_inventory_management.yml | 8 +- .../vars/vars_site_management.yml | 106 +++++++++--------- .../vars/vars_swim_management.yml | 8 +- 4 files changed, 62 insertions(+), 62 deletions(-) diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index ff19b97491..2c35a63ea6 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -4,7 +4,7 @@ design_sites: area: name: TEST_SITE_DEVICE_CREDENTIALS parent_name: 'Global' - type: area + site_type: area credentials_details: diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 81affd1938..00aa503a64 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -218,7 +218,7 @@ design_sites: area: name: ITest_Area parent_name: Global - type: area + site_type: area - site: building: name: ITest_Building @@ -227,7 +227,7 @@ design_sites: latitude: 12.969910 longitude: 77.597960 country: India - type: building + site_type: building - site: floor: name: ITest_Floor1 @@ -237,7 +237,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor associate_wired_device: @@ -269,7 +269,7 @@ delete_sites: area: name: ITest_Area parent_name: Global - type: area + site_type: area delete_devices: diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 4d66c9a628..88cee28a78 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -5,37 +5,37 @@ design_sites: area: name: USA-Test parent_name: Global - type: area + site_type: area - site: area: name: SAN JOSE parent_name: Global/USA-Test - type: area + site_type: area - site: area: name: RTP parent_name: Global/USA-Test - type: area + site_type: area - site: area: name: BayAreaGuest parent_name: Global/USA-Test - type: area + site_type: area - site: area: name: New York parent_name: Global/USA-Test - type: area + site_type: area - site: area: name: SAN-FRANCISCO parent_name: Global/USA-Test - type: area + site_type: area - site: area: name: BERKELEY parent_name: Global/USA-Test - type: area + site_type: area - site: building: name: BLD10 @@ -44,7 +44,7 @@ design_sites: latitude: 35.85992111421487 longitude: -78.8829258991226 country: United States - type: building + site_type: building - site: building: name: BLD11 @@ -53,7 +53,7 @@ design_sites: latitude: 35.86059627310624 longitude: -78.88105620286412 country: United States - type: building + site_type: building - site: building: name: BLD12 @@ -62,7 +62,7 @@ design_sites: latitude: 35.8611847591779 longitude: -78.88217248318003 country: United States - type: building + site_type: building - site: building: name: BLD23 @@ -71,7 +71,7 @@ design_sites: latitude: 37.398188 longitude: -121.912974 country: United States - type: building + site_type: building - site: building: name: BLD20 @@ -80,7 +80,7 @@ design_sites: latitude: 37.415947 longitude: -121.916327 country: United States - type: building + site_type: building - site: building: name: BLD_GB @@ -89,7 +89,7 @@ design_sites: latitude: 37.415947 longitude: -121.916327 country: United States - type: building + site_type: building - site: building: name: BLDNYC @@ -98,7 +98,7 @@ design_sites: latitude: 37.398188 longitude: -121.912974 country: United States - type: building + site_type: building - site: building: name: BLD_SF @@ -107,7 +107,7 @@ design_sites: latitude: 37.398188 longitude: -121.912974 country: United States - type: building + site_type: building - site: building: name: BLD_SF1 @@ -116,7 +116,7 @@ design_sites: latitude: 37.398188 longitude: -121.912974 country: United States - type: building + site_type: building - site: building: name: BLDBERK @@ -125,7 +125,7 @@ design_sites: latitude: 37.415947 longitude: -121.916327 country: United States - type: building + site_type: building - site: floor: name: BLD10_FLOOR1 @@ -135,7 +135,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: BLD10_FLOOR2 @@ -145,7 +145,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: BLD10_FLOOR3 @@ -155,7 +155,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 3 - type: floor + site_type: floor - site: floor: name: BLD11_FLOOR1 @@ -165,7 +165,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: BLD11_FLOOR2 @@ -175,7 +175,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: BLD11_FLOOR3 @@ -185,7 +185,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 3 - type: floor + site_type: floor - site: floor: name: BLD12_FLOOR1 @@ -195,7 +195,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: BLD12_FLOOR2 @@ -205,7 +205,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: BLD12_FLOOR3 @@ -215,7 +215,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 3 - type: floor + site_type: floor - site: floor: name: FLOOR1_LEVEL1 @@ -225,7 +225,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR1_LEVEL2 @@ -235,7 +235,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR1_LEVEL3 @@ -245,7 +245,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR1_LEVEL4 @@ -255,7 +255,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: BLD20_FLOOR1 @@ -265,7 +265,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: BLD20_FLOOR2 @@ -275,7 +275,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: FLOOR1 @@ -285,7 +285,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR2 @@ -295,7 +295,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: FLOOR1 @@ -305,7 +305,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR2 @@ -315,7 +315,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: FLOOR1 @@ -325,7 +325,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR2 @@ -335,7 +335,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: FLOOR1_LEVEL1 @@ -345,19 +345,19 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor #India-Test Site Hierarchy - site: area: name: India-Test parent_name: Global - type: area + site_type: area - site: area: name: Bangalore parent_name: Global/India-Test - type: area + site_type: area - site: building: name: Mantri Square @@ -366,7 +366,7 @@ design_sites: latitude: 12.969910 longitude: 77.597960 country: India - type: building + site_type: building - site: floor: name: Floor1 @@ -376,21 +376,21 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor #Mexico Site Hierarchy - site: area: name: Mexico-Test parent_name: Global - type: area + site_type: area #Canada Site Hierarchy - site: area: name: Canada-Test parent_name: Global - type: area + site_type: area update_sites: @@ -402,7 +402,7 @@ update_sites: latitude: 38.8611847591779 longitude: 72.88217248318003 country: United States - type: building + site_type: building - site: floor: name: FLOOR1 @@ -412,7 +412,7 @@ update_sites: length: 200.00 height: 20.00 floor_number: 1 - type: floor + site_type: floor - site: building: name: Mantri Square @@ -421,7 +421,7 @@ update_sites: latitude: 18.969910 longitude: 20.597960 country: India - type: building + site_type: building - site: floor: name: Floor1 @@ -431,7 +431,7 @@ update_sites: length: 200.00 height: 20.00 floor_number: 1 - type: floor + site_type: floor delete_sites: @@ -439,19 +439,19 @@ delete_sites: area: name: USA-Test parent_name: Global - type: area + site_type: area - site: area: name: India-Test parent_name: Global - type: area + site_type: area - site: area: name: Mexico-Test parent_name: Global - type: area + site_type: area - site: area: name: Canada-Test parent_name: Global - type: area + site_type: area diff --git a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml index 440ba7077f..acc69524a0 100644 --- a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml +++ b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml @@ -55,7 +55,7 @@ design_sites: area: name: ITest_Swim_Area parent_name: Global - type: area + site_type: area - site: building: name: ITest_Swim_Building @@ -64,7 +64,7 @@ design_sites: latitude: 12.969910 longitude: 77.597960 country: India - type: building + site_type: building - site: floor: name: ITest_Swim_Floor1 @@ -74,7 +74,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor device_details: @@ -114,7 +114,7 @@ delete_sites: area: name: ITest_Swim_Area parent_name: Global - type: area + site_type: area delete_devices: From 78671c9722bd70a508df9ed844450dcd1c2c05ad Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 11:48:06 -0400 Subject: [PATCH 233/358] pnp IT changes --- .circleci/config.yml | 21 +++++- .../tests/test_pnp_management.yml | 70 +++++++------------ .../vars/vars_pnp_management.yml | 10 +-- 3 files changed, 45 insertions(+), 56 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 44c43788e8..945cec1026 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -296,6 +296,19 @@ jobs: set -x rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME + post_pnp_testing: + machine: true + resource_class: rukapse/dnacenter-ansible + working_directory: ~/repo + + steps: + - when: + condition: << pipeline.parameters.run-pnp >> + steps: + - run: + command: | + python ${HOME}/static/pnp_script.py + workflows: @@ -330,14 +343,14 @@ workflows: plugins/modules/discovery_workflow_manager.py run-discovery true plugins/modules/inventory_workflow_manager.py run-inventory true plugins/modules/swim_workflow_manager.py run-swim true - plugins/modules/pnp_workflow_manager.py run-swim true + plugins/modules/pnp_workflow_manager.py run-pnp true tests/integration/ccc_site_management/.* run-site true tests/integration/ccc_device_credential_management/.* run-devicecredential true tests/integration/ccc_discovery_management/.* run-discovery true tests/integration/ccc_inventory_management/.* run-inventory true tests/integration/ccc_swim_management/.* run-swim true - tests/integration/ccc_pnp_management/.* run-swim true + tests/integration/ccc_pnp_management/.* run-pnp true integration-testing: when: << pipeline.parameters.run-any >> @@ -351,3 +364,7 @@ workflows: parameters: ansible_cisco_dnac_version: - "6.9.0" + + - post_pnp_testing: + requires: + - sanity-tests diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml index fbb923d623..68137c4d51 100644 --- a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml @@ -45,6 +45,14 @@ # - "{{ item }}" # loop: "{{ vars_map.bulk.add }}" + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + ############################################# # Add device but not Claim PNP Device # ############################################# @@ -165,63 +173,35 @@ config: - "{{ item }}" loop: "{{ vars_map.pnp_claim.cat9k }}" - tags: claim_cat9k + register: result_claim_device - - name: Debug Adding ad claiming devices but not claiming + - name: Debug Add and Claim device debug: var: item - loop: "{{ result_add_device.results }}" - when: result_add_device is defined + loop: "{{ result_claim_device.results }}" + when: result_claim_device is defined ############################################# -# Delete Claimed Devices # +# Delete Devices # ############################################# - # - name: Delete PnP devices - # cisco.dnac.pnp_workflow_manager: + # - name: Delete device + # cisco.dnac.inventory_workflow_manager: # <<: *dnac_login # state: deleted # config: # - "{{ item }}" - # loop: "{{ vars_map.pnp_claim.delete-cat9k }}" - # register: result_delete_device + # loop: "{{ vars_map.delete_devices }}" + # register: result_device_deleted - # - name: Debug delete unclaimed devices - # debug: - # var: item - # loop: "{{ result_delete_device.results }}" - # when: result_delete_device is defined + # # - name: Debug item + # # debug: + # # var: item + # # loop: "{{ result_device_deleted.results }}" + # # when: result_device_deleted is defined - # - name: Assert deletion of unclaimed PnP devices + # - name: Assert device deletion success # assert: # that: - # - item.changed == true - # - "'Deleted Successfully' in item.msg" - # loop: "{{ result_delete_device.results }}" - # when: result_delete_device is defined - - -# ############################################# -# # Delete Devices # -# ############################################# - -# - name: Delete device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_devices }}" -# register: result_device_deleted - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_device_deleted.results }}" -# # when: result_device_deleted is defined - -# - name: Assert device deletion success -# assert: -# that: -# - result_device_deleted.changed == true -# when: result_device_deleted is defined + # - result_device_deleted.changed == true + # when: result_device_deleted is defined diff --git a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml index 247edd940e..8aacfb4ea4 100644 --- a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml @@ -20,19 +20,11 @@ pnp_claim: project_name: Onboarding Configuration template_name: "Ansible_PNP_Switch" template_details: - hostname: SJ-EN-9300 interface: TwoGigabitEthernet1/0/2 image_name: cat9k_iosxe.17.12.02.SPA.bin device_info: - serial_number: FJC2721271T - hostname: SJ-EN-9300 - state: Unclaimed - pid: C9300-48T - - delete-cat9k: - - device_info: - - serial_number: FJC2721271T - hostname: SJ-EN-9300 + hostname: Switch state: Unclaimed pid: C9300-48T From 5bdd7e521bcdfe393a9a25b4a970538be612d49c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 15:43:56 -0400 Subject: [PATCH 234/358] final testing --- .../tests/test_inventory_management.yml | 40 +++++++++---------- .../vars/vars_inventory_management.yml | 2 +- .../tests/test_swim_management.yml | 14 +++---- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index 9eaf332e12..b3aff6fdc5 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -137,28 +137,28 @@ # Update Device Role Detials # ############################################# - - name: Update device role details - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.device_role_updates }}" - register: result_update_device_role + # - name: Update device role details + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_role_updates }}" + # register: result_update_device_role - - name: Debug item - debug: - var: item - loop: "{{ result_update_device_role.results }}" - when: result_update_device_role is defined + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_role.results }}" + # when: result_update_device_role is defined - - name: Assert device role update - assert: - that: - - result_update_device_role.changed == true - - "'Device role was successfully updated' in item.response.progress" - loop: "{{ result_update_device_role.results }}" - when: result_update_device_role is defined + # - name: Assert device role update + # assert: + # that: + # - result_update_device_role.changed == true + # - "'Device role was successfully updated' in item.response.progress" + # loop: "{{ result_update_device_role.results }}" + # when: result_update_device_role is defined ############################################# # Update Device Interface Description # diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 00aa503a64..26c56ac68a 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -145,7 +145,7 @@ device_role_updates: - ip_address_list: ["204.1.2.5"] device_updated: True update_device_role: - role: ACCESS + role: CORE device_int_update_post_rolechange: diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml index 6d36c3629d..527cdff26b 100644 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -145,13 +145,13 @@ # var: item # loop: "{{ result_import_image.results }}" - - name: Assert import images - assert: - that: - - item.changed == true - - '"imported successfully" in item.msg' - loop: "{{ result_import_image.results }}" - when: result_import_image is defined + # - name: Assert import images + # assert: + # that: + # - item.changed == true + # - '"imported successfully" in item.msg' + # loop: "{{ result_import_image.results }}" + # when: result_import_image is defined ############################################# # TAG IMAGE # From 9fb0a960c9bc119e4e249aed044ae15eb9737df6 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 18:04:11 -0400 Subject: [PATCH 235/358] pnp update --- .../tests/test_assign_credentials.yml | 336 +++---- .../test_device_credential_management.yml | 196 ++-- .../vars/vars_assign_credentials.yml | 3 +- .../tests/test_discovery_management.yml | 494 +++++----- .../vars/vars_misc.yml | 2 +- .../tests/test_inventory_management.yml | 932 +++++++++--------- .../vars/vars_inventory_management.yml | 12 +- .../defaults/main.yml | 2 - .../meta/main.yml | 1 - .../tasks/main.yml | 34 - .../test_network_settings_management.yml | 173 ---- .../vars_network_setttings_management.yml | 0 .../tests/test_pnp_management.yml | 26 +- .../vars/vars_pnp_management.yml | 15 +- .../tests/test_site_management.yml | 184 ++-- .../vars/vars_site_management.yml | 107 +- .../tests/test_swim_management.yml | 566 +++++------ .../vars/vars_swim_management.yml | 59 +- 18 files changed, 1474 insertions(+), 1668 deletions(-) delete mode 100644 tests/integration/ccc_network_settings_management/defaults/main.yml delete mode 100644 tests/integration/ccc_network_settings_management/meta/main.yml delete mode 100644 tests/integration/ccc_network_settings_management/tasks/main.yml delete mode 100644 tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml delete mode 100644 tests/integration/ccc_network_settings_management/vars/vars_network_setttings_management.yml diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml index 498ab204f4..1134875c7b 100755 --- a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml @@ -20,170 +20,172 @@ dnac_log_level: DEBUG config_verify: true - - debug: - msg: "{{ vars_map.credentials_details }}" - - debug: - msg: "{{ vars_map.design_sites }}" - -# ############################################# -# # Pre Tests Clean Up # -# ############################################# - -# - name: Clean up site before test -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.design_sites }}" - -# - name: Clean up device credentials before test -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" - -# ############################################# -# # CREATE SITE # -# ############################################# - -# - name: Create sites from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# register: result_create_site -# loop: "{{ vars_map.design_sites }}" -# tags: merged - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_site.results }}" -# # when: result_create_site is defined - -# - name: Assert area creation success for each site -# assert: -# that: -# - item.changed == true -# - item.response.status == "SUCCESS" -# - "'created successfully' in item.msg" -# loop: "{{ result_create_site.results }}" -# when: result_create_site is defined - -# ############################################# -# # Create Credentials # -# ############################################# - -# - name: Create Credentials -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" -# tags: merged -# register: result_create_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_credentials.results }}" -# # when: result_create_credentials is defined - -# - name: Assert Device Credential Creation -# assert: -# that: -# - item.changed == true -# - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" -# - item.response[0].globalCredential.Validation == "Success" -# loop: "{{ result_create_credentials.results }}" -# when: result_create_credentials is defined - -# ############################################# -# # Assign Credentials to site # -# ############################################# - -# - name: Assign Credentials to design_sites -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_assign }}" -# tags: assign -# register: result_assign_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_assign_credentials.results }}" -# # when: result_assign_credentials is defined - -# - name: Assert assign Credentials to sites -# assert: -# that: -# - item.changed == true -# - "'Device Credential Assigned to a site is Successfully' in item.response[0].assignCredential['Assign Credentials'].msg" -# loop: "{{ result_assign_credentials.results }}" -# when: result_assign_credentials is defined - -# ############################################# -# # DELETE SITE # -# ############################################# - -# - name: Delete site from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# register: result_delete_site -# loop: "{{ vars_map.design_sites }}" -# tags: deleted - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_site.results }}" -# # when: result_delete_site is defined - -# - name: Assert deletion of area success for each site -# assert: -# that: -# - item.changed == true -# - "'deleted successfully' in item.response" -# loop: "{{ result_delete_site.results }}" -# when: result_delete_site is defined - -# ############################################# -# # Delete Credentials # -# ############################################# - -# - name: Delete Credentials -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" -# tags: deleted -# register: result_delete_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_credentials.results }}" -# # when: result_delete_credentials is defined - -# - name: Assert Global Credential Deletion -# assert: -# that: -# - item.changed == true -# - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" -# - item.response[0].globalCredential.Validation == "Success" -# loop: "{{ result_delete_credentials.results }}" -# when: result_delete_credentials is defined + # - debug: + # msg: "{{ vars_map.design_sites }}" + # - debug: + # msg: "{{ vars_map.credentials_details }}" + # - debug: + # msg: "{{ vars_map.credentials_assign }}" + +############################################# +# Pre Tests Clean Up # +############################################# + + - name: Clean up site before test + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.design_sites }}" + + - name: Clean up device credentials before test + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + +############################################# +# CREATE SITE # +############################################# + + - name: Create sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + register: result_create_site + loop: "{{ vars_map.design_sites }}" + tags: merged + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + + - name: Assert area creation success for each site + assert: + that: + - item.changed == true + - item.response.status == "SUCCESS" + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined + +############################################# +# Create Credentials # +############################################# + + - name: Create Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: merged + register: result_create_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_credentials.results }}" + # when: result_create_credentials is defined + + - name: Assert Device Credential Creation + assert: + that: + - item.changed == true + - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_create_credentials.results }}" + when: result_create_credentials is defined + +############################################# +# Assign Credentials to site # +############################################# + + - name: Assign Credentials to design_sites + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_assign }}" + tags: assign + register: result_assign_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_assign_credentials.results }}" + # when: result_assign_credentials is defined + + - name: Assert assign Credentials to sites + assert: + that: + - item.changed == true + - "'Device Credential Assigned to a site is Successfully' in item.response[0].assignCredential['Assign Credentials'].msg" + loop: "{{ result_assign_credentials.results }}" + when: result_assign_credentials is defined + +############################################# +# DELETE SITE # +############################################# + + - name: Delete site from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + register: result_delete_site + loop: "{{ vars_map.design_sites }}" + tags: deleted + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined + + - name: Assert deletion of area success for each site + assert: + that: + - item.changed == true + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined + +############################################# +# Delete Credentials # +############################################# + + - name: Delete Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: deleted + register: result_delete_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_credentials.results }}" + # when: result_delete_credentials is defined + + - name: Assert Global Credential Deletion + assert: + that: + - item.changed == true + - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_delete_credentials.results }}" + when: result_delete_credentials is defined diff --git a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml index f593ebb51c..f4f9af6f3e 100644 --- a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml @@ -25,101 +25,101 @@ # - debug: # msg: "{{ vars_map.credentials_update }}" -# ############################################# -# # Pre Tests Clean Up # -# ############################################# - -# - name: Clean up device credentials before test -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" - -# ############################################# -# # Create Credentials # -# ############################################# - -# - name: Create Credentials -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" -# tags: merged -# register: result_create_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_credentials.results }}" -# # when: result_create_credentials is defined - -# - name: Assert Device Credential Creation -# assert: -# that: -# - item.changed == true -# - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" -# - item.response[0].globalCredential.Validation == "Success" -# loop: "{{ result_create_credentials.results }}" -# when: result_create_credentials is defined - -# ############################################# -# # Update Credentials # -# ############################################# - -# - name: Update Credentials -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_update }}" -# tags: update -# register: result_update_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_credentials.results }}" -# # when: result_update_credentials is defined - -# - name: Assert Device Credential Update -# assert: -# that: -# - item.changed == true -# - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" -# - item.response[0].globalCredential.Validation == "Success" -# loop: "{{ result_update_credentials.results }}" -# when: result_update_credentials is defined - -# ############################################# -# # Delete Credentials # -# ############################################# - -# - name: Delete Credentials -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# with_list: "{{ vars_map.credentials_details }}" -# tags: deleted -# register: result_delete_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_credentials.results }}" -# # when: result_delete_credentials is defined - -# - name: Assert Device Credential Deletion -# assert: -# that: -# - item.changed == true -# - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" -# - item.response[0].globalCredential.Validation == "Success" -# loop: "{{ result_delete_credentials.results }}" -# when: result_delete_credentials is defined +############################################# +# Pre Tests Clean Up # +############################################# + + - name: Clean up device credentials before test + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + +############################################# +# Create Credentials # +############################################# + + - name: Create Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: merged + register: result_create_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_credentials.results }}" + # when: result_create_credentials is defined + + - name: Assert Device Credential Creation + assert: + that: + - item.changed == true + - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_create_credentials.results }}" + when: result_create_credentials is defined + +############################################# +# Update Credentials # +############################################# + + - name: Update Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_update }}" + tags: update + register: result_update_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_credentials.results }}" + # when: result_update_credentials is defined + + - name: Assert Device Credential Update + assert: + that: + - item.changed == true + - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_update_credentials.results }}" + when: result_update_credentials is defined + +############################################# +# Delete Credentials # +############################################# + + - name: Delete Credentials + cisco.dnac.device_credential_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + with_list: "{{ vars_map.credentials_details }}" + tags: deleted + register: result_delete_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_credentials.results }}" + # when: result_delete_credentials is defined + + - name: Assert Device Credential Deletion + assert: + that: + - item.changed == true + - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" + - item.response[0].globalCredential.Validation == "Success" + loop: "{{ result_delete_credentials.results }}" + when: result_delete_credentials is defined diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml index a1f4b9c886..2c35a63ea6 100755 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml @@ -4,8 +4,7 @@ design_sites: area: name: TEST_SITE_DEVICE_CREDENTIALS parent_name: 'Global' - type: area - + site_type: area credentials_details: diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml index bb358ffff6..b1b5019922 100644 --- a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml @@ -38,249 +38,251 @@ # msg: "{{ vars_map.lldp }}" # - debug: # msg: "{{ vars_map.cidr }}" - -# ############################################# -# # Pre Tests Clean Up # -# ############################################# - -# - name: Delete discoveries before test -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map_delete.delete_discoveries }}" - -# ############################################# -# # Create Single IP Address Discovery # -# ############################################# - -# - name: Discover a single IP Address -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.single_ip }}" -# register: result_singleip_discovery - -# # - name: Debug item -# # debug: -# # var: result_singleip_discovery - -# - name: Check single IP discovery creation -# assert: -# that: -# - result_singleip_discovery.changed == true -# - "'Discovery Created Successfully' in result_singleip_discovery.results | map(attribute='msg') | list" -# when: result_singleip_discovery is defined - -# ############################################# -# # Create Range IP Address Discovery # -# ############################################# - -# - name: Discover an IP Address Range -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.ip_range }}" -# register: result_ip_range_discovery - -# # - name: Debug item -# # debug: -# # var: result_ip_range_discovery - -# - name: Check IP address range discovery creation -# assert: -# that: -# - result_ip_range_discovery.changed == true -# - "'Discovery Created Successfully' in result_ip_range_discovery.results | map(attribute='msg') | list" -# when: result_ip_range_discovery is defined - -# ############################################# -# # Create Multi Range IP Address Discovery # -# ############################################# - -# - name: Discover Multi IP Address Ranges -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.multi_range }}" -# register: result_multi_range_discovery - -# # - name: Debug item -# # debug: -# # var: result_multi_range_discovery - -# - name: Check multi range IP address discovery creation -# assert: -# that: -# - result_multi_range_discovery.changed == true -# - "'Discovery Created Successfully' in result_multi_range_discovery.results | map(attribute='msg') | list" -# when: result_multi_range_discovery is defined - -# ############################################# -# # Create Discovery using CDP # -# ############################################# - -# - name: Discover using CDP -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.cdp }}" -# register: result_cdp_discovery - -# # - name: Debug item -# # debug: -# # var: result_cdp_discovery - -# - name: Check CDP discovery creation -# assert: -# that: -# - result_cdp_discovery.changed == true -# - "'Discovery Created Successfully' in result_cdp_discovery.results | map(attribute='msg') | list" -# when: result_cdp_discovery is defined - -# ############################################# -# # Create Discovery using LLDP # -# ############################################# - -# - name: Discover using LLDP -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.lldp }}" -# register: result_lldp_discovery - -# # - name: Debug item -# # debug: -# # var: result_lldp_discovery - -# - name: Check LLDP discovery creation -# assert: -# that: -# - result_lldp_discovery.changed == true -# - "'Discovery Created Successfully' in result_lldp_discovery.results | map(attribute='msg') | list" -# when: result_lldp_discovery is defined - -# ############################################# -# # Create Discovery using CIDR # -# ############################################# - -# - name: Discover using CIDR -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.cidr }}" -# register: result_cidr_discovery - -# # - name: Debug item -# # debug: -# # var: result_cidr_discovery - -# - name: Check CIDR discovery creation -# assert: -# that: -# - result_cidr_discovery.changed == true -# - "'Discovery Created Successfully' in result_cidr_discovery.results | map(attribute='msg') | list" -# when: result_cidr_discovery is defined - -# ############################################# -# # Create Multiple Discoveries # -# ############################################# - -# - name: Add new item with "preferred_mgmt_ip_method" -# set_fact: -# vars_map_preferred_mgmt: {} - -# - name: Add preferred_mgmt_ip_method to vars_map_preferred_mgmt -# set_fact: -# vars_map_preferred_mgmt: "{{ vars_map_preferred_mgmt | combine({item + '_preferred_mgmt': vars_map[item] | map('combine', {'preferred_mgmt_ip_method': 'UseLoopBack'}) | map('combine', {'discovery_name': vars_map[item][0]['discovery_name'] + ' - preferred_mgmt' }) | list}) }}" -# loop: "{{ vars_map.keys() }}" -# tags: multiple_discoveries - -# - name: Set vars_map_multiple -# set_fact: -# vars_map_multiple: "{{ vars_map | combine(vars_map_preferred_mgmt) }}" -# tags: multiple_discoveries - -# - name: Print the updated vars_map_multiple -# debug: -# var: vars_map_multiple -# tags: multiple_discoveries - -# - name: Create multiple Discoveries -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ vars_map_multiple[item][0] }}" -# with_items: "{{ vars_map_multiple }}" -# tags: multiple_discoveries -# register: result_multiple_discoveries - -# # - name: Debug item -# # debug: -# # var: result_multiple_discoveries -# # when: result_multiple_discoveries is defined - -# - name: Check if multiple discoveries were successfull -# assert: -# that: -# - item.changed == true -# - "'Discovery Created Successfully' in item.msg" -# loop: "{{ result_multiple_discoveries.results }}" -# when: result_multiple_discoveries is defined - -# ############################################# -# # Delete Discovery by name # -# ############################################# - -# - name: Delete all discovery -# cisco.dnac.discovery_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map_delete.delete_discoveries }}" -# register: result_delete_discoveries - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_discoveries.results }}" - -# - name: Check if discovery was successfully deleted -# assert: -# that: -# - item.changed == true -# - "'Successfully deleted discovery' in item.msg" -# loop: "{{ result_delete_discoveries.results }}" -# when: result_delete_discoveries is defined - -# ############################################ -# # Delete ALL Discoveries # -# ############################################ - -# # - name: Delete all discoveries that were created -# # cisco.dnac.discovery_workflow_manager: -# # <<: *dnac_login -# # state: deleted -# # config: -# # - delete_all: True -# # register: result_delete_all - -# # - name: Debug item -# # debug: -# # var: result_delete_all -# # when: result_delete_all is defined + # - debug: + # msg: "{{ vars_map_delete.delete_discoveries }}" + +############################################# +# Pre Tests Clean Up # +############################################# + + - name: Delete discoveries before test + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map_delete.delete_discoveries }}" + +############################################# +# Create Single IP Address Discovery # +############################################# + + - name: Discover a single IP Address + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.single_ip }}" + register: result_singleip_discovery + + # - name: Debug item + # debug: + # var: result_singleip_discovery + + - name: Check single IP discovery creation + assert: + that: + - result_singleip_discovery.changed == true + - "'Discovery Created Successfully' in result_singleip_discovery.results | map(attribute='msg') | list" + when: result_singleip_discovery is defined + +############################################# +# Create Range IP Address Discovery # +############################################# + + - name: Discover an IP Address Range + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.ip_range }}" + register: result_ip_range_discovery + + # - name: Debug item + # debug: + # var: result_ip_range_discovery + + - name: Check IP address range discovery creation + assert: + that: + - result_ip_range_discovery.changed == true + - "'Discovery Created Successfully' in result_ip_range_discovery.results | map(attribute='msg') | list" + when: result_ip_range_discovery is defined + +############################################# +# Create Multi Range IP Address Discovery # +############################################# + + - name: Discover Multi IP Address Ranges + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.multi_range }}" + register: result_multi_range_discovery + + # - name: Debug item + # debug: + # var: result_multi_range_discovery + + - name: Check multi range IP address discovery creation + assert: + that: + - result_multi_range_discovery.changed == true + - "'Discovery Created Successfully' in result_multi_range_discovery.results | map(attribute='msg') | list" + when: result_multi_range_discovery is defined + +############################################# +# Create Discovery using CDP # +############################################# + + - name: Discover using CDP + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.cdp }}" + register: result_cdp_discovery + + # - name: Debug item + # debug: + # var: result_cdp_discovery + + - name: Check CDP discovery creation + assert: + that: + - result_cdp_discovery.changed == true + - "'Discovery Created Successfully' in result_cdp_discovery.results | map(attribute='msg') | list" + when: result_cdp_discovery is defined + +############################################# +# Create Discovery using LLDP # +############################################# + + - name: Discover using LLDP + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.lldp }}" + register: result_lldp_discovery + + # - name: Debug item + # debug: + # var: result_lldp_discovery + + - name: Check LLDP discovery creation + assert: + that: + - result_lldp_discovery.changed == true + - "'Discovery Created Successfully' in result_lldp_discovery.results | map(attribute='msg') | list" + when: result_lldp_discovery is defined + +############################################# +# Create Discovery using CIDR # +############################################# + + - name: Discover using CIDR + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.cidr }}" + register: result_cidr_discovery + + # - name: Debug item + # debug: + # var: result_cidr_discovery + + - name: Check CIDR discovery creation + assert: + that: + - result_cidr_discovery.changed == true + - "'Discovery Created Successfully' in result_cidr_discovery.results | map(attribute='msg') | list" + when: result_cidr_discovery is defined + +############################################# +# Create Multiple Discoveries # +############################################# + + - name: Add new item with "preferred_mgmt_ip_method" + set_fact: + vars_map_preferred_mgmt: {} + + - name: Add preferred_mgmt_ip_method to vars_map_preferred_mgmt + set_fact: + vars_map_preferred_mgmt: "{{ vars_map_preferred_mgmt | combine({item + '_preferred_mgmt': vars_map[item] | map('combine', {'preferred_mgmt_ip_method': 'UseLoopBack'}) | map('combine', {'discovery_name': vars_map[item][0]['discovery_name'] + ' - preferred_mgmt' }) | list}) }}" + loop: "{{ vars_map.keys() }}" + tags: multiple_discoveries + + - name: Set vars_map_multiple + set_fact: + vars_map_multiple: "{{ vars_map | combine(vars_map_preferred_mgmt) }}" + tags: multiple_discoveries + + - name: Print the updated vars_map_multiple + debug: + var: vars_map_multiple + tags: multiple_discoveries + + - name: Create multiple Discoveries + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ vars_map_multiple[item][0] }}" + with_items: "{{ vars_map_multiple }}" + tags: multiple_discoveries + register: result_multiple_discoveries + + # - name: Debug item + # debug: + # var: result_multiple_discoveries + # when: result_multiple_discoveries is defined + + - name: Check if multiple discoveries were successfull + assert: + that: + - item.changed == true + - "'Discovery Created Successfully' in item.msg" + loop: "{{ result_multiple_discoveries.results }}" + when: result_multiple_discoveries is defined + +############################################# +# Delete Discovery by name # +############################################# + + - name: Delete all discovery + cisco.dnac.discovery_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map_delete.delete_discoveries }}" + register: result_delete_discoveries + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_discoveries.results }}" + + - name: Check if discovery was successfully deleted + assert: + that: + - item.changed == true + - "'Successfully deleted discovery' in item.msg" + loop: "{{ result_delete_discoveries.results }}" + when: result_delete_discoveries is defined + +############################################ +# Delete ALL Discoveries # +############################################ + + # - name: Delete all discoveries that were created + # cisco.dnac.discovery_workflow_manager: + # <<: *dnac_login + # state: deleted + # config: + # - delete_all: True + # register: result_delete_all + + # - name: Debug item + # debug: + # var: result_delete_all + # when: result_delete_all is defined diff --git a/tests/integration/ccc_discovery_management/vars/vars_misc.yml b/tests/integration/ccc_discovery_management/vars/vars_misc.yml index c732b7d402..4c9ca90bb6 100755 --- a/tests/integration/ccc_discovery_management/vars/vars_misc.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_misc.yml @@ -11,4 +11,4 @@ delete_discoveries: - discovery_name: Multi Range Discovery - preferred_mgmt - discovery_name: CDP Discovery - preferred_mgmt - discovery_name: LLDP Discovery - preferred_mgmt - - discovery_name: CIDR Discovery - preferred_mgmt \ No newline at end of file + - discovery_name: CIDR Discovery - preferred_mgmt diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index d5e66346f8..c091a35200 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -27,459 +27,483 @@ # - debug: # msg: "{{ vars_map.device_interface_updates }}" # - debug: + # msg: "{{ vars_map.device_role_updates }}" + # - debug: + # msg: "{{ vars_map.device_int_update_post_rolechange }}" + # - debug: + # msg: "{{ vars_map.device_resync }}" + # - debug: + # msg: "{{ vars_map.create_assign_udf }}" + # - debug: + # msg: "{{ vars_map.update_udf }}" + # - debug: + # msg: "{{ vars_map.delete_udf }}" + # - debug: + # msg: "{{ vars_map.export_device_details }}" + # - debug: + # msg: "{{ vars_map.export_credential_details }}" + # - debug: + # msg: "{{ vars_map.design_sites }}" + # - debug: + # msg: "{{ vars_map.associate_wired_device }}" + # - debug: + # msg: "{{ vars_map.associate_wireless_device }}" + # - debug: + # msg: "{{ vars_map.delete_sites }}" + # - debug: # msg: "{{ vars_map.delete_devices }}" -# ############################################# -# # Clean Up # -# ############################################# - -# - name: Delete device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_devices }}" -# register: result_device_deleted - -# - name: Delete site -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" -# register: result_delete_site - -# ############################################# -# # Add Devices # -# ############################################# - -# - name: Add new device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_details }}" -# register: result_add_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_add_device.results }}" - -# - name: Assert device addition success -# assert: -# that: -# - item.changed == true -# - "'added to Cisco Catalyst Center' in item.msg" -# loop: "{{ result_add_device.results }}" -# when: result_add_device is defined - -# ############################################# -# # Update Device Credential Details # -# ############################################# - -# - name: Update device details -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_credential_updates }}" -# register: result_update_device_credentials - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_device_credentials.results }}" -# # when: result_update_device_credentials is defined - -# - name: Assert update -# assert: -# that: -# - item.changed == true -# loop: "{{ result_update_device_credentials.results }}" -# when: result_update_device_credentials is defined - -# ############################################ -# # Update Device Interface Detials # -# ############################################# - -# # - name: Pause for 60 seconds before updating interfaces -# # pause: -# # seconds: 60 - -# # - name: Update device interface details -# # cisco.dnac.inventory_workflow_manager: -# # <<: *dnac_login -# # state: merged -# # config: -# # - "{{ item }}" -# # loop: "{{ vars_map.device_interface_updates }}" -# # register: result_update_device_interface - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_device_interface.results }}" -# # when: result_update_device_interface is defined - -# # - name: Assert update -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_update_device_interface.results }}" -# # when: result_update_device_interface is defined - -# ############################################# -# # Update Device Role Detials # -# ############################################# - -# - name: Update device role details -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_role_updates }}" -# register: result_update_device_role - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_update_device_role.results }}" -# when: result_update_device_role is defined - -# - name: Assert device role update -# assert: -# that: -# - result_update_device_role.changed == true -# - "'Device role was successfully updated' in item.response.progress" -# loop: "{{ result_update_device_role.results }}" -# when: result_update_device_role is defined - -# ############################################# -# # Update Device Interface Description # -# ############################################# - -# # - name: Pause for 60 seconds before updating interfaces -# # pause: -# # seconds: 60 - -# # - name: Update device interface description post changing role to non-access -# # cisco.dnac.inventory_workflow_manager: -# # <<: *dnac_login -# # state: merged -# # config: -# # - "{{ item }}" -# # loop: "{{ vars_map.device_int_update_post_rolechange }}" -# # register: result_update_device_interface - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_device_interface.results }}" -# # when: result_update_device_interface is defined - -# # - name: Assert update -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_update_device_interface.results }}" -# # when: result_update_device_interface is defined - -# ############################################# -# # Resync Device # -# ############################################# - -# - name: Resync Device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_resync }}" -# register: result_resync_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_resync_device.results }}" -# # when: result_resync_device is defined - -# - name: Assert device resync -# assert: -# that: -# - result_resync_device.changed == true -# - "'Synced devices' in item.response.progress" -# loop: "{{ result_resync_device.results }}" -# when: result_resync_device is defined - -# ############################################# -# # Create & Assign User Defined Field # -# ############################################# - -# - name: Create & Assign user defined field -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.create_assign_udf }}" -# register: result_create_assign_udf - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_assign_udf.results }}" -# # when: result_create_assign_udf is defined - -# - name: Assert user defined field creation and assignment -# assert: -# that: -# - item.changed == true -# loop: "{{ result_create_assign_udf.results }}" -# when: result_create_assign_udf is defined - -# ############################################# -# # Update User Defined Field # -# ############################################# - -# - name: Update user defined field -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.update_udf }}" -# register: result_update_udf - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_assign_udf.results }}" -# # when: result_update_udf is defined - -# - name: Assert user defined field updated -# assert: -# that: -# - item.changed == true -# loop: "{{ result_update_udf.results }}" -# when: result_update_udf is defined - - -# ############################################# -# # Delete User Defined Field # -# ############################################# - -# - name: Delete user defined field -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_udf }}" -# register: result_delete_udf - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_udf.results }}" -# # when: result_delete_udf is defined - -# - name: Assert user defined field deletion -# assert: -# that: -# - result_delete_udf.changed == true -# - "'deleted successfully' in item.response.progress" -# loop: "{{ result_delete_udf.results }}" -# when: result_delete_udf is defined - - -# ############################################# -# # Export Device Details # -# ############################################# - -# - name: Export Device Details in a CSV file -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.export_device_details }}" -# register: result_export_details - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_export_details.results }}" -# # when: result_export_details is defined - -# - name: Assert device details export -# assert: -# that: -# - item.changed == true -# loop: "{{ result_export_details.results }}" -# when: result_export_details is defined - -# ############################################# -# # Export Device Credential Details # -# ############################################# - -# - name: Export Credential Device Details in a CSV file -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.export_credential_details }}" -# register: result_export_credential_details - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_export_credential_details.results }}" -# # when: result_export_credential_details is defined - -# - name: Assert device credential details export -# assert: -# that: -# - item.changed == true -# loop: "{{ result_export_credential_details.results }}" -# when: result_export_credential_details is defined - - -# ############################################# -# # CREATE SITE # -# ############################################# - -# - name: Create sites from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.design_sites }}" -# register: result_create_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_site.results }}" -# # when: result_create_site is defined - -# - name: Assert area creation success for each site -# assert: -# that: -# - item.changed == true -# - item.response.status == "SUCCESS" -# - "'created successfully' in item.msg" -# loop: "{{ result_create_site.results }}" -# when: result_create_site is defined - -# ############################################# -# # ASSOCIATE WIRED DEVICE TO SITE # -# ############################################# - -# - name: Assign wired device to site and then provision -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.associate_wired_device }}" -# register: result_associate_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_associate_device.results }}" -# # when: result_associate_device is defined - -# - name: Assert Assign wired device to site and then provision -# assert: -# that: -# - item.changed == true -# loop: "{{ result_associate_device.results }}" -# when: result_associate_device is defined - - -# ############################################# -# # ASSOCIATE WIRELESS DEVICE TO SITE # -# ############################################# - -# # - name: Assign wireless device to site and then provision -# # cisco.dnac.inventory_workflow_manager: -# # <<: *dnac_login -# # state: merged -# # config: -# # - "{{ item }}" -# # loop: "{{ vars_map.associate_wireless_device }}" -# # register: result_associate_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_associate_device.results }}" -# # when: result_associate_device is defined - -# # - name: Assert Assign wireless device to site and then provision -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_associate_device.results }}" -# # when: result_associate_device is defined - -# ############################################# -# # Delete Devices # -# ############################################# - -# - name: Delete device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_devices }}" -# register: result_device_deleted - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_device_deleted.results }}" -# # when: result_device_deleted is defined - -# - name: Assert device deletion success -# assert: -# that: -# - result_device_deleted.changed == true -# when: result_device_deleted is defined - -# ############################################# -# # DELETE SITE # -# ############################################# - -# - name: Delete sites from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" -# register: result_delete_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_site.results }}" -# # when: result_delete_site is defined - -# - name: Assert deletion of area success for each site -# assert: -# that: -# - item.changed == true -# - "'deleted successfully' in item.response" -# loop: "{{ result_delete_site.results }}" -# when: result_delete_site is defined +############################################# +# Clean Up # +############################################# + + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + - name: Delete site + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site + +############################################# +# Add Devices # +############################################# + + - name: Add new device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_details }}" + register: result_add_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_add_device.results }}" + + - name: Assert device addition success + assert: + that: + - item.changed == true + - "'added to Cisco Catalyst Center' in item.msg" + loop: "{{ result_add_device.results }}" + when: result_add_device is defined + +############################################# +# Update Device Credential Details # +############################################# + + - name: Update device details + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_credential_updates }}" + register: result_update_device_credentials + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_credentials.results }}" + # when: result_update_device_credentials is defined + + - name: Assert update + assert: + that: + - item.changed == true + loop: "{{ result_update_device_credentials.results }}" + when: result_update_device_credentials is defined + +############################################ +# Update Device Interface Detials # +############################################# + + # - name: Pause for 60 seconds before updating interfaces + # pause: + # seconds: 60 + + # - name: Update device interface details + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_interface_updates }}" + # register: result_update_device_interface + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + + # - name: Assert update + # assert: + # that: + # - item.changed == true + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + +############################################# +# Update Device Role Detials # +############################################# + + # - name: Update device role details + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_role_updates }}" + # register: result_update_device_role + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_role.results }}" + # when: result_update_device_role is defined + + # - name: Assert device role update + # assert: + # that: + # - result_update_device_role.changed == true + # - "'Device role was successfully updated' in item.response.progress" + # loop: "{{ result_update_device_role.results }}" + # when: result_update_device_role is defined + +############################################# +# Update Device Interface Description # +############################################# + + # - name: Pause for 60 seconds before updating interfaces + # pause: + # seconds: 60 + + # - name: Update device interface description post changing role to non-access + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.device_int_update_post_rolechange }}" + # register: result_update_device_interface + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + + # - name: Assert update + # assert: + # that: + # - item.changed == true + # loop: "{{ result_update_device_interface.results }}" + # when: result_update_device_interface is defined + +############################################# +# Resync Device # +############################################# + + - name: Resync Device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_resync }}" + register: result_resync_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_resync_device.results }}" + # when: result_resync_device is defined + + - name: Assert device resync + assert: + that: + - result_resync_device.changed == true + - "'Synced devices' in item.response.progress" + loop: "{{ result_resync_device.results }}" + when: result_resync_device is defined + +############################################# +# Create & Assign User Defined Field # +############################################# + + - name: Create & Assign user defined field + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.create_assign_udf }}" + register: result_create_assign_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_assign_udf.results }}" + # when: result_create_assign_udf is defined + + - name: Assert user defined field creation and assignment + assert: + that: + - item.changed == true + loop: "{{ result_create_assign_udf.results }}" + when: result_create_assign_udf is defined + +############################################# +# Update User Defined Field # +############################################# + + - name: Update user defined field + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.update_udf }}" + register: result_update_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_assign_udf.results }}" + # when: result_update_udf is defined + + - name: Assert user defined field updated + assert: + that: + - item.changed == true + loop: "{{ result_update_udf.results }}" + when: result_update_udf is defined + + +############################################# +# Delete User Defined Field # +############################################# + + - name: Delete user defined field + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_udf }}" + register: result_delete_udf + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_udf.results }}" + # when: result_delete_udf is defined + + - name: Assert user defined field deletion + assert: + that: + - result_delete_udf.changed == true + - "'deleted successfully' in item.response.progress" + loop: "{{ result_delete_udf.results }}" + when: result_delete_udf is defined + + +############################################# +# Export Device Details # +############################################# + + - name: Export Device Details in a CSV file + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.export_device_details }}" + register: result_export_details + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_export_details.results }}" + # when: result_export_details is defined + + - name: Assert device details export + assert: + that: + - item.changed == true + loop: "{{ result_export_details.results }}" + when: result_export_details is defined + +############################################# +# Export Device Credential Details # +############################################# + + - name: Export Credential Device Details in a CSV file + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.export_credential_details }}" + register: result_export_credential_details + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_export_credential_details.results }}" + # when: result_export_credential_details is defined + + - name: Assert device credential details export + assert: + that: + - item.changed == true + loop: "{{ result_export_credential_details.results }}" + when: result_export_credential_details is defined + + +############################################# +# CREATE SITE # +############################################# + + - name: Create sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.design_sites }}" + register: result_create_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + + - name: Assert area creation success for each site + assert: + that: + - item.changed == true + - item.response.status == "SUCCESS" + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined + +############################################# +# ASSOCIATE WIRED DEVICE TO SITE # +############################################# + + - name: Assign wired device to site and then provision + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.associate_wired_device }}" + register: result_associate_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_associate_device.results }}" + # when: result_associate_device is defined + + - name: Assert Assign wired device to site and then provision + assert: + that: + - item.changed == true + loop: "{{ result_associate_device.results }}" + when: result_associate_device is defined + + +############################################# +# ASSOCIATE WIRELESS DEVICE TO SITE # +############################################# + + # - name: Assign wireless device to site and then provision + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.associate_wireless_device }}" + # register: result_associate_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_associate_device.results }}" + # when: result_associate_device is defined + + # - name: Assert Assign wireless device to site and then provision + # assert: + # that: + # - item.changed == true + # loop: "{{ result_associate_device.results }}" + # when: result_associate_device is defined + +############################################# +# Delete Devices # +############################################# + + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_device_deleted.results }}" + # when: result_device_deleted is defined + + - name: Assert device deletion success + assert: + that: + - result_device_deleted.changed == true + when: result_device_deleted is defined + +############################################# +# DELETE SITE # +############################################# + + - name: Delete sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined + + - name: Assert deletion of area success for each site + assert: + that: + - item.changed == true + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 824565d0c1..26c56ac68a 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -145,7 +145,7 @@ device_role_updates: - ip_address_list: ["204.1.2.5"] device_updated: True update_device_role: - role: ACCESS + role: CORE device_int_update_post_rolechange: @@ -218,7 +218,7 @@ design_sites: area: name: ITest_Area parent_name: Global - type: area + site_type: area - site: building: name: ITest_Building @@ -227,7 +227,7 @@ design_sites: latitude: 12.969910 longitude: 77.597960 country: India - type: building + site_type: building - site: floor: name: ITest_Floor1 @@ -237,7 +237,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor associate_wired_device: @@ -269,10 +269,10 @@ delete_sites: area: name: ITest_Area parent_name: Global - type: area + site_type: area delete_devices: - ip_address_list: ["204.1.2.5"] #ip_address_list: ["204.1.2.5", "204.192.6.200"] - clean_config: False \ No newline at end of file + clean_config: False diff --git a/tests/integration/ccc_network_settings_management/defaults/main.yml b/tests/integration/ccc_network_settings_management/defaults/main.yml deleted file mode 100644 index 55a93fc23d..0000000000 --- a/tests/integration/ccc_network_settings_management/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_network_settings_management/meta/main.yml b/tests/integration/ccc_network_settings_management/meta/main.yml deleted file mode 100644 index 5514b6a40c..0000000000 --- a/tests/integration/ccc_network_settings_management/meta/main.yml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_network_settings_management/tasks/main.yml b/tests/integration/ccc_network_settings_management/tasks/main.yml deleted file mode 100644 index 09e0832ca2..0000000000 --- a/tests/integration/ccc_network_settings_management/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: collect ccc test cases - find: - paths: "{{ role_path }}/tests" - patterns: "{{ testcase }}.yml" - connection: local - register: ccc_cases - tags: sanity - -- debug: - msg: "CCC Cases: {{ ccc_cases }}" - -- set_fact: - test_cases: - files: "{{ ccc_cases.files }}" - tags: sanity - -- debug: - msg: "Test Cases: {{ test_cases }}" - -- name: set test_items - set_fact: - test_items: "{{ test_cases.files | map(attribute='path') | list }}" - tags: sanity - -- debug: - msg: "Test Items: {{ test_items }}" - -- name: run test cases (connection=httpapi) - include_tasks: "{{ test_case_to_run }}" - loop: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml b/tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml deleted file mode 100644 index 9b329a8aab..0000000000 --- a/tests/integration/ccc_network_settings_management/tests/test_network_settings_management.yml +++ /dev/null @@ -1,173 +0,0 @@ ---- -- debug: msg="Starting device credential management test" -- debug: msg="Role Path {{ role_path }}" - -- block: - - name: Load vars and declare dnac vars - include_vars: - file: "{{ role_path }}/vars/main.yml" - name: vars_map - vars: - dnac_login: &dnac_login - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG - config_verify: true - - - debug: - msg: "{{ vars_map.design_sites }}" - - debug: - msg: "{{ vars_map. }}" - - -# ############################################# -# # Pre Tests Clean Up # -# ############################################# - -# - name: Clean up site before test -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.design_sites }}" - -# - name: Clean up before tests -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map. }}" - - -# ############################################# -# # CREATE SITE # -# ############################################# - -# - name: Create sites from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# register: result_create_site -# loop: "{{ vars_map.design_sites }}" -# tags: merged - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_site.results }}" -# # when: result_create_site is defined - -# - name: Assert area creation success for each site -# assert: -# that: -# - item.changed == true -# - item.response.status == "SUCCESS" -# - "'created successfully' in item.msg" -# loop: "{{ result_create_site.results }}" -# when: result_create_site is defined - -# ############################################# -# # UPDATE NETWORK SETTINGS # -# ############################################# - - -# ############################################# -# # Create Global Pool # -# ############################################# - -# - name: Create Global Pool -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map. }}" -# tags: merged -# register: result_create_global_pool - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_create_global_pool.results }}" -# when: result_create_global_pool is defined - -# # - name: Assert Global Pool Creation -# # assert: -# # that: -# # - item.changed == true -# # - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" -# # - item.response[0].globalCredential.Validation == "Success" -# # loop: "{{ result_create_global_pool.results }}" -# # when: result_create_global_pool is defined - -# ############################################# -# # Update Global Pool # -# ############################################# - -# - name: Update Global Pool -# cisco.dnac.device_credential_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# with_list: "{{ vars_map. }}" -# tags: update -# register: result_update_global_pool - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_update_credentials.results }}" -# when: result_update_credentials is defined - -# # - name: Assert Global Credential Update -# # assert: -# # that: -# # - item.changed == true -# # - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" -# # - item.response[0].globalCredential.Validation == "Success" -# # loop: "{{ result_update_global_pool.results }}" -# # when: result_update_global_pool is defined - -# ############################################# -# # Delete Global Pool # -# ############################################# - - -# ############################################# -# # DELETE SITE # -# ############################################# - -# - name: Delete site from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# register: result_delete_site -# loop: "{{ vars_map.design_sites }}" -# tags: deleted - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_site.results }}" -# # when: result_delete_site is defined - -# - name: Assert deletion of area success for each site -# assert: -# that: -# - item.changed == true -# - "'deleted successfully' in item.response" -# loop: "{{ result_delete_site.results }}" -# when: result_delete_site is defined diff --git a/tests/integration/ccc_network_settings_management/vars/vars_network_setttings_management.yml b/tests/integration/ccc_network_settings_management/vars/vars_network_setttings_management.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml index 68137c4d51..b5638c1002 100644 --- a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml @@ -22,8 +22,13 @@ # - debug: - # msg: "{{ vars_map.device_details }}" - + # msg: "{{ vars_map.pnp_delete }}" + # - debug: + # msg: "{{ vars_map.pnp_claim }}" + # - debug: + # msg: "{{ vars_map.bulk }}" + # - debug: + # msg: "{{ vars_map.delete_devices }}" ############################################# # Clean Up # @@ -160,6 +165,7 @@ # - item.changed == true # - "'Deleted Successfully' in item.msg" # loop: "{{ result_delete_device.results }}" + # when: result_delete_device is defined ############################################# @@ -181,6 +187,22 @@ loop: "{{ result_claim_device.results }}" when: result_claim_device is defined + - name: Assert Add and Claim device + assert: + that: + - item.changed == true + - "'Claimed Successfully' in item.msg" + loop: "{{ result_claim_device.results }}" + when: result_claim_device is defined + +############################################# +# Pause to Complete Provisioning # +############################################# + + - name: Pause for 5 minutes + pause: + seconds: 300 + ############################################# # Delete Devices # ############################################# diff --git a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml index 8aacfb4ea4..b4ea491383 100644 --- a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml @@ -16,17 +16,18 @@ pnp_delete: pnp_claim: cat9k: - - site_name: Global/ITest_PnP_Area/ITest_PnP_Building - project_name: Onboarding Configuration - template_name: "Ansible_PNP_Switch" - template_details: - interface: TwoGigabitEthernet1/0/2 - image_name: cat9k_iosxe.17.12.02.SPA.bin - device_info: + - device_info: - serial_number: FJC2721271T hostname: Switch state: Unclaimed pid: C9300-48T + site_name: Global/ITest_PnP_Area/ITest_PnP_Building + template_name: "Ansible_PNP_Switch" + project_name: Onboarding Configuration + template_params: + hostname: SJ-EN-9300 + interface: GigabitEthernet1/1/4 + bulk: add: diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml index 62f2114416..6f703e4e70 100644 --- a/tests/integration/ccc_site_management/tests/test_site_management.yml +++ b/tests/integration/ccc_site_management/tests/test_site_management.yml @@ -27,95 +27,95 @@ # - debug: # msg: "{{ vars_map.delete_sites }}" -# ############################################# -# # Clean Up # -# ############################################# - -# - name: Clean up before test -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" - -# ############################################# -# # CREATE SITES # -# ############################################# - -# - name: Create sites -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.design_sites }}" -# register: result_create_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_site.results }}" -# # when: result_create_site is defined - -# - name: Assert area creation success for each site -# assert: -# that: -# - item.changed == true -# - "'created successfully' in item.msg" -# loop: "{{ result_create_site.results }}" -# when: result_create_site is defined - -# ############################################# -# # UPDATE SITES # -# ############################################# - -# - name: Update sites -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.update_sites }}" -# register: result_update_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_update_site.results }}" -# # when: result_update_site is defined - -# - name: Assert area update success for each site -# assert: -# that: -# - item.changed == true -# - "'Updated Successfully' in item.msg" -# loop: "{{ result_update_site.results }}" -# when: result_update_site is defined - -# ############################################# -# # DELETE SITES # -# ############################################# - -# - name: Delete sites -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" -# register: result_delete_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_site.results }}" -# # when: result_delete_site is defined - -# - name: Assert deletion success for each site -# assert: -# that: -# - item.changed == true -# - "'deleted successfully' in item.response" -# loop: "{{ result_delete_site.results }}" -# when: result_delete_site is defined +############################################# +# Clean Up # +############################################# + + - name: Clean up before test + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + +############################################# +# CREATE SITES # +############################################# + + - name: Create sites + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.design_sites }}" + register: result_create_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + + - name: Assert area creation success for each site + assert: + that: + - item.changed == true + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined + +############################################# +# UPDATE SITES # +############################################# + + - name: Update sites + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.update_sites }}" + register: result_update_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_update_site.results }}" + # when: result_update_site is defined + + - name: Assert area update success for each site + assert: + that: + - item.changed == true + - "'Updated Successfully' in item.msg" + loop: "{{ result_update_site.results }}" + when: result_update_site is defined + +############################################# +# DELETE SITES # +############################################# + + - name: Delete sites + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined + + - name: Assert deletion success for each site + assert: + that: + - item.changed == true + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml index 6989c9e864..88cee28a78 100644 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ b/tests/integration/ccc_site_management/vars/vars_site_management.yml @@ -5,37 +5,37 @@ design_sites: area: name: USA-Test parent_name: Global - type: area + site_type: area - site: area: name: SAN JOSE parent_name: Global/USA-Test - type: area + site_type: area - site: area: name: RTP parent_name: Global/USA-Test - type: area + site_type: area - site: area: name: BayAreaGuest parent_name: Global/USA-Test - type: area + site_type: area - site: area: name: New York parent_name: Global/USA-Test - type: area + site_type: area - site: area: name: SAN-FRANCISCO parent_name: Global/USA-Test - type: area + site_type: area - site: area: name: BERKELEY parent_name: Global/USA-Test - type: area + site_type: area - site: building: name: BLD10 @@ -44,7 +44,7 @@ design_sites: latitude: 35.85992111421487 longitude: -78.8829258991226 country: United States - type: building + site_type: building - site: building: name: BLD11 @@ -53,7 +53,7 @@ design_sites: latitude: 35.86059627310624 longitude: -78.88105620286412 country: United States - type: building + site_type: building - site: building: name: BLD12 @@ -62,7 +62,7 @@ design_sites: latitude: 35.8611847591779 longitude: -78.88217248318003 country: United States - type: building + site_type: building - site: building: name: BLD23 @@ -71,7 +71,7 @@ design_sites: latitude: 37.398188 longitude: -121.912974 country: United States - type: building + site_type: building - site: building: name: BLD20 @@ -80,7 +80,7 @@ design_sites: latitude: 37.415947 longitude: -121.916327 country: United States - type: building + site_type: building - site: building: name: BLD_GB @@ -89,7 +89,7 @@ design_sites: latitude: 37.415947 longitude: -121.916327 country: United States - type: building + site_type: building - site: building: name: BLDNYC @@ -98,7 +98,7 @@ design_sites: latitude: 37.398188 longitude: -121.912974 country: United States - type: building + site_type: building - site: building: name: BLD_SF @@ -107,7 +107,7 @@ design_sites: latitude: 37.398188 longitude: -121.912974 country: United States - type: building + site_type: building - site: building: name: BLD_SF1 @@ -116,7 +116,7 @@ design_sites: latitude: 37.398188 longitude: -121.912974 country: United States - type: building + site_type: building - site: building: name: BLDBERK @@ -125,7 +125,7 @@ design_sites: latitude: 37.415947 longitude: -121.916327 country: United States - type: building + site_type: building - site: floor: name: BLD10_FLOOR1 @@ -135,7 +135,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: BLD10_FLOOR2 @@ -145,7 +145,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: BLD10_FLOOR3 @@ -155,7 +155,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 3 - type: floor + site_type: floor - site: floor: name: BLD11_FLOOR1 @@ -165,7 +165,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: BLD11_FLOOR2 @@ -175,7 +175,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: BLD11_FLOOR3 @@ -185,7 +185,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 3 - type: floor + site_type: floor - site: floor: name: BLD12_FLOOR1 @@ -195,7 +195,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: BLD12_FLOOR2 @@ -205,7 +205,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: BLD12_FLOOR3 @@ -215,7 +215,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 3 - type: floor + site_type: floor - site: floor: name: FLOOR1_LEVEL1 @@ -225,7 +225,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR1_LEVEL2 @@ -235,7 +235,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR1_LEVEL3 @@ -245,7 +245,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR1_LEVEL4 @@ -255,7 +255,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: BLD20_FLOOR1 @@ -265,7 +265,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: BLD20_FLOOR2 @@ -275,7 +275,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: FLOOR1 @@ -285,7 +285,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR2 @@ -295,7 +295,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: FLOOR1 @@ -305,7 +305,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR2 @@ -315,7 +315,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: FLOOR1 @@ -325,7 +325,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor - site: floor: name: FLOOR2 @@ -335,7 +335,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 2 - type: floor + site_type: floor - site: floor: name: FLOOR1_LEVEL1 @@ -345,19 +345,19 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor #India-Test Site Hierarchy - site: area: name: India-Test parent_name: Global - type: area + site_type: area - site: area: name: Bangalore parent_name: Global/India-Test - type: area + site_type: area - site: building: name: Mantri Square @@ -366,7 +366,7 @@ design_sites: latitude: 12.969910 longitude: 77.597960 country: India - type: building + site_type: building - site: floor: name: Floor1 @@ -376,21 +376,21 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor #Mexico Site Hierarchy - site: area: name: Mexico-Test parent_name: Global - type: area + site_type: area #Canada Site Hierarchy - site: area: name: Canada-Test parent_name: Global - type: area + site_type: area update_sites: @@ -402,7 +402,7 @@ update_sites: latitude: 38.8611847591779 longitude: 72.88217248318003 country: United States - type: building + site_type: building - site: floor: name: FLOOR1 @@ -412,7 +412,7 @@ update_sites: length: 200.00 height: 20.00 floor_number: 1 - type: floor + site_type: floor - site: building: name: Mantri Square @@ -421,7 +421,7 @@ update_sites: latitude: 18.969910 longitude: 20.597960 country: India - type: building + site_type: building - site: floor: name: Floor1 @@ -431,8 +431,7 @@ update_sites: length: 200.00 height: 20.00 floor_number: 1 - type: floor - + site_type: floor delete_sites: @@ -440,19 +439,19 @@ delete_sites: area: name: USA-Test parent_name: Global - type: area + site_type: area - site: area: name: India-Test parent_name: Global - type: area + site_type: area - site: area: name: Mexico-Test parent_name: Global - type: area + site_type: area - site: area: name: Canada-Test parent_name: Global - type: area + site_type: area diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml index 7106432a92..c85f9ec465 100644 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -20,286 +20,300 @@ dnac_log_level: DEBUG # - debug: - # msg: "{{ vars_map. }}" + # msg: "{{ vars_map.image_details }}" # - debug: - # msg: "{{ vars_map. }}" + # msg: "{{ vars_map.image_golden_tagging_details }}" # - debug: - # msg: "{{ vars_map. }}" + # msg: "{{ vars_map.image_distributation_details }}" + # - debug: + # msg: "{{ vars_map.image_activation_details }}" + # - debug: + # msg: "{{ vars_map.image_golden_untagging_details }}" + # - debug: + # msg: "{{ vars_map.design_sites }}" + # - debug: + # msg: "{{ vars_map.device_details }}" + # - debug: + # msg: "{{ vars_map.associate_wired_device }}" + # - debug: + # msg: "{{ vars_map.delete_sites }}" + # - debug: + # msg: "{{ vars_map.delete_devices }}" ############################################# # Clean Up # ############################################# -# - name: Delete device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_devices }}" -# register: result_device_deleted - -# - name: Delete site -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" -# register: result_delete_site - -# ############################################# -# # CREATE SITE # -# ############################################# - -# - name: Create sites -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.design_sites }}" -# register: result_create_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_create_site.results }}" -# # when: result_create_site is defined - -# - name: Assert area creation success for each site -# assert: -# that: -# - item.changed == true -# - "'created successfully' in item.msg" -# loop: "{{ result_create_site.results }}" -# when: result_create_site is defined - -# ############################################# -# # Add Devices # -# ############################################# - -# - name: Add new device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.device_details }}" -# register: result_add_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_add_device.results }}" - -# - name: Assert device addition success -# assert: -# that: -# - item.changed == true -# - "'added to Cisco Catalyst Center' in item.msg" -# loop: "{{ result_add_device.results }}" -# when: result_add_device is defined - -# ############################################# -# # ASSOCIATE WIRED DEVICE TO SITE # -# ############################################# - -# - name: Assign wired device to site and then provision -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.associate_wired_device }}" -# register: result_associate_device - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_associate_device.results }}" -# # when: result_associate_device is defined - -# - name: Assert Assign wired device to site and then provision -# assert: -# that: -# - item.changed == true -# loop: "{{ result_associate_device.results }}" -# when: result_associate_device is defined - - -# ############################################# -# # IMPORT IMAGE # -# ############################################# - -# - name: SWIM task - import -# cisco.dnac.swim_workflow_manager: -# <<: *dnac_login -# config: -# - "{{ item }}" -# loop: "{{ vars_map.image_details }}" -# register: result_import_image - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_import_image.results }}" - -# # - name: Assert import images -# # assert: -# # that: -# # - item.changed == true -# # - '"imported successfully" in item.msg' -# # loop: "{{ result_import_image.results }}" -# # when: result_import_image is defined - -# ############################################# -# # TAG IMAGE # -# ############################################# - -# - name: SWIM task - tag -# cisco.dnac.swim_workflow_manager: -# <<: *dnac_login -# config: -# - "{{ item }}" -# loop: "{{ vars_map.image_golden_tagging_details}}" -# register: result_tag_image - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_tag_image.results }}" - -# - name: Assert tag images -# assert: -# that: -# - item.changed == true -# - '"Tagging image" in item.msg' -# loop: "{{ result_tag_image.results }}" -# when: result_tag_image is defined - -# ############################################# -# # DISTRIBUTE # -# ############################################# - -# - name: SWIM task - distribute stack -# cisco.dnac.swim_workflow_manager: -# <<: *dnac_login -# config: -# - "{{ item }}" -# loop: "{{ vars_map.image_distributation_details }}" -# register: result_distribute_stack - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_distribute_stack.results }}" - -# # - name: Assert distribution -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_distribute_stack.results }}" -# # when: result_distribute_stack is defined - -# ############################################# -# # ACTIVATE IMAGE # -# ############################################# - -# - name: SWIM task - activate -# cisco.dnac.swim_workflow_manager: -# <<: *dnac_login -# config: -# - "{{ item }}" -# loop: "{{ vars_map.image_activation_details }}" -# register: result_activate_image - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_activate_image.results }}" - -# # - name: Assert image activation -# # assert: -# # that: -# # - item.changed == true -# # loop: "{{ result_activate_image.results }}" -# # when: result_activate_image is defined - -# ############################################# -# # UNTAG IMAGE # -# ############################################# - -# - name: SWIM task - untag -# cisco.dnac.swim_workflow_manager: -# <<: *dnac_login -# config: -# - "{{ item }}" -# loop: "{{ vars_map.image_golden_untagging_details }}" -# register: result_untag_image - -# - name: Debug item -# debug: -# var: item -# loop: "{{ result_untag_image.results }}" - -# - name: Assert untag images -# assert: -# that: -# - item.changed == true -# - '"Untagging of image" in item.msg' -# - '"successful" in item.msg' -# loop: "{{ result_untag_image.results }}" -# when: result_untag_image is defined - -# ############################################# -# # Delete Devices # -# ############################################# - -# - name: Delete device -# cisco.dnac.inventory_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_devices }}" -# register: result_device_deleted - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_device_deleted.results }}" -# # when: result_device_deleted is defined - -# - name: Assert device deletion success -# assert: -# that: -# - result_device_deleted.changed == true -# when: result_device_deleted is defined - -# ############################################# -# # DELETE SITE # -# ############################################# - -# - name: Delete sites from design_sites config -# cisco.dnac.site_workflow_manager: -# <<: *dnac_login -# state: deleted -# config: -# - "{{ item }}" -# loop: "{{ vars_map.delete_sites }}" -# register: result_delete_site - -# # - name: Debug item -# # debug: -# # var: item -# # loop: "{{ result_delete_site.results }}" -# # when: result_delete_site is defined - -# - name: Assert deletion of area success for each site -# assert: -# that: -# - item.changed == true -# - "'deleted successfully' in item.response" -# loop: "{{ result_delete_site.results }}" -# when: result_delete_site is defined + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + - name: Delete site + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site + +############################################# +# CREATE SITE # +############################################# + + - name: Create sites + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.design_sites }}" + register: result_create_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_create_site.results }}" + # when: result_create_site is defined + + - name: Assert area creation success for each site + assert: + that: + - item.changed == true + - "'created successfully' in item.msg" + loop: "{{ result_create_site.results }}" + when: result_create_site is defined + +############################################# +# Add Devices # +############################################# + + - name: Add new device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_details }}" + register: result_add_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_add_device.results }}" + + - name: Assert device addition success + assert: + that: + - item.changed == true + - "'added to Cisco Catalyst Center' in item.msg" + loop: "{{ result_add_device.results }}" + when: result_add_device is defined + +############################################# +# ASSOCIATE WIRED DEVICE TO SITE # +############################################# + + - name: Assign wired device to site and then provision + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.associate_wired_device }}" + register: result_associate_device + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_associate_device.results }}" + # when: result_associate_device is defined + + - name: Assert Assign wired device to site and then provision + assert: + that: + - item.changed == true + loop: "{{ result_associate_device.results }}" + when: result_associate_device is defined + + +############################################# +# IMPORT IMAGE # +############################################# + + - name: SWIM task - import + cisco.dnac.swim_workflow_manager: + <<: *dnac_login + config: + - "{{ item }}" + loop: "{{ vars_map.image_details }}" + register: result_import_image + + - name: Debug item + debug: + var: item + loop: "{{ result_import_image.results }}" + + # - name: Assert import images + # assert: + # that: + # - item.changed == true + # - '"imported successfully" in item.msg' + # loop: "{{ result_import_image.results }}" + # when: result_import_image is defined + +############################################# +# TAG IMAGE # +############################################# + + - name: SWIM task - tag + cisco.dnac.swim_workflow_manager: + <<: *dnac_login + config: + - "{{ item }}" + loop: "{{ vars_map.image_golden_tagging_details}}" + register: result_tag_image + + - name: Debug item + debug: + var: item + loop: "{{ result_tag_image.results }}" + + - name: Assert tag images + assert: + that: + - item.changed == true + - '"Tagging image" in item.msg' + loop: "{{ result_tag_image.results }}" + when: result_tag_image is defined + +############################################# +# DISTRIBUTE # +############################################# + + - name: SWIM task - distribute stack + cisco.dnac.swim_workflow_manager: + <<: *dnac_login + config: + - "{{ item }}" + loop: "{{ vars_map.image_distributation_details }}" + register: result_distribute_stack + + - name: Debug item + debug: + var: item + loop: "{{ result_distribute_stack.results }}" + + # - name: Assert distribution + # assert: + # that: + # - item.changed == true + # loop: "{{ result_distribute_stack.results }}" + # when: result_distribute_stack is defined + +############################################# +# ACTIVATE IMAGE # +############################################# + + - name: SWIM task - activate + cisco.dnac.swim_workflow_manager: + <<: *dnac_login + config: + - "{{ item }}" + loop: "{{ vars_map.image_activation_details }}" + register: result_activate_image + + - name: Debug item + debug: + var: item + loop: "{{ result_activate_image.results }}" + + # - name: Assert image activation + # assert: + # that: + # - item.changed == true + # loop: "{{ result_activate_image.results }}" + # when: result_activate_image is defined + +############################################# +# UNTAG IMAGE # +############################################# + + - name: SWIM task - untag + cisco.dnac.swim_workflow_manager: + <<: *dnac_login + config: + - "{{ item }}" + loop: "{{ vars_map.image_golden_untagging_details }}" + register: result_untag_image + + - name: Debug item + debug: + var: item + loop: "{{ result_untag_image.results }}" + + - name: Assert untag images + assert: + that: + - item.changed == true + - '"Untagging of image" in item.msg' + - '"successful" in item.msg' + loop: "{{ result_untag_image.results }}" + when: result_untag_image is defined + +############################################# +# Delete Devices # +############################################# + + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_device_deleted.results }}" + # when: result_device_deleted is defined + + - name: Assert device deletion success + assert: + that: + - result_device_deleted.changed == true + when: result_device_deleted is defined + +############################################# +# DELETE SITE # +############################################# + + - name: Delete sites from design_sites config + cisco.dnac.site_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_sites }}" + register: result_delete_site + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_delete_site.results }}" + # when: result_delete_site is defined + + - name: Assert deletion of area success for each site + assert: + that: + - item.changed == true + - "'deleted successfully' in item.response" + loop: "{{ result_delete_site.results }}" + when: result_delete_site is defined diff --git a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml index 04198145ef..3d041cb266 100644 --- a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml +++ b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml @@ -48,13 +48,14 @@ image_golden_untagging_details: device_image_family_name: "Cisco Catalyst 9300 Switch" tagging: False + design_sites: # Create site to associate device to - site: area: name: ITest_Swim_Area parent_name: Global - type: area + site_type: area - site: building: name: ITest_Swim_Building @@ -63,7 +64,7 @@ design_sites: latitude: 12.969910 longitude: 77.597960 country: India - type: building + site_type: building - site: floor: name: ITest_Swim_Floor1 @@ -73,7 +74,7 @@ design_sites: length: 100.00 height: 10.00 floor_number: 1 - type: floor + site_type: floor device_details: @@ -113,58 +114,10 @@ delete_sites: area: name: ITest_Swim_Area parent_name: Global - type: area + site_type: area delete_devices: - ip_address_list: ["204.1.2.3"] #ip_address_list: ["204.1.2.5", "204.192.6.200"] - clean_config: False - -#http://172.21.236.183/swim/V1712_2_CCO/cat9k_iosxe.17.12.02.SPA.bin -#device_family_name: "Switches and Hubs" -#IMAGE FAMILY NAME "Cisco Catalyst 9300 Switch" -#device_series_name = -# - - -# --- -# image_details: -# - type: "remote" -# url_details: -# payload: -# - source_url: "http://172.21.236.183/swim/V1712_2_CCO/cat9k_iosxe.17.12.02.SPA.bin" -# is_third_party: false -# device_role: "ACCESS" -# image_name: cat9k_iosxe.17.12.02.SPA.bin -# # device_family_name: "Wireless Controller" -# device_family_name: "Switches and Hubs" - -# # device_type: "Cisco Catalyst 9800-40 Wireless Controller" -# device_image_family_name: "Cisco Catalyst 9300 Switch" -# site_name: "Global/USA/San Francisco/BGL_18" -# # site_name: "" -# # device_serial_number: "FJC2327U0S2" -# # Device with IP - 204.192.3.40 -# # device_serial_number: "FJC2721271T" -# # Device with IP - 204.192.3.40 - - -# # - type: "local" -# # local_image_details: -# # file_path: "/Users/abmahesh/Downloads/cat9k_iosxe.17.12.01.SPA.bin" -# # is_third_party: false -# # device_role: "ACCESS" -# # device_family_name: "Cisco Catalyst 9300 Switch" -# # device_serial_number: "FJC271924K0" -# # site_name: "Global/USA/San Francisco/BGL_18" - - -# # - type: "url" -# # urlDetails: -# # payload: -# # - sourceURL: "http://10.104.118.10/swim/17.12/C9800-SW-iosxe-wlc.BLD_POLARIS_DEV_LATEST_20230402_072041_V17_12_0_8.SSA.bin" -# # isThirdParty: false -# # device_role: "ALL" -# # device_family_name: "Cisco Catalyst 9800-40 Wireless Controller" -# # device_serial_number: "FOX2639PAY7" \ No newline at end of file + clean_config: False \ No newline at end of file From 4cce1baae1d7077fc107f4623eb4e6bbb51fdab8 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 18:05:15 -0400 Subject: [PATCH 236/358] pnp claim IT --- .circleci/config.yml | 6 +- .../tests/test_pnp_management.yml | 56 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 945cec1026..d60a3a9de9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -365,6 +365,6 @@ workflows: ansible_cisco_dnac_version: - "6.9.0" - - post_pnp_testing: - requires: - - sanity-tests + # - post_pnp_testing: + # requires: + # - sanity-tests diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml index b5638c1002..272dc91720 100644 --- a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml @@ -172,36 +172,36 @@ # Add and Claim PNP Device # ############################################# - - name: Add and Claim PnP devices - cisco.dnac.pnp_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.pnp_claim.cat9k }}" - register: result_claim_device - - - name: Debug Add and Claim device - debug: - var: item - loop: "{{ result_claim_device.results }}" - when: result_claim_device is defined - - - name: Assert Add and Claim device - assert: - that: - - item.changed == true - - "'Claimed Successfully' in item.msg" - loop: "{{ result_claim_device.results }}" - when: result_claim_device is defined +# - name: Add and Claim PnP devices +# cisco.dnac.pnp_workflow_manager: +# <<: *dnac_login +# state: merged +# config: +# - "{{ item }}" +# loop: "{{ vars_map.pnp_claim.cat9k }}" +# register: result_claim_device + +# - name: Debug Add and Claim device +# debug: +# var: item +# loop: "{{ result_claim_device.results }}" +# when: result_claim_device is defined + +# - name: Assert Add and Claim device +# assert: +# that: +# - item.changed == true +# - "'Claimed Successfully' in item.msg" +# loop: "{{ result_claim_device.results }}" +# when: result_claim_device is defined -############################################# -# Pause to Complete Provisioning # -############################################# +# ############################################# +# # Pause to Complete Provisioning # +# ############################################# - - name: Pause for 5 minutes - pause: - seconds: 300 +# - name: Pause for 5 minutes +# pause: +# seconds: 300 ############################################# # Delete Devices # From 8048112b230926b97639ae32c072f0f1a83dd650 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 18:50:02 -0400 Subject: [PATCH 237/358] modified run-all --- .circleci/config.yml | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 923ebb154a..860c733efe 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -155,51 +155,45 @@ jobs: steps: - when: - condition: << pipeline.parameters.run-site >> + condition: + - or: [ << pipeline.parameters.run-site >>, << pipeline.parameters.run-all >> ] steps: - run: command: | echo " - ccc_site_management" >> ccc_roles.yml - when: - condition: << pipeline.parameters.run-devicecredential >> + condition: + - or: [ << pipeline.parameters.run-devicecredential >>, << pipeline.parameters.run-all >> ] steps: - run: command: | echo " - ccc_device_credential_management" >> ccc_roles.yml - when: - condition: << pipeline.parameters.run-discovery >> + condition: + - or: [ << pipeline.parameters.run-discovery >>, << pipeline.parameters.run-all >> ] steps: - run: command: | echo " - ccc_discovery_management" >> ccc_roles.yml - when: - condition: << pipeline.parameters.run-inventory >> + condition: + - or: [ << pipeline.parameters.run-inventory >>, << pipeline.parameters.run-all >> ] steps: - run: command: | echo " - ccc_inventory_management" >> ccc_roles.yml - when: - condition: << pipeline.parameters.run-swim >> + condition: + - or: [ << pipeline.parameters.run-swim >>, << pipeline.parameters.run-all >> ] steps: - run: command: | echo " - ccc_swim_management" >> ccc_roles.yml - - when: - condition: << pipeline.parameters.run-all >> - steps: - - run: - command: | - echo " - ccc_site_management" >> ccc_roles.yml - echo " - ccc_device_credential_management" >> ccc_roles.yml - echo " - ccc_discovery_management" >> ccc_roles.yml - echo " - ccc_inventory_management" >> ccc_roles.yml - echo " - ccc_swim_management" >> ccc_roles.yml - - run: command: cat ccc_roles.yml From 458b8e76f5b69059f5a95cfd7c77c9374e8af804 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 19:03:08 -0400 Subject: [PATCH 238/358] modified run-all --- .circleci/config.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 860c733efe..1b6684fa83 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -156,7 +156,7 @@ jobs: steps: - when: condition: - - or: [ << pipeline.parameters.run-site >>, << pipeline.parameters.run-all >> ] + or: [ << pipeline.parameters.run-site >>, << pipeline.parameters.run-all >> ] steps: - run: command: | @@ -164,7 +164,7 @@ jobs: - when: condition: - - or: [ << pipeline.parameters.run-devicecredential >>, << pipeline.parameters.run-all >> ] + or: [ << pipeline.parameters.run-devicecredential >>, << pipeline.parameters.run-all >> ] steps: - run: command: | @@ -172,7 +172,7 @@ jobs: - when: condition: - - or: [ << pipeline.parameters.run-discovery >>, << pipeline.parameters.run-all >> ] + or: [ << pipeline.parameters.run-discovery >>, << pipeline.parameters.run-all >> ] steps: - run: command: | @@ -180,7 +180,7 @@ jobs: - when: condition: - - or: [ << pipeline.parameters.run-inventory >>, << pipeline.parameters.run-all >> ] + or: [ << pipeline.parameters.run-inventory >>, << pipeline.parameters.run-all >> ] steps: - run: command: | @@ -188,7 +188,7 @@ jobs: - when: condition: - - or: [ << pipeline.parameters.run-swim >>, << pipeline.parameters.run-all >> ] + or: [ << pipeline.parameters.run-swim >>, << pipeline.parameters.run-all >> ] steps: - run: command: | From 990ed7e9af8c7486d02cf1605849516734a3777b Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 19:07:22 -0400 Subject: [PATCH 239/358] final testing --- .../tests/test_assign_credentials.yml | 9 +++++---- .../tests/test_device_credential_management.yml | 1 + .../tests/test_discovery_management.yml | 1 + .../tests/test_inventory_management.yml | 1 + .../ccc_site_management/tests/test_site_management.yml | 1 + .../ccc_swim_management/tests/test_swim_management.yml | 1 + 6 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml index 3e76d3dae9..2e86b24f16 100755 --- a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml @@ -20,10 +20,11 @@ dnac_log_level: DEBUG config_verify: true - - debug: - msg: "{{ vars_map.credentials_details }}" - - debug: - msg: "{{ vars_map.design_sites }}" + # - debug: + # msg: "{{ vars_map.credentials_details }}" + # - debug: + # msg: "{{ vars_map.design_sites }}" + ############################################# # Pre Tests Clean Up # diff --git a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml index f4f9af6f3e..291032e421 100644 --- a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml @@ -25,6 +25,7 @@ # - debug: # msg: "{{ vars_map.credentials_update }}" + ############################################# # Pre Tests Clean Up # ############################################# diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml index 2663f741ac..a0833831d8 100644 --- a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml @@ -39,6 +39,7 @@ # - debug: # msg: "{{ vars_map.cidr }}" + ############################################# # Pre Tests Clean Up # ############################################# diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index b3aff6fdc5..cd9e719007 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -29,6 +29,7 @@ # - debug: # msg: "{{ vars_map.delete_devices }}" + ############################################# # Clean Up # ############################################# diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml index 6f703e4e70..f83b773195 100644 --- a/tests/integration/ccc_site_management/tests/test_site_management.yml +++ b/tests/integration/ccc_site_management/tests/test_site_management.yml @@ -27,6 +27,7 @@ # - debug: # msg: "{{ vars_map.delete_sites }}" + ############################################# # Clean Up # ############################################# diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml index 527cdff26b..99c5f1b490 100644 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -26,6 +26,7 @@ # - debug: # msg: "{{ vars_map. }}" + ############################################# # Clean Up # ############################################# From 26f6a1c7d07b16890213824c78bdfa8312fdaa56 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 19:36:08 -0400 Subject: [PATCH 240/358] final testing --- .circleci/config.yml | 2 ++ .../tests/test_discovery_management.yml | 1 - .../tests/test_inventory_management.yml | 1 - .../ccc_swim_management/tests/test_swim_management.yml | 1 - 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1b6684fa83..271b22c6b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -212,6 +212,8 @@ jobs: CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> CIRCLE_PROJECT_BRANCHNAME: << pipeline.trigger_parameters.github_app.branch >> + timeout: 90m + steps: - run: name: Debug information diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml index a0833831d8..2663f741ac 100644 --- a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml @@ -39,7 +39,6 @@ # - debug: # msg: "{{ vars_map.cidr }}" - ############################################# # Pre Tests Clean Up # ############################################# diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index cd9e719007..b3aff6fdc5 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -29,7 +29,6 @@ # - debug: # msg: "{{ vars_map.delete_devices }}" - ############################################# # Clean Up # ############################################# diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml index 99c5f1b490..527cdff26b 100644 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -26,7 +26,6 @@ # - debug: # msg: "{{ vars_map. }}" - ############################################# # Clean Up # ############################################# From 3906434a9e063f49648a6b4e1bd0e949533cebe3 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 19:42:58 -0400 Subject: [PATCH 241/358] final testing --- .circleci/config.yml | 2 ++ .../tests/test_discovery_management.yml | 1 + .../tests/test_inventory_management.yml | 1 + .../ccc_swim_management/tests/test_swim_management.yml | 1 + 4 files changed, 5 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 271b22c6b1..c931dfef92 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -274,6 +274,8 @@ jobs: ansible-playbook -i hosts ccc_roles.yml + no_output_timeout: 60m + - run: name: Remove Existing Directory command: | diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml index 2663f741ac..a0833831d8 100644 --- a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml @@ -39,6 +39,7 @@ # - debug: # msg: "{{ vars_map.cidr }}" + ############################################# # Pre Tests Clean Up # ############################################# diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index b3aff6fdc5..cd9e719007 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -29,6 +29,7 @@ # - debug: # msg: "{{ vars_map.delete_devices }}" + ############################################# # Clean Up # ############################################# diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml index 527cdff26b..99c5f1b490 100644 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -26,6 +26,7 @@ # - debug: # msg: "{{ vars_map. }}" + ############################################# # Clean Up # ############################################# From 812fedd52d14d822bc2e6036ad83336f02debc41 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 19:44:22 -0400 Subject: [PATCH 242/358] final testing --- .circleci/config.yml | 2 -- .../tests/test_assign_credentials.yml | 1 - .../tests/test_device_credential_management.yml | 1 - .../tests/test_discovery_management.yml | 1 - .../tests/test_inventory_management.yml | 1 - .../ccc_site_management/tests/test_site_management.yml | 1 - .../ccc_swim_management/tests/test_swim_management.yml | 1 - 7 files changed, 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c931dfef92..ebcc4d4bf7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -212,8 +212,6 @@ jobs: CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> CIRCLE_PROJECT_BRANCHNAME: << pipeline.trigger_parameters.github_app.branch >> - timeout: 90m - steps: - run: name: Debug information diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml index 2e86b24f16..5bc730ed29 100755 --- a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml @@ -25,7 +25,6 @@ # - debug: # msg: "{{ vars_map.design_sites }}" - ############################################# # Pre Tests Clean Up # ############################################# diff --git a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml index 291032e421..f4f9af6f3e 100644 --- a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml @@ -25,7 +25,6 @@ # - debug: # msg: "{{ vars_map.credentials_update }}" - ############################################# # Pre Tests Clean Up # ############################################# diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml index a0833831d8..2663f741ac 100644 --- a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml @@ -39,7 +39,6 @@ # - debug: # msg: "{{ vars_map.cidr }}" - ############################################# # Pre Tests Clean Up # ############################################# diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index cd9e719007..b3aff6fdc5 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -29,7 +29,6 @@ # - debug: # msg: "{{ vars_map.delete_devices }}" - ############################################# # Clean Up # ############################################# diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml index f83b773195..6f703e4e70 100644 --- a/tests/integration/ccc_site_management/tests/test_site_management.yml +++ b/tests/integration/ccc_site_management/tests/test_site_management.yml @@ -27,7 +27,6 @@ # - debug: # msg: "{{ vars_map.delete_sites }}" - ############################################# # Clean Up # ############################################# diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml index 99c5f1b490..527cdff26b 100644 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -26,7 +26,6 @@ # - debug: # msg: "{{ vars_map. }}" - ############################################# # Clean Up # ############################################# From f2392447da9cbd8e8fdf43d43089f8668fb02607 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 21:44:40 -0400 Subject: [PATCH 243/358] inventory bug test --- .circleci/config.yml | 2 +- .../vars/vars_discovery_management.yml | 19 ++++++++++++++++--- .../tests/test_inventory_management.yml | 5 ++--- .../tests/test_swim_management.yml | 2 +- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ebcc4d4bf7..9cd601122e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -270,7 +270,7 @@ jobs: export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 export ANSIBLE_ROLES_PATH=/home/circleci/repo/dnacenter-ansible/tests/integration - ansible-playbook -i hosts ccc_roles.yml + ansible-playbook -i hosts ccc_roles.yml -vvvv no_output_timeout: 60m diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index 577a50e0f1..2f71ad04fa 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -12,6 +12,8 @@ single_ip: snmp_v3_credential_list: - description: snmpV3 username: v3Public2 + retry: 1 + timeout: 2 ip_range: @@ -49,6 +51,8 @@ ip_range: start_index: 1 records_to_return: 1000 snmp_version: v2 + retry: 1 + timeout: 2 # Single IP Discovery an already existing discovery # Test case - deleted and recreated when discovery with same name @@ -58,6 +62,8 @@ ip_range: - 204.1.2.3 protocol_order: ssh global_cli_len: 3 + retry: 1 + timeout: 2 multi_range: @@ -88,6 +94,8 @@ multi_range: auth_password: Lablab#1234 privacy_type: AES256 privacy_password: Lablab#1234 + retry: 1 + timeout: 2 cdp: @@ -109,6 +117,8 @@ cdp: auth_password: Lablab#1234 privacy_type: AES256 privacy_password: Lablab#1234 + retry: 1 + timeout: 2 lldp: @@ -118,7 +128,6 @@ lldp: - 204.1.2.1 lldp_level: 16 protocol_order: ssh - discovery_specific_credentials: cli_credentials_list: - username: cisco @@ -130,7 +139,9 @@ lldp: auth_type: SHA auth_password: Lablab#1234 privacy_type: AES256 - privacy_password: Lablab#1234 + privacy_password: Lablab#1234 + retry: 1 + timeout: 2 cidr: @@ -140,7 +151,6 @@ cidr: - 204.1.2.0/24 prefix_length: 30 protocol_order: ssh - discovery_specific_credentials: cli_credentials_list: - username: cisco @@ -153,3 +163,6 @@ cidr: auth_password: Lablab#1234 privacy_type: AES256 privacy_password: Lablab#1234 + retry: 1 + timeout: 2 + diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index b3aff6fdc5..27f19c482d 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -40,7 +40,6 @@ config: - "{{ item }}" loop: "{{ vars_map.delete_devices }}" - register: result_device_deleted - name: Delete site cisco.dnac.site_workflow_manager: @@ -49,7 +48,6 @@ config: - "{{ item }}" loop: "{{ vars_map.delete_sites }}" - register: result_delete_site ############################################# # Add Devices # @@ -454,7 +452,8 @@ - name: Assert device deletion success assert: that: - - result_device_deleted.changed == true + - item.changed == true + loop: "{{ result_device_deleted.results }}" when: result_device_deleted is defined ############################################# diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml index 527cdff26b..883a5837cc 100644 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -179,7 +179,7 @@ when: result_tag_image is defined ############################################# -# DISTRIBUTE # +# DISTRIBUTE # ############################################# - name: SWIM task - distribute stack From 6936db1b0bb5c96dc8d3f503f040dcd0320e3646 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 21:48:38 -0400 Subject: [PATCH 244/358] test inventory bug --- .../tests/test_inventory_management.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index 27f19c482d..b6474433db 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -431,7 +431,7 @@ # when: result_associate_device is defined ############################################# -# Delete Devices # +# Delete Device # ############################################# - name: Delete device From 03860620be6b3851e7507716154edb43821f8b75 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 21:55:01 -0400 Subject: [PATCH 245/358] testing swim --- .../ccc_swim_management/tests/test_swim_management.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml index 883a5837cc..592773c6c1 100644 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -253,7 +253,7 @@ when: result_untag_image is defined ############################################# -# Delete Devices # +# Delete Device # ############################################# - name: Delete device From 002bb29448a4c93ff56cb0203b8010615af39151 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 22:04:02 -0400 Subject: [PATCH 246/358] final testing --- .circleci/config.yml | 4 ++-- .../vars/vars_discovery_management.yml | 4 ++-- .../tests/test_inventory_management.yml | 8 ++++++++ .../ccc_swim_management/tests/test_swim_management.yml | 8 ++++++++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9cd601122e..3d7e4547d3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -270,9 +270,9 @@ jobs: export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 export ANSIBLE_ROLES_PATH=/home/circleci/repo/dnacenter-ansible/tests/integration - ansible-playbook -i hosts ccc_roles.yml -vvvv + ansible-playbook -i hosts ccc_roles.yml - no_output_timeout: 60m + no_output_timeout: 120m - run: name: Remove Existing Directory diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index 2f71ad04fa..e11b3aff1a 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -54,8 +54,8 @@ ip_range: retry: 1 timeout: 2 - # Single IP Discovery an already existing discovery - # Test case - deleted and recreated when discovery with same name + # Single IP Discovery an already existing discovery. + # Test case - deleted and recreated when discovery with same name. - discovery_name: Single IP Discovery discovery_type: "RANGE" ip_address_list: diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index b6474433db..cf5b4fe3b9 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -456,6 +456,14 @@ loop: "{{ result_device_deleted.results }}" when: result_device_deleted is defined +############################################# +# PAUSE # +############################################# + + - name: Pause for 120 seconds + pause: + seconds: 120 + ############################################# # DELETE SITE # ############################################# diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml index 592773c6c1..f729fa02ca 100644 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -277,6 +277,14 @@ - result_device_deleted.changed == true when: result_device_deleted is defined +############################################# +# PAUSE # +############################################# + + - name: Pause for 120 seconds + pause: + seconds: 120 + ############################################# # DELETE SITE # ############################################# From 854254740aab03d46d32fcbd933369ee896045a2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 23:38:17 -0400 Subject: [PATCH 247/358] fixing sanity bugs --- .../vars/vars_discovery_management.yml | 2 -- .../vars/vars_inventory_management.yml | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index e11b3aff1a..ecb46ac6a8 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -47,7 +47,6 @@ ip_range: auth_password: Lablab#1234 privacy_type: AES256 privacy_password: Lablab#1234 - protocol_order: ssh start_index: 1 records_to_return: 1000 snmp_version: v2 @@ -165,4 +164,3 @@ cidr: privacy_password: Lablab#1234 retry: 1 timeout: 2 - diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 26c56ac68a..0b3aac8ab4 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -192,10 +192,10 @@ delete_udf: # User defined fields - ip_address_list: ["204.1.2.5"] add_user_defined_field: - - name: "Test123" + - name: "Test123" - ip_address_list: ["204.1.2.5"] add_user_defined_field: - - name: "Test321" + - name: "Test321" export_device_details: From 3829a7fd51f7b8c5b3c81ccb5d80bef9eae0005f Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 27 Mar 2024 23:47:29 -0400 Subject: [PATCH 248/358] sanity test bug fixes --- .../tests/test_assign_credentials.yml | 0 .../vars/vars_assign_credentials.yml | 0 tests/integration/ccc_discovery_management/vars/vars_misc.yml | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml mode change 100755 => 100644 tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml mode change 100755 => 100644 tests/integration/ccc_discovery_management/vars/vars_misc.yml diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml old mode 100755 new mode 100644 diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml old mode 100755 new mode 100644 diff --git a/tests/integration/ccc_discovery_management/vars/vars_misc.yml b/tests/integration/ccc_discovery_management/vars/vars_misc.yml old mode 100755 new mode 100644 From 0e62c4a494d81a4b56f6392638fd6beefafca122 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 00:05:09 -0400 Subject: [PATCH 249/358] changes to inventory IT post latet changes merge --- .../tests/test_inventory_management.yml | 30 +++++++++---------- .../vars/vars_inventory_management.yml | 18 +++-------- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index cf5b4fe3b9..983b61f938 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -135,14 +135,14 @@ # Update Device Role Detials # ############################################# - # - name: Update device role details - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_role_updates }}" - # register: result_update_device_role + - name: Update device role details + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_role_updates }}" + register: result_update_device_role # - name: Debug item # debug: @@ -150,13 +150,13 @@ # loop: "{{ result_update_device_role.results }}" # when: result_update_device_role is defined - # - name: Assert device role update - # assert: - # that: - # - result_update_device_role.changed == true - # - "'Device role was successfully updated' in item.response.progress" - # loop: "{{ result_update_device_role.results }}" - # when: result_update_device_role is defined + - name: Assert device role update + assert: + that: + - result_update_device_role.changed == true + - "'role updated successfully' in item.response.progress" + loop: "{{ result_update_device_role.results }}" + when: result_update_device_role is defined ############################################# # Update Device Interface Description # diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 0b3aac8ab4..59a93b0dcf 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -54,7 +54,6 @@ device_credential_updates: # Update CLI password - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True # CLI Credentials password: "Cisco#1234" @@ -63,7 +62,6 @@ device_credential_updates: # Update SNMP privacy type - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True # SNMP Credentials snmp_priv_protocol: "AES192" @@ -72,7 +70,6 @@ device_credential_updates: # Update SNMP username - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True # SNMP Credentials snmp_username: "v3Public2-2" @@ -81,7 +78,6 @@ device_credential_updates: # Update SNMP mode - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True # SNMP Credentials snmp_version: v3 @@ -90,7 +86,6 @@ device_credential_updates: # Update cli_transport - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True #change cli_transport from ssh to telnet cli_transport: telnet @@ -98,7 +93,6 @@ device_credential_updates: # SNMPv2 credentials - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True snmp_version: v2 snmp_ro_community: 'j5aj#0z%' @@ -107,7 +101,6 @@ device_credential_updates: # Reverse changes - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True # CLI Credentials username: "cisco" @@ -130,7 +123,6 @@ device_credential_updates: device_interface_updates: # Update Interface Details - ip_address_list: ["204.1.2.5"] - device_updated: True # Interface details update_interface_details: interface_name: ["GigabitEthernet1/0/8"] @@ -143,18 +135,16 @@ device_interface_updates: device_role_updates: #Update role from access to core - ip_address_list: ["204.1.2.5"] - device_updated: True - update_device_role: - role: CORE + role: CORE device_int_update_post_rolechange: # Update Interface description - ip_address_list: ["204.1.2.5"] - device_updated: True # Interface details - interface_name: ["GigabitEthernet1/0/23"] - description: "Testing for updating interface description post changing role" + update_interface_details: + interface_name: ["GigabitEthernet1/0/23"] + description: "Testing for updating interface description post changing role" device_resync: From 2f8dd6f8867a825e2b0f6b5e1c9fb932bf9574ed Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 00:07:08 -0400 Subject: [PATCH 250/358] reduced retry and timeout --- .../vars/vars_discovery_management.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index ecb46ac6a8..2675249da7 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -13,7 +13,7 @@ single_ip: - description: snmpV3 username: v3Public2 retry: 1 - timeout: 2 + timeout: 1 ip_range: @@ -62,7 +62,7 @@ ip_range: protocol_order: ssh global_cli_len: 3 retry: 1 - timeout: 2 + timeout: 1 multi_range: @@ -94,7 +94,7 @@ multi_range: privacy_type: AES256 privacy_password: Lablab#1234 retry: 1 - timeout: 2 + timeout: 1 cdp: @@ -117,7 +117,7 @@ cdp: privacy_type: AES256 privacy_password: Lablab#1234 retry: 1 - timeout: 2 + timeout: 1 lldp: @@ -140,7 +140,7 @@ lldp: privacy_type: AES256 privacy_password: Lablab#1234 retry: 1 - timeout: 2 + timeout: 1 cidr: @@ -163,4 +163,4 @@ cidr: privacy_type: AES256 privacy_password: Lablab#1234 retry: 1 - timeout: 2 + timeout: 1 From 5ffea393618e41cae378616f807d04c18d15f381 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 00:20:33 -0400 Subject: [PATCH 251/358] inventory IT changes --- .../ccc_inventory_management/vars/vars_inventory_management.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 59a93b0dcf..e18d865aa8 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -135,7 +135,7 @@ device_interface_updates: device_role_updates: #Update role from access to core - ip_address_list: ["204.1.2.5"] - role: CORE + role: ACCESS device_int_update_post_rolechange: From d8b5228bbfd664f25e91533286645bc367da8e78 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 00:23:52 -0400 Subject: [PATCH 252/358] inventory IT changes --- .../ccc_inventory_management/vars/vars_inventory_management.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index e18d865aa8..59a93b0dcf 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -135,7 +135,7 @@ device_interface_updates: device_role_updates: #Update role from access to core - ip_address_list: ["204.1.2.5"] - role: ACCESS + role: CORE device_int_update_post_rolechange: From e5f63e6d1c0c74f82c103441a3cca6f6fa03c2c7 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 00:29:33 -0400 Subject: [PATCH 253/358] inventory IT changes --- .../ccc_inventory_management/tests/test_inventory_management.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index 983b61f938..90b8948f8c 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -154,7 +154,6 @@ assert: that: - result_update_device_role.changed == true - - "'role updated successfully' in item.response.progress" loop: "{{ result_update_device_role.results }}" when: result_update_device_role is defined From 8b22c6eb2523a0a1986ea1fb1573ec6ea2cdf155 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 02:16:51 -0400 Subject: [PATCH 254/358] integration tests --- .../tests/test_inventory_management.yml | 3 ++- .../vars/vars_inventory_management.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index 90b8948f8c..cc2f61809f 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -153,7 +153,8 @@ - name: Assert device role update assert: that: - - result_update_device_role.changed == true + - item.changed == true + - "'role updated successfully' in item.response" loop: "{{ result_update_device_role.results }}" when: result_update_device_role is defined diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 59a93b0dcf..e18d865aa8 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -135,7 +135,7 @@ device_interface_updates: device_role_updates: #Update role from access to core - ip_address_list: ["204.1.2.5"] - role: CORE + role: ACCESS device_int_update_post_rolechange: From a454a7895f47706d8464814aa7951b5006747779 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 14:36:08 -0400 Subject: [PATCH 255/358] pnp test case added --- .circleci/config.yml | 40 +++----- .../tests/test_assign_credentials.yml | 4 +- .../tests/test_discovery_management.yml | 2 - .../vars/vars_discovery_management.yml | 23 +++-- .../tests/test_swim_management.yml | 96 +++++++++---------- .../vars/vars_swim_management.yml | 2 +- 6 files changed, 79 insertions(+), 88 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d60a3a9de9..5664e9116c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -158,60 +158,53 @@ jobs: steps: - when: - condition: << pipeline.parameters.run-site >> + condition: + or: [ << pipeline.parameters.run-site >>, << pipeline.parameters.run-all >> ] steps: - run: command: | echo " - ccc_site_management" >> ccc_roles.yml - when: - condition: << pipeline.parameters.run-devicecredential >> + condition: + or: [ << pipeline.parameters.run-devicecredential >>, << pipeline.parameters.run-all >> ] steps: - run: command: | echo " - ccc_device_credential_management" >> ccc_roles.yml - when: - condition: << pipeline.parameters.run-discovery >> + condition: + or: [ << pipeline.parameters.run-discovery >>, << pipeline.parameters.run-all >> ] steps: - run: command: | echo " - ccc_discovery_management" >> ccc_roles.yml - when: - condition: << pipeline.parameters.run-inventory >> + condition: + or: [ << pipeline.parameters.run-inventory >>, << pipeline.parameters.run-all >> ] steps: - run: command: | echo " - ccc_inventory_management" >> ccc_roles.yml - when: - condition: << pipeline.parameters.run-swim >> + condition: + or: [ << pipeline.parameters.run-swim >>, << pipeline.parameters.run-all >> ] steps: - run: command: | echo " - ccc_swim_management" >> ccc_roles.yml - when: - condition: << pipeline.parameters.run-pnp >> + condition: + or: [ << pipeline.parameters.run-pnp >>, << pipeline.parameters.run-all >> ] steps: - run: command: | echo " - ccc_pnp_management" >> ccc_roles.yml - - - when: - condition: << pipeline.parameters.run-all >> - steps: - - run: - command: | - echo " - ccc_site_management" >> ccc_roles.yml - echo " - ccc_device_credential_management" >> ccc_roles.yml - echo " - ccc_discovery_management" >> ccc_roles.yml - echo " - ccc_inventory_management" >> ccc_roles.yml - echo " - ccc_swim_management" >> ccc_roles.yml - echo " - ccc_pnp_management" >> ccc_roles.yml - - run: command: cat ccc_roles.yml @@ -288,7 +281,9 @@ jobs: export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 export ANSIBLE_ROLES_PATH=/home/circleci/repo/dnacenter-ansible/tests/integration - ansible-playbook -i hosts ccc_roles.yml + ansible-playbook -i hosts ccc_roles.yml + + no_output_timeout: 120m - run: name: Remove Existing Directory @@ -309,7 +304,6 @@ jobs: command: | python ${HOME}/static/pnp_script.py - workflows: pre-testing: @@ -364,7 +358,3 @@ workflows: parameters: ansible_cisco_dnac_version: - "6.9.0" - - # - post_pnp_testing: - # requires: - # - sanity-tests diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml index 1134875c7b..5bc730ed29 100755 --- a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml +++ b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml @@ -20,12 +20,10 @@ dnac_log_level: DEBUG config_verify: true - # - debug: - # msg: "{{ vars_map.design_sites }}" # - debug: # msg: "{{ vars_map.credentials_details }}" # - debug: - # msg: "{{ vars_map.credentials_assign }}" + # msg: "{{ vars_map.design_sites }}" ############################################# # Pre Tests Clean Up # diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml index b1b5019922..2663f741ac 100644 --- a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml @@ -38,8 +38,6 @@ # msg: "{{ vars_map.lldp }}" # - debug: # msg: "{{ vars_map.cidr }}" - # - debug: - # msg: "{{ vars_map_delete.delete_discoveries }}" ############################################# # Pre Tests Clean Up # diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index 577a50e0f1..2675249da7 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -12,6 +12,8 @@ single_ip: snmp_v3_credential_list: - description: snmpV3 username: v3Public2 + retry: 1 + timeout: 1 ip_range: @@ -45,19 +47,22 @@ ip_range: auth_password: Lablab#1234 privacy_type: AES256 privacy_password: Lablab#1234 - protocol_order: ssh start_index: 1 records_to_return: 1000 snmp_version: v2 + retry: 1 + timeout: 2 - # Single IP Discovery an already existing discovery - # Test case - deleted and recreated when discovery with same name + # Single IP Discovery an already existing discovery. + # Test case - deleted and recreated when discovery with same name. - discovery_name: Single IP Discovery discovery_type: "RANGE" ip_address_list: - 204.1.2.3 protocol_order: ssh global_cli_len: 3 + retry: 1 + timeout: 1 multi_range: @@ -88,6 +93,8 @@ multi_range: auth_password: Lablab#1234 privacy_type: AES256 privacy_password: Lablab#1234 + retry: 1 + timeout: 1 cdp: @@ -109,6 +116,8 @@ cdp: auth_password: Lablab#1234 privacy_type: AES256 privacy_password: Lablab#1234 + retry: 1 + timeout: 1 lldp: @@ -118,7 +127,6 @@ lldp: - 204.1.2.1 lldp_level: 16 protocol_order: ssh - discovery_specific_credentials: cli_credentials_list: - username: cisco @@ -130,7 +138,9 @@ lldp: auth_type: SHA auth_password: Lablab#1234 privacy_type: AES256 - privacy_password: Lablab#1234 + privacy_password: Lablab#1234 + retry: 1 + timeout: 1 cidr: @@ -140,7 +150,6 @@ cidr: - 204.1.2.0/24 prefix_length: 30 protocol_order: ssh - discovery_specific_credentials: cli_credentials_list: - username: cisco @@ -153,3 +162,5 @@ cidr: auth_password: Lablab#1234 privacy_type: AES256 privacy_password: Lablab#1234 + retry: 1 + timeout: 1 diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml index c85f9ec465..f729fa02ca 100644 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ b/tests/integration/ccc_swim_management/tests/test_swim_management.yml @@ -20,25 +20,11 @@ dnac_log_level: DEBUG # - debug: - # msg: "{{ vars_map.image_details }}" + # msg: "{{ vars_map. }}" # - debug: - # msg: "{{ vars_map.image_golden_tagging_details }}" + # msg: "{{ vars_map. }}" # - debug: - # msg: "{{ vars_map.image_distributation_details }}" - # - debug: - # msg: "{{ vars_map.image_activation_details }}" - # - debug: - # msg: "{{ vars_map.image_golden_untagging_details }}" - # - debug: - # msg: "{{ vars_map.design_sites }}" - # - debug: - # msg: "{{ vars_map.device_details }}" - # - debug: - # msg: "{{ vars_map.associate_wired_device }}" - # - debug: - # msg: "{{ vars_map.delete_sites }}" - # - debug: - # msg: "{{ vars_map.delete_devices }}" + # msg: "{{ vars_map. }}" ############################################# # Clean Up # @@ -154,10 +140,10 @@ loop: "{{ vars_map.image_details }}" register: result_import_image - - name: Debug item - debug: - var: item - loop: "{{ result_import_image.results }}" + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_import_image.results }}" # - name: Assert import images # assert: @@ -179,10 +165,10 @@ loop: "{{ vars_map.image_golden_tagging_details}}" register: result_tag_image - - name: Debug item - debug: - var: item - loop: "{{ result_tag_image.results }}" + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_tag_image.results }}" - name: Assert tag images assert: @@ -193,7 +179,7 @@ when: result_tag_image is defined ############################################# -# DISTRIBUTE # +# DISTRIBUTE # ############################################# - name: SWIM task - distribute stack @@ -204,17 +190,17 @@ loop: "{{ vars_map.image_distributation_details }}" register: result_distribute_stack - - name: Debug item - debug: - var: item - loop: "{{ result_distribute_stack.results }}" - - # - name: Assert distribution - # assert: - # that: - # - item.changed == true + # - name: Debug item + # debug: + # var: item # loop: "{{ result_distribute_stack.results }}" - # when: result_distribute_stack is defined + + - name: Assert distribution + assert: + that: + - item.changed == true + loop: "{{ result_distribute_stack.results }}" + when: result_distribute_stack is defined ############################################# # ACTIVATE IMAGE # @@ -228,17 +214,17 @@ loop: "{{ vars_map.image_activation_details }}" register: result_activate_image - - name: Debug item - debug: - var: item - loop: "{{ result_activate_image.results }}" - - # - name: Assert image activation - # assert: - # that: - # - item.changed == true + # - name: Debug item + # debug: + # var: item # loop: "{{ result_activate_image.results }}" - # when: result_activate_image is defined + + - name: Assert image activation + assert: + that: + - item.changed == true + loop: "{{ result_activate_image.results }}" + when: result_activate_image is defined ############################################# # UNTAG IMAGE # @@ -252,10 +238,10 @@ loop: "{{ vars_map.image_golden_untagging_details }}" register: result_untag_image - - name: Debug item - debug: - var: item - loop: "{{ result_untag_image.results }}" + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_untag_image.results }}" - name: Assert untag images assert: @@ -267,7 +253,7 @@ when: result_untag_image is defined ############################################# -# Delete Devices # +# Delete Device # ############################################# - name: Delete device @@ -291,6 +277,14 @@ - result_device_deleted.changed == true when: result_device_deleted is defined +############################################# +# PAUSE # +############################################# + + - name: Pause for 120 seconds + pause: + seconds: 120 + ############################################# # DELETE SITE # ############################################# diff --git a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml index 3d041cb266..acc69524a0 100644 --- a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml +++ b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml @@ -120,4 +120,4 @@ delete_sites: delete_devices: - ip_address_list: ["204.1.2.3"] #ip_address_list: ["204.1.2.5", "204.192.6.200"] - clean_config: False \ No newline at end of file + clean_config: False From 5df1c0f294bb2c5fc9aabd8c868f22238781101a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 14:36:31 -0400 Subject: [PATCH 256/358] added pnp ITs --- .../tests/test_inventory_management.yml | 59 ++--- .../vars/vars_inventory_management.yml | 22 +- .../tests/test_pnp_management.yml | 248 +++++++++--------- .../vars/vars_pnp_management.yml | 1 + 4 files changed, 151 insertions(+), 179 deletions(-) diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml index c091a35200..121a208c83 100644 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml @@ -27,30 +27,6 @@ # - debug: # msg: "{{ vars_map.device_interface_updates }}" # - debug: - # msg: "{{ vars_map.device_role_updates }}" - # - debug: - # msg: "{{ vars_map.device_int_update_post_rolechange }}" - # - debug: - # msg: "{{ vars_map.device_resync }}" - # - debug: - # msg: "{{ vars_map.create_assign_udf }}" - # - debug: - # msg: "{{ vars_map.update_udf }}" - # - debug: - # msg: "{{ vars_map.delete_udf }}" - # - debug: - # msg: "{{ vars_map.export_device_details }}" - # - debug: - # msg: "{{ vars_map.export_credential_details }}" - # - debug: - # msg: "{{ vars_map.design_sites }}" - # - debug: - # msg: "{{ vars_map.associate_wired_device }}" - # - debug: - # msg: "{{ vars_map.associate_wireless_device }}" - # - debug: - # msg: "{{ vars_map.delete_sites }}" - # - debug: # msg: "{{ vars_map.delete_devices }}" ############################################# @@ -64,7 +40,6 @@ config: - "{{ item }}" loop: "{{ vars_map.delete_devices }}" - register: result_device_deleted - name: Delete site cisco.dnac.site_workflow_manager: @@ -73,7 +48,6 @@ config: - "{{ item }}" loop: "{{ vars_map.delete_sites }}" - register: result_delete_site ############################################# # Add Devices # @@ -161,14 +135,14 @@ # Update Device Role Detials # ############################################# - # - name: Update device role details - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_role_updates }}" - # register: result_update_device_role + - name: Update device role details + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.device_role_updates }}" + register: result_update_device_role # - name: Debug item # debug: @@ -179,8 +153,8 @@ # - name: Assert device role update # assert: # that: - # - result_update_device_role.changed == true - # - "'Device role was successfully updated' in item.response.progress" + # - item.changed == true + # - "'role updated successfully' in item.response" # loop: "{{ result_update_device_role.results }}" # when: result_update_device_role is defined @@ -457,7 +431,7 @@ # when: result_associate_device is defined ############################################# -# Delete Devices # +# Delete Device # ############################################# - name: Delete device @@ -478,9 +452,18 @@ - name: Assert device deletion success assert: that: - - result_device_deleted.changed == true + - item.changed == true + loop: "{{ result_device_deleted.results }}" when: result_device_deleted is defined +############################################# +# PAUSE # +############################################# + + - name: Pause for 120 seconds + pause: + seconds: 120 + ############################################# # DELETE SITE # ############################################# diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml index 26c56ac68a..e18d865aa8 100644 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml @@ -54,7 +54,6 @@ device_credential_updates: # Update CLI password - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True # CLI Credentials password: "Cisco#1234" @@ -63,7 +62,6 @@ device_credential_updates: # Update SNMP privacy type - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True # SNMP Credentials snmp_priv_protocol: "AES192" @@ -72,7 +70,6 @@ device_credential_updates: # Update SNMP username - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True # SNMP Credentials snmp_username: "v3Public2-2" @@ -81,7 +78,6 @@ device_credential_updates: # Update SNMP mode - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True # SNMP Credentials snmp_version: v3 @@ -90,7 +86,6 @@ device_credential_updates: # Update cli_transport - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True #change cli_transport from ssh to telnet cli_transport: telnet @@ -98,7 +93,6 @@ device_credential_updates: # SNMPv2 credentials - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True snmp_version: v2 snmp_ro_community: 'j5aj#0z%' @@ -107,7 +101,6 @@ device_credential_updates: # Reverse changes - type: "NETWORK_DEVICE" ip_address_list: ["204.1.2.5"] - device_updated: True credential_update: True # CLI Credentials username: "cisco" @@ -130,7 +123,6 @@ device_credential_updates: device_interface_updates: # Update Interface Details - ip_address_list: ["204.1.2.5"] - device_updated: True # Interface details update_interface_details: interface_name: ["GigabitEthernet1/0/8"] @@ -143,18 +135,16 @@ device_interface_updates: device_role_updates: #Update role from access to core - ip_address_list: ["204.1.2.5"] - device_updated: True - update_device_role: - role: CORE + role: ACCESS device_int_update_post_rolechange: # Update Interface description - ip_address_list: ["204.1.2.5"] - device_updated: True # Interface details - interface_name: ["GigabitEthernet1/0/23"] - description: "Testing for updating interface description post changing role" + update_interface_details: + interface_name: ["GigabitEthernet1/0/23"] + description: "Testing for updating interface description post changing role" device_resync: @@ -192,10 +182,10 @@ delete_udf: # User defined fields - ip_address_list: ["204.1.2.5"] add_user_defined_field: - - name: "Test123" + - name: "Test123" - ip_address_list: ["204.1.2.5"] add_user_defined_field: - - name: "Test321" + - name: "Test321" export_device_details: diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml index 272dc91720..ed1d644b09 100644 --- a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml @@ -34,23 +34,23 @@ # Clean Up # ############################################# - # - name: Delete PnP devices - # cisco.dnac.pnp_workflow_manager: - # <<: *dnac_login - # state: deleted - # config: - # - "{{ item }}" - # loop: "{{ vars_map.pnp_delete.delete }}" - - # - name: Delete PnP devices - # cisco.dnac.pnp_workflow_manager: - # <<: *dnac_login - # state: deleted - # config: - # - "{{ item }}" - # loop: "{{ vars_map.bulk.add }}" + - name: Delete PnP devices + cisco.dnac.pnp_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.pnp_delete.delete }}" - - name: Delete device + - name: Delete PnP devices + cisco.dnac.pnp_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.bulk.add }}" + + - name: Delete device from Inventory cisco.dnac.inventory_workflow_manager: <<: *dnac_login state: deleted @@ -62,14 +62,14 @@ # Add device but not Claim PNP Device # ############################################# - # - name: Adding devices but not claiming - # cisco.dnac.pnp_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.pnp_delete.add }}" - # register: result_add_device + - name: Adding devices but not claiming + cisco.dnac.pnp_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.pnp_delete.add }}" + register: result_add_device # - name: Debug Adding devices but not claiming # debug: @@ -77,26 +77,26 @@ # loop: "{{ result_add_device.results }}" # when: result_add_device is defined - # - name: Assert adding devices but not claiming - # assert: - # that: - # - item.changed == true - # - "'Only Device Added Successfully' in item.msg" - # loop: "{{ result_add_device.results }}" - # when: result_add_device is defined + - name: Assert adding devices but not claiming + assert: + that: + - item.changed == true + - "'Only Device Added Successfully' in item.msg" + loop: "{{ result_add_device.results }}" + when: result_add_device is defined ############################################# # Delete Unclaimed Devices # ############################################# - # - name: Delete PnP devices - # cisco.dnac.pnp_workflow_manager: - # <<: *dnac_login - # state: deleted - # config: - # - "{{ item }}" - # loop: "{{ vars_map.pnp_delete.delete }}" - # register: result_delete_device + - name: Delete PnP devices + cisco.dnac.pnp_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.pnp_delete.delete }}" + register: result_delete_device # - name: Debug delete unclaimed devices # debug: @@ -104,27 +104,26 @@ # loop: "{{ result_delete_device.results }}" # when: result_delete_device is defined - # - name: Assert deletion of unclaimed PnP devices - # assert: - # that: - # - item.changed == true - # - "'Deleted Successfully' in item.msg" - # loop: "{{ result_delete_device.results }}" - # when: result_delete_device is defined - + - name: Assert deletion of unclaimed PnP devices + assert: + that: + - item.changed == true + - "'Deleted Successfully' in item.msg" + loop: "{{ result_delete_device.results }}" + when: result_delete_device is defined ############################################# # Bulk Add device but not Claim PNP Device # ############################################# - # - name: Bulk Adding devices but not claiming - # cisco.dnac.pnp_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.bulk.add }}" - # register: result_add_device + - name: Bulk Adding devices but not claiming + cisco.dnac.pnp_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.bulk.add }}" + register: result_add_device # - name: Debug Bulk Adding devices but not claiming # debug: @@ -132,26 +131,26 @@ # loop: "{{ result_add_device.results }}" # when: result_add_device is defined - # - name: Assert bulk adding devices but not claiming - # assert: - # that: - # - item.changed == true - # - "'imported successfully' in item.msg" - # loop: "{{ result_add_device.results }}" - # when: result_add_device is defined + - name: Assert bulk adding devices but not claiming + assert: + that: + - item.changed == true + - "'imported successfully' in item.msg" + loop: "{{ result_add_device.results }}" + when: result_add_device is defined ############################################# # Bulk Delete Unclaimed Devices # ############################################# - # - name: Delete Bulk Unclaimed PnP devices - # cisco.dnac.pnp_workflow_manager: - # <<: *dnac_login - # state: deleted - # config: - # - "{{ item }}" - # loop: "{{ vars_map.bulk.add }}" - # register: result_delete_device + - name: Delete Bulk Unclaimed PnP devices + cisco.dnac.pnp_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.bulk.add }}" + register: result_delete_device # - name: Debug Bulk delete unclaimed devices # debug: @@ -159,71 +158,70 @@ # loop: "{{ result_delete_device.results }}" # when: result_delete_device is defined - # - name: Assert Bulk deletion of unclaimed PnP devices - # assert: - # that: - # - item.changed == true - # - "'Deleted Successfully' in item.msg" - # loop: "{{ result_delete_device.results }}" - # when: result_delete_device is defined - + - name: Assert Bulk deletion of unclaimed PnP devices + assert: + that: + - item.changed == true + - "'Deleted Successfully' in item.msg" + loop: "{{ result_delete_device.results }}" + when: result_delete_device is defined ############################################# # Add and Claim PNP Device # ############################################# -# - name: Add and Claim PnP devices -# cisco.dnac.pnp_workflow_manager: -# <<: *dnac_login -# state: merged -# config: -# - "{{ item }}" -# loop: "{{ vars_map.pnp_claim.cat9k }}" -# register: result_claim_device - -# - name: Debug Add and Claim device -# debug: -# var: item -# loop: "{{ result_claim_device.results }}" -# when: result_claim_device is defined - -# - name: Assert Add and Claim device -# assert: -# that: -# - item.changed == true -# - "'Claimed Successfully' in item.msg" -# loop: "{{ result_claim_device.results }}" -# when: result_claim_device is defined + - name: Add and Claim PnP devices + cisco.dnac.pnp_workflow_manager: + <<: *dnac_login + state: merged + config: + - "{{ item }}" + loop: "{{ vars_map.pnp_claim.cat9k }}" + register: result_claim_device + + # - name: Debug Add and Claim device + # debug: + # var: item + # loop: "{{ result_claim_device.results }}" + # when: result_claim_device is defined + + - name: Assert Add and Claim device + assert: + that: + - item.changed == true + - "'Claimed Successfully' in item.msg" + loop: "{{ result_claim_device.results }}" + when: result_claim_device is defined -# ############################################# -# # Pause to Complete Provisioning # -# ############################################# +############################################# +# Pause to Complete Provisioning # +############################################# -# - name: Pause for 5 minutes -# pause: -# seconds: 300 + - name: Pause for 6 minutes + pause: + seconds: 360 ############################################# # Delete Devices # ############################################# - # - name: Delete device - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: deleted - # config: - # - "{{ item }}" - # loop: "{{ vars_map.delete_devices }}" - # register: result_device_deleted - - # # - name: Debug item - # # debug: - # # var: item - # # loop: "{{ result_device_deleted.results }}" - # # when: result_device_deleted is defined - - # - name: Assert device deletion success - # assert: - # that: - # - result_device_deleted.changed == true + - name: Delete device + cisco.dnac.inventory_workflow_manager: + <<: *dnac_login + state: deleted + config: + - "{{ item }}" + loop: "{{ vars_map.delete_devices }}" + register: result_device_deleted + + # - name: Debug item + # debug: + # var: item + # loop: "{{ result_device_deleted.results }}" # when: result_device_deleted is defined + + - name: Assert device deletion success + assert: + that: + - result_device_deleted.changed == true + when: result_device_deleted is defined diff --git a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml index b4ea491383..40708dcf32 100644 --- a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml @@ -14,6 +14,7 @@ pnp_delete: state: Unclaimed pid: C9300-48T + pnp_claim: cat9k: - device_info: From cddeaf0efe95247dd9be6eee46a4a9d03bc3b0bf Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 14:46:24 -0400 Subject: [PATCH 257/358] pnp ITs --- .circleci/config.yml | 3 +++ .../ccc_pnp_management/tests/test_pnp_management.yml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5664e9116c..c88949f3af 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -358,3 +358,6 @@ workflows: parameters: ansible_cisco_dnac_version: - "6.9.0" + - post_pnp_testing: + requires: + - sanity-tests diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml index ed1d644b09..7e18e2bdfb 100644 --- a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml @@ -202,7 +202,7 @@ seconds: 360 ############################################# -# Delete Devices # +# Delete Devicec # ############################################# - name: Delete device From 0d3fd53fb3fd497e1f8353553996149a3d47927c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 14:49:31 -0400 Subject: [PATCH 258/358] pnp ITs --- .circleci/config.yml | 4 ++-- .../ccc_pnp_management/tests/test_pnp_management.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c88949f3af..36b28857f7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -359,5 +359,5 @@ workflows: ansible_cisco_dnac_version: - "6.9.0" - post_pnp_testing: - requires: - - sanity-tests + requires: + - sanity-tests diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml index 7e18e2bdfb..ed1d644b09 100644 --- a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml @@ -202,7 +202,7 @@ seconds: 360 ############################################# -# Delete Devicec # +# Delete Devices # ############################################# - name: Delete device From e61034b5c1e1f818cc4cc4c1336e019bb03a2b09 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 18:27:31 -0400 Subject: [PATCH 259/358] commented pnp test --- .circleci/config.yml | 6 +- .../tests/test_pnp_management.yml | 76 +++++++++---------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 36b28857f7..63d15297a5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -358,6 +358,6 @@ workflows: parameters: ansible_cisco_dnac_version: - "6.9.0" - - post_pnp_testing: - requires: - - sanity-tests + # - post_pnp_testing: + # requires: + # - sanity-tests diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml index ed1d644b09..6367523a43 100644 --- a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml @@ -50,13 +50,13 @@ - "{{ item }}" loop: "{{ vars_map.bulk.add }}" - - name: Delete device from Inventory - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_devices }}" + # - name: Delete device from Inventory + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: deleted + # config: + # - "{{ item }}" + # loop: "{{ vars_map.delete_devices }}" ############################################# # Add device but not Claim PNP Device # @@ -170,14 +170,14 @@ # Add and Claim PNP Device # ############################################# - - name: Add and Claim PnP devices - cisco.dnac.pnp_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.pnp_claim.cat9k }}" - register: result_claim_device + # - name: Add and Claim PnP devices + # cisco.dnac.pnp_workflow_manager: + # <<: *dnac_login + # state: merged + # config: + # - "{{ item }}" + # loop: "{{ vars_map.pnp_claim.cat9k }}" + # register: result_claim_device # - name: Debug Add and Claim device # debug: @@ -185,34 +185,34 @@ # loop: "{{ result_claim_device.results }}" # when: result_claim_device is defined - - name: Assert Add and Claim device - assert: - that: - - item.changed == true - - "'Claimed Successfully' in item.msg" - loop: "{{ result_claim_device.results }}" - when: result_claim_device is defined + # - name: Assert Add and Claim device + # assert: + # that: + # - item.changed == true + # - "'Claimed Successfully' in item.msg" + # loop: "{{ result_claim_device.results }}" + # when: result_claim_device is defined ############################################# # Pause to Complete Provisioning # ############################################# - - name: Pause for 6 minutes - pause: - seconds: 360 + # - name: Pause for 10 minutes + # pause: + # seconds: 600 ############################################# # Delete Devices # ############################################# - - name: Delete device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_devices }}" - register: result_device_deleted + # - name: Delete device + # cisco.dnac.inventory_workflow_manager: + # <<: *dnac_login + # state: deleted + # config: + # - "{{ item }}" + # loop: "{{ vars_map.delete_devices }}" + # register: result_device_deleted # - name: Debug item # debug: @@ -220,8 +220,8 @@ # loop: "{{ result_device_deleted.results }}" # when: result_device_deleted is defined - - name: Assert device deletion success - assert: - that: - - result_device_deleted.changed == true - when: result_device_deleted is defined + # - name: Assert device deletion success + # assert: + # that: + # - result_device_deleted.changed == true + # when: result_device_deleted is defined From dc01220ed230356afd780387c5f5db5047b2827a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 28 Mar 2024 18:29:43 -0400 Subject: [PATCH 260/358] commented pnp test --- .../integration/ccc_pnp_management/tests/test_pnp_management.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml index 6367523a43..2fa02a6b51 100644 --- a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml +++ b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml @@ -20,7 +20,6 @@ dnac_log_level: DEBUG config_verify: true - # - debug: # msg: "{{ vars_map.pnp_delete }}" # - debug: From b68cd8f4b38ee834072319d5a9ee77105a92863b Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 8 Apr 2024 16:23:27 -0400 Subject: [PATCH 261/358] reduced the number of ip range to 7 in discovery IT --- .../ccc_discovery_management/vars/vars_discovery_management.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index 2675249da7..55623c1f89 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -76,8 +76,6 @@ multi_range: - 204.1.2.7 - 204.1.2.8 - 204.1.2.9 - - 204.1.2.10 - - 204.1.2.11 ip_filter_list: - 204.1.2.3 protocol_order: ssh From e1140742b92629f5906c6cf270af12e7e90ce03d Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 10 Apr 2024 17:00:26 +0530 Subject: [PATCH 262/358] Added a new feature on reserved pool (Accessing using the name of the global pool) --- .../network_settings_workflow_manager.yml | 20 +- .../network_settings_workflow_manager.py | 1097 ++++++++++------- 2 files changed, 663 insertions(+), 454 deletions(-) diff --git a/playbooks/network_settings_workflow_manager.yml b/playbooks/network_settings_workflow_manager.yml index 36b88ac2db..c98b9e1495 100644 --- a/playbooks/network_settings_workflow_manager.yml +++ b/playbooks/network_settings_workflow_manager.yml @@ -17,7 +17,7 @@ dnac_log_append: True dnac_log_file_path: "{{ dnac_log_file_path }}" state: merged - config_verify: True + # config_verify: True config: - global_pool_details: settings: @@ -30,18 +30,28 @@ dhcp_server_ips: [] #use this for updating dns_server_ips: [] #use this for updating # prev_name: Global_Pool2 + - name: Global_Pool3 + gateway: '' #use this for updating + ip_address_space: IPv4 #required when we are creating + cidr: 10.0.0.0/8 #required when we are creating + pool_type: Generic + dhcp_server_ips: [] #use this for updating + dns_server_ips: [] #use this for updating + # prev_name: Global_Pool2 reserve_pool_details: - ipv6_address_space: True - ipv4_global_pool: 100.0.0.0/8 + - ipv6_address_space: True + # ipv4_global_pool: 100.0.0.0/8 + ipv4_global_pool_name: Global_Pool1 ipv4_prefix: True ipv4_prefix_length: 9 ipv4_subnet: 100.128.0.0 ipv4_gateway: 100.128.0.1 - # ipv4_dns_servers: [100.128.0.1] + ipv4_dns_servers: [] name: IP_Pool_3 ipv6_prefix: True ipv6_prefix_length: 64 ipv6_global_pool: 2001:db8::/64 + # ipv6_global_pool_name: Global_Pool2 ipv6_subnet: '2001:db8::' site_name: Global/Chennai/Trill slaac_support: True @@ -104,5 +114,5 @@ ip_pool: - name: Global_Pool2 reserve_pool_details: - name: IP_Pool_3 + - name: IP_Pool_3 site_name: Global/Chennai/Trill diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index 71fb089428..a411071922 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -112,8 +112,16 @@ type: str version_added: 4.0.0 ipv4_global_pool: - description: IP v4 Global pool address with cidr, example 175.175.0.0/16. + description: + - IP v4 Global pool address with cidr, example 175.175.0.0/16. + - If both 'ipv6_global_pool' and 'ipv4_global_pool_name' are provided, the 'ipv4_global_pool' will be given priority. type: str + ipv4_global_pool_name: + description: + - Specifies the name assigned to the Ip v4 Global IP Pool. + - If both 'ipv4_global_pool' and 'ipv4_global_pool_name' are provided, the 'ipv4_global_pool' will be given priority. + type: str + version_added: 6.14.0 ipv4_prefix: description: ip4 prefix length is enabled or ipv4 total Host input is enabled type: bool @@ -150,10 +158,16 @@ For example, "2001:0db8:0123:4567:89ab:cdef:0003:0003". type: str ipv6_global_pool: - description: > - IPv6 Global pool address with cidr this is required when ipv6_address_space - value is true, example 2001 db8 85a3 /64. + description: + - IPv6 Global pool address with cidr this is required when ipv6_address_space value is true, example 2001 db8 85a3 /64. + - If both 'ipv6_global_pool' and 'ipv6_global_pool_name' are provided, the 'ipv6_global_pool' will be given priority. type: str + ipv6_global_pool_name: + description: + - Specifies the name assigned to the Ip v6 Global IP Pool. + - If both 'ipv6_global_pool' and 'ipv6_global_pool_name' are provided, the 'ipv6_global_pool' will be given priority. + type: str + version_added: 6.14.0 ipv6_prefix: description: > Ipv6 prefix value is true, the ip6 prefix length input field is enabled, @@ -163,7 +177,7 @@ description: IPv6 prefix length is required when the ipv6_prefix value is true. type: int ipv6_subnet: - description: IPv6 Subnet address, example 2001 db8 85a3 0 100. + description: IPv6 Subnet address, example 2001:db8:85a3:0:100. type: str ipv6_total_host: description: The total number of hosts for IPv6 is required if the 'ipv6_prefix' is set to false. @@ -341,7 +355,7 @@ """ EXAMPLES = r""" -- name: Create global pool, reserve an ip pool and network +- name: Create global pool cisco.dnac.network_settings_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -365,8 +379,23 @@ pool_type: Generic dhcp_server_ips: list dns_server_ips: list - reserve_pool_details: - ipv6_address_space: True + +- name: Create reserve an ip pool + cisco.dnac.network_settings_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + state: merged + config_verify: True + config: + - reserve_pool_details: + - ipv6_address_space: True ipv4_global_pool: string ipv4_prefix: True ipv4_prefix_length: 9 @@ -379,7 +408,69 @@ site_name: string slaac_support: True pool_type: LAN - network_management_details: + +- name: Create reserve an ip pool using global pool name + cisco.dnac.network_settings_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + state: merged + config_verify: True + config: + - reserve_pool_details: + - ipv6_address_space: True + ipv4_global_pool_name: string + ipv4_prefix: True + ipv4_prefix_length: 9 + ipv4_subnet: string + name: string + ipv6_prefix: True + ipv6_prefix_length: 64 + ipv6_global_pool_name: string + ipv6_subnet: string + site_name: string + slaac_support: True + pool_type: LAN + +- name: Delete reserved pool + cisco.dnac.network_settings_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + state: deleted + config_verify: True + config: + - reserve_pool_details: + - name: string + site_name: string + +- name: Manage the network functions + cisco.dnac.network_settings_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + state: merged + config_verify: True + config: + - network_management_details: settings: dhcp_server: list dns_server: @@ -499,6 +590,7 @@ def validate_input(self): "type": 'dict', "ip_pool": { "type": 'list', + "elements": 'dict', "ip_address_space": {"type": 'string'}, "dhcp_server_ips": {"type": 'list'}, "dns_server_ips": {"type": 'list'}, @@ -511,7 +603,8 @@ def validate_input(self): } }, "reserve_pool_details": { - "type": 'dict', + "type": 'list', + "elements": 'dict', "name": {"type": 'string'}, "prev_name": {"type": 'string'}, "ipv6_address_space": {"type": 'bool'}, @@ -653,7 +746,10 @@ def get_obj_params(self, get_object): try: if get_object == "GlobalPool": obj_params = [ - ("settings", "settings"), + ("IpAddressSpace", "IpAddressSpace"), + ("dhcpServerIps", "dhcpServerIps"), + ("dnsServerIps", "dnsServerIps"), + ("gateway", "gateway"), ] elif get_object == "ReservePool": obj_params = [ @@ -737,28 +833,24 @@ def get_global_pool_params(self, pool_info): self.log("Global Pool Details: {0}".format(pool_info), "DEBUG") global_pool = { - "settings": { - "ippool": [{ - "dhcpServerIps": pool_info.get("dhcpServerIps"), - "dnsServerIps": pool_info.get("dnsServerIps"), - "ipPoolCidr": pool_info.get("ipPoolCidr"), - "ipPoolName": pool_info.get("ipPoolName"), - "type": pool_info.get("ipPoolType").capitalize() - }] - } + "dhcpServerIps": pool_info.get("dhcpServerIps"), + "dnsServerIps": pool_info.get("dnsServerIps"), + "ipPoolCidr": pool_info.get("ipPoolCidr"), + "ipPoolName": pool_info.get("ipPoolName"), + "type": pool_info.get("ipPoolType").capitalize() } self.log("Formated global pool details: {0}".format(global_pool), "DEBUG") - global_ippool = global_pool.get("settings").get("ippool")[0] + # global_ippool = global_pool.get("settings").get("ippool")[0] if pool_info.get("ipv6") is False: - global_ippool.update({"IpAddressSpace": "IPv4"}) + global_pool.update({"IpAddressSpace": "IPv4"}) else: - global_ippool.update({"IpAddressSpace": "IPv6"}) + global_pool.update({"IpAddressSpace": "IPv6"}) - self.log("ip_address_space: {0}".format(global_ippool.get("IpAddressSpace")), "DEBUG") + self.log("ip_address_space: {0}".format(global_pool.get("IpAddressSpace")), "DEBUG") if not pool_info["gateways"]: - global_ippool.update({"gateway": ""}) + global_pool.update({"gateway": ""}) else: - global_ippool.update({"gateway": pool_info.get("gateways")[0]}) + global_pool.update({"gateway": pool_info.get("gateways")[0]}) return global_pool @@ -1017,11 +1109,12 @@ def global_pool_exists(self, name): self.log("Global ip pool name: {0}".format(name), "DEBUG") self.log("Global pool details: {0}".format(global_pool_details), "DEBUG") if not global_pool_details: - self.log("Global pool {0} does not exist".format(name), "INFO") + self.log("Global pool '{0}' does not exist".format(name), "INFO") return global_pool global_pool.update({"exists": True}) global_pool.update({"id": global_pool_details.get("id")}) global_pool["details"] = self.get_global_pool_params(global_pool_details) + # global_pool.get("details").update({"id": global_pool_details.get("id")}) self.log("Formatted global pool details: {0}".format(global_pool), "DEBUG") return global_pool @@ -1060,7 +1153,7 @@ def reserve_pool_exists(self, name, site_name): family="network_settings", function="get_reserve_ip_subpool", op_modifies=True, - params={"siteId": site_id} + params={"site_id": site_id} ) if not isinstance(response, dict): reserve_pool.update({"success": False}) @@ -1083,25 +1176,25 @@ def reserve_pool_exists(self, name, site_name): self.log("Reserved pool id: {0}".format(reserve_pool.get("id")), "DEBUG") return reserve_pool - def get_have_global_pool(self, config): + def get_have_global_pool(self, global_pool_details): """ Get the current Global Pool information from Cisco Catalyst Center based on the provided playbook details. check this API using check_return_status. Parameters: - config (dict) - Playbook details containing Global Pool configuration. + global_pool_details (dict) - Playbook details containing Global Pool configuration. Returns: self - The current object with updated information. """ - global_pool = { - "exists": False, - "details": None, - "id": None - } - global_pool_settings = config.get("global_pool_details").get("settings") + # global_pool = { + # "exists": False, + # "details": None, + # "id": None + # } + global_pool_settings = global_pool_details.get("settings") if global_pool_settings is None: self.msg = "settings in global_pool_details is missing in the playbook" self.status = "failed" @@ -1113,116 +1206,123 @@ def get_have_global_pool(self, config): self.status = "failed" return self - name = global_pool_ippool[0].get("name") - if name is None: - self.msg = "Mandatory Parameter name required" - self.status = "failed" - return self - - # If the Global Pool doesn't exist and a previous name is provided - # Else try using the previous name - global_pool = self.global_pool_exists(name) - self.log("Global pool details: {0}".format(global_pool), "DEBUG") - prev_name = global_pool_ippool[0].get("prev_name") - if global_pool.get("exists") is False and \ - prev_name is not None: - global_pool = self.global_pool_exists(prev_name) - if global_pool.get("exists") is False: - self.msg = "Prev name {0} doesn't exist in global_pool_details".format(prev_name) + global_pool = [] + global_pool_ptr = 0 + for pool_details in global_pool_ippool: + name = pool_details.get("name") + if name is None: + self.msg = "Mandatory Parameter name '{0}' required for global pool".format(name) self.status = "failed" return self - self.log("Global pool exists: {0}".format(global_pool.get("exists")), "DEBUG") - self.log("Current Site: {0}".format(global_pool.get("details")), "DEBUG") + # If the Global Pool doesn't exist and a previous name is provided + # Else try using the previous name + global_pool.append(self.global_pool_exists(name)) + self.log("Global pool details of '{0}': {1}".format(name, global_pool[global_pool_ptr]), "DEBUG") + prev_name = pool_details.get("prev_name") + if global_pool[global_pool_ptr].get("exists") is False and \ + prev_name is not None: + global_pool.append(self.global_pool_exists(prev_name)) + if global_pool.get("exists") is False: + self.msg = "Prev name {0} doesn't exist in global_pool_details".format(prev_name) + self.status = "failed" + return self + global_pool_ptr += 1 + + self.log("Global pool details: {0}".format(global_pool), "DEBUG") self.have.update({"globalPool": global_pool}) self.msg = "Collecting the global pool details from the Cisco Catalyst Center" self.status = "success" return self - def get_have_reserve_pool(self, config): + def get_have_reserve_pool(self, reserve_pool_details): """ Get the current Reserved Pool information from Cisco Catalyst Center based on the provided playbook details. Check this API using check_return_status Parameters: - config (list of dict) - Playbook details containing Reserved Pool configuration. + reserve_pool_details (list of dict) - Playbook details containing Reserved Pool configuration. Returns: self - The current object with updated information. """ - reserve_pool = { - "exists": False, - "details": None, - "id": None - } - reserve_pool_details = config.get("reserve_pool_details") - name = reserve_pool_details.get("name") - if name is None: - self.msg = "Mandatory Parameter name required in reserve_pool_details\n" - self.status = "failed" - return self - - site_name = reserve_pool_details.get("site_name") - self.log("Site Name: {0}".format(site_name), "DEBUG") - if site_name is None: - self.msg = "Missing parameter 'site_name' in reserve_pool_details" - self.status = "failed" - return self - - # Check if the Reserved Pool exists in Cisco Catalyst Center - # based on the provided name and site name - reserve_pool = self.reserve_pool_exists(name, site_name) - if not reserve_pool.get("success"): - return self.check_return_status() - self.log("Reserved pool details: {0}".format(reserve_pool), "DEBUG") + # reserve_pool = { + # "exists": False, + # "details": None, + # "id": None + # } + + reserve_pool = [] + reserve_pool_ptr = 0 + for item in reserve_pool_details: + name = item.get("name") + if name is None: + self.msg = "Mandatory Parameter name required in reserve_pool_details." + self.status = "failed" + return self + site_name = item.get("site_name") + self.log("Site Name: {0}".format(site_name), "DEBUG") + if site_name is None: + self.msg = "Missing parameter 'site_name' in reserve_pool_details" + self.status = "failed" + return self - # If the Reserved Pool doesn't exist and a previous name is provided - # Else try using the previous name - prev_name = reserve_pool_details.get("prev_name") - if reserve_pool.get("exists") is False and \ - prev_name is not None: - reserve_pool = self.reserve_pool_exists(prev_name, site_name) - if not reserve_pool.get("success"): + # Check if the Reserved Pool exists in Cisco Catalyst Center + # based on the provided name and site name + reserve_pool.append(self.reserve_pool_exists(name, site_name)) + if not reserve_pool[reserve_pool_ptr].get("success"): return self.check_return_status() + self.log("Reserved pool details for '{0}': {1}".format(name, reserve_pool[reserve_pool_ptr]), "DEBUG") + + # If the Reserved Pool doesn't exist and a previous name is provided + # Else try using the previous name + prev_name = item.get("prev_name") + if reserve_pool[reserve_pool_ptr].get("exists") is False and \ + prev_name is not None: + reserve_pool.append(self.reserve_pool_exists(prev_name, site_name)) + if not reserve_pool[reserve_pool_ptr].get("success"): + return self.check_return_status() + + # If the previous name doesn't exist in Cisco Catalyst Center, return with error + if reserve_pool[reserve_pool_ptr].get("exists") is False: + self.msg = "Prev name {0} doesn't exist in reserve_pool_details".format(prev_name) + self.status = "failed" + return self - # If the previous name doesn't exist in Cisco Catalyst Center, return with error - if reserve_pool.get("exists") is False: - self.msg = "Prev name {0} doesn't exist in reserve_pool_details".format(prev_name) - self.status = "failed" - return self + self.log("Reserved pool exists: {0}".format(reserve_pool[reserve_pool_ptr].get("exists")), "DEBUG") + self.log("Reserved pool: {0}".format(reserve_pool[reserve_pool_ptr].get("details")), "DEBUG") - self.log("Reserved pool exists: {0}".format(reserve_pool.get("exists")), "DEBUG") - self.log("Reserved pool: {0}".format(reserve_pool.get("details")), "DEBUG") + # If reserve pool exist, convert ipv6AddressSpace to the required format (boolean) + if reserve_pool[reserve_pool_ptr].get("exists"): + reserve_pool_info = reserve_pool[reserve_pool_ptr].get("details") + if reserve_pool_info.get("ipv6AddressSpace") == "False": + reserve_pool_info.update({"ipv6AddressSpace": False}) + else: + reserve_pool_info.update({"ipv6AddressSpace": True}) - # If reserve pool exist, convert ipv6AddressSpace to the required format (boolean) - if reserve_pool.get("exists"): - reserve_pool_details = reserve_pool.get("details") - if reserve_pool_details.get("ipv6AddressSpace") == "False": - reserve_pool_details.update({"ipv6AddressSpace": False}) - else: - reserve_pool_details.update({"ipv6AddressSpace": True}) + reserve_pool_ptr += 1 self.log("Reserved pool details: {0}".format(reserve_pool), "DEBUG") self.have.update({"reservePool": reserve_pool}) - self.msg = "Collecting the reserve pool details from the Cisco Catalyst Center" + self.msg = "Collected the reserve pool details from the Cisco Catalyst Center" self.status = "success" return self - def get_have_network(self, config): + def get_have_network(self, network_details): """ Get the current Network details from Cisco Catalyst Center based on the provided playbook details. Parameters: - config (dict) - Playbook details containing Network Management configuration. + network_details (dict) - Playbook details containing Network Management configuration. Returns: self - The current object with updated Network information. """ network = {} - site_name = config.get("network_management_details").get("site_name") + site_name = network_details.get("site_name") if site_name is None: self.msg = "Mandatory Parameter 'site_name' missing" self.status = "failed" @@ -1255,20 +1355,58 @@ def get_have(self, config): Reserved Pool, and Network information. """ - if config.get("global_pool_details") is not None: - self.get_have_global_pool(config).check_return_status() + global_pool_details = config.get("global_pool_details") + if global_pool_details is not None: + self.get_have_global_pool(global_pool_details).check_return_status() - if config.get("reserve_pool_details") is not None: - self.get_have_reserve_pool(config).check_return_status() + reserve_pool_details = config.get("reserve_pool_details") + if reserve_pool_details is not None: + self.get_have_reserve_pool(reserve_pool_details).check_return_status() - if config.get("network_management_details") is not None: - self.get_have_network(config).check_return_status() + network_details = config.get("network_management_details") + if network_details is not None: + self.get_have_network(network_details).check_return_status() self.log("Current State (have): {0}".format(self.have), "INFO") self.msg = "Successfully retrieved the details from the Cisco Catalyst Center" self.status = "success" return self + def get_global_pool_cidr(self, global_pool_cidr, global_pool_name): + """ + Get the Ipv4 or Ipv6 global pool cidr from the global pool name. + + Parameters: + global_pool_cidr (dict) - Global pool cidr value of the current item. + global_pool_name (dict) - Global pool name of the current item. + + Returns: + global_pool_cidr (str) - Global pool cidr value of the current item. + """ + + if global_pool_cidr: + return global_pool_cidr + + if not global_pool_name: + self.msg = "Missing parameter 'Global Pool CIDR' or 'Global Pool name' is mandatory under reserve_pool_details." + self.status = "failed" + return self.check_return_status() + + response = self.dnac._exec( + family="network_settings", + function="get_global_pool", + ) + response = response.get("response") + global_pool_details = get_dict_result(response, "ipPoolName", global_pool_name) + if not global_pool_details: + self.msg = "The global_pool_name '{0}' is not valid under reserve_pool_details".format(global_pool_name) + self.status = "failed" + return self.check_return_status() + + self.log("Global Pool '{0}' details: {1}".format(global_pool_name, global_pool_details), "INFO") + global_pool_cidr = global_pool_details.get("ipPoolCidr") + return global_pool_cidr + def get_want_global_pool(self, global_ippool): """ Get all the Global Pool information from playbook @@ -1286,47 +1424,51 @@ def get_want_global_pool(self, global_ippool): # Initialize the desired Global Pool configuration want_global = { "settings": { - "ippool": [{ - "IpAddressSpace": global_ippool.get("ip_address_space"), - "dhcpServerIps": global_ippool.get("dhcp_server_ips"), - "dnsServerIps": global_ippool.get("dns_server_ips"), - "ipPoolName": global_ippool.get("name"), - "ipPoolCidr": global_ippool.get("cidr"), - "gateway": global_ippool.get("gateway"), - "type": global_ippool.get("pool_type"), - }] + "ippool": [] } } - want_ippool = want_global.get("settings").get("ippool")[0] - - # Converting to the required format based on the existing Global Pool - if not self.have.get("globalPool").get("exists"): - if want_ippool.get("dhcpServerIps") is None: - want_ippool.update({"dhcpServerIps": []}) - if want_ippool.get("dnsServerIps") is None: - want_ippool.update({"dnsServerIps": []}) - if want_ippool.get("IpAddressSpace") is None: - want_ippool.update({"IpAddressSpace": ""}) - if want_ippool.get("gateway") is None: - want_ippool.update({"gateway": ""}) - if want_ippool.get("type") is None: - want_ippool.update({"type": "Generic"}) - else: - have_ippool = self.have.get("globalPool").get("details") \ - .get("settings").get("ippool")[0] - - # Copy existing Global Pool information if the desired configuration is not provided - want_ippool.update({ - "IpAddressSpace": have_ippool.get("IpAddressSpace"), - "type": have_ippool.get("type"), - "ipPoolCidr": have_ippool.get("ipPoolCidr") - }) - want_ippool.update({}) - want_ippool.update({}) + want_ippool = want_global.get("settings").get("ippool") + global_pool_ptr = 0 + for pool_details in global_ippool: + pool_values = { + "IpAddressSpace": pool_details.get("ip_address_space"), + "dhcpServerIps": pool_details.get("dhcp_server_ips"), + "dnsServerIps": pool_details.get("dns_server_ips"), + "ipPoolName": pool_details.get("name"), + "ipPoolCidr": pool_details.get("cidr"), + "gateway": pool_details.get("gateway"), + "type": pool_details.get("pool_type"), + } + # Converting to the required format based on the existing Global Pool + if not self.have.get("globalPool")[global_pool_ptr].get("exists"): + if pool_values.get("dhcpServerIps") is None: + pool_values.update({"dhcpServerIps": []}) + if pool_values.get("dnsServerIps") is None: + pool_values.update({"dnsServerIps": []}) + if pool_values.get("IpAddressSpace") is None: + pool_values.update({"IpAddressSpace": ""}) + if pool_values.get("gateway") is None: + pool_values.update({"gateway": ""}) + if pool_values.get("type") is None: + pool_values.update({"type": "Generic"}) + else: + have_ippool = self.have.get("globalPool")[global_pool_ptr].get("details") + + # Copy existing Global Pool information if the desired configuration is not provided + pool_values.update({ + "IpAddressSpace": have_ippool.get("IpAddressSpace"), + "type": have_ippool.get("type"), + "ipPoolCidr": have_ippool.get("ipPoolCidr"), + "id": self.have.get("globalPool")[global_pool_ptr].get("id") + }) + # want_ippool.update({}) + # want_ippool.update({}) - for key in ["dhcpServerIps", "dnsServerIps", "gateway"]: - if want_ippool.get(key) is None and have_ippool.get(key) is not None: - want_ippool[key] = have_ippool[key] + for key in ["dhcpServerIps", "dnsServerIps", "gateway"]: + if pool_values.get(key) is None and have_ippool.get(key) is not None: + pool_values[key] = have_ippool[key] + want_ippool.append(pool_values) + global_pool_ptr += 1 self.log("Global pool playbook details: {0}".format(want_global), "DEBUG") self.want.update({"wantGlobal": want_global}) @@ -1348,101 +1490,111 @@ def get_want_reserve_pool(self, reserve_pool): self - The current object with updated desired Reserved Pool information. """ - want_reserve = { - "name": reserve_pool.get("name"), - "type": reserve_pool.get("pool_type"), - "ipv6AddressSpace": reserve_pool.get("ipv6_address_space"), - "ipv4GlobalPool": reserve_pool.get("ipv4_global_pool"), - "ipv4Prefix": reserve_pool.get("ipv4_prefix"), - "ipv4PrefixLength": reserve_pool.get("ipv4_prefix_length"), - "ipv4GateWay": reserve_pool.get("ipv4_gateway"), - "ipv4DhcpServers": reserve_pool.get("ipv4_dhcp_servers"), - "ipv4DnsServers": reserve_pool.get("ipv4_dns_servers"), - "ipv4Subnet": reserve_pool.get("ipv4_subnet"), - "ipv6GlobalPool": reserve_pool.get("ipv6_global_pool"), - "ipv6Prefix": reserve_pool.get("ipv6_prefix"), - "ipv6PrefixLength": reserve_pool.get("ipv6_prefix_length"), - "ipv6GateWay": reserve_pool.get("ipv6_gateway"), - "ipv6DhcpServers": reserve_pool.get("ipv6_dhcp_servers"), - "ipv6Subnet": reserve_pool.get("ipv6_subnet"), - "ipv6DnsServers": reserve_pool.get("ipv6_dns_servers"), - "ipv4TotalHost": reserve_pool.get("ipv4_total_host"), - "ipv6TotalHost": reserve_pool.get("ipv6_total_host") - } - - # Check for missing mandatory parameters in the playbook - if not want_reserve.get("name"): - self.msg = "Missing mandatory parameter 'name' in reserve_pool_details" - self.status = "failed" - return self - - if want_reserve.get("ipv4Prefix") is True: - if want_reserve.get("ipv4Subnet") is None and \ - want_reserve.get("ipv4TotalHost") is None: - self.msg = "missing parameter 'ipv4_subnet' or 'ipv4TotalHost' \ - while adding the ipv4 in reserve_pool_details" + want_reserve = [] + reserve_pool_ptr = 0 + for item in reserve_pool: + pool_values = { + "name": item.get("name"), + "type": item.get("pool_type"), + "ipv6AddressSpace": item.get("ipv6_address_space"), + "ipv4GlobalPool": self.get_global_pool_cidr(item.get("ipv4_global_pool"), + item.get("ipv4_global_pool_name")), + "ipv4Prefix": item.get("ipv4_prefix"), + "ipv4PrefixLength": item.get("ipv4_prefix_length"), + "ipv4GateWay": item.get("ipv4_gateway"), + "ipv4DhcpServers": item.get("ipv4_dhcp_servers"), + "ipv4DnsServers": item.get("ipv4_dns_servers"), + "ipv4Subnet": item.get("ipv4_subnet"), + "ipv6GlobalPool": self.get_global_pool_cidr(item.get("ipv6_global_pool"), + item.get("ipv6_global_pool_name")), + "ipv6Prefix": item.get("ipv6_prefix"), + "ipv6PrefixLength": item.get("ipv6_prefix_length"), + "ipv6GateWay": item.get("ipv6_gateway"), + "ipv6DhcpServers": item.get("ipv6_dhcp_servers"), + "ipv6Subnet": item.get("ipv6_subnet"), + "ipv6DnsServers": item.get("ipv6_dns_servers"), + "ipv4TotalHost": item.get("ipv4_total_host"), + "ipv6TotalHost": item.get("ipv6_total_host") + } + # Check for missing mandatory parameters in the playbook + if not pool_values.get("name"): + self.msg = "Missing mandatory parameter 'name' in reserve_pool_details '{0}' element" \ + .format(reserve_pool_ptr + 1) self.status = "failed" return self - if want_reserve.get("ipv6Prefix") is True: - if want_reserve.get("ipv6Subnet") is None and \ - want_reserve.get("ipv6TotalHost") is None: - self.msg = "missing parameter 'ipv6_subnet' or 'ipv6TotalHost' \ - while adding the ipv6 in reserve_pool_details" - self.status = "failed" - return self + if pool_values.get("ipv4Prefix") is True: + if pool_values.get("ipv4Subnet") is None and \ + pool_values.get("ipv4TotalHost") is None: + self.msg = "missing parameter 'ipv4_subnet' or 'ipv4TotalHost' \ + while adding the ipv4 in reserve_pool_details '{0}' element".format(reserve_pool_ptr + 1) + self.status = "failed" + return self - self.log("Reserved IP pool playbook details: {0}".format(want_reserve), "DEBUG") + if pool_values.get("ipv6Prefix") is True: + if pool_values.get("ipv6Subnet") is None and \ + pool_values.get("ipv6TotalHost") is None: + self.msg = "missing parameter 'ipv6_subnet' or 'ipv6TotalHost' \ + while adding the ipv6 in reserve_pool_details '{0}' element".format(reserve_pool_ptr + 1) + self.status = "failed" + return self - # If there are no existing Reserved Pool details, validate and set defaults - if not self.have.get("reservePool").get("details"): - if not want_reserve.get("ipv4GlobalPool"): - self.msg = "missing parameter 'ipv4GlobalPool' in reserve_pool_details" - self.status = "failed" - return self + self.log("Reserved IP pool playbook details: {0}".format(pool_values), "DEBUG") - if not want_reserve.get("ipv4PrefixLength"): - self.msg = "missing parameter 'ipv4_prefix_length' in reserve_pool_details" - self.status = "failed" - return self + # If there are no existing Reserved Pool details, validate and set defaults + if not self.have.get("reservePool")[reserve_pool_ptr].get("details"): + if not pool_values.get("ipv4GlobalPool"): + self.msg = "missing parameter 'ipv4GlobalPool' in reserve_pool_details '{0}' element" \ + .format(reserve_pool_ptr + 1) + self.status = "failed" + return self + + if not pool_values.get("ipv4PrefixLength"): + self.msg = "missing parameter 'ipv4_prefix_length' in reserve_pool_details '{0}' element" \ + .format(reserve_pool_ptr + 1) + self.status = "failed" + return self - if want_reserve.get("type") is None: - want_reserve.update({"type": "Generic"}) - if want_reserve.get("ipv4GateWay") is None: - want_reserve.update({"ipv4GateWay": ""}) - if want_reserve.get("ipv4DhcpServers") is None: - want_reserve.update({"ipv4DhcpServers": []}) - if want_reserve.get("ipv4DnsServers") is None: - want_reserve.update({"ipv4DnsServers": []}) - if want_reserve.get("ipv6AddressSpace") is None: - want_reserve.update({"ipv6AddressSpace": False}) - if want_reserve.get("slaacSupport") is None: - want_reserve.update({"slaacSupport": True}) - if want_reserve.get("ipv4TotalHost") is None: - del want_reserve['ipv4TotalHost'] - if want_reserve.get("ipv6AddressSpace") is True: - want_reserve.update({"ipv6Prefix": True}) + if pool_values.get("type") is None: + pool_values.update({"type": "Generic"}) + if pool_values.get("ipv4GateWay") is None: + pool_values.update({"ipv4GateWay": ""}) + if pool_values.get("ipv4DhcpServers") is None: + pool_values.update({"ipv4DhcpServers": []}) + if pool_values.get("ipv4DnsServers") is None: + pool_values.update({"ipv4DnsServers": []}) + if pool_values.get("ipv6AddressSpace") is None: + pool_values.update({"ipv6AddressSpace": False}) + if pool_values.get("slaacSupport") is None: + pool_values.update({"slaacSupport": True}) + if pool_values.get("ipv4TotalHost") is None: + del pool_values['ipv4TotalHost'] + if pool_values.get("ipv6AddressSpace") is True: + pool_values.update({"ipv6Prefix": True}) + else: + del pool_values['ipv6Prefix'] + + if not pool_values.get("ipv6AddressSpace"): + keys_to_check = ['ipv6GlobalPool', 'ipv6PrefixLength', + 'ipv6GateWay', 'ipv6DhcpServers', + 'ipv6DnsServers', 'ipv6TotalHost'] + for key in keys_to_check: + if pool_values.get(key) is None: + del pool_values[key] else: - del want_reserve['ipv6Prefix'] - - if not want_reserve.get("ipv6AddressSpace"): - keys_to_check = ['ipv6GlobalPool', 'ipv6PrefixLength', - 'ipv6GateWay', 'ipv6DhcpServers', - 'ipv6DnsServers', 'ipv6TotalHost'] - for key in keys_to_check: - if want_reserve.get(key) is None: - del want_reserve[key] - else: - keys_to_delete = ['type', 'ipv4GlobalPool', - 'ipv4Prefix', 'ipv4PrefixLength', - 'ipv4TotalHost', 'ipv4Subnet'] - for key in keys_to_delete: - if key in want_reserve: - del want_reserve[key] + keys_to_delete = ['type', 'ipv4GlobalPool', + 'ipv4Prefix', 'ipv4PrefixLength', + 'ipv4TotalHost', 'ipv4Subnet'] + for key in keys_to_delete: + if key in pool_values: + del pool_values[key] + + want_reserve.append(pool_values) + reserve_pool_ptr += 1 self.want.update({"wantReserve": want_reserve}) - self.log("Desired State (want): {0}".format(self.want), "INFO") - self.msg = "Collecting the reserve pool details from the playbook" + self.log("Reserved Pool details: {0}".format(want_reserve), "INFO") + self.msg = "Collected the reserved pool details from the playbook" self.status = "success" return self @@ -1680,7 +1832,7 @@ def get_want_network(self, network_management_details): self.log("Network playbook details: {0}".format(want_network), "DEBUG") self.want.update({"wantNetwork": want_network}) - self.msg = "Collecting the network details from the playbook" + self.msg = "Collected the network details from the playbook" self.status = "success" return self @@ -1696,7 +1848,7 @@ def get_want(self, config): """ if config.get("global_pool_details"): - global_ippool = config.get("global_pool_details").get("settings").get("ip_pool")[0] + global_ippool = config.get("global_pool_details").get("settings").get("ip_pool") self.get_want_global_pool(global_ippool).check_return_status() if config.get("reserve_pool_details"): @@ -1713,26 +1865,41 @@ def get_want(self, config): self.status = "success" return self - def update_global_pool(self, config): + def update_global_pool(self, global_pool): """ Update/Create Global Pool in Cisco Catalyst Center with fields provided in playbook Parameters: - config (list of dict) - Playbook details + global_pool (list of dict) - Global Pool playbook details Returns: None """ - name = config.get("global_pool_details") \ - .get("settings").get("ip_pool")[0].get("name") + create_global_pool = [] + update_global_pool = [] + global_pool_ptr = 0 result_global_pool = self.result.get("response")[0].get("globalPool") - result_global_pool.get("response").update({name: {}}) + want_global_pool = self.want.get("wantGlobal").get("settings").get("ippool") + self.log("Global pool playbook details: {0}".format(global_pool)) + for item in self.have.get("globalPool"): + result_global_pool.get("msg") \ + .update({want_global_pool[global_pool_ptr].get("ipPoolName"): {}}) + if item.get("exists") is True: + update_global_pool.append(want_global_pool[global_pool_ptr]) + else: + create_global_pool.append(want_global_pool[global_pool_ptr]) - # Check pool exist, if not create and return - if not self.have.get("globalPool").get("exists"): - pool_params = self.want.get("wantGlobal") - self.log("Desired State for global pool (want): {0}".format(pool_params), "DEBUG") + global_pool_ptr += 1 + + # Check create_global_pool; if yes, create the global pool + if create_global_pool: + self.log("Global pool(s) details to be created: {0}".format(create_global_pool), "INFO") + pool_params = { + "settings": { + "ippool": copy.deepcopy(create_global_pool) + } + } response = self.dnac._exec( family="network_settings", function="create_global_pool", @@ -1740,133 +1907,140 @@ def update_global_pool(self, config): params=pool_params, ) self.check_execution_response_status(response).check_return_status() - self.log("Successfully created global pool '{0}'.".format(name), "INFO") - result_global_pool.get("response").get(name) \ - .update({"globalPool Details": self.want.get("wantGlobal")}) - result_global_pool.get("msg").update({name: "Global Pool Created Successfully"}) - return - - # Pool exists, check update is required - if not self.requires_update(self.have.get("globalPool").get("details"), - self.want.get("wantGlobal"), self.global_pool_obj_params): - self.log("Global pool '{0}' doesn't require an update".format(name), "INFO") - result_global_pool.get("response").get(name).update({ - "Cisco Catalyst Center params": - self.have.get("globalPool").get("details").get("settings").get("ippool")[0] - }) - result_global_pool.get("response").get(name).update({ - "Id": self.have.get("globalPool").get("id") - }) - result_global_pool.get("msg").update({ - name: "Global pool doesn't require an update" - }) - return - - self.log("Global pool requires update", "DEBUG") - # Pool Exists - pool_params = copy.deepcopy(self.want.get("wantGlobal")) - pool_params_ippool = pool_params.get("settings").get("ippool")[0] - pool_params_ippool.update({"id": self.have.get("globalPool").get("id")}) - self.log("Desired State for global pool (want): {0}".format(pool_params), "DEBUG") - keys_to_remove = ["IpAddressSpace", "ipPoolCidr", "type"] - for key in keys_to_remove: - del pool_params["settings"]["ippool"][0][key] - - have_ippool = self.have.get("globalPool").get("details").get("settings").get("ippool")[0] - keys_to_update = ["dhcpServerIps", "dnsServerIps", "gateway"] - for key in keys_to_update: - if pool_params_ippool.get(key) is None: - pool_params_ippool[key] = have_ippool.get(key) - - self.log("Desired global pool details (want): {0}".format(pool_params), "DEBUG") - response = self.dnac._exec( - family="network_settings", - function="update_global_pool", - op_modifies=True, - params=pool_params, - ) - - self.check_execution_response_status(response).check_return_status() - self.log("Global pool '{0}' updated successfully".format(name), "INFO") - result_global_pool.get("response").get(name) \ - .update({"Id": self.have.get("globalPool").get("details").get("id")}) - result_global_pool.get("msg").update({name: "Global Pool Updated Successfully"}) + self.log("Successfully created global pool successfully.", "INFO") + for item in pool_params.get("settings").get("ippool"): + name = item.get("ipPoolName") + self.log("Global pool '{0}' created successfully.".format(name)) + result_global_pool.get("response").update({"created": pool_params}) + result_global_pool.get("msg").update({name: "Global Pool Created Successfully"}) + + if update_global_pool: + final_update_global_pool = [] + # Pool exists, check update is required + for item in update_global_pool: + name = item.get("ipPoolName") + for pool_value in self.have.get("globalPool"): + if pool_value.get("exists") and pool_value.get("details").get("ipPoolName") == name: + if not self.requires_update(pool_value.get("details"), item, self.global_pool_obj_params): + self.log("Global pool '{0}' doesn't require an update".format(name), "INFO") + result_global_pool.get("msg").update({name: "Global pool doesn't require an update"}) + elif item not in final_update_global_pool: + final_update_global_pool.append(item) + + if final_update_global_pool: + self.log("Global pool requires update", "DEBUG") + + # Pool(s) needs update + pool_params = { + "settings": { + "ippool": copy.deepcopy(final_update_global_pool) + } + } + self.log("Desired State for global pool (want): {0}".format(pool_params), "DEBUG") + keys_to_remove = ["IpAddressSpace", "ipPoolCidr", "type"] + for item in pool_params["settings"]["ippool"]: + for key in keys_to_remove: + del item[key] + + self.log("Desired global pool details (want): {0}".format(pool_params), "DEBUG") + response = self.dnac._exec( + family="network_settings", + function="update_global_pool", + op_modifies=True, + params=pool_params, + ) + + self.check_execution_response_status(response).check_return_status() + self.log("Global pool '{0}' updated successfully".format(name), "INFO") + for item in pool_params.get("settings").get("ippool"): + name = item.get("ipPoolName") + self.log("Global pool '{0}' Updated successfully.".format(name)) + result_global_pool.get("response").update({"globalPool Details": pool_params}) + result_global_pool.get("msg").update({name: "Global Pool Updated Successfully"}) + + self.log("The Global Pool config operations are successful") return - def update_reserve_pool(self, config): + def update_reserve_pool(self, reserve_pool): """ Update or Create a Reserve Pool in Cisco Catalyst Center based on the provided configuration. This method checks if a reserve pool with the specified name exists in Cisco Catalyst Center. If it exists and requires an update, it updates the pool. If not, it creates a new pool. Parameters: - config (list of dict) - Playbook details containing Reserve Pool information. + reserve_pool (list of dict) - Playbook details containing Reserve Pool information. Returns: None """ - name = config.get("reserve_pool_details").get("name") - result_reserve_pool = self.result.get("response")[1].get("reservePool") - result_reserve_pool.get("response").update({name: {}}) - self.log("Current reserved pool details in Catalyst Center: {0}" - .format(self.have.get("reservePool").get("details")), "DEBUG") - self.log("Desired reserved pool details in Catalyst Center: {0}" - .format(self.want.get("wantReserve")), "DEBUG") - - # Check pool exist, if not create and return - self.log("IPv4 global pool: {0}" - .format(self.want.get("wantReserve").get("ipv4GlobalPool")), "DEBUG") - site_name = config.get("reserve_pool_details").get("site_name") - reserve_params = self.want.get("wantReserve") - site_id = self.get_site_id(site_name) - reserve_params.update({"site_id": site_id}) - if not self.have.get("reservePool").get("exists"): - self.log("Desired reserved pool details (want): {0}".format(reserve_params), "DEBUG") + reserve_pool_ptr = -1 + for item in reserve_pool: + reserve_pool_ptr += 1 + name = item.get("name") + result_reserve_pool = self.result.get("response")[1].get("reservePool") + self.log("Current reserved pool '{0}' details in Catalyst Center: {1}" + .format(name, self.have.get("reservePool")[reserve_pool_ptr].get("details")), "DEBUG") + self.log("Desired reserved pool '{0}' details in Catalyst Center: {1}" + .format(name, self.want.get("wantReserve")[reserve_pool_ptr]), "DEBUG") + + # Check pool exist, if not create and return + self.log("IPv4 reserved pool '{0}': {1}" + .format(name, self.want.get("wantReserve")[reserve_pool_ptr].get("ipv4GlobalPool")), "DEBUG") + site_name = item.get("site_name") + reserve_params = self.want.get("wantReserve")[reserve_pool_ptr] + site_id = self.get_site_id(site_name) + reserve_params.update({"site_id": site_id}) + if not self.have.get("reservePool")[reserve_pool_ptr].get("exists"): + self.log("Desired reserved pool '{0}' details (want): {1}" + .format(name, reserve_params), "DEBUG") + response = self.dnac._exec( + family="network_settings", + function="reserve_ip_subpool", + op_modifies=True, + params=reserve_params, + ) + self.check_execution_response_status(response).check_return_status() + self.log("Successfully created IP subpool reservation '{0}'.".format(name), "INFO") + result_reserve_pool.get("response") \ + .update({name: self.want.get("wantReserve")[reserve_pool_ptr]}) + result_reserve_pool.get("msg") \ + .update({name: "Ip Subpool Reservation Created Successfully"}) + continue + + # Check update is required + if not self.requires_update(self.have.get("reservePool")[reserve_pool_ptr].get("details"), + self.want.get("wantReserve")[reserve_pool_ptr], + self.reserve_pool_obj_params): + self.log("Reserved ip subpool '{0}' doesn't require an update".format(name), "INFO") + result_reserve_pool.get("msg") \ + .update({name: "Reserved ip subpool doesn't require an update"}) + continue + + self.log("Reserved ip pool '{0}' requires an update".format(name), "DEBUG") + + # Pool Exists + self.log("Current reserved ip pool '{0}' details in Catalyst Center: {1}" + .format(name, self.have.get("reservePool")), "DEBUG") + self.log("Desired reserved ip pool '{0}' details: {1}" + .format(name, self.want.get("wantReserve")), "DEBUG") + reserve_params.update({"id": self.have.get("reservePool")[reserve_pool_ptr].get("id")}) response = self.dnac._exec( family="network_settings", - function="reserve_ip_subpool", + function="update_reserve_ip_subpool", op_modifies=True, params=reserve_params, ) self.check_execution_response_status(response).check_return_status() - self.log("Successfully created IP subpool reservation '{0}'.".format(name), "INFO") - result_reserve_pool.get("response").get(name) \ - .update({"reservePool Details": self.want.get("wantReserve")}) - result_reserve_pool.get("msg") \ - .update({name: "Ip Subpool Reservation Created Successfully"}) - return - - # Check update is required - if not self.requires_update(self.have.get("reservePool").get("details"), - self.want.get("wantReserve"), self.reserve_pool_obj_params): - self.log("Reserved ip subpool '{0}' doesn't require an update".format(name), "INFO") + self.log("Reserved ip subpool '{0}' updated successfully.".format(name), "INFO") + result_reserve_pool.get("response") \ + .update({name: self.have.get("reservePool")[reserve_pool_ptr].get("details")}) result_reserve_pool.get("response").get(name) \ - .update({"Cisco Catalyst Center params": self.have.get("reservePool").get("details")}) - result_reserve_pool.get("response").get(name) \ - .update({"Id": self.have.get("reservePool").get("id")}) + .update({"Id": self.have.get("reservePool")[reserve_pool_ptr].get("id")}) result_reserve_pool.get("msg") \ - .update({name: "Reserve ip subpool doesn't require an update"}) - return + .update({name: "Reserved Ip Subpool updated successfully."}) - self.log("Reserved ip pool '{0}' requires an update".format(name), "DEBUG") - # Pool Exists - self.log("Current reserved ip pool '{0}' details in Catalyst Center: {1}" - .format(name, self.have.get("reservePool")), "DEBUG") - self.log("Desired reserved ip pool '{0}' details: {1}" - .format(name, self.want.get("wantReserve")), "DEBUG") - reserve_params.update({"id": self.have.get("reservePool").get("id")}) - response = self.dnac._exec( - family="network_settings", - function="update_reserve_ip_subpool", - op_modifies=True, - params=reserve_params, - ) - self.check_execution_response_status(response).check_return_status() - self.log("Reserved ip subpool '{0}' updated successfully.".format(name), "INFO") - result_reserve_pool['msg'] = "Reserved Ip Subpool Updated Successfully" - result_reserve_pool.get("response").get(name) \ - .update({"Reservation details": self.have.get("reservePool").get("details")}) + self.log("Reserved Ip Subpool Updated Successfully") return def update_network(self, config): @@ -1933,95 +2107,106 @@ def get_diff_merged(self, config): self """ - if config.get("global_pool_details") is not None: - self.update_global_pool(config) + global_pool = config.get("global_pool_details") + if global_pool is not None: + self.update_global_pool(global_pool) - if config.get("reserve_pool_details") is not None: - self.update_reserve_pool(config) + reserve_pool = config.get("reserve_pool_details") + if reserve_pool is not None: + self.update_reserve_pool(reserve_pool) if config.get("network_management_details") is not None: self.update_network(config) return self - def delete_reserve_pool(self, name): + def delete_reserve_pool(self, reserve_pool_details): """ Delete a Reserve Pool by name in Cisco Catalyst Center Parameters: - name (str) - The name of the Reserve Pool to be deleted. + reserve_pool_details (list of dict) - Reserverd pool playbook details. Returns: self """ - reserve_pool_exists = self.have.get("reservePool").get("exists") - result_reserve_pool = self.result.get("response")[1].get("reservePool") - - if not reserve_pool_exists: - result_reserve_pool.get("response").update({name: "Reserve Pool not found"}) - self.msg = "Reserved Ip Subpool Not Found" - self.status = "success" - return self + reserve_pool_ptr = -1 + for item in reserve_pool_details: + reserve_pool_ptr += 1 + name = item.get("name") + reserve_pool_exists = self.have.get("reservePool")[reserve_pool_ptr].get("exists") + result_reserve_pool = self.result.get("response")[1].get("reservePool") + + if not reserve_pool_exists: + result_reserve_pool.get("msg").update({name: "Reserve Pool not found"}) + self.log("Reserved Ip Subpool '{0}' not found".format(name)) + continue + + self.log("Reserved IP pool scheduled for deletion: {0}" + .format(self.have.get("reservePool")[reserve_pool_ptr].get("name")), "INFO") + _id = self.have.get("reservePool")[reserve_pool_ptr].get("id") + self.log("Reserved pool '{0}' id: {1}".format(name, _id), "DEBUG") + response = self.dnac._exec( + family="network_settings", + function="release_reserve_ip_subpool", + op_modifies=True, + params={"id": _id}, + ) + self.check_execution_response_status(response).check_return_status() + executionid = response.get("executionId") + result_reserve_pool = self.result.get("response")[1].get("reservePool") + result_reserve_pool.get("response").update({name: {}}) + result_reserve_pool.get("response").get(name) \ + .update({"Execution Id": executionid}) + result_reserve_pool.get("msg") \ + .update({name: "Ip subpool reservation released successfully"}) - self.log("Reserved IP pool scheduled for deletion: {0}" - .format(self.have.get("reservePool").get("name")), "INFO") - _id = self.have.get("reservePool").get("id") - self.log("Reserved pool {0} id: {1}".format(name, _id), "DEBUG") - response = self.dnac._exec( - family="network_settings", - function="release_reserve_ip_subpool", - op_modifies=True, - params={"id": _id}, - ) - self.check_execution_response_status(response).check_return_status() - executionid = response.get("executionId") - result_reserve_pool = self.result.get("response")[1].get("reservePool") - result_reserve_pool.get("response").update({name: {}}) - result_reserve_pool.get("response").get(name) \ - .update({"Execution Id": executionid}) - result_reserve_pool.get("msg") \ - .update({name: "Ip subpool reservation released successfully"}) - self.msg = "Reserved pool - {0} released successfully".format(name) + self.msg = "Reserved pool(s) released successfully" self.status = "success" return self - def delete_global_pool(self, name): + def delete_global_pool(self, global_pool_details): """ Delete a Global Pool by name in Cisco Catalyst Center Parameters: - name (str) - The name of the Global Pool to be deleted. + global_pool_details (dict) - Global pool details of the playbook Returns: self """ - global_pool_exists = self.have.get("globalPool").get("exists") result_global_pool = self.result.get("response")[0].get("globalPool") - if not global_pool_exists: - result_global_pool.get("response").update({name: "Global Pool not found"}) - self.msg = "Global pool Not Found" - self.status = "success" - return self + global_pool_ptr = 0 + for item in self.have.get("globalPool"): + global_pool_exists = item.get("exists") + name = global_pool_details.get("settings").get("ip_pool")[global_pool_ptr].get("name") + global_pool_ptr += 1 + if not global_pool_exists: + result_global_pool.get("msg").update({name: "Global Pool not found"}) + self.log("Global pool '{0}' not found".format(name)) + continue + + id = item.get("id") + response = self.dnac._exec( + family="network_settings", + function="delete_global_ip_pool", + op_modifies=True, + params={"id": id}, + ) - response = self.dnac._exec( - family="network_settings", - function="delete_global_ip_pool", - op_modifies=True, - params={"id": self.have.get("globalPool").get("id")}, - ) + # Check the execution status + self.check_execution_response_status(response).check_return_status() + executionid = response.get("executionId") - # Check the execution status - self.check_execution_response_status(response).check_return_status() - executionid = response.get("executionId") + # Update result information + result_global_pool = self.result.get("response")[0].get("globalPool") + result_global_pool.get("response").update({name: {}}) + result_global_pool.get("response").get(name).update({"Execution Id": executionid}) + result_global_pool.get("msg").update({name: "Global pool deleted successfully"}) - # Update result information - result_global_pool = self.result.get("response")[0].get("globalPool") - result_global_pool.get("response").update({name: {}}) - result_global_pool.get("response").get(name).update({"Execution Id": executionid}) - result_global_pool.get("msg").update({name: "Pool deleted successfully"}) - self.msg = "Global pool - {0} deleted successfully".format(name) + self.msg = "Global pools deleted successfully" self.status = "success" return self @@ -2036,14 +2221,13 @@ def get_diff_deleted(self, config): self """ - if config.get("reserve_pool_details") is not None: - name = config.get("reserve_pool_details").get("name") - self.delete_reserve_pool(name).check_return_status() + reserve_pool_details = config.get("reserve_pool_details") + if reserve_pool_details is not None: + self.delete_reserve_pool(reserve_pool_details).check_return_status() - if config.get("global_pool_details") is not None: - name = config.get("global_pool_details") \ - .get("settings").get("ip_pool")[0].get("name") - self.delete_global_pool(name).check_return_status() + global_pool_details = config.get("global_pool_details") + if global_pool_details is not None: + self.delete_global_pool(global_pool_details).check_return_status() return self @@ -2064,33 +2248,39 @@ def verify_diff_merged(self, config): self.log("Current State (have): {0}".format(self.have), "INFO") self.log("Requested State (want): {0}".format(self.want), "INFO") if config.get("global_pool_details") is not None: + global_pool_ptr = 0 self.log("Desired State of global pool (want): {0}" .format(self.want.get("wantGlobal")), "DEBUG") self.log("Current State of global pool (have): {0}" - .format(self.have.get("globalPool").get("details")), "DEBUG") - if self.requires_update(self.have.get("globalPool").get("details"), - self.want.get("wantGlobal"), self.global_pool_obj_params): - self.msg = "Global Pool Config is not applied to the Cisco Catalyst Center" - self.status = "failed" - return self + .format(self.have.get("globalPool")), "DEBUG") + for item in self.want.get("wantGlobal").get("settings").get("ippool"): + if self.requires_update(self.have.get("globalPool")[global_pool_ptr].get("details"), + item, self.global_pool_obj_params): + self.msg = "Global Pool Config is not applied to the Cisco Catalyst Center" + self.status = "failed" + return self - self.log("Successfully validated global pool '{0}'.".format(self.want - .get("wantGlobal").get("settings").get("ippool")[0].get("ipPoolName")), "INFO") + global_pool_ptr += 1 + + self.log("Successfully validated global pool(s).", "INFO") self.result.get("response")[0].get("globalPool").update({"Validation": "Success"}) if config.get("reserve_pool_details") is not None: - if self.requires_update(self.have.get("reservePool").get("details"), - self.want.get("wantReserve"), self.reserve_pool_obj_params): - self.log("Desired State for reserve pool (want): {0}" - .format(self.want.get("wantReserve")), "DEBUG") - self.log("Current State for reserve pool (have): {0}" - .format(self.have.get("reservePool").get("details")), "DEBUG") - self.msg = "Reserved Pool Config is not applied to the Cisco Catalyst Center" - self.status = "failed" - return self + reserve_pool_ptr = 0 + self.log("Desired State for reserve pool (want): {0}" + .format(self.want.get("wantReserve")), "DEBUG") + self.log("Current State for reserve pool (have): {0}" + .format(self.have.get("reservePool")), "DEBUG") + for item in self.want.get("wantReserve"): + if self.requires_update(self.have.get("reservePool")[reserve_pool_ptr].get("details"), + item, self.reserve_pool_obj_params): + self.msg = "Reserved Pool Config is not applied to the Cisco Catalyst Center" + self.status = "failed" + return self + + reserve_pool_ptr += 1 - self.log("Successfully validated the reserved pool '{0}'." - .format(self.want.get("wantReserve").get("name")), "INFO") + self.log("Successfully validated the reserved pool(s)", "INFO") self.result.get("response")[1].get("reservePool").update({"Validation": "Success"}) if config.get("network_management_details") is not None: @@ -2126,27 +2316,36 @@ def verify_diff_deleted(self, config): self.log("Current State (have): {0}".format(self.have), "INFO") self.log("Desired State (want): {0}".format(self.want), "INFO") if config.get("global_pool_details") is not None: - global_pool_exists = self.have.get("globalPool").get("exists") - if global_pool_exists: - self.msg = "Global Pool Config is not applied to the Cisco Catalyst Center" - self.status = "failed" - return self + global_pool_ptr = 0 + global_pool_details = self.have.get("globalPool") + for item in global_pool_details: + global_pool_exists = item.get("exists") + name = config.get("global_pool_details").get("settings") \ + .get("ip_pool")[global_pool_ptr].get("name") + if global_pool_exists: + self.msg = "Global Pool Config '{0}' is not applied to the Cisco Catalyst Center" \ + .format(name) + self.status = "failed" + return self - self.log("Successfully validated absence of Global Pool '{0}'." - .format(config.get("global_pool_details") - .get("settings").get("ip_pool")[0].get("name")), "INFO") + self.log("Successfully validated absence of Global Pool '{0}'.".format(name), "INFO") + global_pool_ptr += 1 self.result.get("response")[0].get("globalPool").update({"Validation": "Success"}) if config.get("reserve_pool_details") is not None: - reserve_pool_exists = self.have.get("reservePool").get("exists") - if reserve_pool_exists: - self.msg = "Reserved Pool Config is not applied to the Catalyst Center" - self.status = "failed" - return self + reserve_pool_ptr = 0 + reserve_pool_details = self.have.get("reservePool") + for item in reserve_pool_details: + reserve_pool_exists = item.get("exists") + name = config.get("reserve_pool_details")[reserve_pool_ptr].get("name") + if reserve_pool_exists: + self.msg = "Reserved Pool Config '{0}' is not applied to the Catalyst Center" \ + .format(name) + self.status = "failed" + return self - self.log("Successfully validated the absence of Reserve Pool '{0}'." - .format(config.get("reserve_pool_details").get("name")), "INFO") - self.result.get("response")[1].get("reservePool").update({"Validation": "Success"}) + self.log("Successfully validated the absence of Reserve Pool '{0}'.".format(name), "INFO") + self.result.get("response")[1].get("reservePool").update({"Validation": "Success"}) self.msg = "Successfully validated the absence of Global Pool/Reserve Pool" self.status = "success" From 7165e1ee0fbbc006a6d3d02b8030d7c86af80295 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Thu, 11 Apr 2024 18:10:13 -0400 Subject: [PATCH 263/358] network compliance module --- .circleci/config.yml | 10 +- .../network_compliance_workflow_manager.yml | 33 ++ .../network_compliance_workflow_manager.py | 486 ++++++++++++++++++ .../vars/vars_discovery_management.yml | 8 +- .../defaults/main.yml | 2 + .../meta/main.yml | 1 + .../tasks/main.yml | 34 ++ .../test_network_compliance_management.yml | 45 ++ .../vars_network_compliance_management.yml | 3 + .../vars/vars_swim_management.yml | 1 - 10 files changed, 613 insertions(+), 10 deletions(-) create mode 100644 playbooks/network_compliance_workflow_manager.yml create mode 100644 plugins/modules/network_compliance_workflow_manager.py create mode 100644 tests/integration/ccc_network_compliance_management/defaults/main.yml create mode 100644 tests/integration/ccc_network_compliance_management/meta/main.yml create mode 100644 tests/integration/ccc_network_compliance_management/tasks/main.yml create mode 100644 tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml create mode 100644 tests/integration/ccc_network_compliance_management/vars/vars_network_compliance_management.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index 4068dac7c9..7e06379335 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -40,7 +40,7 @@ jobs: parameters: ansible_cisco_dnac_version: type: string - default: "6.9.0" + default: "6.13.2" machine: true resource_class: rukapse/dnacenter-ansible @@ -69,7 +69,7 @@ jobs: parameters: ansible_cisco_dnac_version: type: string - default: "6.9.0" + default: "6.13.2" machine: true resource_class: rukapse/dnacenter-ansible @@ -214,7 +214,7 @@ jobs: parameters: ansible_cisco_dnac_version: type: string - default: "6.9.0" + default: "6.13.2" machine: true resource_class: rukapse/dnacenter-ansible @@ -317,7 +317,7 @@ workflows: matrix: parameters: ansible_cisco_dnac_version: - - "6.9.0" + - "6.13.2" requires: - pre @@ -359,7 +359,7 @@ workflows: matrix: parameters: ansible_cisco_dnac_version: - - "6.9.0" + - "6.13.2" # - post_pnp_testing: # requires: # - sanity-tests diff --git a/playbooks/network_compliance_workflow_manager.yml b/playbooks/network_compliance_workflow_manager.yml new file mode 100644 index 0000000000..949e314521 --- /dev/null +++ b/playbooks/network_compliance_workflow_manager.yml @@ -0,0 +1,33 @@ +--- +- name: Testing + hosts: dnac_servers + gather_facts: no + + vars_files: + - "credentials.yml" + + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + config_verify: true + + tasks: + + - name: Testing + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global" + run_compliance: + trigger_full: True + categories: ['INTENT','RUNNING_CONFIG'] + sync_device_config: False diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py new file mode 100644 index 0000000000..cb08f3b414 --- /dev/null +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -0,0 +1,486 @@ + +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2024, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +import time + +__metaclass__ = type +__author__ = ("Madhan Sankaranarayanan, Rugvedi Kapse") + + +DOCUMENTATION = r""" +--- +module: network_compliance_workflow_manager +short_description: +description: +version_added: '6.6.0' +extends_documentation_fragment: + - cisco.dnac.workflow_manager_params +author: Rugvedi Kapse (@rukapse) +options: + config: + + + +""" + +EXAMPLES = r""" +- name: + cisco.dnac.network_compliance_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: "{{dnac_log}}" + config: + + +""" + +RETURN = r""" +#Case_1: + +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.dnac.plugins.module_utils.dnac import ( + DnacBase, + validate_list_of_dicts, + get_dict_result, +) + +class NetworkCompliance(DnacBase): + """Class containing member attributes for network_compliance_workflow_manager module""" + + def __init__(self, module): + """ + Initialize an instance of the class. + + Parameters: + - module: The module associated with the class instance. + + Returns: + The method does not return a value. + """ + + super().__init__(module) + + + def validate_input(self, state=None): + """ + Validate the fields provided in the playbook. Checks the + configuration provided in the playbook against a predefined + specification to ensure it adheres to the expected structure + and data types. + + Returns: + The method returns an instance of the class with updated attributes: + - self.msg: A message describing the validation result. + - self.status: The status of the validation (either 'success' or 'failed'). + - self.validated_config: If successful, a validated version of the + 'config' parameter. + """ + + if not self.config: + self.msg = "config not available in playbook for validation" + self.status = "success" + self.log(self.msg, "ERROR") + return self + + temp_spec = { + 'ip_address_list': {'type': 'list', 'elements': 'str', 'required': False}, + 'site_name': {'type': 'str', 'required': False}, + 'run_compliance': {'type': 'dict','required': False}, + 'sync_device_config': {'type': 'bool', 'required': False, 'default': False}, + } + + # Validate device params + valid_temp, invalid_params = validate_list_of_dicts( + self.config, temp_spec + ) + + if invalid_params: + self.msg = "Invalid parameters in playbook: {0}".format(invalid_params) + self.log(self.msg, "ERROR") + self.status = "failed" + return self + + self.validated_config = valid_temp + + self.msg = "Successfully validated playbook configuration parameters using 'validated_input': {0}".format(str(valid_temp)) + self.log(self.msg, "INFO") + self.status = "success" + + return self + + def validate_ip4_address_list(self, ip_address_list): + """ + Validates the IP address list provided in the playbook. + """ + for ip in ip_address_list: + if not self.is_valid_ipv4(ip): + msg = "IP address {0} is not valid".format(ip) + self.log(msg, "ERROR") + self.module.fail_json(msg) + + self.log("Successfully validated the IP address/es: {0}", "DEBUG") + + def validate_run_compliance(self, run_compliance): + trigger_full = run_compliance.get('trigger_full') + categories = run_compliance.get('categories') + + if not trigger_full or not categories: + self.log("Both trigger_full and categories are required parameters for running compliance.", "ERROR") + self.status = "failed" + return self + + for category in categories: + if category.upper() not in ['RUNNING_CONFIG', 'INTENT']: + self.log(f"Invalid category provided: {category}. Valid categories are 'RUNNING_CONFIG' or 'INTENT'.", "ERROR") + self.status = "failed" + return self + + self.log("Successfully validated run_compliance parameters.", "DEBUG") + + + def site_exists(self, site_name): + """ + Parameters: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Returns: + tuple: A tuple containing two values: + - site_exists (bool): A boolean indicating whether the site exists (True) or not (False). + - site_id (str or None): The ID of the site if it exists, or None if the site is not found. + Description: + This method checks the existence of a site in the Catalyst Center. If the site is found,it sets 'site_exists' to True, + retrieves the site's ID, and returns both values in a tuple. If the site does not exist, 'site_exists' is set + to False, and 'site_id' is None. If an exception occurs during the site lookup, an exception is raised. + """ + + site_exists = False + site_id = None + response = None + try: + response = self.dnac._exec( + family="sites", + function='get_site', + op_modifies=True, + params={"name": site_name}, + ) + except Exception as e: + self.msg = "An exception occurred: Site '{0}' does not exist in the Cisco Catalyst Center".format(site_name) + self.log(self.msg, "ERROR") + self.module.fail_json(msg=self.msg) + + if response: + self.log("Received API response from 'get_site': {0}".format(str(response)), "DEBUG") + site = response.get("response") + site_id = site[0].get("id") + site_exists = True + + return (site_exists, site_id) + + def get_device_ids_from_ip(self, ip_address_list): + mgmt_ip_instance_id_map = {} + for device_ip in ip_address_list: + try: + response = self.dnac._exec( + family="devices", + function='get_device_list', + op_modifies=True, + params={"managementIpAddress": device_ip} + ) + + if response: + self.log("Received API response from 'get_device_list' for device: {0}".format(str(response)), "DEBUG") + response = response.get("response") + if not response: + continue + for device_info in response: + if device_info["reachabilityStatus"] == "Reachable": + device_id = response[0]["id"] + mgmt_ip_instance_id_map[device_ip] = device_id + + except Exception as e: + error_message = "Error while fetching device ID for device: '{0}' from Cisco Catalyst Center: {1}".format(device_ip, str(e)) + self.log(error_message, "ERROR") + + return mgmt_ip_instance_id_map + + def get_device_ids_from_site(self, site_name, site_id): + #device_id_list = [] + mgmt_ip_instance_id_map = {} + + site_params = { + "site_id": site_id, + } + + #Get + try: + response = self.dnac._exec( + family="sites", + function='get_membership', + op_modifies=True, + params=site_params, + ) + if response: + self.log("Received API response from 'get_membership': {0}".format(str(response)), "DEBUG") + site_response_list = [] + for item in response['device']: + if item['response']: + for item_dict in item['response']: + site_response_list.append(item_dict) + + except Exception as e: + self.log("Unable to fetch the device(s) associated to the site '{0}' due to '{1}'".format(site_name, str(e)), "WARNING") + return device_id_list + + self.log("Received API response from 'get_membership': {0}".format(str(response)), "DEBUG") + response = response['device'] + + # Iterate over the devices in the site membership + for item in response: + if item['response']: + for item_dict in item['response']: + # Check if the device is reachable + if item_dict["reachabilityStatus"] == "Reachable": + #device_id_list.append(item_dict["instanceUuid"]) + mgmt_ip_instance_id_map[item_dict["managementIpAddress"]] = item_dict["instanceUuid"] + else: + msg = 'Unable to get deviceId for device {0} in site {1} as its status is {2}'.format( + item["managementIpAddress"], site_name, item["reachabilityStatus"]) + self.log(msg, "CRITICAL") + self.module.fail_json(msg=msg) + + if not mgmt_ip_instance_id_map: + msg = 'Site: {0} provided in the playbook does not have any reachable devices'.format(site_name) + self.log(msg, "ERROR") + self.module.fail_json(msg=msg) + + return mgmt_ip_instance_id_map + + def get_device_id_list(self, ip_address_list, site_name): + """ + Get the list of unique device IDs for list of specified management IP addresses of devices in Cisco Catalyst Center. + Parameters: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + device_ips (list): The management IP addresses of devices for which you want to retrieve the device IDs. + Returns: + list: The list of unique device IDs for the specified devices. + Description: + Queries Cisco Catalyst Center to retrieve the unique device ID associated with a device having the specified + IP address. If the device is not found in Cisco Catalyst Center, then print the log message with error severity. + """ + if site_name and ip_address_list: + (site_exists, site_id) = self.site_exists(site_name) + if site_exists: + site_mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) + iplist_mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) + mgmt_ip_instance_id_map = { + ip: instance_id + for ip, instance_id in iplist_mgmt_ip_instance_id_map.items() + if ip in site_mgmt_ip_instance_id_map + } + elif site_name and not ip_address_list: + (site_exists, site_id) = self.site_exists(site_name) + if site_exists: + mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_id) + elif ip_address_list and not site_name: + mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) + + + return mgmt_ip_instance_id_map + + def get_want(self, config): + """ + """ + + #Validate either ip_address_list OR site_name is present + ip_address_list = config.get('ip_address_list') + site_name = config.get('site_name') + + if not ip_address_list and not site_name: + msg = 'ip_address_list is {} and site_name is {}. Either the ip_address_list or the site_name must be provided.'.format(ip_address_list, site_name) + self.log(msg, "ERROR") + self.module.fail_json(msg=msg) + + #Validate valid ip_addresses + if ip_address_list: + self.validate_ip4_address_list(ip_address_list) + + mgmt_ip_instance_id_map = self.get_device_id_list(ip_address_list, site_name) + self.log('Retrieved device_id_list : {0}'.format(mgmt_ip_instance_id_map), 'DEBUG') + + #Validate run_compliance parameters + run_compliance = config.get('run_compliance') + sync_device_config = config.get('sync_device_config') + if run_compliance: + self.validate_run_compliance(run_compliance) + + run_compliance_params = { + 'triggerFull': config.get('run_compliance').get('trigger_full'), + 'categories': config.get('run_compliance').get('categories'), + 'deviceUuids': list(mgmt_ip_instance_id_map.values()), + } + else: + run_compliance_params = {} + + if sync_device_config: + sync_device_config_params = { + 'deviceId': list(mgmt_ip_instance_id_map.values()) + + } + else: + sync_device_config_params = {} + + want = {} + want = dict( + ip_address_list = ip_address_list, + site_name = site_name, + mgmt_ip_instance_id_map = mgmt_ip_instance_id_map, + run_compliance_params=run_compliance_params, + sync_device_config_params=sync_device_config_params + ) + self.want = want + self.log("Desired State (want): {0}".format(str(self.want)), "INFO") + + return self + + + def run_compliance(self, run_compliance_params): + + result = self.dnac_apply['exec']( + family="compliance", + function="run_compliance", + params=run_compliance_params, + op_modifies=True, + ) + + self.log("The response received post Run Compliance API call is {0}".format(str(result)), "DEBUG") + + self.result.update(dict(run_compliance_result=result)) + self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") + return result.response.get('taskId') + + def sync_device_config(self, sync_device_config_params): + result = self.dnac_apply['exec']( + family="compliance", + function="sync_device_config_params", + params=commit_device_configuration, + op_modifies=True, + ) + + self.log("The response received post Commit Configuration API call is {0}".format(str(result)), "DEBUG") + + self.result.update(dict(sync_device_configuration_result=result)) + self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") + return result.response.get('taskId') + + def get_merged_task_status(self, task_id, task_name, ip_address_list): + result = False + params = dict(task_id=task_id) + start_time = time.time() + while True: + + # Check if the elapsed time exceeds the timeout + if time.time() - start_time > 300: + self.log("Task {0} with task id {1} has not completed within the timeout period.".format(task_name, task_id), "CRITICAL") + self.module.fail_json(msg="Task execution timed out.") + break + + response = self.dnac_apply['exec']( + family="task", + function='get_task_by_id', + params=params, + op_modifies=True, + ) + response = response.response + self.log("Task status for the task id {0} is {1}, is_error: {2}".format(str(task_id), str(response), str(response.get('isError'))), "INFO") + + # Check for success status + if not response.get('isError') and 'success' in response.get('progress').lower(): + self.log("Task {0} with task id {1} has completed successfully on device/s: {2} .".format(task_name, str(task_id), ip_address_list), "INFO") + result = True + + self.status = "success" + self.msg = "{0} has completed successfully on device/s: {1}".format(task_name, ip_address_list) + self.result['response'] = self.msg + self.result['changed'] = True + self.result['status'] = "success" + self.log(self.msg, "INFO") + break + + # Check for failed status + if response.get('isError') or 'failed' in response.get('progress').lower(): + msg = 'Task {0} with task id {1} has not completed on device/s {2}- Reason: {3}'.format( + task_name, task_id, ip_address_list, response.get("failureReason")) + self.log(msg, "CRITICAL") + self.module.fail_json(msg=msg) + break + + def get_diff_merged(self): + if self.want.get('run_compliance_params'): + result_task_id = self.run_compliance(self.want.get('run_compliance_params')) + self.get_merged_task_status(result_task_id, 'Run Compliance', list(self.want.get('mgmt_ip_instance_id_map').keys())) + + if self.want.get('sync_device_config_params'): + result_task_id = self.sync_device_config(self.want.get('sync_device_config_params')) + self.get_merged_task_status(result_task_id, 'Commit Device Configuration', list(self.want.get('mgmt_ip_instance_id_map').keys())) + + +def main(): + """ main entry point for module execution + """ + + element_spec = {'dnac_host': {'required': True, 'type': 'str'}, + 'dnac_port': {'type': 'str', 'default': '443'}, + 'dnac_username': {'type': 'str', 'default': 'admin', 'aliases': ['user']}, + 'dnac_password': {'type': 'str', 'no_log': True}, + 'dnac_verify': {'type': 'bool', 'default': 'True'}, + 'dnac_version': {'type': 'str', 'default': '2.2.3.3'}, + 'dnac_debug': {'type': 'bool', 'default': False}, + 'dnac_log_level': {'type': 'str', 'default': 'WARNING'}, + "dnac_log_file_path": {"type": 'str', "default": 'dnac.log'}, + "dnac_log_append": {"type": 'bool', "default": True}, + 'dnac_log': {'type': 'bool', 'default': False}, + 'validate_response_schema': {'type': 'bool', 'default': True}, + 'config_verify': {'type': 'bool', "default": False}, + 'dnac_api_task_timeout': {'type': 'int', "default": 1200}, + 'dnac_task_poll_interval': {'type': 'int', "default": 2}, + 'config': {'required': True, 'type': 'list', 'elements': 'dict'}, + 'state': {'default': 'merged', 'choices': ['merged']} + } + + module = AnsibleModule(argument_spec=element_spec, + supports_check_mode=False) + + ccc_network_compliance = NetworkCompliance(module) + state = ccc_network_compliance.params.get("state") + + if state not in ccc_network_compliance.supported_states: + ccc_network_compliance.status = "invalid" + ccc_network_compliance.msg = "State {0} is invalid".format(state) + ccc_network_compliance.check_return_status() + + ccc_network_compliance.validate_input().check_return_status() + config_verify = ccc_network_compliance.params.get("config_verify") + + for config in ccc_network_compliance.validated_config: + ccc_network_compliance.get_want(config) + ccc_network_compliance.get_diff_merged() + + module.exit_json(**ccc_network_compliance.result) + + + +if __name__ == "__main__": + main() + diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml index 55623c1f89..b9a587e452 100644 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml @@ -7,11 +7,11 @@ single_ip: protocol_order: ssh global_credentials: cli_credentials_list: - - description: CLI - username: cli + - description: CLIa + username: cli-a snmp_v3_credential_list: - - description: snmpV3 - username: v3Public2 + - description: SNMPv3 Test a + username: admin retry: 1 timeout: 1 diff --git a/tests/integration/ccc_network_compliance_management/defaults/main.yml b/tests/integration/ccc_network_compliance_management/defaults/main.yml new file mode 100644 index 0000000000..55a93fc23d --- /dev/null +++ b/tests/integration/ccc_network_compliance_management/defaults/main.yml @@ -0,0 +1,2 @@ +--- +testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_network_compliance_management/meta/main.yml b/tests/integration/ccc_network_compliance_management/meta/main.yml new file mode 100644 index 0000000000..5514b6a40c --- /dev/null +++ b/tests/integration/ccc_network_compliance_management/meta/main.yml @@ -0,0 +1 @@ +dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_network_compliance_management/tasks/main.yml b/tests/integration/ccc_network_compliance_management/tasks/main.yml new file mode 100644 index 0000000000..09e0832ca2 --- /dev/null +++ b/tests/integration/ccc_network_compliance_management/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: collect ccc test cases + find: + paths: "{{ role_path }}/tests" + patterns: "{{ testcase }}.yml" + connection: local + register: ccc_cases + tags: sanity + +- debug: + msg: "CCC Cases: {{ ccc_cases }}" + +- set_fact: + test_cases: + files: "{{ ccc_cases.files }}" + tags: sanity + +- debug: + msg: "Test Cases: {{ test_cases }}" + +- name: set test_items + set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + tags: sanity + +- debug: + msg: "Test Items: {{ test_items }}" + +- name: run test cases (connection=httpapi) + include_tasks: "{{ test_case_to_run }}" + loop: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml b/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml new file mode 100644 index 0000000000..acf6845e6f --- /dev/null +++ b/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml @@ -0,0 +1,45 @@ +--- +- debug: msg="Starting site management test" +- debug: msg="Role Path {{ role_path }}" + +- block: + - name: Load vars and declare dnac vars + include_vars: + file: "{{ role_path }}/vars/vars_network_compliance_management.yml" + name: vars_map + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: true + dnac_log_level: DEBUG + config_verify: true + + # - debug: + # msg: "{{ vars_map. }}" + + +############################################# +# # +############################################# + + - name: Run Compliance + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + dnac_log_append: False + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/India/Bangalore/Mantri Square/Floor1" + run_compliance: + trigger_full: True + categories: ['INTENT','RUNNING_CONFIG'] + sync_device_config: False + + + + \ No newline at end of file diff --git a/tests/integration/ccc_network_compliance_management/vars/vars_network_compliance_management.yml b/tests/integration/ccc_network_compliance_management/vars/vars_network_compliance_management.yml new file mode 100644 index 0000000000..849169c71a --- /dev/null +++ b/tests/integration/ccc_network_compliance_management/vars/vars_network_compliance_management.yml @@ -0,0 +1,3 @@ +--- + + diff --git a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml index acc69524a0..ca884bd85e 100644 --- a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml +++ b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml @@ -13,7 +13,6 @@ image_details: - source_url: http://10.197.156.28/stda/abimishr/cat9k_iosxe.17.12.01.SPA.bin third_party: False - image_golden_tagging_details: - tagging_details: image_name: "cat9k_iosxe.17.12.01.SPA.bin" From dcf59313da5c3972648f67b565dcab891b5db188 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Sat, 13 Apr 2024 00:00:04 +0530 Subject: [PATCH 264/358] Used offset to find the global pool details --- .../network_settings_workflow_manager.py | 91 ++++++++++++------- 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index a411071922..4e86b08822 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -1095,26 +1095,34 @@ def global_pool_exists(self, name): "details": None, "id": None } - response = self.dnac._exec( - family="network_settings", - function="get_global_pool", - ) - if not isinstance(response, dict): - self.log("Failed to retrieve the global pool details - " - "Response is not a dictionary", "CRITICAL") - return global_pool - - all_global_pool_details = response.get("response") - global_pool_details = get_dict_result(all_global_pool_details, "ipPoolName", name) - self.log("Global ip pool name: {0}".format(name), "DEBUG") - self.log("Global pool details: {0}".format(global_pool_details), "DEBUG") - if not global_pool_details: - self.log("Global pool '{0}' does not exist".format(name), "INFO") - return global_pool - global_pool.update({"exists": True}) - global_pool.update({"id": global_pool_details.get("id")}) - global_pool["details"] = self.get_global_pool_params(global_pool_details) - # global_pool.get("details").update({"id": global_pool_details.get("id")}) + is_pool_found = False + value = 1 + while(not is_pool_found): + response = self.dnac._exec( + family="network_settings", + function="get_global_pool", + params={"offset": value} + ) + value += 25 + if not isinstance(response, dict): + self.log("Failed to retrieve the global pool details - " + "Response is not a dictionary", "CRITICAL") + return global_pool + + all_global_pool_details = response.get("response") + if not all_global_pool_details: + self.log("Global pool '{0}' does not exist".format(name), "INFO") + return global_pool + + global_pool_details = get_dict_result(all_global_pool_details, "ipPoolName", name) + if global_pool_details: + self.log("Global ip pool name: {0}".format(name), "DEBUG") + self.log("Global pool details: {0}".format(global_pool_details), "DEBUG") + global_pool.update({"exists": True}) + global_pool.update({"id": global_pool_details.get("id")}) + global_pool["details"] = self.get_global_pool_params(global_pool_details) + # global_pool.get("details").update({"id": global_pool_details.get("id")}) + is_pool_found = True self.log("Formatted global pool details: {0}".format(global_pool), "DEBUG") return global_pool @@ -1392,19 +1400,36 @@ def get_global_pool_cidr(self, global_pool_cidr, global_pool_name): self.status = "failed" return self.check_return_status() - response = self.dnac._exec( - family="network_settings", - function="get_global_pool", - ) - response = response.get("response") - global_pool_details = get_dict_result(response, "ipPoolName", global_pool_name) - if not global_pool_details: - self.msg = "The global_pool_name '{0}' is not valid under reserve_pool_details".format(global_pool_name) - self.status = "failed" - return self.check_return_status() + is_pool_found = False + value = 1 + while(not is_pool_found): + response = self.dnac._exec( + family="network_settings", + function="get_global_pool", + params={"offset": value} + ) + value += 25 + if not isinstance(response, dict): + self.log("Failed to retrieve the global pool details - " + "Response is not a dictionary", "CRITICAL") + self.msg = "Failed to retrieve the global pool details - Response is not a dictionary" + self.status = "failed" + return self.check_return_status() + + all_global_pool_details = response.get("response") + if not all_global_pool_details: + self.msg = "The global_pool_name '{0}' is not valid under reserve_pool_details".format(global_pool_name) + self.status = "failed" + return self.check_return_status() + + global_pool_details = get_dict_result(all_global_pool_details, "ipPoolName", global_pool_name) + if global_pool_details: + self.log("Global ip pool name: {0}".format(global_pool_name), "DEBUG") + self.log("Global pool details: {0}".format(global_pool_details), "DEBUG") + global_pool_cidr = global_pool_details.get("ipPoolCidr") + is_pool_found = True - self.log("Global Pool '{0}' details: {1}".format(global_pool_name, global_pool_details), "INFO") - global_pool_cidr = global_pool_details.get("ipPoolCidr") + self.log("Global Pool '{0}' cidr: {1}".format(global_pool_name, global_pool_cidr), "INFO") return global_pool_cidr def get_want_global_pool(self, global_ippool): @@ -1928,7 +1953,7 @@ def update_global_pool(self, global_pool): final_update_global_pool.append(item) if final_update_global_pool: - self.log("Global pool requires update", "DEBUG") + self.log("Global pool requires update", "INFO") # Pool(s) needs update pool_params = { From 68a2ac5a5e99654e63731d797e8de1d58f5ab6bb Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Sat, 13 Apr 2024 00:04:05 +0530 Subject: [PATCH 265/358] Resolved the sanity errors --- plugins/modules/network_settings_workflow_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index 4e86b08822..47adfbdda6 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -1097,7 +1097,7 @@ def global_pool_exists(self, name): } is_pool_found = False value = 1 - while(not is_pool_found): + while (not is_pool_found): response = self.dnac._exec( family="network_settings", function="get_global_pool", @@ -1402,7 +1402,7 @@ def get_global_pool_cidr(self, global_pool_cidr, global_pool_name): is_pool_found = False value = 1 - while(not is_pool_found): + while (not is_pool_found): response = self.dnac._exec( family="network_settings", function="get_global_pool", From c42a6e708ff40a7f0c2240f1ca6fc26551b2fb2a Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Mon, 15 Apr 2024 10:24:16 +0530 Subject: [PATCH 266/358] Enhanced log result messaged for updating role of multiple devices --- plugins/modules/inventory_intent.py | 16 +++++++++++----- plugins/modules/inventory_workflow_manager.py | 16 +++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index e9542a01f0..2de7f0782b 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -3032,6 +3032,7 @@ def get_diff_merged(self, config): devices_to_update_role = self.get_device_ips_from_config_priority() device_role = self.config[0].get('role') role_update_count = 0 + role_updated_list = [] for device_ip in devices_to_update_role: device_id = self.get_device_ids([device_ip]) @@ -3076,10 +3077,8 @@ def get_diff_merged(self, config): if 'successfully' in progress or 'succesfully' in progress: self.status = "success" - self.result['changed'] = True - self.msg = "Device(s) '{0}' role updated successfully to '{1}'".format(str(devices_to_update_role), device_role) - self.result['response'] = self.msg - self.log(self.msg, "INFO") + self.log("Device '{0}' role updated successfully to '{1}'".format(device_ip, device_role), "INFO") + role_updated_list.append(device_ip) break elif execution_details.get("isError"): self.status = "failed" @@ -3100,10 +3099,17 @@ def get_diff_merged(self, config): self.status = "success" self.result['changed'] = False self.msg = """The device role '{0}' is already set in Cisco Catalyst Center, no device role update is needed for the - devices {1}.""".format(device_role, str(devices_to_update_role)) + device(s) {1}.""".format(device_role, str(devices_to_update_role)) self.log(self.msg, "INFO") self.result['response'] = self.msg + if role_updated_list: + self.status = "success" + self.result['changed'] = True + self.msg = "Device(s) '{0}' role updated successfully to '{1}'".format(str(role_updated_list), device_role) + self.result['response'] = self.msg + self.log(self.msg, "INFO") + if credential_update: device_to_update = self.get_device_ips_from_config_priority() # Update Device details and credentails diff --git a/plugins/modules/inventory_workflow_manager.py b/plugins/modules/inventory_workflow_manager.py index 5ec69bb447..79edfb59e1 100644 --- a/plugins/modules/inventory_workflow_manager.py +++ b/plugins/modules/inventory_workflow_manager.py @@ -3023,6 +3023,7 @@ def get_diff_merged(self, config): devices_to_update_role = self.get_device_ips_from_config_priority() device_role = self.config[0].get('role') role_update_count = 0 + role_updated_list = [] for device_ip in devices_to_update_role: device_id = self.get_device_ids([device_ip]) @@ -3067,10 +3068,8 @@ def get_diff_merged(self, config): if 'successfully' in progress or 'succesfully' in progress: self.status = "success" - self.result['changed'] = True - self.msg = "Device(s) '{0}' role updated successfully to '{1}'".format(str(devices_to_update_role), device_role) - self.result['response'] = self.msg - self.log(self.msg, "INFO") + self.log("Device '{0}' role updated successfully to '{1}'".format(device_ip, device_role), "INFO") + role_updated_list.append(device_ip) break elif execution_details.get("isError"): self.status = "failed" @@ -3091,10 +3090,17 @@ def get_diff_merged(self, config): self.status = "success" self.result['changed'] = False self.msg = """The device role '{0}' is already set in Cisco Catalyst Center, no device role update is needed for the - devices {1}.""".format(device_role, str(devices_to_update_role)) + device(s) {1}.""".format(device_role, str(devices_to_update_role)) self.log(self.msg, "INFO") self.result['response'] = self.msg + if role_updated_list: + self.status = "success" + self.result['changed'] = True + self.msg = "Device(s) '{0}' role updated successfully to '{1}'".format(str(role_updated_list), device_role) + self.result['response'] = self.msg + self.log(self.msg, "INFO") + if credential_update: device_to_update = self.get_device_ips_from_config_priority() From 3a18a1a6ccfe8b8b535ce063f9148a70e6326379 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Mon, 15 Apr 2024 13:01:21 +0530 Subject: [PATCH 267/358] Changed the playbook and documentation order as per GUI --- .../network_settings_workflow_manager.yml | 56 +-- .../network_settings_workflow_manager.py | 385 +++++++++--------- 2 files changed, 221 insertions(+), 220 deletions(-) diff --git a/playbooks/network_settings_workflow_manager.yml b/playbooks/network_settings_workflow_manager.yml index c98b9e1495..877b7849ca 100644 --- a/playbooks/network_settings_workflow_manager.yml +++ b/playbooks/network_settings_workflow_manager.yml @@ -13,33 +13,36 @@ dnac_verify: "{{ dnac_verify }}" dnac_debug: "{{ dnac_debug }}" dnac_log: True - dnac_log_level: "{{ dnac_log_level }}" + dnac_log_level: DEBUG dnac_log_append: True dnac_log_file_path: "{{ dnac_log_file_path }}" state: merged - # config_verify: True + config_verify: True config: - global_pool_details: settings: ip_pool: - name: Global_Pool2 - gateway: '' #use this for updating + pool_type: Generic ip_address_space: IPv6 #required when we are creating cidr: 2001:db8::/64 #required when we are creating - pool_type: Generic + gateway: '' #use this for updating dhcp_server_ips: [] #use this for updating dns_server_ips: [] #use this for updating # prev_name: Global_Pool2 - name: Global_Pool3 - gateway: '' #use this for updating + pool_type: Generic ip_address_space: IPv4 #required when we are creating cidr: 10.0.0.0/8 #required when we are creating - pool_type: Generic + gateway: '' #use this for updating dhcp_server_ips: [] #use this for updating dns_server_ips: [] #use this for updating # prev_name: Global_Pool2 reserve_pool_details: - - ipv6_address_space: True + - site_name: Global/Chennai/Trill + name: IP_Pool_3 + pool_type: LAN + ipv6_address_space: True # ipv4_global_pool: 100.0.0.0/8 ipv4_global_pool_name: Global_Pool1 ipv4_prefix: True @@ -47,44 +50,43 @@ ipv4_subnet: 100.128.0.0 ipv4_gateway: 100.128.0.1 ipv4_dns_servers: [] - name: IP_Pool_3 ipv6_prefix: True ipv6_prefix_length: 64 ipv6_global_pool: 2001:db8::/64 # ipv6_global_pool_name: Global_Pool2 ipv6_subnet: '2001:db8::' - site_name: Global/Chennai/Trill slaac_support: True # prev_name: IP_Pool_4 - pool_type: LAN network_management_details: + site_name: Global/Chennai settings: - dhcp_server: - - 10.0.0.1 - dns_server: - domain_name: cisco.com - primary_ip_address: 10.0.0.2 - secondary_ip_address: 10.0.0.3 + network_aaa: #works only if we system settigns is set + ip_address: 10.0.0.21 #Mandatory for ISE, sec ip for AAA + network: 10.0.0.20 + protocol: TACACS + servers: AAA + # shared_secret: string #ISE client_and_endpoint_aaa: #works only if we system settigns is set ip_address: 10.197.156.42 #Mandatory for ISE, sec ip for AAA network: 10.0.0.20 protocol: RADIUS servers: AAA # shared_secret: string #ISE + dhcp_server: + - 10.0.0.1 + dns_server: + domain_name: cisco.com + primary_ip_address: 10.0.0.2 + secondary_ip_address: 10.0.0.3 + ntp_server: + - 10.0.0.5 + timezone: GMT message_of_the_day: banner_message: hello retain_existing_banner: 'true' netflow_collector: ip_address: 10.0.0.4 port: 443 - network_aaa: #works only if we system settigns is set - ip_address: 10.0.0.21 #Mandatory for ISE, sec ip for AAA - network: 10.0.0.20 - protocol: TACACS - servers: AAA - # shared_secret: string #ISE - ntp_server: - - 10.0.0.5 snmp_server: configure_dnac_ip: false # ip_addresses: @@ -93,8 +95,6 @@ configure_dnac_ip: false # ip_addresses: # - 10.0.0.7 - timezone: GMT - site_name: Global/Chennai - name: Delete Global Pool and Release Pool Reservation cisco.dnac.network_settings_workflow_manager: @@ -114,5 +114,5 @@ ip_pool: - name: Global_Pool2 reserve_pool_details: - - name: IP_Pool_3 - site_name: Global/Chennai/Trill + - site_name: Global/Chennai/Trill + name: IP_Pool_3 diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index 47adfbdda6..d31393237e 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -54,18 +54,19 @@ elements: dict type: list suboptions: - dhcp_server_ips: + name: + description: Specifies the name assigned to the Global IP Pool. + type: str + pool_type: description: > - The DHCP server IPs responsible for automatically assigning IP addresses - and network configuration parameters to devices on a local network. - elements: str - type: list - dns_server_ips: - description: Responsible for translating domain names into corresponding IP addresses. - elements: str - type: list - gateway: - description: Serves as an entry or exit point for data traffic between networks. + Includes both the Generic Ip Pool and Tunnel Ip Pool. + Generic - Used for general purpose within the network such as device + management or communication between the network devices. + Tunnel - Designated for the tunnel interfaces to encapsulate packets + within the network protocol. It is used in VPN connections, + GRE tunnels, or other types of overlay networks. + default: Generic + choices: [Generic, Tunnel] type: str ip_address_space: description: IP address space either IPv4 or IPv6. @@ -75,42 +76,58 @@ Defines the IP pool's Classless Inter-Domain Routing block, enabling systematic IP address distribution within a network. type: str + gateway: + description: Serves as an entry or exit point for data traffic between networks. + type: str + dhcp_server_ips: + description: > + The DHCP server IPs responsible for automatically assigning IP addresses + and network configuration parameters to devices on a local network. + elements: str + type: list + dns_server_ips: + description: Responsible for translating domain names into corresponding IP addresses. + elements: str + type: list prev_name: description: > The former identifier for the global pool. It should be used exclusively when you need to update the global pool's name. type: str - name: - description: Specifies the name assigned to the Global IP Pool. - type: str - pool_type: - description: > - Includes both the Generic Ip Pool and Tunnel Ip Pool. - Generic - Used for general purpose within the network such as device - management or communication between the network devices. - Tunnel - Designated for the tunnel interfaces to encapsulate packets - within the network protocol. It is used in VPN connections, - GRE tunnels, or other types of overlay networks. - default: Generic - choices: [Generic, Tunnel] - type: str reserve_pool_details: description: Reserved IP subpool details from the global pool. type: dict suboptions: - ipv4_dhcp_servers: - description: Specifies the IPv4 addresses for DHCP servers, for example, "1.1.1.1". - elements: str - type: list - ipv4_dns_servers: - description: Specifies the IPv4 addresses for DNS servers, for example, "4.4.4.4". - elements: str - type: list - ipv4_gateway: - description: Provides the gateway's IPv4 address, for example, "175.175.0.1". + site_name: + description: > + The name of the site provided as a path parameter, used + to specify where the IP sub-pool will be reserved. type: str - version_added: 4.0.0 + name: + description: Name of the reserve IP subpool. + type: str + pool_type: + description: Type of the reserve ip sub pool. + Generic - Used for general purpose within the network such as device + management or communication between the network devices. + LAN - Used for the devices and the resources within the Local Area Network + such as device connectivity, internal communication, or services. + Management - Used for the management purposes such as device management interfaces, + management access, or other administrative functions. + Service - Used for the network services and application such as DNS (Domain Name System), + DHCP (Dynamic Host Configuration Protocol), NTP (Network Time Protocol). + WAN - Used for the devices and resources with the Wide Area Network such as remote + sites interconnection with other network or services hosted within WAN. + default: Generic + choices: [Generic, LAN, Management, Service, WAN] + type: str + ipv6_address_space: + description: > + Determines whether both IPv6 and IPv4 inputs are required. + If set to false, only IPv4 inputs are required. + If set to true, both IPv6 and IPv4 inputs are required. + type: bool ipv4_global_pool: description: - IP v4 Global pool address with cidr, example 175.175.0.0/16. @@ -122,24 +139,30 @@ - If both 'ipv4_global_pool' and 'ipv4_global_pool_name' are provided, the 'ipv4_global_pool' will be given priority. type: str version_added: 6.14.0 + ipv4_subnet: + description: Indicates the IPv4 subnet address, for example, "175.175.0.0". + type: str ipv4_prefix: description: ip4 prefix length is enabled or ipv4 total Host input is enabled type: bool ipv4_prefix_length: description: The ipv4 prefix length is required when ipv4_prefix value is true. type: int - ipv4_subnet: - description: Indicates the IPv4 subnet address, for example, "175.175.0.0". - type: str ipv4_total_host: description: The total number of hosts for IPv4, required when the 'ipv4_prefix' is set to false. type: int - ipv6_address_space: - description: > - Determines whether both IPv6 and IPv4 inputs are required. - If set to false, only IPv4 inputs are required. - If set to true, both IPv6 and IPv4 inputs are required. - type: bool + ipv4_gateway: + description: Provides the gateway's IPv4 address, for example, "175.175.0.1". + type: str + version_added: 4.0.0 + ipv4_dhcp_servers: + description: Specifies the IPv4 addresses for DHCP servers, for example, "1.1.1.1". + elements: str + type: list + ipv4_dns_servers: + description: Specifies the IPv4 addresses for DNS servers, for example, "4.4.4.4". + elements: str + type: list ipv6_dhcp_servers: description: > Specifies the IPv6 addresses for DHCP servers in the format. @@ -159,7 +182,7 @@ type: str ipv6_global_pool: description: - - IPv6 Global pool address with cidr this is required when ipv6_address_space value is true, example 2001 db8 85a3 /64. + - IPv6 Global pool address with cidr, this is required when ipv6_address_space value is true, example 2001 db8 85a3 /64. - If both 'ipv6_global_pool' and 'ipv6_global_pool_name' are provided, the 'ipv6_global_pool' will be given priority. type: str ipv6_global_pool_name: @@ -168,6 +191,9 @@ - If both 'ipv6_global_pool' and 'ipv6_global_pool_name' are provided, the 'ipv6_global_pool' will be given priority. type: str version_added: 6.14.0 + ipv6_subnet: + description: IPv6 Subnet address, example 2001:db8:85a3:0:100. + type: str ipv6_prefix: description: > Ipv6 prefix value is true, the ip6 prefix length input field is enabled, @@ -176,51 +202,49 @@ ipv6_prefix_length: description: IPv6 prefix length is required when the ipv6_prefix value is true. type: int - ipv6_subnet: - description: IPv6 Subnet address, example 2001:db8:85a3:0:100. - type: str ipv6_total_host: description: The total number of hosts for IPv6 is required if the 'ipv6_prefix' is set to false. type: int - name: - description: Name of the reserve IP subpool. - type: str prev_name: description: The former name associated with the reserved IP sub-pool. type: str - site_name: - description: > - The name of the site provided as a path parameter, used - to specify where the IP sub-pool will be reserved. - type: str slaac_support: description: > Allows devices on IPv6 networks to self-configure their IP addresses autonomously, eliminating the need for manual setup. type: bool - pool_type: - description: Type of the reserve ip sub pool. - Generic - Used for general purpose within the network such as device - management or communication between the network devices. - LAN - Used for the devices and the resources within the Local Area Network - such as device connectivity, internal communication, or services. - Management - Used for the management purposes such as device management interfaces, - management access, or other administrative functions. - Service - Used for the network services and application such as DNS (Domain Name System), - DHCP (Dynamic Host Configuration Protocol), NTP (Network Time Protocol). - WAN - Used for the devices and resources with the Wide Area Network such as remote - sites interconnection with other network or services hosted within WAN. - default: Generic - choices: [Generic, LAN, Management, Service, WAN] - type: str network_management_details: description: Set default network settings for the site type: dict suboptions: + site_name: + description: > + The name of the site provided as a path parameter, used + to specify where the IP sub-pool will be reserved. + type: str settings: description: Network management details settings. type: dict suboptions: + network_aaa: + description: Network V2's network_aaa. + suboptions: + ip_address: + description: IP address for AAA and ISE server (eg 1.1.1.1). + type: str + network: + description: IP Address for AAA or ISE server (eg 2.2.2.2). + type: str + protocol: + description: Protocol for AAA or ISE serve (eg RADIUS). + type: str + servers: + description: Server type for AAA Network (eg AAA). + type: str + shared_secret: + description: Shared secret for ISE Server. + type: str + type: dict client_and_endpoint_aaa: description: Network V2's clientAndEndpoint_aaa. suboptions: @@ -257,6 +281,13 @@ description: Secondary IP Address for DHCP (eg 3.3.3.3). type: str type: dict + ntp_server: + description: IP address for NTP server (eg 1.1.1.2). + elements: str + type: list + timezone: + description: Input for time zone (eg Africa/Abidjan). + type: str message_of_the_day: description: Network V2's messageOfTheday. suboptions: @@ -277,29 +308,6 @@ description: Port for NetFlow Collector (eg; 443). type: int type: dict - network_aaa: - description: Network V2's network_aaa. - suboptions: - ip_address: - description: IP address for AAA and ISE server (eg 1.1.1.1). - type: str - network: - description: IP Address for AAA or ISE server (eg 2.2.2.2). - type: str - protocol: - description: Protocol for AAA or ISE serve (eg RADIUS). - type: str - servers: - description: Server type for AAA Network (eg AAA). - type: str - shared_secret: - description: Shared secret for ISE Server. - type: str - type: dict - ntp_server: - description: IP address for NTP server (eg 1.1.1.2). - elements: str - type: list snmp_server: description: Network V2's snmpServer. suboptions: @@ -322,14 +330,6 @@ elements: str type: list type: dict - timezone: - description: Input for time zone (eg Africa/Abidjan). - type: str - site_name: - description: > - The name of the site provided as a path parameter, used - to specify where the IP sub-pool will be reserved. - type: str requirements: - dnacentersdk == 2.4.5 - python >= 3.5 @@ -373,10 +373,10 @@ settings: ip_pool: - name: string - gateway: string + pool_type: Generic ip_address_space: string cidr: string - pool_type: Generic + gateway: string dhcp_server_ips: list dns_server_ips: list @@ -395,19 +395,19 @@ config_verify: True config: - reserve_pool_details: - - ipv6_address_space: True + - site_name: string + name: string + pool_type: LAN + ipv6_address_space: True ipv4_global_pool: string ipv4_prefix: True ipv4_prefix_length: 9 ipv4_subnet: string - name: string ipv6_prefix: True ipv6_prefix_length: 64 ipv6_global_pool: string ipv6_subnet: string - site_name: string slaac_support: True - pool_type: LAN - name: Create reserve an ip pool using global pool name cisco.dnac.network_settings_workflow_manager: @@ -424,19 +424,19 @@ config_verify: True config: - reserve_pool_details: - - ipv6_address_space: True + - name: string + site_name: string + pool_type: LAN + ipv6_address_space: True ipv4_global_pool_name: string ipv4_prefix: True ipv4_prefix_length: 9 ipv4_subnet: string - name: string ipv6_prefix: True ipv6_prefix_length: 64 ipv6_global_pool_name: string ipv6_subnet: string - site_name: string slaac_support: True - pool_type: LAN - name: Delete reserved pool cisco.dnac.network_settings_workflow_manager: @@ -453,8 +453,8 @@ config_verify: True config: - reserve_pool_details: - - name: string - site_name: string + - site_name: string + name: string - name: Manage the network functions cisco.dnac.network_settings_workflow_manager: @@ -471,34 +471,35 @@ config_verify: True config: - network_management_details: + site_name: string settings: + network_aaa: + network: string + protocol: string + servers: string + client_and_endpoint_aaa: + network: string + protocol: string + servers: string dhcp_server: list dns_server: domain_name: string primary_ip_address: string secondary_ip_address: string - client_and_endpoint_aaa: - network: string - protocol: string - servers: string + ntp_server: list + timezone: string message_of_the_day: banner_message: string retain_existing_banner: string netflow_collector: ip_address: string port: 443 - network_aaa: - network: string - protocol: string - servers: string - ntp_server: list snmp_server: configure_dnac_ip: True ip_addresses: list syslog_server: configure_dnac_ip: True ip_addresses: list - site_name: string """ RETURN = r""" @@ -1097,7 +1098,7 @@ def global_pool_exists(self, name): } is_pool_found = False value = 1 - while (not is_pool_found): + while(not is_pool_found): response = self.dnac._exec( family="network_settings", function="get_global_pool", @@ -1215,7 +1216,7 @@ def get_have_global_pool(self, global_pool_details): return self global_pool = [] - global_pool_ptr = 0 + global_pool_index = 0 for pool_details in global_pool_ippool: name = pool_details.get("name") if name is None: @@ -1226,16 +1227,16 @@ def get_have_global_pool(self, global_pool_details): # If the Global Pool doesn't exist and a previous name is provided # Else try using the previous name global_pool.append(self.global_pool_exists(name)) - self.log("Global pool details of '{0}': {1}".format(name, global_pool[global_pool_ptr]), "DEBUG") + self.log("Global pool details of '{0}': {1}".format(name, global_pool[global_pool_index]), "DEBUG") prev_name = pool_details.get("prev_name") - if global_pool[global_pool_ptr].get("exists") is False and \ + if global_pool[global_pool_index].get("exists") is False and \ prev_name is not None: global_pool.append(self.global_pool_exists(prev_name)) if global_pool.get("exists") is False: self.msg = "Prev name {0} doesn't exist in global_pool_details".format(prev_name) self.status = "failed" return self - global_pool_ptr += 1 + global_pool_index += 1 self.log("Global pool details: {0}".format(global_pool), "DEBUG") self.have.update({"globalPool": global_pool}) @@ -1263,7 +1264,7 @@ def get_have_reserve_pool(self, reserve_pool_details): # } reserve_pool = [] - reserve_pool_ptr = 0 + reserve_pool_index = 0 for item in reserve_pool_details: name = item.get("name") if name is None: @@ -1280,37 +1281,37 @@ def get_have_reserve_pool(self, reserve_pool_details): # Check if the Reserved Pool exists in Cisco Catalyst Center # based on the provided name and site name reserve_pool.append(self.reserve_pool_exists(name, site_name)) - if not reserve_pool[reserve_pool_ptr].get("success"): + if not reserve_pool[reserve_pool_index].get("success"): return self.check_return_status() - self.log("Reserved pool details for '{0}': {1}".format(name, reserve_pool[reserve_pool_ptr]), "DEBUG") + self.log("Reserved pool details for '{0}': {1}".format(name, reserve_pool[reserve_pool_index]), "DEBUG") # If the Reserved Pool doesn't exist and a previous name is provided # Else try using the previous name prev_name = item.get("prev_name") - if reserve_pool[reserve_pool_ptr].get("exists") is False and \ + if reserve_pool[reserve_pool_index].get("exists") is False and \ prev_name is not None: reserve_pool.append(self.reserve_pool_exists(prev_name, site_name)) - if not reserve_pool[reserve_pool_ptr].get("success"): + if not reserve_pool[reserve_pool_index].get("success"): return self.check_return_status() # If the previous name doesn't exist in Cisco Catalyst Center, return with error - if reserve_pool[reserve_pool_ptr].get("exists") is False: + if reserve_pool[reserve_pool_index].get("exists") is False: self.msg = "Prev name {0} doesn't exist in reserve_pool_details".format(prev_name) self.status = "failed" return self - self.log("Reserved pool exists: {0}".format(reserve_pool[reserve_pool_ptr].get("exists")), "DEBUG") - self.log("Reserved pool: {0}".format(reserve_pool[reserve_pool_ptr].get("details")), "DEBUG") + self.log("Reserved pool exists: {0}".format(reserve_pool[reserve_pool_index].get("exists")), "DEBUG") + self.log("Reserved pool: {0}".format(reserve_pool[reserve_pool_index].get("details")), "DEBUG") # If reserve pool exist, convert ipv6AddressSpace to the required format (boolean) - if reserve_pool[reserve_pool_ptr].get("exists"): - reserve_pool_info = reserve_pool[reserve_pool_ptr].get("details") + if reserve_pool[reserve_pool_index].get("exists"): + reserve_pool_info = reserve_pool[reserve_pool_index].get("details") if reserve_pool_info.get("ipv6AddressSpace") == "False": reserve_pool_info.update({"ipv6AddressSpace": False}) else: reserve_pool_info.update({"ipv6AddressSpace": True}) - reserve_pool_ptr += 1 + reserve_pool_index += 1 self.log("Reserved pool details: {0}".format(reserve_pool), "DEBUG") self.have.update({"reservePool": reserve_pool}) @@ -1402,7 +1403,7 @@ def get_global_pool_cidr(self, global_pool_cidr, global_pool_name): is_pool_found = False value = 1 - while (not is_pool_found): + while(not is_pool_found): response = self.dnac._exec( family="network_settings", function="get_global_pool", @@ -1453,7 +1454,7 @@ def get_want_global_pool(self, global_ippool): } } want_ippool = want_global.get("settings").get("ippool") - global_pool_ptr = 0 + global_pool_index = 0 for pool_details in global_ippool: pool_values = { "IpAddressSpace": pool_details.get("ip_address_space"), @@ -1465,7 +1466,7 @@ def get_want_global_pool(self, global_ippool): "type": pool_details.get("pool_type"), } # Converting to the required format based on the existing Global Pool - if not self.have.get("globalPool")[global_pool_ptr].get("exists"): + if not self.have.get("globalPool")[global_pool_index].get("exists"): if pool_values.get("dhcpServerIps") is None: pool_values.update({"dhcpServerIps": []}) if pool_values.get("dnsServerIps") is None: @@ -1477,14 +1478,14 @@ def get_want_global_pool(self, global_ippool): if pool_values.get("type") is None: pool_values.update({"type": "Generic"}) else: - have_ippool = self.have.get("globalPool")[global_pool_ptr].get("details") + have_ippool = self.have.get("globalPool")[global_pool_index].get("details") # Copy existing Global Pool information if the desired configuration is not provided pool_values.update({ "IpAddressSpace": have_ippool.get("IpAddressSpace"), "type": have_ippool.get("type"), "ipPoolCidr": have_ippool.get("ipPoolCidr"), - "id": self.have.get("globalPool")[global_pool_ptr].get("id") + "id": self.have.get("globalPool")[global_pool_index].get("id") }) # want_ippool.update({}) # want_ippool.update({}) @@ -1493,7 +1494,7 @@ def get_want_global_pool(self, global_ippool): if pool_values.get(key) is None and have_ippool.get(key) is not None: pool_values[key] = have_ippool[key] want_ippool.append(pool_values) - global_pool_ptr += 1 + global_pool_index += 1 self.log("Global pool playbook details: {0}".format(want_global), "DEBUG") self.want.update({"wantGlobal": want_global}) @@ -1516,7 +1517,7 @@ def get_want_reserve_pool(self, reserve_pool): """ want_reserve = [] - reserve_pool_ptr = 0 + reserve_pool_index = 0 for item in reserve_pool: pool_values = { "name": item.get("name"), @@ -1544,7 +1545,7 @@ def get_want_reserve_pool(self, reserve_pool): # Check for missing mandatory parameters in the playbook if not pool_values.get("name"): self.msg = "Missing mandatory parameter 'name' in reserve_pool_details '{0}' element" \ - .format(reserve_pool_ptr + 1) + .format(reserve_pool_index + 1) self.status = "failed" return self @@ -1552,7 +1553,7 @@ def get_want_reserve_pool(self, reserve_pool): if pool_values.get("ipv4Subnet") is None and \ pool_values.get("ipv4TotalHost") is None: self.msg = "missing parameter 'ipv4_subnet' or 'ipv4TotalHost' \ - while adding the ipv4 in reserve_pool_details '{0}' element".format(reserve_pool_ptr + 1) + while adding the ipv4 in reserve_pool_details '{0}' element".format(reserve_pool_index + 1) self.status = "failed" return self @@ -1560,23 +1561,23 @@ def get_want_reserve_pool(self, reserve_pool): if pool_values.get("ipv6Subnet") is None and \ pool_values.get("ipv6TotalHost") is None: self.msg = "missing parameter 'ipv6_subnet' or 'ipv6TotalHost' \ - while adding the ipv6 in reserve_pool_details '{0}' element".format(reserve_pool_ptr + 1) + while adding the ipv6 in reserve_pool_details '{0}' element".format(reserve_pool_index + 1) self.status = "failed" return self self.log("Reserved IP pool playbook details: {0}".format(pool_values), "DEBUG") # If there are no existing Reserved Pool details, validate and set defaults - if not self.have.get("reservePool")[reserve_pool_ptr].get("details"): + if not self.have.get("reservePool")[reserve_pool_index].get("details"): if not pool_values.get("ipv4GlobalPool"): self.msg = "missing parameter 'ipv4GlobalPool' in reserve_pool_details '{0}' element" \ - .format(reserve_pool_ptr + 1) + .format(reserve_pool_index + 1) self.status = "failed" return self if not pool_values.get("ipv4PrefixLength"): self.msg = "missing parameter 'ipv4_prefix_length' in reserve_pool_details '{0}' element" \ - .format(reserve_pool_ptr + 1) + .format(reserve_pool_index + 1) self.status = "failed" return self @@ -1615,7 +1616,7 @@ def get_want_reserve_pool(self, reserve_pool): del pool_values[key] want_reserve.append(pool_values) - reserve_pool_ptr += 1 + reserve_pool_index += 1 self.want.update({"wantReserve": want_reserve}) self.log("Reserved Pool details: {0}".format(want_reserve), "INFO") @@ -1903,19 +1904,19 @@ def update_global_pool(self, global_pool): create_global_pool = [] update_global_pool = [] - global_pool_ptr = 0 + global_pool_index = 0 result_global_pool = self.result.get("response")[0].get("globalPool") want_global_pool = self.want.get("wantGlobal").get("settings").get("ippool") self.log("Global pool playbook details: {0}".format(global_pool)) for item in self.have.get("globalPool"): result_global_pool.get("msg") \ - .update({want_global_pool[global_pool_ptr].get("ipPoolName"): {}}) + .update({want_global_pool[global_pool_index].get("ipPoolName"): {}}) if item.get("exists") is True: - update_global_pool.append(want_global_pool[global_pool_ptr]) + update_global_pool.append(want_global_pool[global_pool_index]) else: - create_global_pool.append(want_global_pool[global_pool_ptr]) + create_global_pool.append(want_global_pool[global_pool_index]) - global_pool_ptr += 1 + global_pool_index += 1 # Check create_global_pool; if yes, create the global pool if create_global_pool: @@ -1999,24 +2000,24 @@ def update_reserve_pool(self, reserve_pool): None """ - reserve_pool_ptr = -1 + reserve_pool_index = -1 for item in reserve_pool: - reserve_pool_ptr += 1 + reserve_pool_index += 1 name = item.get("name") result_reserve_pool = self.result.get("response")[1].get("reservePool") self.log("Current reserved pool '{0}' details in Catalyst Center: {1}" - .format(name, self.have.get("reservePool")[reserve_pool_ptr].get("details")), "DEBUG") + .format(name, self.have.get("reservePool")[reserve_pool_index].get("details")), "DEBUG") self.log("Desired reserved pool '{0}' details in Catalyst Center: {1}" - .format(name, self.want.get("wantReserve")[reserve_pool_ptr]), "DEBUG") + .format(name, self.want.get("wantReserve")[reserve_pool_index]), "DEBUG") # Check pool exist, if not create and return self.log("IPv4 reserved pool '{0}': {1}" - .format(name, self.want.get("wantReserve")[reserve_pool_ptr].get("ipv4GlobalPool")), "DEBUG") + .format(name, self.want.get("wantReserve")[reserve_pool_index].get("ipv4GlobalPool")), "DEBUG") site_name = item.get("site_name") - reserve_params = self.want.get("wantReserve")[reserve_pool_ptr] + reserve_params = self.want.get("wantReserve")[reserve_pool_index] site_id = self.get_site_id(site_name) reserve_params.update({"site_id": site_id}) - if not self.have.get("reservePool")[reserve_pool_ptr].get("exists"): + if not self.have.get("reservePool")[reserve_pool_index].get("exists"): self.log("Desired reserved pool '{0}' details (want): {1}" .format(name, reserve_params), "DEBUG") response = self.dnac._exec( @@ -2028,14 +2029,14 @@ def update_reserve_pool(self, reserve_pool): self.check_execution_response_status(response).check_return_status() self.log("Successfully created IP subpool reservation '{0}'.".format(name), "INFO") result_reserve_pool.get("response") \ - .update({name: self.want.get("wantReserve")[reserve_pool_ptr]}) + .update({name: self.want.get("wantReserve")[reserve_pool_index]}) result_reserve_pool.get("msg") \ .update({name: "Ip Subpool Reservation Created Successfully"}) continue # Check update is required - if not self.requires_update(self.have.get("reservePool")[reserve_pool_ptr].get("details"), - self.want.get("wantReserve")[reserve_pool_ptr], + if not self.requires_update(self.have.get("reservePool")[reserve_pool_index].get("details"), + self.want.get("wantReserve")[reserve_pool_index], self.reserve_pool_obj_params): self.log("Reserved ip subpool '{0}' doesn't require an update".format(name), "INFO") result_reserve_pool.get("msg") \ @@ -2049,7 +2050,7 @@ def update_reserve_pool(self, reserve_pool): .format(name, self.have.get("reservePool")), "DEBUG") self.log("Desired reserved ip pool '{0}' details: {1}" .format(name, self.want.get("wantReserve")), "DEBUG") - reserve_params.update({"id": self.have.get("reservePool")[reserve_pool_ptr].get("id")}) + reserve_params.update({"id": self.have.get("reservePool")[reserve_pool_index].get("id")}) response = self.dnac._exec( family="network_settings", function="update_reserve_ip_subpool", @@ -2059,9 +2060,9 @@ def update_reserve_pool(self, reserve_pool): self.check_execution_response_status(response).check_return_status() self.log("Reserved ip subpool '{0}' updated successfully.".format(name), "INFO") result_reserve_pool.get("response") \ - .update({name: self.have.get("reservePool")[reserve_pool_ptr].get("details")}) + .update({name: self.have.get("reservePool")[reserve_pool_index].get("details")}) result_reserve_pool.get("response").get(name) \ - .update({"Id": self.have.get("reservePool")[reserve_pool_ptr].get("id")}) + .update({"Id": self.have.get("reservePool")[reserve_pool_index].get("id")}) result_reserve_pool.get("msg") \ .update({name: "Reserved Ip Subpool updated successfully."}) @@ -2156,11 +2157,11 @@ def delete_reserve_pool(self, reserve_pool_details): self """ - reserve_pool_ptr = -1 + reserve_pool_index = -1 for item in reserve_pool_details: - reserve_pool_ptr += 1 + reserve_pool_index += 1 name = item.get("name") - reserve_pool_exists = self.have.get("reservePool")[reserve_pool_ptr].get("exists") + reserve_pool_exists = self.have.get("reservePool")[reserve_pool_index].get("exists") result_reserve_pool = self.result.get("response")[1].get("reservePool") if not reserve_pool_exists: @@ -2169,8 +2170,8 @@ def delete_reserve_pool(self, reserve_pool_details): continue self.log("Reserved IP pool scheduled for deletion: {0}" - .format(self.have.get("reservePool")[reserve_pool_ptr].get("name")), "INFO") - _id = self.have.get("reservePool")[reserve_pool_ptr].get("id") + .format(self.have.get("reservePool")[reserve_pool_index].get("name")), "INFO") + _id = self.have.get("reservePool")[reserve_pool_index].get("id") self.log("Reserved pool '{0}' id: {1}".format(name, _id), "DEBUG") response = self.dnac._exec( family="network_settings", @@ -2203,11 +2204,11 @@ def delete_global_pool(self, global_pool_details): """ result_global_pool = self.result.get("response")[0].get("globalPool") - global_pool_ptr = 0 + global_pool_index = 0 for item in self.have.get("globalPool"): global_pool_exists = item.get("exists") - name = global_pool_details.get("settings").get("ip_pool")[global_pool_ptr].get("name") - global_pool_ptr += 1 + name = global_pool_details.get("settings").get("ip_pool")[global_pool_index].get("name") + global_pool_index += 1 if not global_pool_exists: result_global_pool.get("msg").update({name: "Global Pool not found"}) self.log("Global pool '{0}' not found".format(name)) @@ -2273,37 +2274,37 @@ def verify_diff_merged(self, config): self.log("Current State (have): {0}".format(self.have), "INFO") self.log("Requested State (want): {0}".format(self.want), "INFO") if config.get("global_pool_details") is not None: - global_pool_ptr = 0 + global_pool_index = 0 self.log("Desired State of global pool (want): {0}" .format(self.want.get("wantGlobal")), "DEBUG") self.log("Current State of global pool (have): {0}" .format(self.have.get("globalPool")), "DEBUG") for item in self.want.get("wantGlobal").get("settings").get("ippool"): - if self.requires_update(self.have.get("globalPool")[global_pool_ptr].get("details"), + if self.requires_update(self.have.get("globalPool")[global_pool_index].get("details"), item, self.global_pool_obj_params): self.msg = "Global Pool Config is not applied to the Cisco Catalyst Center" self.status = "failed" return self - global_pool_ptr += 1 + global_pool_index += 1 self.log("Successfully validated global pool(s).", "INFO") self.result.get("response")[0].get("globalPool").update({"Validation": "Success"}) if config.get("reserve_pool_details") is not None: - reserve_pool_ptr = 0 + reserve_pool_index = 0 self.log("Desired State for reserve pool (want): {0}" .format(self.want.get("wantReserve")), "DEBUG") self.log("Current State for reserve pool (have): {0}" .format(self.have.get("reservePool")), "DEBUG") for item in self.want.get("wantReserve"): - if self.requires_update(self.have.get("reservePool")[reserve_pool_ptr].get("details"), + if self.requires_update(self.have.get("reservePool")[reserve_pool_index].get("details"), item, self.reserve_pool_obj_params): self.msg = "Reserved Pool Config is not applied to the Cisco Catalyst Center" self.status = "failed" return self - reserve_pool_ptr += 1 + reserve_pool_index += 1 self.log("Successfully validated the reserved pool(s)", "INFO") self.result.get("response")[1].get("reservePool").update({"Validation": "Success"}) @@ -2341,12 +2342,12 @@ def verify_diff_deleted(self, config): self.log("Current State (have): {0}".format(self.have), "INFO") self.log("Desired State (want): {0}".format(self.want), "INFO") if config.get("global_pool_details") is not None: - global_pool_ptr = 0 + global_pool_index = 0 global_pool_details = self.have.get("globalPool") for item in global_pool_details: global_pool_exists = item.get("exists") name = config.get("global_pool_details").get("settings") \ - .get("ip_pool")[global_pool_ptr].get("name") + .get("ip_pool")[global_pool_index].get("name") if global_pool_exists: self.msg = "Global Pool Config '{0}' is not applied to the Cisco Catalyst Center" \ .format(name) @@ -2354,15 +2355,15 @@ def verify_diff_deleted(self, config): return self self.log("Successfully validated absence of Global Pool '{0}'.".format(name), "INFO") - global_pool_ptr += 1 + global_pool_index += 1 self.result.get("response")[0].get("globalPool").update({"Validation": "Success"}) if config.get("reserve_pool_details") is not None: - reserve_pool_ptr = 0 + reserve_pool_index = 0 reserve_pool_details = self.have.get("reservePool") for item in reserve_pool_details: reserve_pool_exists = item.get("exists") - name = config.get("reserve_pool_details")[reserve_pool_ptr].get("name") + name = config.get("reserve_pool_details")[reserve_pool_index].get("name") if reserve_pool_exists: self.msg = "Reserved Pool Config '{0}' is not applied to the Catalyst Center" \ .format(name) From 9772de5842cab6d89479175e06809d117a46107c Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Mon, 15 Apr 2024 13:04:42 +0530 Subject: [PATCH 268/358] Resolved the sanity errors --- plugins/modules/network_settings_workflow_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index d31393237e..943afac62e 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -1098,7 +1098,7 @@ def global_pool_exists(self, name): } is_pool_found = False value = 1 - while(not is_pool_found): + while (not is_pool_found): response = self.dnac._exec( family="network_settings", function="get_global_pool", @@ -1403,7 +1403,7 @@ def get_global_pool_cidr(self, global_pool_cidr, global_pool_name): is_pool_found = False value = 1 - while(not is_pool_found): + while (not is_pool_found): response = self.dnac._exec( family="network_settings", function="get_global_pool", From 70f0ccfca7b053be752040bfdf35520e7200b7b5 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Mon, 15 Apr 2024 17:50:59 +0530 Subject: [PATCH 269/358] Eliminated the useless and redundant variables and optimised the code, made some changes in the logs --- .../network_settings_workflow_manager.py | 66 +++++++------------ 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index 943afac62e..5359aa2723 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -135,7 +135,7 @@ type: str ipv4_global_pool_name: description: - - Specifies the name assigned to the Ip v4 Global IP Pool. + - Specifies the name to be associated with the IPv4 Global IP Pool. - If both 'ipv4_global_pool' and 'ipv4_global_pool_name' are provided, the 'ipv4_global_pool' will be given priority. type: str version_added: 6.14.0 @@ -182,8 +182,9 @@ type: str ipv6_global_pool: description: - - IPv6 Global pool address with cidr, this is required when ipv6_address_space value is true, example 2001 db8 85a3 /64. - - If both 'ipv6_global_pool' and 'ipv6_global_pool_name' are provided, the 'ipv6_global_pool' will be given priority. + - The ipv6_global_pool is a mandatory when the ipv6_address_space is set to true. + - It specifies the global IPv6 address pool using CIDR notation, such as "2001:db8:85a3::/64". + - In cases where both ipv6_global_pool and ipv6_global_pool_name are specified, ipv6_global_pool will take precedence. type: str ipv6_global_pool_name: description: @@ -1096,9 +1097,8 @@ def global_pool_exists(self, name): "details": None, "id": None } - is_pool_found = False value = 1 - while (not is_pool_found): + while True: response = self.dnac._exec( family="network_settings", function="get_global_pool", @@ -1106,9 +1106,10 @@ def global_pool_exists(self, name): ) value += 25 if not isinstance(response, dict): - self.log("Failed to retrieve the global pool details - " - "Response is not a dictionary", "CRITICAL") - return global_pool + self.msg = "Failed to retrieve the global pool details - Response is not a dictionary" + self.log(self.msg, "CRITICAL") + self.status = "failed" + return self.check_return_status() all_global_pool_details = response.get("response") if not all_global_pool_details: @@ -1117,13 +1118,11 @@ def global_pool_exists(self, name): global_pool_details = get_dict_result(all_global_pool_details, "ipPoolName", name) if global_pool_details: - self.log("Global ip pool name: {0}".format(name), "DEBUG") - self.log("Global pool details: {0}".format(global_pool_details), "DEBUG") + self.log("Global pool found with name '{0}': {1}".format(name, global_pool_details), "INFO") global_pool.update({"exists": True}) global_pool.update({"id": global_pool_details.get("id")}) global_pool["details"] = self.get_global_pool_params(global_pool_details) - # global_pool.get("details").update({"id": global_pool_details.get("id")}) - is_pool_found = True + break self.log("Formatted global pool details: {0}".format(global_pool), "DEBUG") return global_pool @@ -1198,11 +1197,6 @@ def get_have_global_pool(self, global_pool_details): self - The current object with updated information. """ - # global_pool = { - # "exists": False, - # "details": None, - # "id": None - # } global_pool_settings = global_pool_details.get("settings") if global_pool_settings is None: self.msg = "settings in global_pool_details is missing in the playbook" @@ -1257,12 +1251,6 @@ def get_have_reserve_pool(self, reserve_pool_details): self - The current object with updated information. """ - # reserve_pool = { - # "exists": False, - # "details": None, - # "id": None - # } - reserve_pool = [] reserve_pool_index = 0 for item in reserve_pool_details: @@ -1401,9 +1389,8 @@ def get_global_pool_cidr(self, global_pool_cidr, global_pool_name): self.status = "failed" return self.check_return_status() - is_pool_found = False value = 1 - while (not is_pool_found): + while True: response = self.dnac._exec( family="network_settings", function="get_global_pool", @@ -1411,24 +1398,23 @@ def get_global_pool_cidr(self, global_pool_cidr, global_pool_name): ) value += 25 if not isinstance(response, dict): - self.log("Failed to retrieve the global pool details - " - "Response is not a dictionary", "CRITICAL") self.msg = "Failed to retrieve the global pool details - Response is not a dictionary" + self.log(self.msg, "CRITICAL") self.status = "failed" return self.check_return_status() all_global_pool_details = response.get("response") if not all_global_pool_details: - self.msg = "The global_pool_name '{0}' is not valid under reserve_pool_details".format(global_pool_name) + self.log("Invalid global_pool_name '{0}' under reserve_pool_details".format(global_pool_name), "ERROR") + self.msg = "No global pool details is available with the global_pool_name: {0}".format(global_pool_name) self.status = "failed" return self.check_return_status() global_pool_details = get_dict_result(all_global_pool_details, "ipPoolName", global_pool_name) if global_pool_details: - self.log("Global ip pool name: {0}".format(global_pool_name), "DEBUG") - self.log("Global pool details: {0}".format(global_pool_details), "DEBUG") global_pool_cidr = global_pool_details.get("ipPoolCidr") - is_pool_found = True + self.log("Global pool found with name '{0}': {1}".format(global_pool_name, global_pool_details), "INFO") + break self.log("Global Pool '{0}' cidr: {1}".format(global_pool_name, global_pool_cidr), "INFO") return global_pool_cidr @@ -1487,9 +1473,6 @@ def get_want_global_pool(self, global_ippool): "ipPoolCidr": have_ippool.get("ipPoolCidr"), "id": self.have.get("globalPool")[global_pool_index].get("id") }) - # want_ippool.update({}) - # want_ippool.update({}) - for key in ["dhcpServerIps", "dnsServerIps", "gateway"]: if pool_values.get(key) is None and have_ippool.get(key) is not None: pool_values[key] = have_ippool[key] @@ -1907,7 +1890,7 @@ def update_global_pool(self, global_pool): global_pool_index = 0 result_global_pool = self.result.get("response")[0].get("globalPool") want_global_pool = self.want.get("wantGlobal").get("settings").get("ippool") - self.log("Global pool playbook details: {0}".format(global_pool)) + self.log("Global pool playbook details: {0}".format(global_pool), "DEBUG") for item in self.have.get("globalPool"): result_global_pool.get("msg") \ .update({want_global_pool[global_pool_index].get("ipPoolName"): {}}) @@ -1936,7 +1919,7 @@ def update_global_pool(self, global_pool): self.log("Successfully created global pool successfully.", "INFO") for item in pool_params.get("settings").get("ippool"): name = item.get("ipPoolName") - self.log("Global pool '{0}' created successfully.".format(name)) + self.log("Global pool '{0}' created successfully.".format(name), "INFO") result_global_pool.get("response").update({"created": pool_params}) result_global_pool.get("msg").update({name: "Global Pool Created Successfully"}) @@ -1977,14 +1960,13 @@ def update_global_pool(self, global_pool): ) self.check_execution_response_status(response).check_return_status() - self.log("Global pool '{0}' updated successfully".format(name), "INFO") for item in pool_params.get("settings").get("ippool"): name = item.get("ipPoolName") - self.log("Global pool '{0}' Updated successfully.".format(name)) + self.log("Global pool '{0}' Updated successfully.".format(name), "INFO") result_global_pool.get("response").update({"globalPool Details": pool_params}) result_global_pool.get("msg").update({name: "Global Pool Updated Successfully"}) - self.log("The Global Pool config operations are successful") + self.log("The Global Pool config operations are successful", "INFO") return def update_reserve_pool(self, reserve_pool): @@ -2066,7 +2048,7 @@ def update_reserve_pool(self, reserve_pool): result_reserve_pool.get("msg") \ .update({name: "Reserved Ip Subpool updated successfully."}) - self.log("Reserved Ip Subpool Updated Successfully") + self.log("Reserved Ip Subpool Updated Successfully", "INFO") return def update_network(self, config): @@ -2166,7 +2148,7 @@ def delete_reserve_pool(self, reserve_pool_details): if not reserve_pool_exists: result_reserve_pool.get("msg").update({name: "Reserve Pool not found"}) - self.log("Reserved Ip Subpool '{0}' not found".format(name)) + self.log("Reserved Ip Subpool '{0}' not found".format(name), "INFO") continue self.log("Reserved IP pool scheduled for deletion: {0}" @@ -2211,7 +2193,7 @@ def delete_global_pool(self, global_pool_details): global_pool_index += 1 if not global_pool_exists: result_global_pool.get("msg").update({name: "Global Pool not found"}) - self.log("Global pool '{0}' not found".format(name)) + self.log("Global pool '{0}' not found".format(name), "INFO") continue id = item.get("id") From 77adb7609e28fc399cadbd247d4f2094e67aff74 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Mon, 15 Apr 2024 18:13:58 +0530 Subject: [PATCH 270/358] Addressed the review comments --- plugins/modules/network_settings_workflow_manager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index 5359aa2723..ffbb77397f 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -1406,7 +1406,7 @@ def get_global_pool_cidr(self, global_pool_cidr, global_pool_name): all_global_pool_details = response.get("response") if not all_global_pool_details: self.log("Invalid global_pool_name '{0}' under reserve_pool_details".format(global_pool_name), "ERROR") - self.msg = "No global pool details is available with the global_pool_name: {0}".format(global_pool_name) + self.msg = "No information found for the global pool named '{0}'".format(global_pool_name) self.status = "failed" return self.check_return_status() @@ -1966,7 +1966,7 @@ def update_global_pool(self, global_pool): result_global_pool.get("response").update({"globalPool Details": pool_params}) result_global_pool.get("msg").update({name: "Global Pool Updated Successfully"}) - self.log("The Global Pool config operations are successful", "INFO") + self.log("Global pool configuration operations completed successfully.", "INFO") return def update_reserve_pool(self, reserve_pool): @@ -2048,7 +2048,7 @@ def update_reserve_pool(self, reserve_pool): result_reserve_pool.get("msg") \ .update({name: "Reserved Ip Subpool updated successfully."}) - self.log("Reserved Ip Subpool Updated Successfully", "INFO") + self.log("Updated reserved IP subpool successfully", "INFO") return def update_network(self, config): From 6b7274ef141b767bf3d2a984e11045667fb64294 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 15 Apr 2024 09:56:27 -0400 Subject: [PATCH 271/358] network compliance module --- plugins/modules/network_compliance_workflow_manager.py | 4 ++-- .../tests/test_network_compliance_management.yml | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index cb08f3b414..9ce86d17e7 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -373,8 +373,8 @@ def run_compliance(self, run_compliance_params): def sync_device_config(self, sync_device_config_params): result = self.dnac_apply['exec']( family="compliance", - function="sync_device_config_params", - params=commit_device_configuration, + function="commit_device_configuration", + params=sync_device_config_params, op_modifies=True, ) diff --git a/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml b/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml index acf6845e6f..b7b099d199 100644 --- a/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml +++ b/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml @@ -1,5 +1,5 @@ --- -- debug: msg="Starting site management test" +- debug: msg="Starting network compliance management test" - debug: msg="Role Path {{ role_path }}" - block: @@ -34,11 +34,10 @@ dnac_log_append: False config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - site_name: "Global/India/Bangalore/Mantri Square/Floor1" + sync_device_config: False run_compliance: trigger_full: True - categories: ['INTENT','RUNNING_CONFIG'] - sync_device_config: False + categories: ['INTENT'] From c971c042d2224cd36b4fd7219d6d246ef34f2632 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Mon, 15 Apr 2024 22:09:41 +0530 Subject: [PATCH 272/358] Update device credentials giving error because API is taking empty string for http credentials from exported csv file --- plugins/modules/inventory_intent.py | 4 ++++ plugins/modules/inventory_workflow_manager.py | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index 2de7f0782b..10c4b92873 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -3235,6 +3235,10 @@ def get_diff_merged(self, config): if not playbook_params['httpPort']: playbook_params['httpPort'] = device_data.get('http_port', None) + for key, value in playbook_params.items(): + if value == " ": + playbook_params[key] = None + try: if playbook_params['updateMgmtIPaddressList']: new_mgmt_ipaddress = playbook_params['updateMgmtIPaddressList'][0]['newMgmtIpAddress'] diff --git a/plugins/modules/inventory_workflow_manager.py b/plugins/modules/inventory_workflow_manager.py index 79edfb59e1..dd3ab593ad 100644 --- a/plugins/modules/inventory_workflow_manager.py +++ b/plugins/modules/inventory_workflow_manager.py @@ -3227,6 +3227,10 @@ def get_diff_merged(self, config): if not playbook_params['httpPort']: playbook_params['httpPort'] = device_data.get('http_port', None) + for key, value in playbook_params.items(): + if value == " ": + playbook_params[key] = None + try: if playbook_params['updateMgmtIPaddressList']: new_mgmt_ipaddress = playbook_params['updateMgmtIPaddressList'][0]['newMgmtIpAddress'] @@ -3251,6 +3255,8 @@ def get_diff_merged(self, config): else: self.log("Playbook parameter for updating devices: {0}".format(str(playbook_params)), "DEBUG") + # import epdb; + # epdb.serve(port=8888) response = self.dnac._exec( family="devices", function='sync_devices', From c087417e8d51616aa03e04434d767d8ae254899c Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Tue, 16 Apr 2024 16:24:13 +0530 Subject: [PATCH 273/358] Resolved the problem with the snmp and syslog servers updation. --- plugins/modules/network_settings_workflow_manager.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index ffbb77397f..a5359b15bb 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -1075,6 +1075,14 @@ def get_network_params(self, site_id): } }) + network_settings_snmp = network_settings.get("snmpServer") + if not network_settings_snmp.get("ipAddresses"): + network_settings_snmp.update({"ipAddresses": []}) + + network_settings_syslog = network_settings.get("syslogServer") + if not network_settings_syslog.get("ipAddresses"): + network_settings_syslog.update({"ipAddresses": []}) + self.log("Formatted playbook network details: {0}".format(network_details), "DEBUG") return network_details From 3b6b758da5136afcf869c0be1d4f7df741090694 Mon Sep 17 00:00:00 2001 From: Abinash Date: Tue, 16 Apr 2024 11:31:19 +0000 Subject: [PATCH 274/358] Adding try and error exception for provision module --- plugins/modules/provision_workflow_manager.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/plugins/modules/provision_workflow_manager.py b/plugins/modules/provision_workflow_manager.py index f31ad3ccfa..c0379c9b98 100644 --- a/plugins/modules/provision_workflow_manager.py +++ b/plugins/modules/provision_workflow_manager.py @@ -479,14 +479,17 @@ class instance for further use. device_type = self.want.get("device_type") if device_type == "wired": - status_response = self.dnac_apply['exec']( - family="sda", - function="get_provisioned_wired_device", - op_modifies=True, - params={ - "device_management_ip_address": self.validated_config[0]["management_ip_address"] - }, - ) + try: + status_response = self.dnac_apply['exec']( + family="sda", + function="get_provisioned_wired_device", + op_modifies=True, + params={ + "device_management_ip_address": self.validated_config[0]["management_ip_address"] + }, + ) + except: + status_response = {} self.log("Wired device's status Response collected from 'get_provisioned_wired_device' API is:{0}".format(str(status_response)), "DEBUG") status = status_response.get("status") self.log("The provisioned status of the wired device is {0}".format(status), "INFO") From 1fc00b22505c81e1c295128a22daf7d8bea20877 Mon Sep 17 00:00:00 2001 From: Abinash Date: Tue, 16 Apr 2024 16:07:30 +0000 Subject: [PATCH 275/358] Adding try and error exception for provision module --- plugins/modules/provision_workflow_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/provision_workflow_manager.py b/plugins/modules/provision_workflow_manager.py index c0379c9b98..1bd3aa5d68 100644 --- a/plugins/modules/provision_workflow_manager.py +++ b/plugins/modules/provision_workflow_manager.py @@ -488,7 +488,7 @@ class instance for further use. "device_management_ip_address": self.validated_config[0]["management_ip_address"] }, ) - except: + except Exception: status_response = {} self.log("Wired device's status Response collected from 'get_provisioned_wired_device' API is:{0}".format(str(status_response)), "DEBUG") status = status_response.get("status") From f75fcfee2f49c3f81dcf5e4831ecc9e1fc3547ba Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Mon, 22 Apr 2024 11:57:46 +0530 Subject: [PATCH 276/358] Fix the issue of Wired Device Provisioning when running second time by handling the exception --- plugins/modules/inventory_intent.py | 50 ++++++++++++------ plugins/modules/inventory_workflow_manager.py | 52 +++++++++++++------ 2 files changed, 70 insertions(+), 32 deletions(-) diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index 10c4b92873..433dd6d908 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -775,6 +775,7 @@ def validate_input(self): 'clean_config': {'type': 'bool'}, 'add_user_defined_field': { 'type': 'list', + 'elements': 'dict', 'name': {'type': 'str'}, 'description': {'type': 'str'}, 'value': {'type': 'str'}, @@ -797,6 +798,7 @@ def validate_input(self): }, 'provision_wired_device': { 'type': 'list', + 'elements': 'dict', 'device_ip': {'type': 'str'}, 'site_name': {'type': 'str'}, 'resync_retry_count': {'default': 200, 'type': 'int'}, @@ -1586,6 +1588,20 @@ def provisioned_wired_device(self): 'siteNameHierarchy': site_name } + # Check the provisioning status of device + device_prov_status = self.get_provision_wired_device(device_ip) + if device_prov_status == 2: + self.status = "success" + already_provision_count += 1 + self.result['changed'] = False + self.msg = "Device '{0}' is already provisioned in the Cisco Catalyst Center".format(device_ip) + continue + if device_prov_status == 3: + self.status = "failed" + error_msg = "Cannot do Provisioning for device {0}.".format(device_ip) + self.log(error_msg, "ERROR") + continue + # Check till device comes into managed state while resync_retry_count: response = self.get_device_response(device_ip) @@ -1629,7 +1645,7 @@ def provisioned_wired_device(self): if response.get("status") == "failed": description = response.get("description") error_msg = "Cannot do Provisioning for device {0} beacuse of {1}".format(device_ip, description) - self.log(error_msg) + self.log(error_msg, "ERROR") continue task_id = response.get("taskId") @@ -1650,9 +1666,6 @@ def provisioned_wired_device(self): # Not returning from here as there might be possiblity that for some devices it comes into exception # but for others it gets provision successfully or If some devices are already provsioned self.handle_provisioning_exception(device_ip, e, device_type) - if "already provisioned" in str(e): - self.log(str(e), "INFO") - already_provision_count += 1 # Check If all the devices are already provsioned, return from here only if already_provision_count == total_devices_to_provisioned: @@ -2465,18 +2478,24 @@ def get_provision_wired_device(self, device_ip): logs the response. """ - response = self.dnac._exec( - family="sda", - function='get_provisioned_wired_device', - op_modifies=True, - params={"device_management_ip_address": device_ip} - ) + try: + flag = 3 + response = self.dnac._exec( + family="sda", + function='get_provisioned_wired_device', + op_modifies=True, + params={"device_management_ip_address": device_ip} + ) - if response.get("status") == "failed": - self.log("Cannot do provisioning for wired device {0} because of {1}.".format(device_ip, response.get('description')), "ERROR") - return False + if response.get("status") == "success" and "retrieved successfully" in response.get("description"): + flag = 2 + self.log("Wired device '{0}' already provisioned in the Cisco Catalyst Center.".format(device_ip), "INFO") - return True + except Exception as e: + if "not provisioned to any site" in str(e): + flag = 1 + + return flag def clear_mac_address(self, interface_id, deploy_mode, interface_name): """ @@ -3608,7 +3627,8 @@ def verify_diff_merged(self, config): for prov_dict in provision_wired_list: device_ip = prov_dict['device_ip'] provision_device_list.append(device_ip) - if not self.get_provision_wired_device(device_ip): + device_prov_status = self.get_provision_wired_device(device_ip) + if device_prov_status == 1 or device_prov_status == 3: provision_wired_flag = False break diff --git a/plugins/modules/inventory_workflow_manager.py b/plugins/modules/inventory_workflow_manager.py index dd3ab593ad..6dd4f00760 100644 --- a/plugins/modules/inventory_workflow_manager.py +++ b/plugins/modules/inventory_workflow_manager.py @@ -774,6 +774,7 @@ def validate_input(self): 'clean_config': {'type': 'bool'}, 'add_user_defined_field': { 'type': 'list', + 'elements': 'dict', 'name': {'type': 'str'}, 'description': {'type': 'str'}, 'value': {'type': 'str'}, @@ -796,6 +797,7 @@ def validate_input(self): }, 'provision_wired_device': { 'type': 'list', + 'elements': 'dict', 'device_ip': {'type': 'str'}, 'site_name': {'type': 'str'}, 'resync_retry_count': {'default': 200, 'type': 'int'}, @@ -1584,6 +1586,20 @@ def provisioned_wired_device(self): 'siteNameHierarchy': site_name } + # Check the provisioning status of device + device_prov_status = self.get_provision_wired_device(device_ip) + if device_prov_status == 2: + self.status = "success" + already_provision_count += 1 + self.result['changed'] = False + self.msg = "Device '{0}' is already provisioned in the Cisco Catalyst Center".format(device_ip) + continue + if device_prov_status == 3: + self.status = "failed" + error_msg = "Cannot do Provisioning for device {0}.".format(device_ip) + self.log(error_msg, "ERROR") + continue + # Check till device comes into managed state while resync_retry_count: response = self.get_device_response(device_ip) @@ -1626,7 +1642,7 @@ def provisioned_wired_device(self): if response.get("status") == "failed": description = response.get("description") error_msg = "Cannot do Provisioning for device {0} beacuse of {1}".format(device_ip, description) - self.log(error_msg) + self.log(error_msg, "ERROR") continue task_id = response.get("taskId") @@ -1647,9 +1663,6 @@ def provisioned_wired_device(self): # Not returning from here as there might be possiblity that for some devices it comes into exception # but for others it gets provision successfully or If some devices are already provsioned self.handle_provisioning_exception(device_ip, e, device_type) - if "already provisioned" in str(e): - self.log(str(e), "INFO") - already_provision_count += 1 # Check If all the devices are already provsioned, return from here only if already_provision_count == total_devices_to_provisioned: @@ -2457,18 +2470,24 @@ def get_provision_wired_device(self, device_ip): logs the response. """ - response = self.dnac._exec( - family="sda", - function='get_provisioned_wired_device', - op_modifies=True, - params={"device_management_ip_address": device_ip} - ) + try: + flag = 3 + response = self.dnac._exec( + family="sda", + function='get_provisioned_wired_device', + op_modifies=True, + params={"device_management_ip_address": device_ip} + ) - if response.get("status") == "failed": - self.log("Cannot do provisioning for wired device {0} because of {1}.".format(device_ip, response.get('description')), "ERROR") - return False + if response.get("status") == "success" and "retrieved successfully" in response.get("description"): + flag = 2 + self.log("Wired device '{0}' already provisioned in the Cisco Catalyst Center.".format(device_ip), "INFO") - return True + except Exception as e: + if "not provisioned to any site" in str(e): + flag = 1 + + return flag def clear_mac_address(self, interface_id, deploy_mode, interface_name): """ @@ -3255,8 +3274,6 @@ def get_diff_merged(self, config): else: self.log("Playbook parameter for updating devices: {0}".format(str(playbook_params)), "DEBUG") - # import epdb; - # epdb.serve(port=8888) response = self.dnac._exec( family="devices", function='sync_devices', @@ -3603,7 +3620,8 @@ def verify_diff_merged(self, config): for prov_dict in provision_wired_list: device_ip = prov_dict['device_ip'] provision_device_list.append(device_ip) - if not self.get_provision_wired_device(device_ip): + device_prov_status = self.get_provision_wired_device(device_ip) + if device_prov_status == 1 or device_prov_status == 3: provision_wired_flag = False break From 3f1ccfb3a6345d733a64ad94029981f4ae586ca5 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Mon, 22 Apr 2024 16:02:41 +0530 Subject: [PATCH 277/358] Add the log message for device prov status flag --- plugins/modules/inventory_intent.py | 3 ++- plugins/modules/inventory_workflow_manager.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index 433dd6d908..f807d53a23 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -1595,6 +1595,7 @@ def provisioned_wired_device(self): already_provision_count += 1 self.result['changed'] = False self.msg = "Device '{0}' is already provisioned in the Cisco Catalyst Center".format(device_ip) + self.log(self.msg, "INFO") continue if device_prov_status == 3: self.status = "failed" @@ -2487,7 +2488,7 @@ def get_provision_wired_device(self, device_ip): params={"device_management_ip_address": device_ip} ) - if response.get("status") == "success" and "retrieved successfully" in response.get("description"): + if response.get("status") == "success" and "Wired Provisioned device detail retrieved successfully." in response.get("description"): flag = 2 self.log("Wired device '{0}' already provisioned in the Cisco Catalyst Center.".format(device_ip), "INFO") diff --git a/plugins/modules/inventory_workflow_manager.py b/plugins/modules/inventory_workflow_manager.py index 6dd4f00760..2d3176c932 100644 --- a/plugins/modules/inventory_workflow_manager.py +++ b/plugins/modules/inventory_workflow_manager.py @@ -1593,6 +1593,7 @@ def provisioned_wired_device(self): already_provision_count += 1 self.result['changed'] = False self.msg = "Device '{0}' is already provisioned in the Cisco Catalyst Center".format(device_ip) + self.log(self.msg, "INFO") continue if device_prov_status == 3: self.status = "failed" From 7ac485e2e19e5d622582fbb82eceef4d8215a555 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 22 Apr 2024 11:29:56 -0400 Subject: [PATCH 278/358] network compliance module --- .../network_compliance_workflow_manager.py | 629 +++++++++++++++--- .../test_network_compliance_management.yml | 79 ++- 2 files changed, 619 insertions(+), 89 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 9ce86d17e7..f03a8e6a09 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -1,35 +1,124 @@ - #!/usr/bin/python # -*- coding: utf-8 -*- - # Copyright (c) 2024, Cisco Systems # GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) +"""Ansible module to perform Network Compliance Operations on devices in Cisco Catalyst Center.""" from __future__ import absolute_import, division, print_function import time __metaclass__ = type -__author__ = ("Madhan Sankaranarayanan, Rugvedi Kapse") - +__author__ = ("Rugvedi Kapse, Madhan Sankaranarayanan") DOCUMENTATION = r""" --- module: network_compliance_workflow_manager -short_description: +short_description: Network Compliance module for managing network compliance tasks on reachable device(s) in Cisco Catalyst Center. description: +- Perform compliance checks or sync configurations on reachable devices using IP Address(s) or Site. +- API to perform full compliance checks or specific category checks on reachable device(s). +- API to sync device configuration on device(s). version_added: '6.6.0' extends_documentation_fragment: - cisco.dnac.workflow_manager_params author: Rugvedi Kapse (@rukapse) + Madhan Sankaranarayanan (@madhansansel) options: + config_verify: + description: Set to True to verify the Cisco Catalyst Center config after applying the playbook config. + type: bool + default: False + state: + description: The state of Cisco Catalyst Center after module completion. + type: str + choices: [merged] + default: merged config: - - - + description: List of device details for running a compliance check or synchronizing device configuration. + type: list + elements: dict + required: True + suboptions: + ip_address_list: + description: List of IP addresses of devices to Run Compliance check on or Sync Device Configuration. + Either ip_address_list or site_name is required for module to execute. + If both ip_address_list and site_name are provided, ip_address_list takes precedence, and the operations are executed + on devices that are in the ip_address_list, but only those from the specified site + elements: str + type: list + site_name: + description: When site_name is specified, the module executes the operation on all the devices located within the specified site. + This is a string value that should represent the complete hierarchical path of the site. + For example: "Global/USA/San Francisco/Building_2/floor_1" + Either site_name or ip_address_list is required for module to execute. + If both site_name and ip_address_list are provided, ip_address_list takes precedence, and the operations are executed + on devices that are in the ip_address_list, but only those from the specified site + type: str + run_compliance: + description: Configuration for running a compliance check on the devices specified in the ip_address_list. + type: dict + suboptions: + trigger_full: + description: Determines if a full compliance check should be triggered. + This parameter is required when running a compliance check. + if it is True then compliance will be triggered for all categories. + If it is False then compliance will be triggered for categories mentioned in categories section. + required: This paramter is required in order to run compliance check on device(s). + type: bool + default: False + categories: + description: Specifying compliance categories allows you to trigger compliance checks only for the mentioned categories. + Compliance's categories are required when trigger_full is set to False. + Category can have any value among ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT' , 'EOX' , 'NETWORK_SETTINGS']. + Category 'INTENT' is mapped to compliance types: NETWORK_SETTINGS, NETWORK_PROFILE, WORKFLOW, FABRIC,APPLICATION_VISIBILITY. + + required: This parameter is required when trigger_full is set to False. + type: bool + default: False + sync_device_config: + description: Determines whether to synchronize the device configuration on the devices specified in the ip_address_list. + This operation, known as "Sync device configuration," primarily addresses the status of the `RUNNING_CONFIG`. + If set to True, and if `RUNNING_CONFIG` status is non-compliant this operation would commit device running configuration + to startup by issuing "write memory" to device. + type: bool + default: False + +requirements: +- dnacentersdk == 2.6.10 +- python >= 3.5 +notes: + - SDK Method used are + compliance.Compliance.run_compliance + compliance.Compliance.commit_device_configuration + task.Task.get_task_by_id + compliance.Compliance.get_compliance_detail + + - Paths used are + post /dna/intent/api/v1/compliance/ + post /dna/intent/api/v1/network-device-config/write-memory + get /dna/intent/api/v1/task/{taskId} + get /dna/intent/api/v1/compliance/detail """ EXAMPLES = r""" -- name: +- name: Run full compliance check on device(s) in the ip_address_list + cisco.dnac.network_compliance_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + run_compliance: + trigger_full: True + +- name: Run full compliance check on device(s) in the site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -39,14 +128,191 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" dnac_log_level: "{{dnac_log_level}}" - dnac_log: "{{dnac_log}}" - config: + dnac_log: False + state: merged + config: + - site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: True + +- name: Run full compliance check on device(s) with both ip_address_list and site + cisco.dnac.network_compliance_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: True + +- name: Run compliance check with specific categories on device(s) in the ip_address_list + cisco.dnac.network_compliance_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + +- name: Run compliance check with specific categories on device(s) in the site + cisco.dnac.network_compliance_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + +- name: Run compliance check with specific categories on device(s) with both ip_address_list and site + cisco.dnac.network_compliance_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + +- name: Sync device configuration on device(s) in the ip_address_list + cisco.dnac.network_compliance_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - site: "Global" + sync_device_config: True +- name: Sync device configuration on device(s) in the site + cisco.dnac.network_compliance_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - site_name: "Global/USA/San Francisco/Building_1/floor_1" + sync_device_config: True +- name: Sync device configuration on device(s) with both ip_address_list and site + cisco.dnac.network_compliance_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + sync_device_config: True + +- name: Run Compliance and sync configuration with both ip_address_list and site + cisco.dnac.network_compliance_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + sync_device_config: True """ RETURN = r""" -#Case_1: +#Case_1: +dnac_response: + description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK + returned: always + type: dict + sample: > + { + "status": "string", + "changed": bool, + "msg": "string" + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } + +#Case_2: When compliance check is run, the response of the compliance status +dnac_response: + description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK + returned: always + type: dict + sample: > + { + "status": "string", + "changed": bool, + "msg": "string" + "response": { + "taskId": "string", + "url": "string" + }, + "data": [list of dictionaries], + "version": "string" + } """ @@ -73,7 +339,6 @@ def __init__(self, module): super().__init__(module) - def validate_input(self, state=None): """ Validate the fields provided in the playbook. Checks the @@ -131,23 +396,23 @@ def validate_ip4_address_list(self, ip_address_list): self.log(msg, "ERROR") self.module.fail_json(msg) - self.log("Successfully validated the IP address/es: {0}", "DEBUG") + self.log("Successfully validated the IP address/es: {0}".format(ip_address_list), "DEBUG") def validate_run_compliance(self, run_compliance): trigger_full = run_compliance.get('trigger_full') categories = run_compliance.get('categories') - - if not trigger_full or not categories: - self.log("Both trigger_full and categories are required parameters for running compliance.", "ERROR") - self.status = "failed" - return self - - for category in categories: - if category.upper() not in ['RUNNING_CONFIG', 'INTENT']: - self.log(f"Invalid category provided: {category}. Valid categories are 'RUNNING_CONFIG' or 'INTENT'.", "ERROR") - self.status = "failed" - return self - + msg = "" + if trigger_full not in [True, False]: + msg = "trigger_full is a required parameter in order to run compliance check on device(s)" + if trigger_full == False and not categories: + msg = "Categories is a required paramtere when trigger_full is set to False." + + if categories and not all(category.upper() in ['INTENT','RUNNING_CONFIG' , 'IMAGE' , 'PSIRT' , 'EOX' , 'NETWORK_SETTINGS'] for category in categories): + msg = "Invalid category provided. Valid categories are ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT', 'EOX', 'NETWORK_SETTINGS']." + + if msg: + self.log(msg, 'ERROR') + self.module.fail_json(msg) self.log("Successfully validated run_compliance parameters.", "DEBUG") @@ -199,8 +464,8 @@ def get_device_ids_from_ip(self, ip_address_list): params={"managementIpAddress": device_ip} ) - if response: - self.log("Received API response from 'get_device_list' for device: {0}".format(str(response)), "DEBUG") + if response.get("response"): + self.log("Received API response from 'get_device_list' for device:{0} response: {1}".format(device_ip, str(response)), "DEBUG") response = response.get("response") if not response: continue @@ -208,6 +473,10 @@ def get_device_ids_from_ip(self, ip_address_list): if device_info["reachabilityStatus"] == "Reachable": device_id = response[0]["id"] mgmt_ip_instance_id_map[device_ip] = device_id + else: + self.msg = "Unable to retrieve device information for {0}. Please ensure that the device exists and is reachable.".format(device_ip) + self.log(self.msg, "ERROR") + self.module.fail_json(msg=self.msg) except Exception as e: error_message = "Error while fetching device ID for device: '{0}' from Cisco Catalyst Center: {1}".format(device_ip, str(e)) @@ -216,7 +485,6 @@ def get_device_ids_from_ip(self, ip_address_list): return mgmt_ip_instance_id_map def get_device_ids_from_site(self, site_name, site_id): - #device_id_list = [] mgmt_ip_instance_id_map = {} site_params = { @@ -252,7 +520,6 @@ def get_device_ids_from_site(self, site_name, site_id): for item_dict in item['response']: # Check if the device is reachable if item_dict["reachabilityStatus"] == "Reachable": - #device_id_list.append(item_dict["instanceUuid"]) mgmt_ip_instance_id_map[item_dict["managementIpAddress"]] = item_dict["instanceUuid"] else: msg = 'Unable to get deviceId for device {0} in site {1} as its status is {2}'.format( @@ -292,7 +559,7 @@ def get_device_id_list(self, ip_address_list, site_name): elif site_name and not ip_address_list: (site_exists, site_id) = self.site_exists(site_name) if site_exists: - mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_id) + mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) elif ip_address_list and not site_name: mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) @@ -302,6 +569,10 @@ def get_device_id_list(self, ip_address_list, site_name): def get_want(self, config): """ """ + run_compliance_params = {} + sync_device_config_params = {} + compliance_detail_params = {} + #Validate either ip_address_list OR site_name is present ip_address_list = config.get('ip_address_list') @@ -323,23 +594,37 @@ def get_want(self, config): run_compliance = config.get('run_compliance') sync_device_config = config.get('sync_device_config') if run_compliance: - self.validate_run_compliance(run_compliance) - run_compliance_params = { 'triggerFull': config.get('run_compliance').get('trigger_full'), - 'categories': config.get('run_compliance').get('categories'), 'deviceUuids': list(mgmt_ip_instance_id_map.values()), } - else: - run_compliance_params = {} + + compliance_detail_params = { + 'deviceUuid': ','.join(list(mgmt_ip_instance_id_map.values())), + } + + if config.get('run_compliance').get('categories'): + categories_copy = config.get('run_compliance').get('categories').copy() + run_compliance_params['categories'] = categories_copy + + compliance_types = config.get('run_compliance').get('categories') + if 'INTENT' in compliance_types: + compliance_types.remove('INTENT') + compliance_types.extend(['NETWORK_PROFILE', 'APPLICATION_VISIBILITY', 'WORKFLOW', 'FABRIC', 'NETWORK_SETTINGS']) + compliance_types = list(set(compliance_types)) + compliance_detail_params['complianceType'] = "', '".join(compliance_types) + compliance_detail_params['complianceType'] = "'" + compliance_detail_params['complianceType'] + "'" if sync_device_config: sync_device_config_params = { 'deviceId': list(mgmt_ip_instance_id_map.values()) + } + compliance_detail_params_sync = { + 'deviceUuid': ','.join(list(mgmt_ip_instance_id_map.values())), + 'complianceType': 'RUNNING_CONFIG' } - else: - sync_device_config_params = {} + want = {} want = dict( @@ -347,13 +632,41 @@ def get_want(self, config): site_name = site_name, mgmt_ip_instance_id_map = mgmt_ip_instance_id_map, run_compliance_params=run_compliance_params, - sync_device_config_params=sync_device_config_params + sync_device_config_params=sync_device_config_params, + compliance_detail_params=compliance_detail_params, + compliance_detail_params_sync=compliance_detail_params_sync ) self.want = want self.log("Desired State (want): {0}".format(str(self.want)), "INFO") return self + def get_compliance_detail(self, compliance_detail_params): + response = self.dnac_apply['exec']( + family="compliance", + function='get_compliance_detail', + params=compliance_detail_params, + op_modifies=True, + ) + response = response.response + + self.log("The response received post get_compliance_detail API call is {0}".format(str(response)), "DEBUG") + return response + + def modify_compliance_response(self, response, mgmt_ip_instance_id_map): + modified_response = {} + + for item in response: + device_uuid = item.get('deviceUuid') + ip_address = next((ip for ip, uuid in mgmt_ip_instance_id_map.items() if uuid == device_uuid), None) + #if ip_address and item.get('status')!= 'NOT_APPLICABLE': + if ip_address: + if ip_address not in modified_response: + modified_response[ip_address] = [] + modified_response[ip_address].append(item) + + return modified_response + def run_compliance(self, run_compliance_params): @@ -364,9 +677,9 @@ def run_compliance(self, run_compliance_params): op_modifies=True, ) - self.log("The response received post Run Compliance API call is {0}".format(str(result)), "DEBUG") + self.log("The response received post run_compliancee API call is {0}".format(str(result)), "DEBUG") - self.result.update(dict(run_compliance_result=result)) + self.result.update(dict(response=result['response'])) self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") return result.response.get('taskId') @@ -378,63 +691,213 @@ def sync_device_config(self, sync_device_config_params): op_modifies=True, ) - self.log("The response received post Commit Configuration API call is {0}".format(str(result)), "DEBUG") + self.log("The response received post commit_device_configuration API call is {0}".format(str(result)), "DEBUG") - self.result.update(dict(sync_device_configuration_result=result)) + self.result.update(dict(response=result['response'])) self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") return result.response.get('taskId') - def get_merged_task_status(self, task_id, task_name, ip_address_list): - result = False - params = dict(task_id=task_id) + def get_task_status(self, task_id, task_name): + response = self.dnac_apply['exec']( + family="task", + function='get_task_by_id', + params=dict(task_id=task_id), + op_modifies=True, + ) + response = response.response + self.log("Task status for the task id {0} is {1}, is_error: {2}".format(str(task_id), str(response), str(response.get('isError'))), "INFO") + return response + + def update_result(self, status, changed, msg, log_level, data=None): + self.status = status + self.result['status'] = status + self.result['msg'] = msg + self.result['changed'] = changed + self.log(msg, log_level) + if status == 'failed': + self.result['failed'] = True + if data: + self.result['data'] = data + return self + + def exit_while_loop(self, start_time, task_id, task_name, response): + if time.time() - start_time > 10: + if response.get('data'): + self.msg = "Task {0} with task id {1} has not completed within the timeout period. Task Status: {2} ".format( + task_name, task_id, response.get('data')) + else: + self.msg = "Task {0} with task id {1} has not completed within the timeout period.".format( + task_name, task_id) + self.update_result('failed', False, self.msg, 'ERROR') + return True + return False + + def handle_error(self, task_name, mgmt_ip_instance_id_map, failure_reason=None): + if failure_reason: + self.msg = "An error occurred while performing {0} on device(s): {1}. The operation failed due to the following reason: {2}".format( + task_name, list(mgmt_ip_instance_id_map.keys()), failure_reason) + else: + self.msg = "An error occurred while performing {0} on device(s): {1}".format( + task_name, list(mgmt_ip_instance_id_map.keys())) + self.update_result('failed', False, self.msg, 'ERROR') + return self + + + def get_compliance_task_status(self, task_id, mgmt_ip_instance_id_map): + task_name = 'Run Compliance Check' start_time = time.time() while True: + response = self.get_task_status(task_id, task_name) # Check if the elapsed time exceeds the timeout - if time.time() - start_time > 300: - self.log("Task {0} with task id {1} has not completed within the timeout period.".format(task_name, task_id), "CRITICAL") - self.module.fail_json(msg="Task execution timed out.") + if self.exit_while_loop(start_time, task_id, task_name, response): + break + + if response.get('isError'): + failure_reason = response.get("failureReason") + self.handle_error(task_name, mgmt_ip_instance_id_map, failure_reason) break - response = self.dnac_apply['exec']( - family="task", - function='get_task_by_id', - params=params, - op_modifies=True, - ) - response = response.response - self.log("Task status for the task id {0} is {1}, is_error: {2}".format(str(task_id), str(response), str(response.get('isError'))), "INFO") - - # Check for success status - if not response.get('isError') and 'success' in response.get('progress').lower(): - self.log("Task {0} with task id {1} has completed successfully on device/s: {2} .".format(task_name, str(task_id), ip_address_list), "INFO") - result = True - - self.status = "success" - self.msg = "{0} has completed successfully on device/s: {1}".format(task_name, ip_address_list) - self.result['response'] = self.msg - self.result['changed'] = True - self.result['status'] = "success" - self.log(self.msg, "INFO") - break - - # Check for failed status - if response.get('isError') or 'failed' in response.get('progress').lower(): - msg = 'Task {0} with task id {1} has not completed on device/s {2}- Reason: {3}'.format( - task_name, task_id, ip_address_list, response.get("failureReason")) - self.log(msg, "CRITICAL") - self.module.fail_json(msg=msg) - break + elif not response.get('isError') and 'success' in response.get('progress').lower(): + self.msg = "{0} has completed successfully on device(s): {1}".format(task_name, list(mgmt_ip_instance_id_map.keys())) + response = self.get_compliance_detail(self.want.get('compliance_detail_params')) + modified_response = self.modify_compliance_response(response, mgmt_ip_instance_id_map) + self.log('Modified {0} Response for device(s) {1} : {2}'.format(task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), 'INFO') + self.update_result('success', True, self.msg, 'INFO', modified_response) + break + + elif 'failed' in response.get('progress').lower(): + self.msg = "Failed to {0} on the following device(s): {1}".format(task_name, list(mgmt_ip_instance_id_map.keys())) + self.update_result('failed', False, self.msg, 'CRITICAL') + break + return self + + def sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): + task_name = 'Sync Device Configuration' + + #Validate if sync is required + response = self.get_compliance_detail(self.want.get('compliance_detail_params_sync')) + modified_response = self.modify_compliance_response(response, mgmt_ip_instance_id_map) + self.log('Modified {0} Response for device(s) {1} : {2}'.format(task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), 'INFO') + + categorized_devices = {'COMPLIANT': {}, 'NON_COMPLIANT': {}, 'OTHER': {}} + for ip_address, compliance_type in modified_response.items(): + if compliance_type[0]['status'] == 'NON_COMPLIANT': + categorized_devices['NON_COMPLIANT'][ip_address] = compliance_type + elif compliance_type[0]['status'] == 'COMPLIANT': + categorized_devices['COMPLIANT'][ip_address] = compliance_type + else: + categorized_devices['OTHER'][ip_address] = compliance_type + + if len(categorized_devices['COMPLIANT']) == len(mgmt_ip_instance_id_map): + self.msg = "Device(s) {0} are already compliant with the RUNNING_CONFIG compliance type. Therefore, {1} is not required.".format( + list(mgmt_ip_instance_id_map.keys()), task_name) + self.update_result('success', False, self.msg, 'INFO',categorized_devices['COMPLIANT']) + return self + + if categorized_devices['OTHER']: + self.msg = "The operation {0} cannot be performed on device(s) {1} because the status of the RUNNING_CONFIG compliance type is not as expected; it should be NON_COMPLIANT.".format( + task_name, list(mgmt_ip_instance_id_map.keys())) + self.update_result('success', False, self.msg, 'INFO',categorized_devices ) + return self + + + start_time = time.time() + while True: + + response = self.get_task_status(task_id, task_name) + + # Check if the elapsed time exceeds the timeout + if self.exit_while_loop(start_time, task_id, task_name, response): + break + + if response.get('isError'): + failure_reason = response.get("failureReason") + self.handle_error(task_name, mgmt_ip_instance_id_map, failure_reason) + break + + elif len(mgmt_ip_instance_id_map) == 1: + ip_address = next(iter(mgmt_ip_instance_id_map)) + progress = response.get('progress', '').lower() + if not response.get('isError') and 'success' in progress: + self.log("Task {0} with task id {1} has completed successfully on device {2}.".format( + task_name, task_id, ip_address), "INFO") + self.msg = "{0} has completed successfully on device: {1}".format(task_name, ip_address) + self.update_result('success', True, self.msg, 'INFO') + break + + elif 'failed' in progress: + self.log('Task {0} with task id {1} has failed on device {2}.'.format( + task_name, task_id, ip_address), "CRITICAL") + + self.msg = "Failed to {0} on the following device(s):".format(task_name, ip_address) + self.update_result('failed', False, self.msg, 'CRITICAL') + break + + elif len(mgmt_ip_instance_id_map) > 1: + data = response.get('data') + if data: + count_values = [count.strip() for count in data.split(',')] + success_count = int(count_values[0].split('=')[1]) + running_count = int(count_values[2].split('=')[1]) + pending_count = int(count_values[3].split('=')[1]) + total_count = int(count_values[-1].split('=')[1]) + + if success_count == len(mgmt_ip_instance_id_map): + self.log("Task {0} with task id {1} has completed successfully on devices: {2}.".format( + task_name, task_id, list(mgmt_ip_instance_id_map.keys())), "INFO") + + self.msg = "{0} has completed successfully on devices: {1}".format(task_name, list(mgmt_ip_instance_id_map.keys())) + self.update_result('success', True, self.msg, 'INFO') + break + + elif running_count == 0 and pending_count == 0 and success_count < len(mgmt_ip_instance_id_map): + status_info = {'Success': {'count': success_count, 'devices': []}, 'Failed': {'count': failure_count, 'devices': []}} + device_actions = response['progress'].split(',') + for action in device_actions: + device_id = action.split('=')[1].strip() + ip_address = next((ip for ip, device_id_map in mgmt_ip_instance_id_map.items() if device_id_map == device_id), None) + if ip_address: + if 'Success' in action: + status_info['Success']['devices'].append({'ip_address': ip_address, 'device_id': device_id}) + elif 'Failed' in action: + status_info['Failure']['devices'].append({'ip_address': ip_address, 'device_id': device_id}) + self.msg = 'Task {0} status: {1}'.format(task_name, status_info) + self.update_result('failed', True, self.msg, 'CRITICAL') + break + return self def get_diff_merged(self): if self.want.get('run_compliance_params'): result_task_id = self.run_compliance(self.want.get('run_compliance_params')) - self.get_merged_task_status(result_task_id, 'Run Compliance', list(self.want.get('mgmt_ip_instance_id_map').keys())) + self.get_compliance_task_status(result_task_id, self.want.get('mgmt_ip_instance_id_map')).check_return_status() if self.want.get('sync_device_config_params'): result_task_id = self.sync_device_config(self.want.get('sync_device_config_params')) - self.get_merged_task_status(result_task_id, 'Commit Device Configuration', list(self.want.get('mgmt_ip_instance_id_map').keys())) + self.sync_config_task_status(result_task_id, self.want.get('mgmt_ip_instance_id_map')).check_return_status() + + return self + + # def get_diff_merged(self): + # action_map = { + # 'run_compliance_params': (self.run_compliance, self.get_compliance_task_status), + # 'sync_device_config_params': (self.sync_device_config, self.sync_config_task_status) + # } + + # if not any(self.want.get(action_param) for action_param in action_map): + # msg = "Network compliance operations are missing from the playbook. You can perform compliance checks or sync device configuration tasks using this module." + # self.log(msg, "ERROR") + # self.module.fail_json(msg) + + # for action_param, (action_func, status_func) in action_map.items(): + # if self.want.get(action_param): + # result_task_id = action_func(self.want.get(action_param)) + # status_func(result_task_id, self.want.get('mgmt_ip_instance_id_map')).check_return_status() + + # return self + def verify_diff_merged(self, config): + pass def main(): """ main entry point for module execution @@ -475,12 +938,12 @@ def main(): for config in ccc_network_compliance.validated_config: ccc_network_compliance.get_want(config) - ccc_network_compliance.get_diff_merged() + ccc_network_compliance.get_diff_state_apply[state]().check_return_status() + # if config_verify: + # ccc_network_compliance.verify_diff_state_apply[state](config).check_return_status() module.exit_json(**ccc_network_compliance.result) - if __name__ == "__main__": main() - diff --git a/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml b/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml index b7b099d199..9a4ed8886e 100644 --- a/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml +++ b/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml @@ -25,20 +25,87 @@ ############################################# -# # +# Run Full Compliance on IP List # ############################################# - - name: Run Compliance + - name: Run full complaince check cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login dnac_log_append: False config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - sync_device_config: False + #site_name: "Global" run_compliance: - trigger_full: True - categories: ['INTENT'] + trigger_full: True + #trigger_full: True + #categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT', 'EOX', 'NETWORK_SETTINGS'] + sync_device_config: True +############################################# +# Run Full Compliance on Site # +############################################# + +# - name: Run full complaince check on Site +# cisco.dnac.network_compliance_workflow_manager: +# <<: *dnac_login +# dnac_log_append: False +# config: +# - site: "Global" +# run_compliance: +# trigger_full: True + +# ############################################# +# # Run Compliance with Categories on IP List # +# ############################################# + +# - name: Run complaince check with specific categories on IP list +# cisco.dnac.network_compliance_workflow_manager: +# <<: *dnac_login +# dnac_log_append: False +# config: +# - #ip_address_list: ['204.1.2.5'] +# ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] +# run_compliance: +# trigger_full: False +# categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + +# ############################################# +# # Run Compliance with Categories on Site # +# ############################################# + +# - name: Run full complaince check +# cisco.dnac.network_compliance_workflow_manager: +# <<: *dnac_login +# dnac_log_append: False +# config: +# - site_name: "Global" +# run_compliance: +# trigger_full: False +# categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + +# ############################################# +# # Sync Device Config on IP List # +# ############################################# + +# - name: Run full complaince check +# cisco.dnac.network_compliance_workflow_manager: +# <<: *dnac_login +# dnac_log_append: False +# config: +# - #ip_address_list: ['204.1.2.5'] +# ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] +# sync_device_config: True + +# ############################################# +# # Sync Device Config on Site # +# ############################################# +# - name: Run full complaince check +# cisco.dnac.network_compliance_workflow_manager: +# <<: *dnac_login +# dnac_log_append: False +# config: +# - site_name: "Global" +# sync_device_config: True - \ No newline at end of file +# \ No newline at end of file From 7691ee2a7022c847f2ec6fe1d4b2c3b3bfd0c7e8 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Tue, 23 Apr 2024 22:39:13 +0530 Subject: [PATCH 279/358] Added the code for adding/updating the configuration of Syslog, SNMP, Email, Rest Webhook Destination, ITSM integration settings along with deletion and write documentation with examples for all destinations and added sample playbook for destinations configuration. --- ...nts_and_notifications_workflow_manager.yml | 65 + playbooks/input_events_and_notification.yml | 40 + ...ents_and_notifications_workflow_manager.py | 2581 +++++++++++++++++ 3 files changed, 2686 insertions(+) create mode 100644 playbooks/events_and_notifications_workflow_manager.yml create mode 100644 playbooks/input_events_and_notification.yml create mode 100644 plugins/modules/events_and_notifications_workflow_manager.py diff --git a/playbooks/events_and_notifications_workflow_manager.yml b/playbooks/events_and_notifications_workflow_manager.yml new file mode 100644 index 0000000000..ac96041e5d --- /dev/null +++ b/playbooks/events_and_notifications_workflow_manager.yml @@ -0,0 +1,65 @@ +--- +- name: Configure channels and create events in Cisco Catalyst Center + hosts: localhost + connection: local + gather_facts: no + vars_files: + - "input_events_and_notification.yml" + - "credentials.yml" + tasks: + - name: Add/update channels with destination and create/update events in Cisco Catalyst Center. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: DEBUG + dnac_log: true + config_verify: true + state: merged + config: + - syslog_destination: + name: "{{item.syslog_destination.name}}" + description: "{{item.syslog_destination.description}}" + host: "{{item.syslog_destination.host}}" + protocol: "{{item.syslog_destination.protocol}}" + port: "{{item.syslog_destination.port}}" + rest_webhook_destination: + name: "{{item.rest_webhook_destination.name}}" + description: "{{item.rest_webhook_destination.description}}" + url: "{{item.rest_webhook_destination.url}}" + method: "{{item.rest_webhook_destination.method}}" + trust_cert: "{{item.rest_webhook_destination.trust_cert}}" + email_destination: + from_email: "{{item.email_destination.from_email}}" + to_email: "{{item.email_destination.to_email}}" + subject: "{{item.email_destination.subject}}" + primary_smtp_config: + hostname: "{{item.email_destination.primary_smtp_config.hostname}}" + port: "{{item.email_destination.primary_smtp_config.port}}" + snmp_destination: + name: "{{item.snmp_destination.name}}" + description: "{{item.snmp_destination.description}}" + ip_address: "{{item.snmp_destination.ip_address}}" + port: "{{item.snmp_destination.port}}" + snmp_version: "{{item.snmp_destination.snmp_version}}" + username: "{{item.snmp_destination.username}}" + snmp_mode: "{{item.snmp_destination.snmp_mode}}" + snmp_auth_type: "{{item.snmp_destination.snmp_auth_type}}" + auth_password: "{{item.snmp_destination.auth_password}}" + snmp_privacy_type: "{{item.snmp_destination.snmp_privacy_type}}" + privacy_password: "{{item.snmp_destination.privacy_password}}" + itsm_setting: + name: "{{item.itsm_setting.name}}" + description: "{{item.itsm_setting.description}}" + connection_settings: + url: "{{item.itsm_setting.connection_settings.url}}" + auth_username: "{{item.itsm_setting.connection_settings.username}}" + auth_password: "{{item.itsm_setting.connection_settings.password}}" + + with_items: "{{ events_notification }}" + tags: + - events_testing diff --git a/playbooks/input_events_and_notification.yml b/playbooks/input_events_and_notification.yml new file mode 100644 index 0000000000..2cae229c01 --- /dev/null +++ b/playbooks/input_events_and_notification.yml @@ -0,0 +1,40 @@ +--- +events_notification: + - syslog_destination: + name: Syslog Demo test + description: "Adding syslog destination for testing" + host: "10.30.0.90" + protocol: "TCP" + port: 652 + rest_webhook_destination: + name: "webhook demo 19" + description: "webhhok description for testing" + url: "https://10.195.227.14/dna" + method: "POST" + trust_cert: False + email_destination: + from_email: "test@cisco.com" + to_email: "abmahesh@cisco.com" + subject: "Ansible testing" + primary_smtp_config: + hostname: "outbound.cisco.com" + port: '25' + snmp_destination: + name: Snmp test + description: "Adding snmp destination for testing for update" + ip_address: "10.30.0.91" + port: '265' + snmp_version: "V3" + username: cisco123 + snmp_mode: AUTH_PRIVACY + snmp_auth_type: SHA + auth_password: authpass123 + snmp_privacy_type: AES128 + privacy_password: privacy123 + itsm_setting: + name: "Playbook itsm demo" + description: "ITSM description for testing" + connection_settings: + url: "https://catalystcente1.com" + username: "catalyst" + password: "catalyst@123" diff --git a/plugins/modules/events_and_notifications_workflow_manager.py b/plugins/modules/events_and_notifications_workflow_manager.py new file mode 100644 index 0000000000..f845c5182e --- /dev/null +++ b/plugins/modules/events_and_notifications_workflow_manager.py @@ -0,0 +1,2581 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2022, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type +__author__ = ("Abhishek Maheshwari, Madhan Sankaranarayanan") + +DOCUMENTATION = r""" +--- +module: events_and_notifications_workflow_manager +short_description: Resource module for Network Device +description: +- Manage operations create, update and delete of the resource Network Device. +- Adds the device with given credential. +- Deletes the network device for the given Id. +- Sync the devices provided as input. +version_added: '6.8.0' +extends_documentation_fragment: + - cisco.dnac.intent_params +author: Abhishek Maheshwari (@abmahesh) + Madhan Sankaranarayanan (@madhansansel) +options: + config_verify: + description: Set to True to verify the Cisco Catalyst Center config after applying the playbook config. + type: bool + default: False + state: + description: The state of Cisco Catalyst Center after module completion. + type: str + choices: [ merged, deleted ] + default: merged + config: + description: List containing the subscription configuration for events, notification on site through one or more channels. + type: list + elements: dict + required: True + suboptions: + syslog_destination: + description: Dictionary containing the details for configuring/updating syslog destination in Cisco Catalyst Center. + type: dict + suboptions: + name: + description: Name of the syslog destination. + type: str + description: + description: Description of the syslog destination. + type: str + host: + description: Hostname or IP address of the syslog server. + type: str + protocol: + description: Protocol used for sending syslog messages (e.g., UDP, TCP). + Transmission Control Protocol (TCP) - It is a connection-oriented protocol used for reliable and ordered communication + between devices on a network. It provides error-checking, retransmission of lost packets, and ensures that data is + delivered in the correct order. + User Datagram Protocol (UDP) - It is a connectionless protocol used for sending datagrams between devices on a network. + It provides a lightweight, best-effort delivery mechanism without guaranteeing delivery or ordering of packets. UDP + is commonly used for real-time applications such as streaming media, online gaming, and VoIP. + type: str + port: + description: Port number on which the syslog server is listening. It must be in the range of 1-65536. + type: int + snmp_destination: + description: Dictionary containing the details for configuring/updating SNMP destination in Cisco Catalyst Center. + type: dict + suboptions: + name: + description: Name of the SNMP destination. + type: str + description: + description: Description of the SNMP destination. + type: str + ip_address: + description: IP address of the SNMP server. + type: str + port: + description: Port number on which the SNMP server is listening. + type: str + snmp_version: + description: SNMP version used for communication (e.g., SNMPv1, SNMPv2c, SNMPv3). + v2 - In this communication between the SNMP manager (such as Cisco Catalyst) and the managed devices + (such as routers, switches, or access points) is based on community strings.Community strings serve + as form of authentication and they are transmitted in clear text, providing no encryption. + v3 - It is the most secure version of SNMP, providing authentication, integrity, and encryption features. + It allows for the use of usernames, authentication passwords, and encryption keys, providing stronger + security compared to v2. + type: str + community: + description: SNMP community string for authentication (Required only if snmpVersion is V2C). + type: str + username: + description: Username for SNMP authentication (Required only if snmpVersion is V3). + type: str + snmp_mode: + description: AUTH_PRIVACY, AUTH_NO_PRIVACY, NO_AUTH_NO_PRIVACY). If snmpVersion is V3 it is required and cannot be NONE. + NO_AUTH_NO_PRIVACY - This mode provides no authentication or encryption for SNMP messages. It means that devices communicating using SNMPv1 do + not require any authentication (username/password) or encryption (data confidentiality). This makes it the least secure option. + AUTH_NO_PRIVACY - This mode provides authentication but no encryption for SNMP messages. Authentication involves validating the source of the + SNMP messages using a community string (similar to a password). However, the data transmitted between devices is not encrypted, + so it's susceptible to eavesdropping. + AUTH_PRIVACY - This mode provides both authentication and encryption for SNMP messages. It offers the highest level of security among the three + options. Authentication ensures that the source of the messages is genuine, and encryption ensures that the data exchanged between + devices is confidential and cannot be intercepted by unauthorized parties. + type: str + snmp_auth_type: + description: SNMP authentication type (e.g., MD5, SHA). + SHA (Secure Hash Algorithm) - It represents a family of cryptographic hash functions designed by the National Security Agency (NSA) + to ensure stronger security. + MD5 (Message Digest Algorithm 5) - is a widely used cryptographic hash function that produces a 128-bit (16-byte) hash value. + In the context of SNMPv3, it is used to authenticate the integrity and authenticity of the messages. + type: str + auth_password: + description: Password for SNMP authentication. + type: str + snmp_privacy_type: + description: SNMP privacy type (e.g., AES128). + type: str + privacy_password: + description: Privacy password for snmp authentication. + type: str + rest_webhook_destination: + description: Dictionary containing the details for configuring/updating Rest Webhook destination in Cisco Catalyst Center. + type: dict + suboptions: + name: + description: The name of the webhook destination. It identifies the webhook within the system. + type: str + description: + description: A brief explanation of what the webhook destination is used for. + type: str + url: + description: The URL to which the webhook will send the request. It should be a fully qualified URL(e.g., https://ciscocatalyst.com). + type: str + method: + description: The HTTP method used by the webhook when sending requests (e.g., POST, PUT). + type: str + trust_cert: + description: A boolean indicating whether the SSL/TLS certificate of the URL should be verified. Set to true to bypass certificate verification. + type: bool + headers: + description: A list of HTTP headers to be included in the webhook request. Each header is represented as a dictionary. + type: list + elements: dict + suboptions: + name: + description: The name of the HTTP header. + type: str + value: + description: The value assigned to the HTTP header. + type: str + default_value: + description: A default value for the HTTP header that can be used if no specific value is provided. + type: str + encrypt: + description: Indicates whether the value of the header should be encrypted. Useful for sensitive data. + type: bool + is_proxy_route: + description: A boolean that determines whether the request should be routed through a proxy. True if routing through a proxy; otherwise, false." + type: bool + email_destination: + description: List containing the subscription configuration for events, notification on site through one or more channels. Also we can create or + configure email destination in Cisco Catalyst Center only once then later we can just modify it. + type: dict + suboptions: + primary_smtp_config: + description: Add the primary configuration for smtp while creating/updating email destination. + type: dict + suboptions: + hostname: + description: Name of the host used for configuring smtp while creating/updating email destination. + type: str + port: + description: Name of the port used for configuring smtp while creating/updating email destination. + type: str + smtp_type: + description: The type of SMTP server connection. Options include(DEFAULT,TLS, SSL). + DEFAULT - This one is selected for basic SMTP connection without encryption. + TLS - This one is selected for secure SMTP communication that begins unencrypted and then upgrades to encrypted using TLS if possible. + SSL - This one is selected for secure SMTP communication that starts encrypted using SSL." + type: str + username: + description: Name of the username used for configuring smtp while creating/updating email destination. + type: str + password: + description: Password used for configuring smtp while creating/updating email destination. + type: str + secondary_smtp_config: + description: Add the secondary configuration for smtp while creating/updating email destination. + type: dict + suboptions: + hostname: + description: Name of the host used for configuring smtp while creating/updating email destination. + type: str + port: + description: Name of the port used for configuring smtp while creating/updating email destination. + type: str + smtp_type: + description: The type of SMTP server connection. Options include(DEFAULT,TLS, SSL). + DEFAULT - This one is selected for basic SMTP connection without encryption. + TLS - This one is selected for secure SMTP communication that begins unencrypted and then upgrades to encrypted using TLS if possible. + SSL - This one is selected for secure SMTP communication that starts encrypted using SSL." + type: str + username: + description: Name of the username used for configuring smtp while creating/updating email destination. + type: str + password: + description: Password used for configuring smtp while creating/updating email destination. + type: str + from_email: + description: Email address from which mail to be sent while creating/updating email destination. + type: str + to_email: + description: Email address which receives mail while creating/updating email destination. + type: str + subject: + description: Subject of the email used for sending mail while creating/updating email destination. + type: str + itsm_setting: + description: Dictionary containing the configuration details necessary for integrating with an IT Service Management (ITSM) system. + type: dict + suboptions: + name: + description: The name of the ITSM configuration. This helps in identifying the integration within the system. Also while deleting + the ITSM Intergration setting from Cisco Catalyst Center. + type: str + description: + description: A brief description of the ITSM settings, outlining its purpose or usage within the organization. + type: str + connection_settings: + description: A dictionary of settings required to establish a connection with the ITSM system. + type: dict + suboptions: + url: + description: The URL of the ITSM system API endpoint. This is the base URL used for ITSM service requests. + type: str + username: + description: The username used for authentication with the ITSM system. This is required for accessing the API. + type: str + password: + description: The password associated with the username for API authentication. It is recommended to handle this data securely. + type: str + + +requirements: +- dnacentersdk >= 2.5.5 +- python >= 3.5 + +notes: + - SDK Method used are + events.Events.get_syslog_destination, + events.Events.create_syslog_destination, + events.Events.update_syslog_destination, + events.Events.get_snmp_destination, + events.Events.create_snmp_destination, + events.Events.update_snmp_destination, + events.Events.get_webhook_destination, + events.Events.create_webhook_destination, + events.Events.update_webhook_destination, + +""" + +EXAMPLES = r""" +- name: Create Syslog destination with given name. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - syslog_destination: + name: Syslog test + description: "Adding syslog destination" + host: "10.30.0.90" + protocol: "TCP" + port: 6553 + +- name: Update Syslog destination with given name. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - syslog_destination: + name: Syslog test + description: "Updating syslog destination." + +- name: Create SNMP destination with given name. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - snmp_destination: + name: Snmp test + description: "Adding snmp destination for testing." + ip_address: "10.30.0.90" + port: "25" + snmp_version: "V3" + username: cisco + snmp_mode: AUTH_PRIVACY + snmp_auth_type: SHA + auth_password: authpass123 + snmp_privacy_type: AES128 + privacy_password: privacy123 + +- name: Update SNMP destination with given name. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - snmp_destination: + name: Snmp test + description: "Updating snmp destination with snmp version v2." + ip_address: "10.30.0.90" + port: "25" + snmp_version: "V2C" + community: "public123" + +- name: Configuring the email destination in the system. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - email_destination: + from_email: "test@cisco.com" + to_email: "demo@cisco.com" + subject: "Ansible testing" + primary_smtp_config: + hostname: "outbound.cisco.com" + port: "25" + smtp_type: "DEFAULT" + +- name: Updating the email destination in the system. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - email_destination: + from_email: "test@cisco.com" + to_email: "demo123@cisco.com" + subject: "Ansible updated email config testing" + +- name: Create Rest Webhook destination with given name. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - rest_webhook_destination: + name: "webhook test" + description: "creating webhook for testing" + url: "https://10.195.227.14/dna" + method: "GET" + trust_cert: False + +- name: Updating Rest Webhook destination with given name. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - rest_webhook_destination: + name: "webhook test" + description: "updating webhook for testing" + +- name: Create ITSM Integration Setting with given name in the system. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - itsm_setting: + name: "ITSM test" + description: "ITSM description for testing" + connection_settings: + url: "http/catalystcenter.com" + username: "catalyst" + password: "catalyst@123" + +- name: Updating ITSM Integration Setting with given name in the system. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: merged + config: + - itsm_setting: + name: "ITSM test" + connection_settings: + url: "http/catalystcenterupdate.com" + password: "catalyst@123" + +- name: Deleting ITSM Integration Setting with given name from the system. + cisco.dnac.events_and_notifications_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + state: deleted + config: + - itsm_setting: + name: "ITSM test" + +""" + +RETURN = r""" + +dnac_response: + description: A dictionary or list with the response returned by the Cisco Catalyst Center Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.dnac.plugins.module_utils.dnac import ( + DnacBase, + validate_list_of_dicts, +) +import re + + +class Events(DnacBase): + """Class containing member attributes for inventory workflow manager module""" + + def __init__(self, module): + super().__init__(module) + self.supported_states = ["merged", "deleted"] + + def validate_input(self): + """ + Validate the fields provided in the playbook. + Checks the configuration provided in the playbook against a predefined specification + to ensure it adheres to the expected structure and data types. + Parameters: + self: The instance of the class containing the 'config' attribute to be validated. + Returns: + The method returns an instance of the class with updated attributes: + - self.msg: A message describing the validation result. + - self.status: The status of the validation (either 'success' or 'failed'). + - self.validated_config: If successful, a validated version of the 'config' parameter. + Example: + To use this method, create an instance of the class and call 'validate_input' on it. + If the validation succeeds, 'self.status' will be 'success' and 'self.validated_config' + will contain the validated configuration. If it fails, 'self.status' will be 'failed', and + 'self.msg' will describe the validation issues. + """ + + temp_spec = { + 'syslog_destination': { + 'type': 'dict', + 'name': {'type': 'str'}, + 'description': {'type': 'str'}, + 'host': {'type': 'str'}, + 'protocol': {'type': 'str'}, + 'port': {'type': 'int'}, + }, + 'snmp_destination': { + 'type': 'dict', + 'name': {'type': 'str'}, + 'description': {'type': 'str'}, + 'ip_address': {'type': 'str'}, + 'port': {'type': 'str'}, + 'snmp_version': {'type': 'str'}, + 'community': {'type': 'str'}, + 'username': {'type': 'str'}, + 'snmp_mode': {'type': 'str'}, + 'snmp_auth_type': {'type': 'str'}, + 'auth_password': {'type': 'str'}, + 'snmp_privacy_type': {'type': 'str'}, + 'privacy_password': {'type': 'str'}, + }, + 'email_destination': { + 'type': 'dict', + 'primary_smtp_config': { + 'type': 'dict', + 'hostname': {'type': 'str'}, + 'port': {'type': 'str'}, + 'smtp_type': {'type': 'str'}, + 'username': {'type': 'str'}, + 'password': {'type': 'str'}, + }, + 'secondary_smtp_config': { + 'type': 'dict', + 'hostname': {'type': 'str'}, + 'port': {'type': 'str'}, + 'smtp_type': {'type': 'str'}, + 'username': {'type': 'str'}, + 'password': {'type': 'str'}, + }, + 'from_email': {'type': 'str'}, + 'to_email': {'type': 'str'}, + 'subject': {'type': 'str'}, + }, + 'rest_webhook_destination': { + 'type': 'dict', + 'name': {'type': 'str'}, + 'description': {'type': 'str'}, + 'url': {'type': 'str'}, + 'method': {'type': 'str'}, + 'trust_cert': {'type': 'bool'}, + 'headers': { + 'type': 'list', + 'elements': 'dict', + 'name': {'type': 'str'}, + 'value': {'type': 'str'}, + 'default_value': {'type': 'str'}, + 'encrypt': {'type': 'bool'}, + }, + 'is_proxy_route': {'type': 'bool'} + }, + 'itsm_setting': { + 'type': 'dict', + 'name': {'type': 'str'}, + 'description': {'type': 'str'}, + 'connection_settings': { + 'type': 'dict', + 'url': {'type': 'str'}, + 'auth_username': {'type': 'str'}, + 'auth_password': {'type': 'str'}, + }, + }, + } + + # Validate device params + valid_temp, invalid_params = validate_list_of_dicts( + self.config, temp_spec + ) + + if invalid_params: + self.msg = "Invalid parameters in playbook: {0}".format(invalid_params) + self.log(self.msg, "ERROR") + self.status = "failed" + return self + + self.validated_config = valid_temp + self.msg = "Successfully validated playbook configuration parameters using 'validate_input': {0}".format(str(valid_temp)) + self.log(self.msg, "INFO") + self.status = "success" + + return self + + def get_have(self, config): + """ + Retrieve and check destinations information present in Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + config (dict): A dictionary containing the configuration details of destinations to be checked. + Returns: + self (object): An instance of a class used for interacting with Cisco Catalyst Center having destination details. + - syslog_destinations (list): A list of syslog destinations existing in Cisco Catalyst Center. + - snmp_destinations (list): A list of SNMP destinations existing in Cisco Catalyst Center. + - webhook_destinations (list): A list of webhook destinations existing in Cisco Catalyst Center. + - email_destination (list): A list of email destinations existing in Cisco Catalyst Center. + - itsm_setting (list): A list of ITSM settings existing in Cisco Catalyst Center. + Description: + This function checks the specified destinations in the playbook against the destinations existing in Cisco Catalyst Center. + It retrieves information about various types of destinations (syslog, SNMP, webhook, email, ITSM) and returns a dictionary + with keys representing each type of destination and corresponding lists of existing destinations in Cisco Catalyst Center. + """ + + have = {} + + if config.get('syslog_destination'): + if self.get_syslog_destination_in_ccc(): + have['syslog_destinations'] = self.get_syslog_destination_in_ccc() + + if config.get('snmp_destination'): + if self.get_snmp_destination_in_ccc(): + have['snmp_destinations'] = self.get_snmp_destination_in_ccc() + + if config.get('rest_webhook_destination'): + if self.get_rest_webhook_destination_in_ccc(): + have['webhook_destinations'] = self.get_rest_webhook_destination_in_ccc() + + if config.get('email_destination'): + if self.get_email_destination_in_ccc(): + have['email_destination'] = self.get_email_destination_in_ccc() + + if config.get('itsm_setting'): + if self.get_itsm_settings_in_ccc(): + have['itsm_setting'] = self.get_itsm_settings_in_ccc() + + self.have = have + self.log("Current State (have): {0}".format(str(self.have)), "INFO") + + return self + + def get_want(self, config): + """ + Retrieve the desired configuration parameters specified in the playbook. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + config (dict): A dictionary containing the desired configuration details specified in the playbook. + Returns: + self (object): An instance of the class with the desired configuration parameters collected from the playbook. + Description: + This function retrieves the desired configuration parameters specified in the playbook and organizes them into a dictionary. + It collects details related to various types of destinations (syslog, SNMP, webhook, email, ITSM) based on the playbook configuration + and stores them in the 'want' attribute of the class instance. + """ + + want = {} + if config.get('syslog_destination'): + want['syslog_details'] = config.get('syslog_destination') + if config.get('snmp_destination'): + want['snmp_details'] = config.get('snmp_destination') + if config.get('rest_webhook_destination'): + want['webhook_details'] = config.get('rest_webhook_destination') + if config.get('email_destination'): + want['email_details'] = config.get('email_destination') + if config.get('itsm_setting'): + want['itsm_details'] = config.get('itsm_setting') + + self.want = want + self.msg = "Successfully collected all parameters from the playbook " + self.status = "success" + self.log("Desired State (want): {0}".format(str(self.want)), "INFO") + + return self + + def get_syslog_destination_in_ccc(self): + """ + Retrieve the details of syslog destinations present in Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Returns: + str: A string containing the details of syslog destinations present in Cisco Catalyst Center. + Description: + This function queries Cisco Catalyst Center to retrieve the details of syslog destinations. + The response contains the status message indicating the syslog destinations present in Cisco Catalyst Center. + If no syslog destinations are found, it returns an empty string. + In case of any errors during the API call, an exception is raised with an error message. + """ + try: + response = self.dnac._exec( + family="event_management", + function='get_syslog_destination' + ) + self.log("Received API response from 'get_syslog_destination': {0}".format(str(response)), "DEBUG") + response = response.get('statusMessage') + + if not response: + self.log("There is no Syslog destination present in Cisco Catalyst Center", "INFO") + return response + + return response + + except Exception as e: + error_message = "Error while getting the details of Syslog destination present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(error_message, "ERROR") + raise Exception(error_message) + + def get_syslog_destination_with_name(self, name): + """ + Retrieve the details of a syslog destination with a specific name from Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + name (str): The name of the syslog destination to retrieve details for. + Returns: + dict: A dictionary containing the details of the syslog destination with the specified name. + Description: + This function queries Cisco Catalyst Center to retrieve the details of a syslog destination with a specific name. + The response contains the status message indicating the syslog destination details. + If no syslog destination is found with the specified name, it returns None. + In case of any errors during the API call, an exception is raised with an error message. + """ + try: + response = self.dnac._exec( + family="event_management", + function='get_syslog_destination', + op_modifies=True, + params={"name": name} + ) + self.log("Received API response from 'get_syslog_destination': {0}".format(str(response)), "DEBUG") + response = response.get('statusMessage') + + if not response: + self.log("There is no Syslog destination added with the name '{0}' in Cisco Catalyst Center".format(name), "INFO") + return response + syslog_details = response[0] + + return syslog_details + + except Exception as e: + error_message = "Error while getting the details of Syslog destination with the name '{0}' from Cisco Catalyst Center: {1}".format(name, str(e)) + self.log(error_message, "ERROR") + raise Exception(error_message) + + def syslog_dest_needs_update(self, syslog_details, syslog_details_in_ccc): + """ + Check if the syslog destination needs an update based on a comparison between desired and current details. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + syslog_details (dict): A dictionary containing the desired syslog destination details. + syslog_details_in_ccc (dict): A dictionary containing the current syslog destination details in Cisco Catalyst Center. + Returns: + bool: A boolean indicating whether an update is needed for the syslog destination. + Description: + This function compares the desired syslog destination details with the current details retrieved from Cisco Catalyst Center. + It iterates through each key-value pair in the desired syslog details and checks if the corresponding value in the current + details matches or if the desired value is empty. If any discrepancy is found, indicating a difference between desired and + current details, the function sets the 'update_needed' flag to True, indicating that an update is needed. + If no discrepancies are found, the function returns False, indicating that no update is needed. + """ + + update_needed = False + for key, value in syslog_details.items(): + if str(syslog_details_in_ccc[key]) == value or value == "": + continue + else: + update_needed = True + + return update_needed + + def add_syslog_destination(self, syslog_details): + """ + Add a syslog destination to Cisco Catalyst Center based on the provided details. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + syslog_details (dict): A dictionary containing the details of the syslog destination to be added. + Returns: + self (object): An instance of the class with the result of the operation. + - If successful, 'status' is set to 'success', 'result['changed']' is True, and 'msg' contains a success message. + - If unsuccessful, 'status' is set to 'failed', 'result['changed']' is False, and 'msg' contains an error message. + Description: + This function adds a syslog destination to Cisco Catalyst Center using the provided details. + It validates the input parameters, including the protocol, and constructs the necessary parameters for the API call. + If the operation is successful, the function sets the appropriate status, logs a success message, and returns the result. + If the operation fails, the function sets the status to 'failed', logs an error message, and returns the result with + details of the failure. + """ + + try: + name = syslog_details.get('name') + description = syslog_details.get('description') + host = syslog_details.get('host') + protocol = syslog_details.get('protocol') + port = syslog_details.get('port', 514) + + if not protocol: + self.status = "failed" + self.msg = "Protocol is needed while configuring the syslog destionation with name '{0}' in Cisco Catalyst Center".format(name) + self.log(self.msg, "ERROR") + return self + + protocol = protocol.upper() + if protocol not in ["TCP", "UDP"]: + self.status = "failed" + self.msg = """Invalid protocol name '{0}' for creating/updating syslog destination in Cisco Catalyst Center. + Select one of the following protocol 'TCP/UDP'.""".format(protocol) + self.log(self.msg, "ERROR") + return self + + add_syslog_params = { + 'name': name, + 'description': description, + 'host': host, + 'protocol': protocol, + 'port': int(port) + } + + response = self.dnac._exec( + family="event_management", + function='create_syslog_destination', + op_modifies=True, + params=add_syslog_params + ) + self.log("Received API response from 'create_syslog_destination': {0}".format(str(response)), "DEBUG") + status = response.get('apiStatus') + + if status == 'SUCCESS': + self.status = "success" + self.result['changed'] = True + self.msg = "Syslog Destination with name '{0}' added successfully in Cisco Catalyst Center".format(name) + self.log(self.msg, "INFO") + self.result['response'] = self.msg + return self + + self.status = "failed" + try: + failure_msg = response.get('errorMessage').get('errors') + except Exception as e: + failure_msg = "Unable to Add syslog destination with name '{0}' in Cisco Catalyst Center".format(name) + + self.log(failure_msg, "ERROR") + self.result['response'] = failure_msg + + except Exception as e: + self.status = "failed" + self.msg = "Error while Adding the Syslog destination with the name '{0}' in Cisco Catalyst Center: {1}".format(name, str(e)) + self.log(self.msg, "ERROR") + + return self + + def update_syslog_destination(self, syslog_details, syslog_details_in_ccc): + """ + Update an existing syslog destination in Cisco Catalyst Center with the provided details. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + syslog_details (dict): A dictionary containing the desired syslog destination details to update. + syslog_details_in_ccc (dict): A dictionary containing the current syslog destination details in Cisco Catalyst Center. + Returns: + self (object): An instance of the class with the result of the operation. + - If successful, 'status' is set to 'success', 'result['changed']' is True, and 'msg' contains a success message. + - If unsuccessful, 'status' is set to 'failed', 'result['changed']' is False, and 'msg' contains an error message. + Description: + This function updates an existing syslog destination in Cisco Catalyst Center with the provided details. + It constructs the parameters required for the API call by merging the desired syslog details with the current details. + If the operation is successful, the function sets the appropriate status, logs a success message, and returns the result. + If the operation fails, the function sets the status to 'failed', logs an error message, returns the result with failure details. + """ + + try: + update_syslog_params = {} + update_syslog_params['name'] = syslog_details.get('name') or syslog_details_in_ccc.get('name') + update_syslog_params['description'] = syslog_details.get('description') or syslog_details_in_ccc.get('description') + update_syslog_params['host'] = syslog_details.get('host') or syslog_details_in_ccc.get('host') + update_syslog_params['protocol'] = syslog_details.get('protocol') or syslog_details_in_ccc.get('protocol') + update_syslog_params['port'] = int(syslog_details.get('port') or syslog_details_in_ccc.get('port')) + update_syslog_params['configId'] = syslog_details_in_ccc.get('configId') + name = update_syslog_params.get('name') + + response = self.dnac._exec( + family="event_management", + function='update_syslog_destination', + op_modifies=True, + params=update_syslog_params + ) + self.log("Received API response from 'update_syslog_destination': {0}".format(str(response)), "DEBUG") + status = response.get('apiStatus') + + if status == 'SUCCESS': + self.status = "success" + self.result['changed'] = True + self.msg = "Syslog Destination with name '{0}' updated successfully in Cisco Catalyst Center".format(name) + self.log(self.msg, "INFO") + self.result['response'] = self.msg + return self + + self.status = "failed" + try: + failure_msg = response.get('errorMessage').get('errors') + except Exception as e: + failure_msg = "Unable to update syslog destination with name '{0}' in Cisco Catalyst Center".format(name) + + self.log(failure_msg, "ERROR") + self.result['response'] = failure_msg + + except Exception as e: + self.status = "failed" + self.msg = "Error while Updating the Syslog destination with the name '{0}' in Cisco Catalyst Center: {1}".format(name, str(e)) + self.log(self.msg, "ERROR") + + return self + + def get_snmp_destination_in_ccc(self): + """ + Retrieve the details of SNMP destinations present in Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Returns: + dict: A dictionary containing the details of SNMP destinations present in Cisco Catalyst Center. + Description: + This function queries Cisco Catalyst Center to retrieve the details of SNMP destinations. + It utilizes the 'event_management' API endpoint with the 'get_snmp_destination' function. + The response contains information about the SNMP destinations present in Cisco Catalyst Center. + If no SNMP destinations are found, it returns an empty dictionary. + """ + try: + response = self.dnac._exec( + family="event_management", + function='get_snmp_destination' + ) + self.log("Received API response from 'get_snmp_destination': {0}".format(str(response)), "DEBUG") + + if not response: + self.log("There is no SNMP destination present in Cisco Catalyst Center", "INFO") + return response + + return response + + except Exception as e: + error_message = "Error while getting the details of SNMP destination present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(error_message, "ERROR") + raise Exception(error_message) + + def collect_snmp_playbook_params(self, snmp_details): + """ + Collect the SNMP playbook parameters based on the provided SNMP details. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + snmp_details (dict): A dictionary containing the SNMP destination details. + Returns: + dict: A dictionary containing the SNMP playbook parameters. + Description: + This function constructs the SNMP playbook parameters based on the provided SNMP destination details. + It extracts relevant information such as name, description etc. + The constructed playbook parameters are returned for further use in the playbook. + """ + + playbook_params = { + 'name': snmp_details.get('name'), + 'description': snmp_details.get('description'), + 'ipAddress': snmp_details.get('ip_address'), + 'port': snmp_details.get('port'), + 'snmpVersion': snmp_details.get('snmp_version') + } + + if playbook_params['snmpVersion'] == "V2C": + playbook_params['community'] = snmp_details.get('community') + else: + playbook_params['userName'] = snmp_details.get('username') + playbook_params['snmpMode'] = snmp_details.get('snmp_mode') + if playbook_params['snmpMode'] == "AUTH_PRIVACY": + playbook_params['snmpAuthType'] = snmp_details.get('snmp_auth_type') + playbook_params['authPassword'] = snmp_details.get('auth_password') + playbook_params['snmpPrivacyType'] = snmp_details.get('snmp_privacy_type', 'AES128') + playbook_params['privacyPassword'] = snmp_details.get('privacy_password') + elif playbook_params['snmpMode'] == "AUTH_NO_PRIVACY": + playbook_params['snmpAuthType'] = snmp_details.get('snmp_auth_type') + playbook_params['authPassword'] = snmp_details.get('auth_password') + + return playbook_params + + def check_snmp_required_parameters(self, snmp_params): + """ + Check if all the required parameters for adding an SNMP destination in Cisco Catalyst Center are present. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + snmp_params (dict): A dictionary containing the SNMP destination parameters. + Returns: + self (object): An instance of the class with the result of the parameter check. + - If all required parameters are present, 'status' is set to 'success', and 'msg' contains a success message. + - If any required parameter is missing, 'status' is set to 'failed', 'msg' contains an error message, + and the missing parameters are logged. + Description: + This function validates whether all the required parameters for adding an SNMP destination in Cisco Catalyst Center + are present in the provided SNMP destination parameters. If any required parameter is missing, it logs an error + message with the missing parameters and sets the status to 'failed'. + If all required parameters are present, it logs a success message and sets the status to 'success'. + """ + + missing_params_list = [] + required_parameter_list = ["name", "description", "ipAddress", "port", "snmpVersion"] + + if snmp_params['snmpVersion'] == "V2C": + required_parameter_list.append("community") + else: + required_parameter_list.extend(["userName", "snmpMode"]) + if snmp_params['snmpMode'] == "AUTH_PRIVACY": + required_parameter_list.extend(["snmpAuthType", "authPassword", "privacyPassword"]) + elif snmp_params['snmpMode'] == "AUTH_NO_PRIVACY": + required_parameter_list.extend(["snmpAuthType", "authPassword"]) + + for item in required_parameter_list: + if snmp_params[item] is None: + missing_params_list.append(item) + + if not missing_params_list: + self.status = "success" + self.msg = "All the required parameters for adding SNMP Destination in Cisco Catalyst Center is present." + self.log(self.msg, "INFO") + return self + + self.status = "failed" + self.msg = "Required parameter '{0}' is missing for adding SNMP Destination in Cisco Catalyst Center".format(str(missing_params_list)) + self.log(self.msg, "ERROR") + + return self + + def add_snmp_destination(self, snmp_params): + """ + Add the SNMP destination in Cisco Catalyst Center using the provided SNMP parameters. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + snmp_params (dict): A dictionary containing the SNMP destination parameters. + + Returns: + self (object): An instance of the class with the result of the SNMP destination addition. + - If the SNMP destination is added successfully, 'status' is set to 'success', + 'changed' is set to True, 'msg' contains a success message, and 'response' contains the API response. + - If the addition fails, 'status' is set to 'failed', 'msg' contains an error message, + and 'response' contains the API error response. + Description: + This function adds an SNMP destination in Cisco Catalyst Center using the provided SNMP parameters. + Upon receiving the API response, it checks the status to determine the success or failure of the operation. + If the addition is successful, it sets the appropriate attributes and logs a success message. + If the addition fails, it logs the error message from the API response. + """ + + try: + response = self.dnac._exec( + family="event_management", + function='create_snmp_destination', + op_modifies=True, + params=snmp_params + ) + self.log("Received API response from 'create_snmp_destination': {0}".format(str(response)), "DEBUG") + status = response.get('apiStatus') + + if status == 'SUCCESS': + self.status = "success" + self.result['changed'] = True + self.msg = "Syslog Destination with name '{0}' added successfully in Cisco Catalyst Center".format(snmp_params.get('name')) + self.log(self.msg, "INFO") + self.result['response'] = self.msg + return self + + self.status = "failed" + try: + failure_msg = response.get('errorMessage').get('errors') + except Exception as e: + failure_msg = "Unable to Add SNMP destination with name '{0}' in Cisco Catalyst Center".format(snmp_params.get('name')) + + self.log(failure_msg, "ERROR") + self.result['response'] = failure_msg + + return self + + except Exception as e: + error_message = """Error while Adding the Syslog destination with the name '{0}' in Cisco Catalyst Center: + {1}""".format(snmp_params.get('name'), str(e)) + self.log(error_message, "ERROR") + raise Exception(error_message) + + def snmp_dest_needs_update(self, snmp_params, snmp_dest_detail_in_ccc): + """ + Determine if an update is needed for the SNMP destination in Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + snmp_params (dict): A dictionary containing the updated SNMP destination parameters. + snmp_dest_detail_in_ccc (dict): A dictionary containing the details of existing SNMP destination in Cisco Catalyst Center. + Returns: + self (object): An instance of the class with the result of the SNMP destination addition. + Description: + This function compares the provided SNMP destination parameters with the existing SNMP destination details + in Cisco Catalyst Center to determine if an update is needed. + If any value is different or empty in the updated parameters compared to the existing details, + it sets 'update_needed' to True, indicating that an update is needed. + Otherwise, if all values match or are empty, it sets 'update_needed' to False. + """ + + update_needed = False + for key, value in snmp_params.items(): + if str(snmp_dest_detail_in_ccc[key]) == str(value) or value == "": + continue + else: + update_needed = True + + return update_needed + + def update_snmp_destination(self, snmp_params, snmp_dest_detail_in_ccc): + """ + Update an existing SNMP destination in Cisco Catalyst Center with the provided parameters. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + snmp_params (dict): A dictionary containing the updated parameters for the SNMP destination. + snmp_dest_detail_in_ccc (dict): A dictionary containing the details of the SNMP destination + currently configured in Cisco Catalyst Center. + Returns: + self (object): An object representing the status of the operation, including whether it was successful or failed, + any error messages encountered during the operation, and whether changes were made to the system. + Description: + This function attempts to update an existing SNMP destination in Cisco Catalyst Center with the provided parameters. + It compares the parameters specified in the playbook (`snmp_params`) with the current configuration of the SNMP destination + in Cisco Catalyst Center (`snmp_dest_detail_in_ccc`). If any parameter differs between the playbook and the current + configuration, the function sends a request to update the SNMP destination with the new parameters. + If the operation is successful, it sets the status to "success" and logs a success message. + If the operation fails, it sets the status to "failed" and logs an error message along with any error details + received from the API response. + """ + try: + update_snmp_params = {} + update_snmp_params['name'] = snmp_params.get('name') or snmp_dest_detail_in_ccc.get('name') + update_snmp_params['description'] = snmp_params.get('description') or snmp_dest_detail_in_ccc.get('description') + update_snmp_params['ipAddress'] = snmp_params.get('ipAddress') or snmp_dest_detail_in_ccc.get('ipAddress') + update_snmp_params['port'] = snmp_params.get('port') or snmp_dest_detail_in_ccc.get('port') + update_snmp_params['snmpVersion'] = snmp_params.get('snmpVersion') or snmp_dest_detail_in_ccc.get('snmpVersion') + + if update_snmp_params.get('port'): + try: + port = int(snmp_params.get('port')) + if port not in range(1, 65536): + self.status = "failed" + self.msg = "Invalid Notification trap port '{0}' given in playbook. Select port from the number range(1, 65536)".format(port) + self.log(self.msg, "ERROR") + return self + except Exception as e: + self.status = "failed" + self.msg = """Invalid datatype for the Notification trap port '{0}' given in playbook. Select port with correct datatype from the + number range(1, 65536.""".format(port) + self.log(self.msg, "ERROR") + return self + + if update_snmp_params['snmpVersion'] == "V2C": + update_snmp_params['community'] = snmp_params.get('community') or snmp_dest_detail_in_ccc.get('community') + else: + update_snmp_params['userName'] = snmp_params.get('userName') or snmp_dest_detail_in_ccc.get('userName') + update_snmp_params['snmpMode'] = snmp_params.get('snmpMode') or snmp_dest_detail_in_ccc.get('snmpMode') + if update_snmp_params['snmpMode'] == "AUTH_PRIVACY": + update_snmp_params['snmpAuthType'] = snmp_params.get('snmpAuthType') or snmp_dest_detail_in_ccc.get('snmpAuthType') + update_snmp_params['authPassword'] = snmp_params.get('authPassword') or snmp_dest_detail_in_ccc.get('authPassword') + update_snmp_params['snmpPrivacyType'] = snmp_params.get('snmpPrivacyType', 'AES128') + update_snmp_params['privacyPassword'] = snmp_params.get('privacyPassword') or snmp_dest_detail_in_ccc.get('privacyPassword') + elif update_snmp_params['snmpMode'] == "AUTH_NO_PRIVACY": + update_snmp_params['snmpAuthType'] = snmp_params.get('snmpAuthType') or snmp_dest_detail_in_ccc.get('snmpAuthType') + update_snmp_params['authPassword'] = snmp_params.get('authPassword') or snmp_dest_detail_in_ccc.get('authPassword') + + update_snmp_params['configId'] = snmp_dest_detail_in_ccc.get('configId') + + response = self.dnac._exec( + family="event_management", + function='update_snmp_destination', + op_modifies=True, + params=update_snmp_params + ) + self.log("Received API response from 'update_snmp_destination': {0}".format(str(response)), "DEBUG") + status = response.get('apiStatus') + + if status == 'SUCCESS': + self.status = "success" + self.result['changed'] = True + self.msg = "SNMP Destination with name '{0}' updated successfully in Cisco Catalyst Center".format(update_snmp_params.get('name')) + self.log(self.msg, "INFO") + self.result['response'] = self.msg + return self + + self.status = "failed" + try: + failure_msg = response.get('errorMessage').get('errors') + except Exception as e: + failure_msg = "Unable to update SNMP destination with name '{0}' in Cisco Catalyst Center".format(update_snmp_params.get('name')) + + self.log(failure_msg, "ERROR") + self.result['response'] = failure_msg + + except Exception as e: + self.status = "failed" + self.msg = "Error while Updating the SNMP destination with name '{0}' in Cisco Catalyst Center: {1}".format(update_snmp_params.get('name'), str(e)) + self.log(self.msg, "ERROR") + + return self + + def get_rest_webhook_destination_in_ccc(self): + """ + Retrieve details of Rest Webhook destinations present in Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Returns: + dict: A dictionary containing details of Rest Webhook destinations present in Cisco Catalyst Center, + or None if no Rest Webhook destinations are found. + Description: + This function retrieves the details of Rest Webhook destinations present in Cisco Catalyst Center + using the 'event_management' API endpoint with the 'get_webhook_destination' function. + If an error occurs during the retrieval process, it logs the error message and raises an Exception. + """ + + try: + response = self.dnac._exec( + family="event_management", + function='get_webhook_destination' + ) + self.log("Received API response from 'get_webhook_destination': {0}".format(str(response)), "DEBUG") + response = response.get('statusMessage') + + if not response: + self.log("There is no Rest Webhook destination present in Cisco Catalyst Center", "INFO") + return response + + return response + + except Exception as e: + error_message = "Error while getting the details of Webhook destination(s) present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(error_message, "ERROR") + raise Exception(error_message) + + def collect_webhook_playbook_params(self, webhook_details): + """ + Collect parameters for configuring a Rest Webhook destination from the playbook. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + webhook_details (dict): A dictionary containing the details of the Rest Webhook destination to be configured. + Returns: + dict: A dictionary containing the collected parameters for configuring the Rest Webhook destination. + Description: + This function collects parameters for configuring a Rest Webhook destination from the playbook. + """ + + playbook_params = { + 'name': webhook_details.get('name'), + 'description': webhook_details.get('description'), + 'url': webhook_details.get('url'), + 'method': webhook_details.get('method', 'POST').upper(), + 'trustCert': webhook_details.get('trust_cert', False), + 'isProxyRoute': webhook_details.get('is_proxy_route', True) + } + + if webhook_details.get('headers'): + headers_list = webhook_details['headers'] + playbook_params['headers'] = [] + for headers in headers_list: + temp_dict = { + 'name': headers.get('name'), + 'value': headers.get('name'), + 'defaultValue': headers.get('default_value'), + 'encrypt': headers.get('encrypt') + } + playbook_params['headers'].append(temp_dict) + + return playbook_params + + def add_webhook_destination(self, webhook_params): + """ + Add or configure REST webhook destination in Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + webhook_params (dict): A dictionary containing the parameters for configuring the REST webhook destination. + Returns: + self (object): An instance of a class representing the status of the operation, including whether it was + successful or failed, any error messages encountered during operation. + Description: + This function attempts to add a REST webhook destination in Cisco Catalyst Center using the provided parameters. + It sends a request to create a webhook destination with the specified parameters. + If the operation is successful, it sets the status to "success" and logs a success message. + If the operation fails, it sets the status to "failed" and logs an error message along with any error details + received from the API response. + """ + + try: + response = self.dnac._exec( + family="event_management", + function='create_webhook_destination', + op_modifies=True, + params=webhook_params + ) + self.log("Received API response from 'create_webhook_destination': {0}".format(str(response)), "DEBUG") + status = response.get('apiStatus') + + if status == 'SUCCESS': + self.status = "success" + self.result['changed'] = True + self.msg = "Webhook Destination with name '{0}' added successfully in Cisco Catalyst Center".format(webhook_params.get('name')) + self.log(self.msg, "INFO") + self.result['response'] = self.msg + return self + + self.status = "failed" + try: + failure_msg = response.get('errorMessage').get('errors') + except Exception as e: + failure_msg = "Unable to Add Webhook destination with name '{0}' in Cisco Catalyst Center".format(webhook_params.get('name')) + + self.log(failure_msg, "ERROR") + self.result['response'] = failure_msg + + except Exception as e: + self.status = "failed" + self.msg = "Error while Adding the Webhook destination with the name '{0}' in Cisco Catalyst Center: {1}".format(webhook_params.get('name'), str(e)) + self.log(self.msg, "ERROR") + + return self + + def webhook_dest_needs_update(self, webhook_params, webhook_dest_detail_in_ccc): + """ + Check if updates are needed for a webhook destination in Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + webhook_params (dict): A dictionary containing the updated parameters for the webhook destination. + webhook_dest_detail_in_ccc (dict): A dictionary containing the details of the webhook destination + currently configured in Cisco Catalyst Center. + Returns: + bool: A boolean value indicating whether updates are needed for the webhook destination. + Description: + This function compares the parameters specified in the playbook (`webhook_params`) with the current configuration + of the webhook destination in Cisco Catalyst Center (`webhook_dest_detail_in_ccc`). If any parameter differs between + the playbook and the current configuration, it returns True, indicating that updates are needed. + If all parameters match or are None, it returns False, indicating that no updates are needed. + """ + + update_needed = False + for key, value in webhook_params.items(): + if webhook_dest_detail_in_ccc[key] == value or value is None: + continue + else: + update_needed = True + + return update_needed + + def remove_duplicates(self, headers_in_ccc): + """ + Remove duplicate headers from a list of header dictionaries. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + headers_in_ccc (list): A list of dictionaries representing headers. + Returns: + list: A list of dictionaries with duplicate headers removed. + Description: + This function takes a list of header dictionaries (`headers_in_ccc`) as input and removes duplicate headers from it. + It iterates through each dictionary in the list and converts it to a tuple of its items. This tuple representation + is used to check if a similar tuple has been seen before. If not, the dictionary is added to the list of unique_dicts. + Finally, it returns the list of dictionaries with duplicate headers removed. + """ + + seen_set = set() + unique_dicts = [] + + for header_dict in headers_in_ccc: + # Convert the dictionary to a tuple of its items + dict_tuple = tuple(sorted(header_dict.items())) + + # Check if the tuple representation of the dictionary has been seen before + if dict_tuple not in seen_set: + seen_set.add(dict_tuple) + unique_dicts.append(header_dict) + + return unique_dicts + + def update_webhook_destination(self, webhook_details, webhook_dest_detail_in_ccc): + """ + Update a webhook destination in Cisco Catalyst Center with the provided details. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + webhook_details (dict): A dictionary containing the details of the webhook destination to be updated. + webhook_dest_detail_in_ccc (dict): A dictionary containing the details of the webhook destination in Cisco Catalyst Center. + Returns: + self (object): An instance of a class representing the status of the operation, including whether it was + successful or failed, any error messages encountered during operation. + Description: + This function updates a webhook destination in Cisco Catalyst Center with the provided details. + It constructs the parameters needed for the update based on the provided and existing details. + Then, it sends an API request to update the webhook destination with the constructed parameters. + If the update is successful, it sets the status to "success" and logs the success message. + If the update fails, it sets the status to "failed" and logs the failure message. + """ + + try: + update_webhook_params = {} + update_webhook_params['name'] = webhook_details.get('name') or webhook_dest_detail_in_ccc.get('name') + update_webhook_params['description'] = webhook_details.get('description') or webhook_dest_detail_in_ccc.get('description') + update_webhook_params['url'] = webhook_details.get('url') or webhook_dest_detail_in_ccc.get('url') + update_webhook_params['method'] = webhook_details.get('method') or webhook_dest_detail_in_ccc.get('method') + update_webhook_params['trust_cert'] = webhook_details.get('trustCert') or webhook_dest_detail_in_ccc.get('trustCert') + update_webhook_params['is_proxy_route'] = webhook_details.get('isProxyRoute') or webhook_dest_detail_in_ccc.get('isProxyRoute') + playbook_headers = webhook_details.get('headers') + headers_in_ccc = webhook_dest_detail_in_ccc.get('headers') + + final_headers_list = [] + if playbook_headers: + if headers_in_ccc: + headers_in_ccc.extend(playbook_headers) + final_headers_list = self.remove_duplicates(headers_in_ccc) + else: + final_headers_list.extend(playbook_headers) + + if not final_headers_list: + final_headers_list = None + + update_webhook_params['headers'] = final_headers_list + update_webhook_params['webhookId'] = webhook_dest_detail_in_ccc.get('webhookId') + + response = self.dnac._exec( + family="event_management", + function='update_webhook_destination', + op_modifies=True, + params=update_webhook_params + ) + self.log("Received API response from 'update_webhook_destination': {0}".format(str(response)), "DEBUG") + name = update_webhook_params.get('name') + status = response.get('apiStatus') + + if status == 'SUCCESS': + self.status = "success" + self.result['changed'] = True + self.msg = "Rest Webhook Destination with name '{0}' updated successfully in Cisco Catalyst Center".format(name) + self.log(self.msg, "INFO") + self.result['response'] = self.msg + return self + + self.status = "failed" + try: + failure_msg = response.get('errorMessage').get('errors') + except Exception as e: + failure_msg = "Unable to update rest webhook destination with name '{0}' in Cisco Catalyst Center".format(name) + + self.log(failure_msg, "ERROR") + self.result['response'] = failure_msg + + except Exception as e: + self.status = "failed" + self.msg = "Error while Updating the Rest Webhook destination with the name '{0}' in Cisco Catalyst Center: {1}".format(name, str(e)) + self.log(self.msg, "ERROR") + + return self + + def get_email_destination_in_ccc(self): + """ + Retrieve the details of the Email destination present in Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Returns: + dict or None: A dictionary containing the details of the Email destination if it exists, + otherwise returns None. + Description: + This function retrieves the details of the Email destination present in Cisco Catalyst Center. + If the Email destination exists, it returns a dictionary containing its details. + If no Email destination is found, it returns None. + """ + + try: + response = self.dnac._exec( + family="event_management", + function='get_email_destination' + ) + self.log("Received API response from 'get_email_destination': {0}".format(str(response)), "DEBUG") + + if not response: + self.log("There is no Email destination present in Cisco Catalyst Center", "INFO") + return response + + return response[0] + + except Exception as e: + error_message = "Error while getting the details of Email destination present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(error_message, "ERROR") + raise Exception(error_message) + + def collect_email_playbook_params(self, email_details): + """ + Collects the parameters required for configuring Email destinations from the playbook. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + email_details (dict): A dictionary containing the Email destination details from the playbook. + Returns: + dict: A dictionary containing the collected parameters for configuring Email destinations. + Description: + This function collects the parameters required for configuring Email destinations from the playbook. + It extracts parameters such as 'fromEmail', 'toEmail', 'subject', and SMTP configurations + (primary and secondary) from the provided email_details dictionary. + """ + + playbook_params = { + 'fromEmail': email_details.get('from_email'), + 'toEmail': email_details.get('to_email'), + 'subject': email_details.get('subject') + } + + if email_details.get('primary_smtp_config'): + primary_smtp_details = email_details.get('primary_smtp_config') + playbook_params['primarySMTPConfig'] = {} + playbook_params['primarySMTPConfig']['hostName'] = primary_smtp_details.get('hostname') + playbook_params['primarySMTPConfig']['port'] = primary_smtp_details.get('port', "25") + playbook_params['primarySMTPConfig']['smtpType'] = primary_smtp_details.get('smtp_type', "DEFAULT") + playbook_params['primarySMTPConfig']['userName'] = primary_smtp_details.get('username', '') + playbook_params['primarySMTPConfig']['password'] = primary_smtp_details.get('password', '') + + if email_details.get('seconday_smtp_config'): + secondary_smtp_details = email_details.get('secondary_smtp_config') + playbook_params['secondarySMTPConfig'] = {} + playbook_params['secondarySMTPConfig']['hostName'] = secondary_smtp_details.get('hostname') + playbook_params['secondarySMTPConfig']['port'] = secondary_smtp_details.get('port') + playbook_params['secondarySMTPConfig']['smtpType'] = secondary_smtp_details.get('smtp_type', "DEFAULT") + playbook_params['secondarySMTPConfig']['userName'] = secondary_smtp_details.get('username', '') + playbook_params['secondarySMTPConfig']['password'] = secondary_smtp_details.get('password', '') + + return playbook_params + + def add_email_destination(self, email_params): + """ + Adds an Email destination in Cisco Catalyst Center using the provided parameters. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + email_params (dict): A dictionary containing the parameters required for adding an Email destination. + Returns: + self (object): An instance of a class representing the status of the operation, including whether it was + successful or failed, any error messages encountered during operation. + Description: + This function adds an Email destination in Cisco Catalyst Center using the provided parameters. + After the API call, it checks the status of the execution using the 'get_status_api_for_events' API. + If the status indicates success, it sets the status of the operation as 'success' and logs an informational message. + If the status indicates failure, it sets the status of the operation as 'failed' and logs an error message. + + """ + + try: + response = self.dnac._exec( + family="event_management", + function='create_email_destination', + op_modifies=True, + params=email_params + ) + self.log("Received API response from 'create_email_destination': {0}".format(str(response)), "DEBUG") + status = response.get('statusUri') + status_execution_id = status.split("/")[-1] + + # Now we check the status of API Events for configuring Email destination + status_response = self.dnac._exec( + family="event_management", + function='get_status_api_for_events', + op_modifies=True, + params={"execution_id": status_execution_id} + ) + self.log("Received API response from 'get_status_api_for_events': {0}".format(str(status_response)), "DEBUG") + + if status_response['apiStatus'] == "SUCCESS": + self.status = "success" + self.result['changed'] = True + self.msg = "Email Destination added successfully in Cisco Catalyst Center" + self.log(self.msg, "INFO") + self.result['response'] = self.msg + return self + + self.status = "failed" + try: + failure_msg = response.get('errorMessage').get('errors') + except Exception as e: + failure_msg = "Unable to Add Email destination in Cisco Catalyst Center" + + self.log(failure_msg, "ERROR") + self.result['response'] = failure_msg + + except Exception as e: + self.status = "failed" + self.msg = "Error while Adding the Email destination in Cisco Catalyst Center: {0}".format(str(e)) + self.log(self.msg, "ERROR") + + return self + + def email_dest_needs_update(self, email_params, email_dest_detail_in_ccc): + """ + Checks if an update is needed for an Email destination based on the provided parameters and details. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + email_params (dict): A dictionary containing the parameters for the Email destination to be updated. + email_dest_detail_in_ccc (dict): A dictionary containing the current details of Email destination in Cisco Catalyst Center. + Returns: + bool: A boolean value indicating whether an update is needed for the Email destination. + Description: + This function compares the parameters of the Email destination specified in email_params + with the current details of the Email destination in Cisco Catalyst Center specified in email_dest_detail_in_ccc. + If any parameter value in email_params differs from the corresponding value in email_dest_detail_in_ccc, + it indicates that an update is needed and returns True else it returns False indicating that no update is needed. + """ + + update_needed = False + + for key, value in email_params.items(): + if isinstance(value, dict): + self.email_dest_needs_update(value, email_dest_detail_in_ccc[key]) + elif email_dest_detail_in_ccc[key] == value or value == "": + continue + else: + update_needed = True + + return update_needed + + def update_email_destination(self, email_details, email_dest_detail_in_ccc): + """ + Updates an Email destination based on the provided parameters and current details. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + email_details (dict): A dictionary containing the updated parameters for the Email destination. + email_dest_detail_in_ccc (dict): A dictionary containing the current details of the Email + destination in Cisco Catalyst Center. + Returns: + self (object): An instance of a class representing the result of the update operation. + Description: + This function updates the Email destination in Cisco Catalyst Center based on the provided email_details + and the current details of the Email destination specified in email_dest_detail_in_ccc. + It constructs the update_email_params dictionary with the updated parameters. + If the update is successful, it sets the status to 'success' and logs a success message. + If the update fails, it sets the status to 'failed' and logs an error message. + Finally, it returns the result object containing the status and response message. + """ + + try: + update_email_params = {} + update_email_params['primarySMTPConfig'] = email_details.get('primarySMTPConfig') or email_dest_detail_in_ccc.get('primarySMTPConfig') + update_email_params['secondarySMTPConfig'] = email_details.get('secondarySMTPConfig') or email_dest_detail_in_ccc.get('secondarySMTPConfig', 'None') + update_email_params['fromEmail'] = email_details.get('fromEmail') or email_dest_detail_in_ccc.get('fromEmail') + update_email_params['toEmail'] = email_details.get('toEmail') or email_dest_detail_in_ccc.get('toEmail') + update_email_params['subject'] = email_details.get('subject') or email_dest_detail_in_ccc.get('subject') + update_email_params['emailConfigId'] = email_dest_detail_in_ccc.get('emailConfigId') + + response = self.dnac._exec( + family="event_management", + function='update_email_destination', + op_modifies=True, + params=update_email_params + ) + self.log("Received API response from 'update_email_destination': {0}".format(str(response)), "DEBUG") + status = response.get('statusUri') + status_execution_id = status.split("/")[-1] + + # Now we check the status of API Events for configuring Email destination + status_response = self.dnac._exec( + family="event_management", + function='get_status_api_for_events', + op_modifies=True, + params={"execution_id": status_execution_id} + ) + self.log("Received API response from 'get_status_api_for_events': {0}".format(str(status_response)), "DEBUG") + + if status_response['apiStatus'] == "SUCCESS": + self.status = "success" + self.result['changed'] = True + self.msg = "Email Destination updated successfully in Cisco Catalyst Center" + self.log(self.msg, "INFO") + self.result['response'] = self.msg + return self + + self.status = "failed" + try: + failure_msg = response.get('errorMessage').get('errors') + except Exception as e: + failure_msg = "Unable to update Email destination in Cisco Catalyst Center" + + self.log(failure_msg, "ERROR") + self.result['response'] = failure_msg + + except Exception as e: + self.status = "failed" + self.msg = "Error while Updating the Email destination in Cisco Catalyst Center: {0}".format(str(e)) + self.log(self.msg, "ERROR") + + return self + + def get_itsm_settings_in_ccc(self): + """ + Retrieves the ITSM Integration Settings present in Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Returns: + dict: A dictionary containing the list of details of ITSM Integration Settings. + Description: + This function retrieves the ITSM Integration Settings present in Cisco Catalyst Center + by executing the 'get_all_itsm_integration_settings' API call. + It logs the API response and extracts the data. + If there are no ITSM Integration Settings, it logs an INFO message. + If an error occurs during the process, it logs an ERROR message and raises an Exception. + """ + + try: + response = self.dnac._exec( + family="itsm_integration", + function='get_all_itsm_integration_settings' + ) + self.log("Received API response from 'get_all_itsm_integration_settings': {0}".format(str(response)), "DEBUG") + response = response.get('data') + if not response: + self.log("There is no ISTM Integration settings present in Cisco Catalyst Center", "INFO") + + return response + + except Exception as e: + error_message = "Error while getting the details of ITSM Integration Settings present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(error_message, "ERROR") + raise Exception(error_message) + + def get_itsm_settings_by_id(self, itsm_id): + """ + Retrieves the ITSM Integration Settings with the specified ID from Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + itsm_id (str): The ID of the ITSM Integration Setting to retrieve. + Returns: + dict: A dictionary containing the ITSM Integration Setting information for the given itsm id. + Description: + This function retrieves the ITSM Integration Setting with the specified ID from Cisco Catalyst Center. + It logs the API response and returns the data if it exists. + If there is no ITSM Integration Setting with the given ID, it logs an INFO message. + If an error occurs during the process, it logs an ERROR message and raises an Exception. + """ + + try: + response = self.dnac._exec( + family="itsm_integration", + function='get_itsm_integration_setting_by_id', + op_modifies=True, + params={"instance_id": itsm_id} + ) + self.log("Received API response from 'get_itsm_integration_setting_by_id': {0}".format(str(response)), "DEBUG") + + if not response: + self.log("There is no ISTM Integration settings with given ID present in Cisco Catalyst Center", "INFO") + + return response + + except Exception as e: + error_message = "Error while getting the details of ITSM Integration Setting by id present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(error_message, "ERROR") + raise Exception(error_message) + + def collect_itsm_playbook_params(self, itsm_details): + """ + Constructs the ITSM playbook parameters from the provided ITSM details. + Args: + self (object): An instance of a class used for ITSM playbook operations. + itsm_details (dict): A dictionary containing details about an ITSM integration. + Returns: + dict: A dictionary structured as required by the ITSM playbook for interaction. + Description: + This function takes a dictionary containing ITSM integration details, and constructs + a set of parameters formatted to meet the requirements of an ITSM playbook. These parameters can then be used to + configure ITSM connections through playbook executions. + """ + + playbook_params = { + 'name': itsm_details.get('name'), + 'description': itsm_details.get('description'), + 'dypName': 'ServiceNowConnection' + } + playbook_params['data'] = {} + + if itsm_details.get('connection_settings'): + connection_details = itsm_details.get('connection_settings') + playbook_params['data']['ConnectionSettings'] = {} + playbook_params['data']['ConnectionSettings']['Url'] = connection_details.get('url') + playbook_params['data']['ConnectionSettings']['Auth_UserName'] = connection_details.get('auth_username') + playbook_params['data']['ConnectionSettings']['Auth_Password'] = connection_details.get('auth_password') + + return playbook_params + + def check_required_itsm_param(self, itsm_params, invalid_itsm_params): + """ + Recursively checks for required ITSM parameters and collects any that are missing. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + itsm_params (dict): A dictionary of ITSM parameters that need validation. + invalid_itsm_params (list): A list to accumulate the keys of missing parameters. + Returns: + list: A list containing the keys of parameters that are found to be missing or None. + Description: + This method iteratively and recursively examines a dictionary of ITSM parameters + to ensure that all necessary parameters except 'description' are present and not None. + If a parameter is found to be missing or explicitly set to None, its key is added to the + 'invalid_itsm_params' list. This function is particularly useful for validating nested + parameter structures commonly found in configurations for ITSM systems. + """ + + for key, value in itsm_params.items(): + if isinstance(value, dict): + self.check_required_itsm_param(value, invalid_itsm_params) + elif key == "description": + continue + elif itsm_params.get(key) is None: + invalid_itsm_params.append(key) + + return invalid_itsm_params + + def create_itsm_integration_setting(self, itsm_params): + """ + Creates a new ITSM integration setting in the Cisco Catalyst Center using provided parameters. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + itsm_params (dict): A dictionary containing the parameters necessary to create an ITSM integration setting. + Returns: + self (object): An instance of a class representing the status of the operation, including whether it was + successful or failed, any error messages encountered during operation. + Description: + This method sends a request to the Cisco Catalyst Center to create an ITSM integration setting based on the + parameters provided in 'itsm_params'. + It then makes an API call and logs the response. If the creation is successful, indicated by the presence + of a 'createdDate' in the response, it logs a success message, sets the internal state to 'success', and + marks the operation as having changed the system state. If the creation fails, it attempts to log any errors + returned by the API or logs a generic failure message if no specific error is provided. + """ + + try: + instance_name = itsm_params.get('name') + response = self.dnac._exec( + family="itsm_integration", + function='create_itsm_integration_setting', + op_modifies=True, + params=itsm_params + ) + self.log("Received API response from 'create_itsm_integration_setting': {0}".format(str(response)), "DEBUG") + created_date = response.get('createdDate') + + if created_date: + self.status = "success" + self.result['changed'] = True + self.msg = "ITSM Integration Settings with name '{0}' has been created successfully in Cisco Catalyst Center".format(instance_name) + self.log(self.msg, "INFO") + self.result['response'] = self.msg + return self + + self.status = "failed" + try: + failure_msg = response.get('errors') + except Exception as e: + failure_msg = "Unable to create ITSM Integration Settings with name '{0}' in Cisco Catalyst Center".format(instance_name) + + self.log(failure_msg, "ERROR") + self.result['response'] = failure_msg + + except Exception as e: + self.status = "failed" + self.msg = "Error while creating the ITSM Integration Settings with name '{0}' in Cisco Catalyst Center: {1}".format(instance_name, str(e)) + self.log(self.msg, "ERROR") + + return self + + def itsm_needs_update(self, itsm_params, itsm_in_ccc): + """ + Checks if the ITSM settings in Cisco Catalyst Center need to be updated based on provided parameters. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + itsm_params (dict): A dictionary containing the new ITSM settings parameters. + itsm_in_ccc (dict): A dictionary containing the existing ITSM settings in the Cisco Catalyst Center. + Returns: + bool: True if an update is required based on the differences between the provided parameters and the existing settings, False otherwise. + Description: + This method compares provided ITSM integration parameters against the current settings stored in the Cisco Catalyst Center + to determine if an update is necessary. + If any of the checked fields or connection settings differ between the provided parameters and the existing settings, the method + will return True indicating an update is required. Otherwise, it returns False. + """ + + itsm_require_update = False + required_params = ["name", "description"] + for key in required_params: + if key == "description" and itsm_params[key]: + if itsm_params[key] != itsm_in_ccc[key]: + itsm_require_update = True + return itsm_require_update + elif itsm_params[key] != itsm_in_ccc[key]: + itsm_require_update = True + return itsm_require_update + + if itsm_params.get('data') is None or itsm_params.get('data').get('ConnectionSettings') is None: + self.log("ITSM Connection settings parameters are not given in the input playbook so no update required.", "INFO") + return itsm_require_update + + url = itsm_params.get('data').get('ConnectionSettings').get('Url') + username = itsm_params.get('data').get('ConnectionSettings').get('Auth_UserName') + + if url and url != itsm_in_ccc.get('data').get('ConnectionSettings').get('Url'): + itsm_require_update = True + if username and username != itsm_in_ccc.get('data').get('ConnectionSettings').get('Auth_UserName'): + itsm_require_update = True + + return itsm_require_update + + def update_itsm_integration_setting(self, itsm_params, itsm_in_ccc): + """ + Updates the ITSM integration settings in the Cisco Catalyst Center based on the provided parameters. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + itsm_params (dict): A dictionary containing the new ITSM settings parameters. + itsm_in_ccc (dict): A dictionary containing the existing ITSM settings in the Cisco Catalyst Center. + Returns: + self (object): The instance itself with updated status and message properties reflecting the result of the operation. + Description: + This method updates existing ITSM integration settings in the Cisco Catalyst Center using the provided new parameters. + The method performs several checks: + - It verifies that the 'Auth_Password' is provided when updating the connection settings. If not, it sets the status + to 'failed' and logs an informational message. + - It validates that the provided URL starts with 'https://'. If the URL is invalid, it sets the status to 'failed' and + logs an informational message. + Upon successful update, the method logs the success and returns the instance with a 'success' status. If the update + fails for any reason (such as an invalid URL or API errors), it logs the failure and returns the instance with a 'failed' + status. + """ + + try: + update_itsm_params = {} + update_itsm_params['name'] = itsm_params.get('name') or itsm_in_ccc.get('name') + update_itsm_params['description'] = itsm_params.get('description') or itsm_in_ccc.get('description') + update_itsm_params['dypName'] = 'ServiceNowConnection' + + update_itsm_params['data'] = {} + update_itsm_params['data']['ConnectionSettings'] = {} + if itsm_params.get('data') is None or itsm_params.get('data').get('ConnectionSettings') is None: + update_itsm_params['data']['ConnectionSettings']['Url'] = itsm_in_ccc.get('data').get('ConnectionSettings').get('Url') + update_itsm_params['data']['ConnectionSettings']['Auth_UserName'] = itsm_in_ccc.get('data').get('ConnectionSettings').get('Auth_UserName') + else: + connection_params = itsm_params.get('data').get('ConnectionSettings') + update_itsm_params['data']['ConnectionSettings']['Url'] = connection_params.get('Url') + update_itsm_params['data']['ConnectionSettings']['Auth_UserName'] = connection_params.get('Auth_UserName') + + if not connection_params.get('Auth_Password'): + self.status = "failed" + self.msg = """Unable to update ITSM setting '{0}' as 'Auth Password' is the required parameter for updating + ITSM Intergartion setting.""".format(update_itsm_params.get('name')) + self.log(self.msg, "INFO") + return self + + update_itsm_params['data']['ConnectionSettings']['Auth_Password'] = connection_params.get('Auth_Password') + + # Check whether the given url is valid or not + url = update_itsm_params.get('data').get('ConnectionSettings').get('Url') + regex_pattern = r'https://\S+' + + if not re.match(regex_pattern, url): + self.status = "failed" + self.msg = "Given url '{0}' is invalid url for ITSM Intergartion setting.It must starts with 'https://'".format(url) + self.log(self.msg, "INFO") + return self + + itsm_param_dict = { + 'payload': update_itsm_params, + 'instance_id': itsm_in_ccc.get('id') + } + + response = self.dnac._exec( + family="itsm_integration", + function='update_itsm_integration_setting', + op_modifies=True, + params=itsm_param_dict, + ) + self.log("Received API response from 'update_itsm_integration_setting': {0}".format(str(response)), "DEBUG") + + updated_date = response.get('updatedDate') + + if updated_date: + self.status = "success" + self.result['changed'] = True + self.msg = """ITSM Integration Settings with name '{0}' has been updated successfully in Cisco Catalyst + Center.""".format(update_itsm_params.get('name')) + self.log(self.msg, "INFO") + self.result['response'] = self.msg + return self + + self.status = "failed" + try: + failure_msg = response.get('errors') + except Exception as e: + failure_msg = "Unable to update ITSM Integration Settings with name '{0}' in Cisco Catalyst Center".format(update_itsm_params.get('name')) + + self.log(failure_msg, "ERROR") + self.result['response'] = failure_msg + + except Exception as e: + self.status = "failed" + self.msg = """Error while Updating the ITSM Integration Settings with name '{0}' in Cisco Catalyst Center due to: + {1}""".format(update_itsm_params.get('name'), str(e)) + self.log(self.msg, "ERROR") + + return self + + def delete_itsm_integration_setting(self, itsm_name, itsm_id): + """ + Deletes a specified ITSM integration setting from the Cisco Catalyst Center. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + itsm_name (str): The name of the ITSM integration setting to be deleted. + itsm_id (str): The unique identifier of the ITSM integration setting to be deleted. + Returns: + self (object): The instance itself with updated status and message properties reflecting the result of the operation. + Description: + This method attempts to delete an ITSM integration setting based on the provided name and ID. + If the deletion is not successful, the method logs an error message and sets the 'status' attribute to 'failed'. + This could occur if the ITSM integration setting does not exist or due to a failure in the API call. + Exceptions caught during the API call are handled by logging an error message detailing the issue and setting the 'status' + attribute to 'failed'. + """ + + try: + response = self.dnac._exec( + family="itsm_integration", + function='delete_itsm_integration_setting', + op_modifies=True, + params={"instance_id": itsm_id} + ) + self.log("Received API response from 'delete_itsm_integration_setting': {0}".format(str(response)), "DEBUG") + + if "successfully" in response: + self.msg = "ISTM Integration settings instance with name '{0}' deleted successfully from Cisco Catalyst Center".format(itsm_name) + self.status = "success" + self.log(self.msg, "INFO") + self.result['changed'] = True + self.result['response'] = self.msg + return self + + self.status = "failed" + self.msg = "Cannot delete ISTM Integration settings instance with name '{0}' from Cisco Catalyst Center".format(itsm_name) + self.log(self.msg, "ERROR") + + except Exception as e: + self.status = "failed" + self.msg = "Error while deleting ITSM Integration Setting with name '{0}' from Cisco Catalyst Center due to: {1}".format(itsm_name, str(e)) + self.log(self.msg, "ERROR") + + return self + + def get_diff_merged(self, config): + """ + Processes the configuration difference and merges them into Cisco Catalyst Center. + This method updates Cisco Catalyst Center configurations based on the differences detected + between the desired state (`want`) and the current state (`have`). It handles different + types of configurations such as syslog, SNMP, REST webhook, email, and ITSM settings. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + config (dict): A dictionary containing various destination settings that may include + syslog destination, SNMP destination, REST webhook destination, + email destination, and ITSM settings. Each key should point to a dictionary + that defines specific configuration for that setting type. + Return: + self (object): Returns the instance itself after potentially modifying internal state to reflect + the status of operation, messages to log, and response details. + Description: + This method acts as a controller that delegates specific tasks such as adding or updating + configurations for syslog, SNMP, REST webhook, email, and ITSM settings in the Cisco Catalyst + Center. It ensures required parameters are present, validates them, and calls the appropriate + methods to add or update the configurations. Error handling is included to manage any exceptions + or invalid configurations, updating the internal state to reflect these errors. + """ + + # Create/Update Syslog destination in Cisco Catalyst Center + if config.get('syslog_destination'): + syslog_details = self.want.get('syslog_details') + name = syslog_details.get('name') + port = syslog_details.get('port') + + if not name: + self.status = "failed" + self.msg = "Name is required parameter for adding/updating syslog destination for creating/updating the event." + self.log(self.msg, "ERROR") + return self + + if not port.isdigit() or (isinstance(port, int) and port not in range(1, 65536)): + self.status = "failed" + self.msg = "Invalid Syslog destination port '{0}' given in playbook. Select port from the number range(1, 65536)".format(port) + self.log(self.msg, "ERROR") + return self + + syslog_details_in_ccc = self.get_syslog_destination_with_name(name) + + if not syslog_details_in_ccc: + # We need to Add the Syslog Destination in the Catalyst Center + self.add_syslog_destination(syslog_details).check_return_status() + else: + # Check destination needs update and if yes then update Syslog Destination + syslog_need_update = self.syslog_dest_needs_update(syslog_details, syslog_details_in_ccc) + if not syslog_need_update: + self.msg = "Syslog Destination with name '{0}' needs no update in Cisco Catalyst Center".format(name) + self.log(self.msg, "INFO") + self.result['changed'] = False + self.result['response'] = self.msg + else: + # Update the syslog destination with given + self.update_syslog_destination(syslog_details, syslog_details_in_ccc).check_return_status() + + # Create/Update snmp destination in Cisco Catalyst Center + if config.get('snmp_destination'): + snmp_details = self.want.get('snmp_details') + destination_name = snmp_details.get('name') + if not destination_name: + self.status = "failed" + self.msg = "Name is required parameter for adding/updating SNMP destination for creating/updating the event." + self.log(self.msg, "ERROR") + return self + + is_destination_exist = False + for snmp_dict in self.have.get('snmp_destinations'): + if snmp_dict['name'] == destination_name: + snmp_dest_detail_in_ccc = snmp_dict + is_destination_exist = True + break + + snmp_params = self.collect_snmp_playbook_params(snmp_details) + if snmp_params.get('port'): + try: + port = int(snmp_params.get('port')) + if port not in range(1, 65536): + self.status = "failed" + self.msg = "Invalid Notification trap port '{0}' given in playbook. Select port from the number range(1, 65536)".format(port) + self.log(self.msg, "ERROR") + return self + except Exception as e: + self.status = "failed" + self.msg = "Invalid Notification trap port '{0}' given in playbook. Select port from the number range(1, 65536)".format(port) + self.log(self.msg, "ERROR") + return self + + if not is_destination_exist: + # Need to Add snmp destination in Cisco Catalyst Center with given playbook params + self.check_snmp_required_parameters(snmp_params).check_return_status() + self.log("""Required parameter validated successfully for adding SNMP Destination with name '{0}' in Cisco + Catalyst Center.""".format(destination_name), "INFO") + self.add_snmp_destination(snmp_params).check_return_status() + else: + # Check destination needs update and if yes then update SNMP Destination + snmp_need_update = self.email_dest_needs_update(snmp_params, snmp_dest_detail_in_ccc) + if not snmp_need_update: + self.msg = "SNMP Destination with name '{0}' needs no update in Cisco Catalyst Center".format(destination_name) + self.log(self.msg, "INFO") + self.result['changed'] = False + self.result['response'] = self.msg + else: + # Update the email destination with given details in the playbook + self.update_snmp_destination(snmp_params, snmp_dest_detail_in_ccc).check_return_status() + + # Create/Update Rest Webhook destination in Cisco Catalyst Center + if config.get('rest_webhook_destination'): + webhook_details = self.want.get('webhook_details') + destination_name = webhook_details.get('name') + + if not destination_name: + self.status = "failed" + self.msg = "Name is required parameter for adding/updating Webhook destination for creating/updating the event." + self.log(self.msg, "ERROR") + return self + + is_destination_exist = False + for webhook_dict in self.have.get('webhook_destinations'): + if webhook_dict['name'] == destination_name: + webhook_dest_detail_in_ccc = webhook_dict + is_destination_exist = True + break + webhook_params = self.collect_webhook_playbook_params(webhook_details) + + if webhook_params.get('method') not in ["POST", "PUT"]: + self.status = "failed" + self.msg = """Invalid Webhook method name '{0}' for creating/updating Webhook destination in Cisco Catalyst Center. + Select one of the following method 'POST/PUT'.""".format(webhook_params.get('method')) + self.log(self.msg, "ERROR") + return self + + if not is_destination_exist: + # Need to Add snmp destination in Cisco Catalyst Center with given playbook params + if not webhook_params['url']: + self.status = "failed" + self.msg = "Url is required parameter for creating Webhook destination for creating/updating the event in Cisco Catalyst Center." + self.log(self.msg, "ERROR") + return self + + self.add_webhook_destination(webhook_params).check_return_status() + else: + # Check destination needs update and if yes then update SNMP Destination + webhook_need_update = self.webhook_dest_needs_update(webhook_params, webhook_dest_detail_in_ccc) + + if not webhook_need_update: + self.msg = "Webhook Destination with name '{0}' needs no update in Cisco Catalyst Center".format(destination_name) + self.log(self.msg, "INFO") + self.result['changed'] = False + self.result['response'] = self.msg + else: + # Update the syslog destination with given + self.update_webhook_destination(webhook_details, webhook_dest_detail_in_ccc).check_return_status() + + # Create/Update Email destination in Cisco Catalyst Center + if config.get('email_destination'): + email_details = self.want.get('email_details') + email_params = self.collect_email_playbook_params(email_details) + + if not self.have.get('email_destination'): + # Need to Add snmp destination in Cisco Catalyst Center with given playbook params + required_params = ['fromEmail', 'toEmail', 'subject'] + invalid_email_params = [] + for item in required_params: + if not email_params[item]: + invalid_email_params.append(item) + if not email_params.get('primarySMTPConfig').get('hostName'): + invalid_email_params.append('hostName') + + if invalid_email_params: + self.status = "failed" + self.msg = """Required parameter '{0}' for configuring Email Destination in Cisco Catalyst Center + is missing.""".format(str(invalid_email_params)) + self.log(self.msg, "ERROR") + self.result['response'] = self.msg + return self + self.log("Required parameter validated successfully for adding Email Destination in Cisco Catalyst Center.", "INFO") + self.add_email_destination(email_params).check_return_status() + else: + # Check destination needs update and if yes then update Email Destination + email_dest_detail_in_ccc = self.have.get('email_destination') + email_need_update = self.email_dest_needs_update(email_params, email_dest_detail_in_ccc) + + if not email_need_update: + self.msg = "Email Destination needs no update in Cisco Catalyst Center" + self.log(self.msg, "INFO") + self.result['changed'] = False + self.result['response'] = self.msg + else: + # Update the email destination with given details in the playbook + self.update_email_destination(email_params, email_dest_detail_in_ccc).check_return_status() + + # Create/Update ITSM Integration Settings in Cisco Catalyst Center + if config.get('itsm_setting'): + itsm_details = self.want.get('itsm_details') + itsm_name = itsm_details.get('name') + if not itsm_name: + self.status = "failed" + self.msg = "Instance name is required parameter for adding/updating ITSM integration setting in Cisco Catalyst Center." + self.log(self.msg, "ERROR") + return self + + itsm_params = self.collect_itsm_playbook_params(itsm_details) + + is_itsm_exist = False + itsm_detail_in_ccc = self.have.get('itsm_setting') + if not itsm_detail_in_ccc: + self.log("There is no ITSM Intergartion setting present in Cisco Catalyst Center", "INFO") + else: + # Check whether the given itsm integration present in Cisco Catalyst Center or not. + for itsm in itsm_detail_in_ccc: + if itsm['name'] == itsm_name: + itsm_id = itsm['id'] + is_itsm_exist = True + break + + if not is_itsm_exist: + # Need to Add snmp destination in Cisco Catalyst Center with given playbook params + invalid_itsm_params = [] + invalid_itsm_params = self.check_required_itsm_param(itsm_params, invalid_itsm_params) + + # Check whether the url is valid or not + url = itsm_params.get('data').get('ConnectionSettings').get('Url') + regex_pattern = r'https://\S+' + + if not re.match(regex_pattern, url): + self.status = "failed" + self.msg = "Given url '{0}' is invalid url for ITSM Intergartion setting.It must starts with 'https://'".format(url) + self.log(self.msg, "INFO") + return self + + if invalid_itsm_params: + self.status = "failed" + self.msg = """Required parameter '{0}' for configuring ITSM Intergartion setting in Cisco Catalyst + Center is missing.""".format(str(invalid_itsm_params)) + self.log(self.msg, "ERROR") + self.result['response'] = self.msg + return self + + self.log("Required parameter validated successfully for configuring ITSM Intergartion setting in Cisco Catalyst Center.", "INFO") + self.create_itsm_integration_setting(itsm_params).check_return_status() + else: + itsm_in_ccc = self.get_itsm_settings_by_id(itsm_id) + if not itsm_in_ccc: + self.status = "failed" + self.msg = "Unable to update as there is no ITSM Integration setting with name '{0}' present in Cisco Catalyst Center".format(itsm_name) + self.log(self.msg, "ERROR") + return self + + # Check destination needs update and if yes then update Email Destination + itsm_need_update = self.itsm_needs_update(itsm_params, itsm_in_ccc) + + if not itsm_need_update: + self.msg = "ITSM Intergartion setting with name '{0}' needs no update in Cisco Catalyst Center".format(itsm_name) + self.log(self.msg, "INFO") + self.result['changed'] = False + self.result['response'] = self.msg + else: + # Update the email destination with given details in the playbook + self.update_itsm_integration_setting(itsm_params, itsm_in_ccc).check_return_status() + + return self + + def get_diff_deleted(self, config): + """ + Handles the deletion of ITSM integration settings in Cisco Catalyst Center based on the configuration provided. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + config (dict): A dictionary containing the 'itsm_setting' key with details about the ITSM integration to be deleted. + Returns: + self (object): The instance of the class with updated status, results, and message based on the deletion operation. + Description: + This function is responsible for deleting an ITSM setting from Cisco Catalyst Center if it exists. + It checks whether the specified ITSM setting exists in the current Catalyst Center configuration. If it exists, + the function proceeds to delete it. If it does not exist or is already deleted, the function updates the instance + status and results to reflect that no change was needed. + """ + + if config.get('itsm_setting'): + itsm_details = self.want.get('itsm_details') + itsm_name = itsm_details.get('name') + itsm_detail_in_ccc = self.have.get('itsm_setting') + if not itsm_detail_in_ccc: + self.status = "success" + self.result['changed'] = False + self.msg = """There is no ITSM Intergartion setting present in Cisco Catalyst Center so cannot delete + the ITSM Integartion setting with name '{0}'""".format(itsm_name) + self.log(self.name, "INFO") + return self + + # Check whether the given itsm integration present in Catalyst Center or not + itsm_exist = False + for itsm in itsm_detail_in_ccc: + if itsm['name'] == itsm_name: + itsm_id = itsm.get('id') + itsm_exist = True + break + if itsm_exist: + self.delete_itsm_integration_setting(itsm_name, itsm_id).check_return_status() + else: + self.msg = "Unable to delete ITSM Integartion setting with name '{0}' as it is not present in Cisco Catalyst Center".format(itsm_name) + self.log(self.msg, "INFO") + self.result['changed'] = False + self.result['response'] = self.msg + + return self + + def verify_diff_merged(self, config): + """ + Verify the addition/update status of configurations in Cisco Catalyst Center. + Parameters: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + config (dict): The configuration details to be verified. + Returns: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Description: + This method verifies whether the specified configurations have been successfully added/updated + in Cisco Catalyst Center as desired. + """ + + self.get_have(config) + self.log("Current State (have): {0}".format(str(self.have)), "INFO") + self.log("Desired State (want): {0}".format(str(self.want)), "INFO") + + if config.get('syslog_destination'): + syslog_details = self.want.get('syslog_details') + syslog_name = syslog_details.get('name') + syslog_details_in_ccc = self.get_syslog_destination_with_name(syslog_name) + + if syslog_details_in_ccc: + self.status = "success" + msg = """Requested Syslog Destination '{0}' have been successfully added/updated to the Cisco Catalyst Center and their + addition/updation has been verified.""".format(syslog_name) + self.log(msg, "INFO") + else: + self.log("""Playbook's input does not match with Cisco Catalyst Center, indicating that the Syslog destination with name + '{0}' addition/updation task may not have executed successfully.""".format(syslog_name), "INFO") + + if config.get('snmp_destination'): + snmp_details = self.want.get('snmp_details') + snmp_dest_name = snmp_details.get('name') + is_snmp_dest_exist = False + + for snmp_dict in self.have.get('snmp_destinations'): + if snmp_dict['name'] == snmp_dest_name: + is_snmp_dest_exist = True + break + + if is_snmp_dest_exist: + self.status = "success" + msg = """Requested SNMP Destination '{0}' have been successfully added/updated to the Cisco Catalyst Center and their + addition/updation has been verified.""".format(snmp_dest_name) + self.log(msg, "INFO") + else: + self.log("""Playbook's input does not match with Cisco Catalyst Center, indicating that the SNMP destination with name + '{0}' addition/updation task may not have executed successfully.""".format(snmp_dest_name), "INFO") + + if config.get('rest_webhook_destination'): + webhook_details = self.want.get('webhook_details') + webhook_name = webhook_details.get('name') + + is_webhook_dest_exist = False + for webhook_dict in self.have.get('webhook_destinations'): + if webhook_dict['name'] == webhook_name: + is_webhook_dest_exist = True + break + if is_webhook_dest_exist: + self.status = "success" + msg = """Requested Rest Webhook Destination '{0}' have been successfully added/updated to the Cisco Catalyst Center and their + addition/updation has been verified.""".format(webhook_name) + self.log(msg, "INFO") + else: + self.log("""Playbook's input does not match with Cisco Catalyst Center, indicating that Rest Webhook destination with name + '{0}' addition/updation task may not have executed successfully.""".format(webhook_name), "INFO") + + if config.get('email_destination'): + + if self.have.get('email_destination'): + self.status = "success" + msg = """Requested Email Destination have been successfully configured to the Cisco Catalyst Center and their + configuration has been verified.""" + self.log(msg, "INFO") + else: + self.log("""Playbook's input does not match with Cisco Catalyst Center, indicating that Email destination configuration + task may not have executed successfully.""", "INFO") + + if config.get('itsm_setting'): + itsm_details = self.want.get('itsm_details') + itsm_name = itsm_details.get('name') + is_itsm_exist = False + itsm_detail_in_ccc = self.have.get('itsm_setting') + + if not itsm_detail_in_ccc: + self.log("There is no ITSM Intergartion setting present in Cisco Catalyst Center", "INFO") + else: + # Check whether the given itsm integration present in Cisco Catalyst Center or not. + for itsm in itsm_detail_in_ccc: + if itsm['name'] == itsm_name: + is_itsm_exist = True + break + + if is_itsm_exist: + self.status = "success" + msg = """Requested ITSM Integration setting '{0}' have been successfully added/updated to the Cisco Catalyst Center + and their addition/updation has been verified.""".format(itsm_name) + self.log(msg, "INFO") + else: + self.log("""Playbook's input does not match with Cisco Catalyst Center, indicating that ITSM Integration setting with + name '{0}' addition/updation task may not have executed successfully.""".format(itsm_name), "INFO") + + return self + + def verify_diff_deleted(self, config): + """ + Verify the deletion status of ITSM Integration Setting in Cisco Catalyst Center. + Parameters: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + config (dict): The configuration details to be verified. + Returns: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Description: + This method checks the deletion status of a configuration in Cisco Catalyst Center. + It validates whether the specified ITSM Integration setting deleted from Cisco Catalyst Center. + """ + + self.get_have(config) + self.log("Current State (have): {0}".format(str(self.have)), "INFO") + self.log("Desired State (want): {0}".format(str(self.want)), "INFO") + + if config.get('itsm_setting'): + itsm_details = self.want.get('itsm_details') + itsm_name = itsm_details.get('name') + itsm_detail_in_ccc = self.have.get('itsm_setting') + itsm_deleted = True + + # Check whether the given itsm integration present in Catalyst Center or not + if not itsm_detail_in_ccc: + itsm_deleted = True + else: + for itsm in itsm_detail_in_ccc: + if itsm['name'] == itsm_name: + itsm_deleted = False + break + + if itsm_deleted: + self.status = "success" + msg = """Requested ITSM Integration setting '{0}' have been successfully deleted from the Cisco Catalyst Center + and their deletion has been verified.""".format(itsm_name) + self.log(msg, "INFO") + else: + self.log("""Playbook's input does not match with Cisco Catalyst Center, indicating that ITSM Integration setting with + name '{0}' deletion task may not have executed successfully.""".format(itsm_name), "INFO") + + return self + + +def main(): + """ main entry point for module execution + """ + + element_spec = {'dnac_host': {'required': True, 'type': 'str'}, + 'dnac_port': {'type': 'str', 'default': '443'}, + 'dnac_username': {'type': 'str', 'default': 'admin', 'aliases': ['user']}, + 'dnac_password': {'type': 'str', 'no_log': True}, + 'dnac_verify': {'type': 'bool', 'default': 'True'}, + 'dnac_version': {'type': 'str', 'default': '2.2.3.3'}, + 'dnac_debug': {'type': 'bool', 'default': False}, + 'dnac_log_level': {'type': 'str', 'default': 'WARNING'}, + "dnac_log_file_path": {"type": 'str', "default": 'dnac.log'}, + "dnac_log_append": {"type": 'bool', "default": True}, + 'dnac_log': {'type': 'bool', 'default': False}, + 'validate_response_schema': {'type': 'bool', 'default': True}, + 'config_verify': {'type': 'bool', "default": False}, + 'dnac_api_task_timeout': {'type': 'int', "default": 1200}, + 'dnac_task_poll_interval': {'type': 'int', "default": 2}, + 'config': {'required': True, 'type': 'list', 'elements': 'dict'}, + 'state': {'default': 'merged', 'choices': ['merged', 'deleted']} + } + + module = AnsibleModule(argument_spec=element_spec, + supports_check_mode=False) + + ccc_events = Events(module) + state = ccc_events.params.get("state") + + if state not in ccc_events.supported_states: + ccc_events.status = "invalid" + ccc_events.msg = "State {0} is invalid".format(state) + ccc_events.check_return_status() + + ccc_events.validate_input().check_return_status() + config_verify = ccc_events.params.get("config_verify") + + for config in ccc_events.validated_config: + ccc_events.reset_values() + ccc_events.get_want(config).check_return_status() + ccc_events.get_have(config).check_return_status() + ccc_events.get_diff_state_apply[state](config).check_return_status() + if config_verify: + ccc_events.verify_diff_state_apply[state](config).check_return_status() + + module.exit_json(**ccc_events.result) + + +if __name__ == '__main__': + main() From 598da3cd5433dfd98896cd166b5623929c5bca00 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 24 Apr 2024 14:48:05 +0530 Subject: [PATCH 280/358] Added a check for the global device credentials while verifying the config --- .../device_credential_workflow_manager.yml | 21 ++++++++++++++++--- .../device_credential_workflow_manager.py | 14 +++++++------ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/playbooks/device_credential_workflow_manager.yml b/playbooks/device_credential_workflow_manager.yml index 3d77584f06..ffdc841100 100644 --- a/playbooks/device_credential_workflow_manager.yml +++ b/playbooks/device_credential_workflow_manager.yml @@ -4,7 +4,7 @@ gather_facts: no connection: local tasks: - - name: Create Credentials and assign it to a site. + - name: Create global device credentials. cisco.dnac.device_credential_workflow_manager: dnac_host: "{{ dnac_host }}" dnac_port: "{{ dnac_port }}" @@ -14,6 +14,7 @@ dnac_debug: "{{ dnac_debug }}" dnac_log: True state: merged + config_verify: True config: - global_credential_details: cli_credential: @@ -54,7 +55,20 @@ port: 443 # old_description: # old_username: - assign_credentials_to_site: + + - name: Assign global device credentials to a site. + cisco.dnac.device_credential_workflow_manager: + dnac_host: "{{ dnac_host }}" + dnac_port: "{{ dnac_port }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: True + state: merged + config_verify: True + config: + - assign_credentials_to_site: cli_credential: description: CLI username: cli @@ -74,7 +88,7 @@ - Global/Chennai/Trill - Global/Chennai/Tidel - - name: Delete Credentials + - name: Delete credentials cisco.dnac.device_credential_workflow_manager: dnac_host: "{{ dnac_host }}" dnac_port: "{{ dnac_port }}" @@ -84,6 +98,7 @@ dnac_debug: "{{ dnac_debug }}" dnac_log: True state: deleted + config_verify: True config: - global_credential_details: cli_credential: diff --git a/plugins/modules/device_credential_workflow_manager.py b/plugins/modules/device_credential_workflow_manager.py index f74aded0d2..95d24bfa37 100644 --- a/plugins/modules/device_credential_workflow_manager.py +++ b/plugins/modules/device_credential_workflow_manager.py @@ -2540,12 +2540,14 @@ def verify_diff_deleted(self, config): credential_types = ["cliCredential", "snmpV2cRead", "snmpV2cWrite", "httpsRead", "httpsWrite", "snmpV3"] for credential_type in credential_types: - for item in have_global_credential.get(credential_type): - if item is not None: - self.msg = "Delete Global Device Credentials config \ - is not applied to the config" - self.status = "failed" - return self + have_global_credential_type = have_global_credential.get(credential_type) + if have_global_credential_type is not None: + for item in have_global_credential_type: + if item is not None: + self.msg = "Delete Global Device Credentials config \ + is not applied to the config" + self.status = "failed" + return self self.log("Successfully validated absence of global device credential.", "INFO") self.result.get("response")[0].get("globalCredential").update({"Validation": "Success"}) From 558b3a7941d9113fac8bd62aca19f32c6db60397 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Wed, 24 Apr 2024 17:50:37 +0530 Subject: [PATCH 281/358] While checking snmp dest needs update, mistakenly call 'email_dest_needs_update' --- plugins/modules/events_and_notifications_workflow_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/events_and_notifications_workflow_manager.py b/plugins/modules/events_and_notifications_workflow_manager.py index f845c5182e..05903144e5 100644 --- a/plugins/modules/events_and_notifications_workflow_manager.py +++ b/plugins/modules/events_and_notifications_workflow_manager.py @@ -2169,7 +2169,7 @@ def get_diff_merged(self, config): self.add_snmp_destination(snmp_params).check_return_status() else: # Check destination needs update and if yes then update SNMP Destination - snmp_need_update = self.email_dest_needs_update(snmp_params, snmp_dest_detail_in_ccc) + snmp_need_update = self.snmp_dest_needs_update(snmp_params, snmp_dest_detail_in_ccc) if not snmp_need_update: self.msg = "SNMP Destination with name '{0}' needs no update in Cisco Catalyst Center".format(destination_name) self.log(self.msg, "INFO") From 6f7c47b4c9bf98c08ae6e19fc2e4cdac6f32752a Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 24 Apr 2024 18:59:25 +0530 Subject: [PATCH 282/358] Addressed the review comments --- .../device_credential_workflow_manager.py | 73 ++++++++----------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/plugins/modules/device_credential_workflow_manager.py b/plugins/modules/device_credential_workflow_manager.py index 95d24bfa37..2fcdcff8ad 100644 --- a/plugins/modules/device_credential_workflow_manager.py +++ b/plugins/modules/device_credential_workflow_manager.py @@ -1128,8 +1128,8 @@ def get_cli_credentials(self, CredentialDetails, global_credentials): if item.get("description") == cliOldDescription \ and item.get("username") == cliOldUsername: if cliDetail: - self.msg = "More than one CLI credential with same \ - old_description and old_username. Pass ID." + self.msg = "More than one CLI credential with same " + \ + "old_description and old_username. Pass ID." self.status = "failed" return self cliDetail = item @@ -1145,8 +1145,8 @@ def get_cli_credentials(self, CredentialDetails, global_credentials): if item.get("description") == cliDescription \ and item.get("username") == cliUsername: if cliDetail: - self.msg = "More than one CLI Credential with same \ - description and username. Pass ID." + self.msg = "More than one CLI Credential with same " + \ + "description and username. Pass ID." self.status = "failed" return self cliDetail = item @@ -1297,8 +1297,8 @@ def get_httpsRead_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsReadOldDescription \ and item.get("username") == httpsReadOldUsername: if httpsReadDetail: - self.msg = "More than one httpsRead credential with same \ - old_description and old_username. Pass ID." + self.msg = "More than one httpsRead credential with same " + \ + "old_description and old_username. Pass ID." self.status = "failed" return self httpsReadDetail = item @@ -1314,8 +1314,8 @@ def get_httpsRead_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsReadDescription \ and item.get("username") == httpsReadUsername: if httpsReadDetail: - self.msg = "More than one httpsRead credential with same \ - description and username. Pass ID." + self.msg = "More than one httpsRead credential with same " + \ + "description and username. Pass ID." self.status = "failed" return self httpsReadDetail = item @@ -1360,14 +1360,14 @@ def get_httpsWrite_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsWriteOldDescription \ and item.get("username") == httpsWriteOldUsername: if httpsWriteDetail: - self.msg = "More than one httpsWrite credential with same \ - old_description and old_username. Pass ID" + self.msg = "More than one httpsWrite credential with same " + \ + "old_description and old_username. Pass ID" self.status = "failed" return self httpsWriteDetail = item if not httpsWriteDetail: - self.msg = "httpsWrite credential old_description or \ - old_username is invalid" + self.msg = "httpsWrite credential old_description or " + \ + "old_username is invalid" self.status = "failed" return self @@ -1533,8 +1533,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_cli_ptr] \ .update({values[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating \ - cliCredential " + str(have_cli_ptr) + self.msg = values[i] + " is mandatory for creating cliCredential " + str(have_cli_ptr) self.status = "failed" return self @@ -1551,8 +1550,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_cli_ptr] \ .update({"password": item.get("password")}) else: - self.msg = "password is mandatory for udpating \ - cliCredential " + str(have_cli_ptr) + self.msg = "password is mandatory for udpating cliCredential " + str(have_cli_ptr) self.status = "failed" return self @@ -1592,8 +1590,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_snmpv2cread_ptr] \ .update({keys[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating \ - snmpV2cRead " + str(have_snmpv2cread_ptr) + self.msg = values[i] + " is mandatory for creating snmpV2cRead " + str(have_snmpv2cread_ptr) self.status = "failed" return self create_snmpv2cread_ptr = create_snmpv2cread_ptr + 1 @@ -1606,8 +1603,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_snmpv2cread_ptr] \ .update({"readCommunity": item.get("read_community")}) else: - self.msg = "read_community is mandatory for updating \ - snmpV2cRead " + str(have_snmpv2cread_ptr) + self.msg = "read_community is mandatory for updating snmpV2cRead " + str(have_snmpv2cread_ptr) self.status = "failed" return self for i in range(1, 3): @@ -1641,8 +1637,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_snmpv2cwrite_ptr] \ .update({keys[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating \ - snmpV2cWrite " + str(have_snmpv2cwrite_ptr) + self.msg = values[i] + " is mandatory for creating snmpV2cWrite " + str(have_snmpv2cwrite_ptr) self.status = "failed" return self create_snmpv2cwrite_ptr = create_snmpv2cwrite_ptr + 1 @@ -1655,8 +1650,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_snmpv2cwrite_ptr] \ .update({"writeCommunity": item.get("write_community")}) else: - self.msg = "write_community is mandatory for updating \ - snmpV2cWrite " + str(have_snmpv2cwrite_ptr) + self.msg = "write_community is mandatory for updating snmpV2cWrite " + str(have_snmpv2cwrite_ptr) self.status = "failed" return self for i in range(1, 3): @@ -1691,8 +1685,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_httpsread_ptr] \ .update({values[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating \ - httpsRead " + str(have_httpsread_ptr) + self.msg = values[i] + " is mandatory for creating httpsRead " + str(have_httpsread_ptr) self.status = "failed" return self if item.get("port"): @@ -1711,8 +1704,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_httpsread_ptr] \ .update({"password": item.get("password")}) else: - self.msg = "password is mandatory for updating \ - httpsRead " + str(have_httpsread_ptr) + self.msg = "password is mandatory for updating httpsRead " + str(have_httpsread_ptr) self.status = "failed" return self for i in range(1, 5): @@ -1745,8 +1737,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_httpswrite_ptr] \ .update({values[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating \ - httpsWrite " + str(have_httpswrite_ptr) + self.msg = values[i] + " is mandatory for creating httpsWrite " + str(have_httpswrite_ptr) self.status = "failed" return self if item.get("port"): @@ -1765,8 +1756,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_httpswrite_ptr] \ .update({"password": item.get("password")}) else: - self.msg = "password is mandatory for updating \ - httpsRead " + str(have_httpswrite_ptr) + self.msg = "password is mandatory for updating httpsRead " + str(have_httpswrite_ptr) self.status = "failed" return self for i in range(1, 5): @@ -1799,8 +1789,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_snmpv3_ptr] \ .update({values[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating \ - snmpV3 " + str(have_snmpv3_ptr) + self.msg = values[i] + " is mandatory for creating snmpV3 " + str(have_snmpv3_ptr) self.status = "failed" return self if item.get("snmp_mode"): @@ -1821,8 +1810,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_snmpv3_ptr] \ .update({keys[auth]: item.get(auth)}) else: - self.msg = auth + " is mandatory for creating \ - snmpV3 " + str(have_snmpv3_ptr) + self.msg = auth + " is mandatory for creating snmpV3 " + str(have_snmpv3_ptr) self.status = "failed" return self if len(item.get("auth_password")) < 8: @@ -1842,8 +1830,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_snmpv3_ptr] \ .update({key[priv]: item.get(priv)}) else: - self.msg = priv + " is mandatory for creating \ - snmpV3 " + str(have_snmpv3_ptr) + self.msg = priv + " is mandatory for creating snmpV3 " + str(have_snmpv3_ptr) self.status = "failed" return self if len(item.get("privacy_password")) < 8: @@ -1851,8 +1838,7 @@ def get_want_device_credentials(self, CredentialDetails): self.status = "failed" return self elif create_credential[create_snmpv3_ptr].get("snmpMode") != "NOAUTHNOPRIV": - self.msg = "snmp_mode in snmpV3 is not \ - ['AUTHPRIV', 'AUTHNOPRIV', 'NOAUTHNOPRIV']" + self.msg = "snmp_mode in snmpV3 is not ['AUTHPRIV', 'AUTHNOPRIV', 'NOAUTHNOPRIV']" self.status = "failed" return self create_snmpv3_ptr = create_snmpv3_ptr + 1 @@ -2513,8 +2499,7 @@ def verify_diff_merged(self, config): self.log("Successfully validated the assign device credential to site", "INFO") self.result.get("response")[0].get("assignCredential").update({"Validation": "Success"}) - self.msg = "Successfully validated the Global Device Credential and \ - Assign Device Credential to Site." + self.msg = "Successfully validated the Global Device Credential and Assign Device Credential to Site." self.status = "success" return self @@ -2544,8 +2529,8 @@ def verify_diff_deleted(self, config): if have_global_credential_type is not None: for item in have_global_credential_type: if item is not None: - self.msg = "Delete Global Device Credentials config \ - is not applied to the config" + self.msg = "The configuration for deleting global device credentials " + \ + "is not being applied to the current configuration" self.status = "failed" return self From e8d9124fc67982a821351b892263955f57e79865 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 24 Apr 2024 19:16:59 +0530 Subject: [PATCH 283/358] Addressed the review comments --- .../device_credential_workflow_manager.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/modules/device_credential_workflow_manager.py b/plugins/modules/device_credential_workflow_manager.py index 2fcdcff8ad..7464589eed 100644 --- a/plugins/modules/device_credential_workflow_manager.py +++ b/plugins/modules/device_credential_workflow_manager.py @@ -1128,8 +1128,8 @@ def get_cli_credentials(self, CredentialDetails, global_credentials): if item.get("description") == cliOldDescription \ and item.get("username") == cliOldUsername: if cliDetail: - self.msg = "More than one CLI credential with same " + \ - "old_description and old_username. Pass ID." + self.msg = "More than one CLI credential with same old_description and old_username. " + \ + "Please provide global device credentials ID." self.status = "failed" return self cliDetail = item @@ -1145,8 +1145,8 @@ def get_cli_credentials(self, CredentialDetails, global_credentials): if item.get("description") == cliDescription \ and item.get("username") == cliUsername: if cliDetail: - self.msg = "More than one CLI Credential with same " + \ - "description and username. Pass ID." + self.msg = "More than one CLI Credential with same description and username. " + \ + "Please provide global device credentials ID." self.status = "failed" return self cliDetail = item @@ -1297,8 +1297,8 @@ def get_httpsRead_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsReadOldDescription \ and item.get("username") == httpsReadOldUsername: if httpsReadDetail: - self.msg = "More than one httpsRead credential with same " + \ - "old_description and old_username. Pass ID." + self.msg = "More than one httpsRead credential with same old_description and old_username. " + \ + "Please provide global device credentials ID." self.status = "failed" return self httpsReadDetail = item @@ -1314,8 +1314,8 @@ def get_httpsRead_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsReadDescription \ and item.get("username") == httpsReadUsername: if httpsReadDetail: - self.msg = "More than one httpsRead credential with same " + \ - "description and username. Pass ID." + self.msg = "More than one httpsRead credential with same description and username. " + \ + "Please provide global device credentials ID." self.status = "failed" return self httpsReadDetail = item @@ -1360,8 +1360,8 @@ def get_httpsWrite_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsWriteOldDescription \ and item.get("username") == httpsWriteOldUsername: if httpsWriteDetail: - self.msg = "More than one httpsWrite credential with same " + \ - "old_description and old_username. Pass ID" + self.msg = "More than one httpsWrite credential with same old_description and old_username. " + \ + "Please provide global device credentials ID." self.status = "failed" return self httpsWriteDetail = item From 8b80dbae9a837c1629265f086d1eaea08568e031 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 24 Apr 2024 19:40:38 +0530 Subject: [PATCH 284/358] Addressed the review comments --- .../device_credential_workflow_manager.py | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/plugins/modules/device_credential_workflow_manager.py b/plugins/modules/device_credential_workflow_manager.py index 7464589eed..fcfb5abdf9 100644 --- a/plugins/modules/device_credential_workflow_manager.py +++ b/plugins/modules/device_credential_workflow_manager.py @@ -1128,8 +1128,8 @@ def get_cli_credentials(self, CredentialDetails, global_credentials): if item.get("description") == cliOldDescription \ and item.get("username") == cliOldUsername: if cliDetail: - self.msg = "More than one CLI credential with same old_description and old_username. " + \ - "Please provide global device credentials ID." + self.msg = "There are multiple CLI credentials with the same old_description and old_username. " + \ + "Kindly provide the ID for the global device credentials." self.status = "failed" return self cliDetail = item @@ -1145,8 +1145,8 @@ def get_cli_credentials(self, CredentialDetails, global_credentials): if item.get("description") == cliDescription \ and item.get("username") == cliUsername: if cliDetail: - self.msg = "More than one CLI Credential with same description and username. " + \ - "Please provide global device credentials ID." + self.msg = "There are multiple CLI credentials with the same description and username. " + \ + "Kindly provide the ID for the global device credentials." self.status = "failed" return self cliDetail = item @@ -1297,8 +1297,8 @@ def get_httpsRead_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsReadOldDescription \ and item.get("username") == httpsReadOldUsername: if httpsReadDetail: - self.msg = "More than one httpsRead credential with same old_description and old_username. " + \ - "Please provide global device credentials ID." + self.msg = "There are multiple httpsRead credentials with the same old_description and old_username. " + \ + "Kindly provide the ID for the global device credentials." self.status = "failed" return self httpsReadDetail = item @@ -1314,8 +1314,8 @@ def get_httpsRead_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsReadDescription \ and item.get("username") == httpsReadUsername: if httpsReadDetail: - self.msg = "More than one httpsRead credential with same description and username. " + \ - "Please provide global device credentials ID." + self.msg = "There are multiple httpsRead credentials with the same description and username. " + \ + "Kindly provide the ID for the global device credentials." self.status = "failed" return self httpsReadDetail = item @@ -1360,8 +1360,8 @@ def get_httpsWrite_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsWriteOldDescription \ and item.get("username") == httpsWriteOldUsername: if httpsWriteDetail: - self.msg = "More than one httpsWrite credential with same old_description and old_username. " + \ - "Please provide global device credentials ID." + self.msg = "There are multiple httpsWrite credentials with the same old_description and old_username. " + \ + "Kindly provide the ID for the global device credentials." self.status = "failed" return self httpsWriteDetail = item @@ -1377,6 +1377,11 @@ def get_httpsWrite_credentials(self, CredentialDetails, global_credentials): for item in httpsWrite_details: if item.get("description") == httpsWriteDescription \ and item.get("username") == httpsWriteUsername: + if httpsWriteDetail: + self.msg = "There are multiple httpsWrite credentials with the same description and username. " + \ + "Kindly provide the ID for the global device credentials." + self.status = "failed" + return self httpsWriteDetail = item httpsWriteDetails.append(httpsWriteDetail) return httpsWriteDetails From 09b6744470604fdbe5e2d25f7f73d0bb7322b877 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Thu, 25 Apr 2024 10:05:10 +0530 Subject: [PATCH 285/358] Changed the log message while adding snmp destination in Catalyst Center --- .../modules/events_and_notifications_workflow_manager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/modules/events_and_notifications_workflow_manager.py b/plugins/modules/events_and_notifications_workflow_manager.py index 05903144e5..78f0bd184a 100644 --- a/plugins/modules/events_and_notifications_workflow_manager.py +++ b/plugins/modules/events_and_notifications_workflow_manager.py @@ -1089,7 +1089,7 @@ def add_snmp_destination(self, snmp_params): if status == 'SUCCESS': self.status = "success" self.result['changed'] = True - self.msg = "Syslog Destination with name '{0}' added successfully in Cisco Catalyst Center".format(snmp_params.get('name')) + self.msg = "SNMP Destination with name '{0}' added successfully in Cisco Catalyst Center".format(snmp_params.get('name')) self.log(self.msg, "INFO") self.result['response'] = self.msg return self @@ -1106,7 +1106,7 @@ def add_snmp_destination(self, snmp_params): return self except Exception as e: - error_message = """Error while Adding the Syslog destination with the name '{0}' in Cisco Catalyst Center: + error_message = """Error while Adding the SNMP destination with the name '{0}' in Cisco Catalyst Center: {1}""".format(snmp_params.get('name'), str(e)) self.log(error_message, "ERROR") raise Exception(error_message) @@ -1176,7 +1176,7 @@ def update_snmp_destination(self, snmp_params, snmp_dest_detail_in_ccc): except Exception as e: self.status = "failed" self.msg = """Invalid datatype for the Notification trap port '{0}' given in playbook. Select port with correct datatype from the - number range(1, 65536.""".format(port) + number range(1, 65536).""".format(port) self.log(self.msg, "ERROR") return self From 09454d9d01006953396294c3660b2c2945321083 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Thu, 25 Apr 2024 10:19:06 +0530 Subject: [PATCH 286/358] Addressed the review comments --- .../device_credential_workflow_manager.py | 176 +++++++++--------- 1 file changed, 93 insertions(+), 83 deletions(-) diff --git a/plugins/modules/device_credential_workflow_manager.py b/plugins/modules/device_credential_workflow_manager.py index fcfb5abdf9..539367ab58 100644 --- a/plugins/modules/device_credential_workflow_manager.py +++ b/plugins/modules/device_credential_workflow_manager.py @@ -951,15 +951,15 @@ def get_cli_params(self, cliDetails): def get_snmpV2cRead_params(self, snmpV2cReadDetails): """ - Format the snmpV2cRead parameters for the snmpV2cRead + Format the snmp_v2c_read parameters for the snmp_v2c_read credential configuration in Cisco Catalyst Center. Parameters: snmpV2cReadDetails (list of dict) - Cisco Catalyst Center - Details containing snmpV2cRead Credentials. + Details containing snmp_v2c_read Credentials. Returns: - snmpV2cRead (list of dict) - Processed snmpV2cRead credential + snmpV2cRead (list of dict) - Processed snmp_v2c_read credential data in the format suitable for the Cisco Catalyst Center config. """ @@ -977,15 +977,15 @@ def get_snmpV2cRead_params(self, snmpV2cReadDetails): def get_snmpV2cWrite_params(self, snmpV2cWriteDetails): """ - Format the snmpV2cWrite parameters for the snmpV2cWrite + Format the snmp_v2c_write parameters for the snmp_v2c_write credential configuration in Cisco Catalyst Center. Parameters: snmpV2cWriteDetails (list of dict) - Cisco Catalyst Center - Details containing snmpV2cWrite Credentials. + Details containing snmp_v2c_write Credentials. Returns: - snmpV2cWrite (list of dict) - Processed snmpV2cWrite credential + snmpV2cWrite (list of dict) - Processed snmp_v2c_write credential data in the format suitable for the Cisco Catalyst Center config. """ @@ -1003,15 +1003,15 @@ def get_snmpV2cWrite_params(self, snmpV2cWriteDetails): def get_httpsRead_params(self, httpsReadDetails): """ - Format the httpsRead parameters for the httpsRead + Format the https_read parameters for the https_read credential configuration in Cisco Catalyst Center. Parameters: httpsReadDetails (list of dict) - Cisco Catalyst Center - Details containing httpsRead Credentials. + Details containing https_read Credentials. Returns: - httpsRead (list of dict) - Processed httpsRead credential + httpsRead (list of dict) - Processed https_read credential data in the format suitable for the Cisco Catalyst Center config. """ @@ -1031,15 +1031,15 @@ def get_httpsRead_params(self, httpsReadDetails): def get_httpsWrite_params(self, httpsWriteDetails): """ - Format the httpsWrite parameters for the httpsWrite + Format the https_write parameters for the https_write credential configuration in Cisco Catalyst Center. Parameters: httpsWriteDetails (list of dict) - Cisco Catalyst Center - Details containing httpsWrite Credentials. + Details containing https_write Credentials. Returns: - httpsWrite (list of dict) - Processed httpsWrite credential + httpsWrite (list of dict) - Processed https_write credential data in the format suitable for the Cisco Catalyst Center config. """ @@ -1059,13 +1059,13 @@ def get_httpsWrite_params(self, httpsWriteDetails): def get_snmpV3_params(self, snmpV3Details): """ - Format the snmpV3 parameters for the snmpV3 credential configuration in Cisco Catalyst Center. + Format the snmp_v3 parameters for the snmp_v3 credential configuration in Cisco Catalyst Center. Parameters: - snmpV3Details (list of dict) - Cisco Catalyst Center details containing snmpV3 Credentials. + snmpV3Details (list of dict) - Cisco Catalyst Center details containing snmp_v3 Credentials. Returns: - snmpV3 (list of dict) - Processed snmpV3 credential + snmpV3 (list of dict) - Processed snmp_v3 credential data in the format suitable for the Cisco Catalyst Center config. """ @@ -1155,7 +1155,7 @@ def get_cli_credentials(self, CredentialDetails, global_credentials): def get_snmpV2cRead_credentials(self, CredentialDetails, global_credentials): """ - Get the current snmpV2cRead Credential from + Get the current snmp_v2c_read Credential from Cisco Catalyst Center based on the provided playbook details. Check this API using the check_return_status. @@ -1164,14 +1164,16 @@ def get_snmpV2cRead_credentials(self, CredentialDetails, global_credentials): global_credentials (dict) - All global device credentials details. Returns: - snmpV2cReadDetails (List) - The current snmpV2cRead. + snmpV2cReadDetails (List) - The current snmp_v2c_read. """ - # Playbook snmpV2cRead Credential details + # Playbook snmp_v2c_read Credential details all_snmpV2cRead = CredentialDetails.get("snmp_v2c_read") - # All snmpV2cRead details from the Cisco Catalyst Center + + # All snmp_v2c_read details from the Cisco Catalyst Center snmpV2cRead_details = global_credentials.get("snmpV2cRead") - # Cisco Catalyst Center details for the snmpV2cRead Credential given in the playbook + + # Cisco Catalyst Center details for the snmp_v2c_read Credential given in the playbook snmpV2cReadDetails = [] if all_snmpV2cRead and snmpV2cRead_details: for snmpV2cReadCredential in all_snmpV2cRead: @@ -1180,7 +1182,7 @@ def get_snmpV2cRead_credentials(self, CredentialDetails, global_credentials): if snmpV2cReadId: snmpV2cReadDetail = get_dict_result(snmpV2cRead_details, "id", snmpV2cReadId) if not snmpV2cReadDetail: - self.msg = "snmpV2cRead credential ID is invalid" + self.msg = "snmp_v2c_read credential ID is invalid" self.status = "failed" return self @@ -1192,7 +1194,7 @@ def get_snmpV2cRead_credentials(self, CredentialDetails, global_credentials): snmpV2cReadOldDescription ) if not snmpV2cReadDetail: - self.msg = "snmpV2cRead credential old_description is invalid" + self.msg = "snmp_v2c_read credential old_description is invalid" self.status = "failed" return self @@ -1208,7 +1210,7 @@ def get_snmpV2cRead_credentials(self, CredentialDetails, global_credentials): def get_snmpV2cWrite_credentials(self, CredentialDetails, global_credentials): """ - Get the current snmpV2cWrite Credential from + Get the current snmp_v2c_write Credential from Cisco Catalyst Center based on the provided playbook details. Check this API using the check_return_status. @@ -1217,14 +1219,16 @@ def get_snmpV2cWrite_credentials(self, CredentialDetails, global_credentials): global_credentials (dict) - All global device credentials details. Returns: - snmpV2cWriteDetails (List) - The current snmpV2cWrite. + snmpV2cWriteDetails (List) - The current snmp_v2c_write. """ - # Playbook snmpV2cWrite Credential details + # Playbook snmp_v2c_write Credential details all_snmpV2cWrite = CredentialDetails.get("snmp_v2c_write") - # All snmpV2cWrite details from the Cisco Catalyst Center + + # All snmp_v2c_write details from the Cisco Catalyst Center snmpV2cWrite_details = global_credentials.get("snmpV2cWrite") - # Cisco Catalyst Center details for the snmpV2cWrite Credential given in the playbook + + # Cisco Catalyst Center details for the snmp_v2c_write Credential given in the playbook snmpV2cWriteDetails = [] if all_snmpV2cWrite and snmpV2cWrite_details: for snmpV2cWriteCredential in all_snmpV2cWrite: @@ -1233,7 +1237,7 @@ def get_snmpV2cWrite_credentials(self, CredentialDetails, global_credentials): if snmpV2cWriteId: snmpV2cWriteDetail = get_dict_result(snmpV2cWrite_details, "id", snmpV2cWriteId) if not snmpV2cWriteDetail: - self.msg = "snmpV2cWrite credential ID is invalid" + self.msg = "snmp_v2c_write credential ID is invalid" self.status = "failed" return self @@ -1245,7 +1249,7 @@ def get_snmpV2cWrite_credentials(self, CredentialDetails, global_credentials): snmpV2cWriteOldDescription ) if not snmpV2cWriteDetail: - self.msg = "snmpV2cWrite credential old_description is invalid " + self.msg = "snmp_v2c_write credential old_description is invalid " self.status = "failed" return self @@ -1261,7 +1265,7 @@ def get_snmpV2cWrite_credentials(self, CredentialDetails, global_credentials): def get_httpsRead_credentials(self, CredentialDetails, global_credentials): """ - Get the current httpsRead Credential from + Get the current https_read Credential from Cisco Catalyst Center based on the provided playbook details. Check this API using the check_return_status. @@ -1270,14 +1274,16 @@ def get_httpsRead_credentials(self, CredentialDetails, global_credentials): global_credentials (dict) - All global device credentials details. Returns: - httpsReadDetails (List) - The current httpsRead. + httpsReadDetails (List) - The current https_read. """ - # Playbook httpsRead Credential details + # Playbook https_read Credential details all_httpsRead = CredentialDetails.get("https_read") - # All httpsRead details from the Cisco Catalyst Center + + # All https_read details from the Cisco Catalyst Center httpsRead_details = global_credentials.get("httpsRead") - # Cisco Catalyst Center details for the httpsRead Credential given in the playbook + + # Cisco Catalyst Center details for the https_read Credential given in the playbook httpsReadDetails = [] if all_httpsRead and httpsRead_details: for httpsReadCredential in all_httpsRead: @@ -1286,7 +1292,7 @@ def get_httpsRead_credentials(self, CredentialDetails, global_credentials): if httpsReadId: httpsReadDetail = get_dict_result(httpsRead_details, "id", httpsReadId) if not httpsReadDetail: - self.msg = "httpsRead credential Id is invalid" + self.msg = "https_read credential Id is invalid" self.status = "failed" return self @@ -1297,13 +1303,13 @@ def get_httpsRead_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsReadOldDescription \ and item.get("username") == httpsReadOldUsername: if httpsReadDetail: - self.msg = "There are multiple httpsRead credentials with the same old_description and old_username. " + \ + self.msg = "There are multiple https_read credentials with the same old_description and old_username. " + \ "Kindly provide the ID for the global device credentials." self.status = "failed" return self httpsReadDetail = item if not httpsReadDetail: - self.msg = "httpsRead credential old_description or old_username is invalid" + self.msg = "https_read credential old_description or old_username is invalid" self.status = "failed" return self @@ -1314,7 +1320,7 @@ def get_httpsRead_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsReadDescription \ and item.get("username") == httpsReadUsername: if httpsReadDetail: - self.msg = "There are multiple httpsRead credentials with the same description and username. " + \ + self.msg = "There are multiple https_read credentials with the same description and username. " + \ "Kindly provide the ID for the global device credentials." self.status = "failed" return self @@ -1324,7 +1330,7 @@ def get_httpsRead_credentials(self, CredentialDetails, global_credentials): def get_httpsWrite_credentials(self, CredentialDetails, global_credentials): """ - Get the current httpsWrite Credential from + Get the current https_write Credential from Cisco Catalyst Center based on the provided playbook details. Check this API using the check_return_status. @@ -1333,14 +1339,16 @@ def get_httpsWrite_credentials(self, CredentialDetails, global_credentials): global_credentials (dict) - All global device credentials details. Returns: - httpsWriteDetails (List) - The current httpsWrite. + httpsWriteDetails (List) - The current https_write. """ - # Playbook httpsWrite Credential details + # Playbook https_write Credential details all_httpsWrite = CredentialDetails.get("https_write") - # All httpsWrite details from the Cisco Catalyst Center + + # All https_write details from the Cisco Catalyst Center httpsWrite_details = global_credentials.get("httpsWrite") - # Cisco Catalyst Center details for the httpsWrite Credential given in the playbook + + # Cisco Catalyst Center details for the https_write Credential given in the playbook httpsWriteDetails = [] if all_httpsWrite and httpsWrite_details: for httpsWriteCredential in all_httpsWrite: @@ -1349,7 +1357,7 @@ def get_httpsWrite_credentials(self, CredentialDetails, global_credentials): if httpsWriteId: httpsWriteDetail = get_dict_result(httpsWrite_details, "id", httpsWriteId) if not httpsWriteDetail: - self.msg = "httpsWrite credential Id is invalid" + self.msg = "https_write credential Id is invalid" self.status = "failed" return self @@ -1360,13 +1368,13 @@ def get_httpsWrite_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsWriteOldDescription \ and item.get("username") == httpsWriteOldUsername: if httpsWriteDetail: - self.msg = "There are multiple httpsWrite credentials with the same old_description and old_username. " + \ + self.msg = "There are multiple https_write credentials with the same old_description and old_username. " + \ "Kindly provide the ID for the global device credentials." self.status = "failed" return self httpsWriteDetail = item if not httpsWriteDetail: - self.msg = "httpsWrite credential old_description or " + \ + self.msg = "https_write credential old_description or " + \ "old_username is invalid" self.status = "failed" return self @@ -1378,7 +1386,7 @@ def get_httpsWrite_credentials(self, CredentialDetails, global_credentials): if item.get("description") == httpsWriteDescription \ and item.get("username") == httpsWriteUsername: if httpsWriteDetail: - self.msg = "There are multiple httpsWrite credentials with the same description and username. " + \ + self.msg = "There are multiple https_write credentials with the same description and username. " + \ "Kindly provide the ID for the global device credentials." self.status = "failed" return self @@ -1388,7 +1396,7 @@ def get_httpsWrite_credentials(self, CredentialDetails, global_credentials): def get_snmpV3_credentials(self, CredentialDetails, global_credentials): """ - Get the current snmpV3 Credential from + Get the current snmp_v3 Credential from Cisco Catalyst Center based on the provided playbook details. Check this API using the check_return_status. @@ -1397,14 +1405,16 @@ def get_snmpV3_credentials(self, CredentialDetails, global_credentials): global_credentials (dict) - All global device credentials details. Returns: - snmpV3Details (List) - The current snmpV3. + snmpV3Details (List) - The current snmp_v3. """ - # Playbook snmpV3 Credential details + # Playbook snmp_v3 Credential details all_snmpV3 = CredentialDetails.get("snmp_v3") - # All snmpV3 details from the Cisco Catalyst Center + + # All snmp_v3 details from the Cisco Catalyst Center snmpV3_details = global_credentials.get("snmpV3") - # Cisco Catalyst Center details for the snmpV3 Credential given in the playbook + + # Cisco Catalyst Center details for the snmp_v3 Credential given in the playbook snmpV3Details = [] if all_snmpV3 and snmpV3_details: for snmpV3Credential in all_snmpV3: @@ -1413,7 +1423,7 @@ def get_snmpV3_credentials(self, CredentialDetails, global_credentials): if snmpV3Id: snmpV3Detail = get_dict_result(snmpV3_details, "id", snmpV3Id) if not snmpV3Detail: - self.msg = "snmpV3 credential id is invalid" + self.msg = "snmp_v3 credential id is invalid" self.status = "failed" return self @@ -1422,7 +1432,7 @@ def get_snmpV3_credentials(self, CredentialDetails, global_credentials): snmpV3Detail = get_dict_result(snmpV3_details, "description", snmpV3OldDescription) if not snmpV3Detail: - self.msg = "snmpV3 credential old_description is invalid" + self.msg = "snmp_v3 credential old_description is invalid" self.status = "failed" return self @@ -1538,7 +1548,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_cli_ptr] \ .update({values[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating cliCredential " + str(have_cli_ptr) + self.msg = values[i] + " is mandatory for creating cli_credential " + str(have_cli_ptr) self.status = "failed" return self @@ -1555,7 +1565,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_cli_ptr] \ .update({"password": item.get("password")}) else: - self.msg = "password is mandatory for udpating cliCredential " + str(have_cli_ptr) + self.msg = "password is mandatory for udpating cli_credential " + str(have_cli_ptr) self.status = "failed" return self @@ -1595,7 +1605,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_snmpv2cread_ptr] \ .update({keys[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating snmpV2cRead " + str(have_snmpv2cread_ptr) + self.msg = values[i] + " is mandatory for creating snmp_v2c_read " + str(have_snmpv2cread_ptr) self.status = "failed" return self create_snmpv2cread_ptr = create_snmpv2cread_ptr + 1 @@ -1608,7 +1618,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_snmpv2cread_ptr] \ .update({"readCommunity": item.get("read_community")}) else: - self.msg = "read_community is mandatory for updating snmpV2cRead " + str(have_snmpv2cread_ptr) + self.msg = "read_community is mandatory for updating snmp_v2c_read " + str(have_snmpv2cread_ptr) self.status = "failed" return self for i in range(1, 3): @@ -1642,7 +1652,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_snmpv2cwrite_ptr] \ .update({keys[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating snmpV2cWrite " + str(have_snmpv2cwrite_ptr) + self.msg = values[i] + " is mandatory for creating snmp_v2c_write " + str(have_snmpv2cwrite_ptr) self.status = "failed" return self create_snmpv2cwrite_ptr = create_snmpv2cwrite_ptr + 1 @@ -1655,7 +1665,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_snmpv2cwrite_ptr] \ .update({"writeCommunity": item.get("write_community")}) else: - self.msg = "write_community is mandatory for updating snmpV2cWrite " + str(have_snmpv2cwrite_ptr) + self.msg = "write_community is mandatory for updating snmp_v2c_write " + str(have_snmpv2cwrite_ptr) self.status = "failed" return self for i in range(1, 3): @@ -1690,7 +1700,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_httpsread_ptr] \ .update({values[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating httpsRead " + str(have_httpsread_ptr) + self.msg = values[i] + " is mandatory for creating https_read " + str(have_httpsread_ptr) self.status = "failed" return self if item.get("port"): @@ -1709,7 +1719,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_httpsread_ptr] \ .update({"password": item.get("password")}) else: - self.msg = "password is mandatory for updating httpsRead " + str(have_httpsread_ptr) + self.msg = "password is mandatory for updating https_read " + str(have_httpsread_ptr) self.status = "failed" return self for i in range(1, 5): @@ -1742,7 +1752,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_httpswrite_ptr] \ .update({values[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating httpsWrite " + str(have_httpswrite_ptr) + self.msg = values[i] + " is mandatory for creating https_write " + str(have_httpswrite_ptr) self.status = "failed" return self if item.get("port"): @@ -1761,7 +1771,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_httpswrite_ptr] \ .update({"password": item.get("password")}) else: - self.msg = "password is mandatory for updating httpsRead " + str(have_httpswrite_ptr) + self.msg = "password is mandatory for updating https_write " + str(have_httpswrite_ptr) self.status = "failed" return self for i in range(1, 5): @@ -1794,7 +1804,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_snmpv3_ptr] \ .update({values[i]: item.get(values[i])}) else: - self.msg = values[i] + " is mandatory for creating snmpV3 " + str(have_snmpv3_ptr) + self.msg = values[i] + " is mandatory for creating snmp_v3 " + str(have_snmpv3_ptr) self.status = "failed" return self if item.get("snmp_mode"): @@ -1815,7 +1825,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_snmpv3_ptr] \ .update({keys[auth]: item.get(auth)}) else: - self.msg = auth + " is mandatory for creating snmpV3 " + str(have_snmpv3_ptr) + self.msg = auth + " is mandatory for creating snmp_v3 " + str(have_snmpv3_ptr) self.status = "failed" return self if len(item.get("auth_password")) < 8: @@ -1835,7 +1845,7 @@ def get_want_device_credentials(self, CredentialDetails): create_credential[create_snmpv3_ptr] \ .update({key[priv]: item.get(priv)}) else: - self.msg = priv + " is mandatory for creating snmpV3 " + str(have_snmpv3_ptr) + self.msg = priv + " is mandatory for creating snmp_v3 " + str(have_snmpv3_ptr) self.status = "failed" return self if len(item.get("privacy_password")) < 8: @@ -1876,7 +1886,7 @@ def get_want_device_credentials(self, CredentialDetails): .get("snmpMode")[have_snmpv3_ptr].get("authType") }) else: - self.msg = "auth_type is required for updating snmpV3 " + \ + self.msg = "auth_type is required for updating snmp_v3 " + \ str(have_snmpv3_ptr) self.status = "failed" return self @@ -1884,7 +1894,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_snmpv3_ptr] \ .update({"authPassword": item.get("auth_password")}) else: - self.msg = "auth_password is required for updating snmpV3 " + \ + self.msg = "auth_password is required for updating snmp_v3 " + \ str(have_snmpv3_ptr) self.status = "failed" return self @@ -1903,7 +1913,7 @@ def get_want_device_credentials(self, CredentialDetails): .get("snmpMode")[have_snmpv3_ptr].get("privacyType") }) else: - self.msg = "privacy_type is required for updating snmpV3 " + \ + self.msg = "privacy_type is required for updating snmp_v3 " + \ str(have_snmpv3_ptr) self.status = "failed" return self @@ -1911,7 +1921,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_snmpv3_ptr] \ .update({"privacyPassword": item.get("privacy_password")}) else: - self.msg = "privacy_password is required for updating snmpV3 " + \ + self.msg = "privacy_password is required for updating snmp_v3 " + \ str(have_snmpv3_ptr) self.status = "failed" return self @@ -1994,17 +2004,17 @@ def get_want_assign_credentials(self, AssignCredentials): snmpV2cReadDescription = snmp_v2c_read.get("description") if snmpV2cReadId or snmpV2cReadDescription: - # All snmpV2cRead details from the Cisco Catalyst Center + # All snmp_v2c_read details from the Cisco Catalyst Center snmpV2cRead_details = global_credentials.get("snmpV2cRead") if not snmpV2cRead_details: - self.msg = "Global snmpV2cRead credential is not available" + self.msg = "Global snmp_v2c_read credential is not available" self.status = "failed" return self snmpV2cReadDetail = None if snmpV2cReadId: snmpV2cReadDetail = get_dict_result(snmpV2cRead_details, "id", snmpV2cReadId) if not snmpV2cReadDetail: - self.msg = "The ID of the snmpV2cRead credential is not valid." + self.msg = "The ID of the snmp_v2c_read credential is not valid." self.status = "failed" return self elif snmpV2cReadDescription: @@ -2012,7 +2022,7 @@ def get_want_assign_credentials(self, AssignCredentials): if item.get("description") == snmpV2cReadDescription: snmpV2cReadDetail = item if not snmpV2cReadDetail: - self.msg = "The username and description for the snmpV2cRead credential are invalid." + self.msg = "The username and description for the snmp_v2c_read credential are invalid." self.status = "failed" return self want.get("assign_credentials").update({"snmpV2ReadId": snmpV2cReadDetail.get("id")}) @@ -2023,17 +2033,17 @@ def get_want_assign_credentials(self, AssignCredentials): snmpV2cWriteDescription = snmp_v2c_write.get("description") if snmpV2cWriteId or snmpV2cWriteDescription: - # All snmpV2cWrite details from the Cisco Catalyst Center + # All snmp_v2c_write details from the Cisco Catalyst Center snmpV2cWrite_details = global_credentials.get("snmpV2cWrite") if not snmpV2cWrite_details: - self.msg = "Global snmpV2cWrite Credential is not available" + self.msg = "Global snmp_v2c_write Credential is not available" self.status = "failed" return self snmpV2cWriteDetail = None if snmpV2cWriteId: snmpV2cWriteDetail = get_dict_result(snmpV2cWrite_details, "id", snmpV2cWriteId) if not snmpV2cWriteDetail: - self.msg = "The ID of the snmpV2cWrite credential is invalid." + self.msg = "The ID of the snmp_v2c_write credential is invalid." self.status = "failed" return self elif snmpV2cWriteDescription: @@ -2041,7 +2051,7 @@ def get_want_assign_credentials(self, AssignCredentials): if item.get("description") == snmpV2cWriteDescription: snmpV2cWriteDetail = item if not snmpV2cWriteDetail: - self.msg = "The username and description of the snmpV2cWrite credential are invalid." + self.msg = "The username and description of the snmp_v2c_write credential are invalid." self.status = "failed" return self want.get("assign_credentials").update({"snmpV2WriteId": snmpV2cWriteDetail.get("id")}) @@ -2114,17 +2124,17 @@ def get_want_assign_credentials(self, AssignCredentials): snmpV3Description = snmp_v3.get("description") if snmpV3Id or snmpV3Description: - # All snmpV3 details from the Cisco Catalyst Center + # All snmp_v3 details from the Cisco Catalyst Center snmpV3_details = global_credentials.get("snmpV3") if not snmpV3_details: - self.msg = "Global snmpV3 Credential is not available." + self.msg = "Global snmp_v3 Credential is not available." self.status = "failed" return self snmpV3Detail = None if snmpV3Id: snmpV3Detail = get_dict_result(snmpV3_details, "id", snmpV3Id) if not snmpV3Detail: - self.msg = "The ID of the snmpV3 credential is not valid." + self.msg = "The ID of the snmp_v3 credential is not valid." self.status = "failed" return self elif snmpV3Description: @@ -2132,7 +2142,7 @@ def get_want_assign_credentials(self, AssignCredentials): if item.get("description") == snmpV3Description: snmpV3Detail = item if not snmpV3Detail: - self.msg = "The username and description for the snmpV2cWrite credential are invalid." + self.msg = "The username and description for the snmp_v2c_write credential are invalid." self.status = "failed" return self want.get("assign_credentials").update({"snmpV3Id": snmpV3Detail.get("id")}) From 0157a4bbc0f3a36a94086a77a550e2c7fc2fc058 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Thu, 25 Apr 2024 10:27:33 +0530 Subject: [PATCH 287/358] Addressed the review comments --- plugins/modules/device_credential_workflow_manager.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/modules/device_credential_workflow_manager.py b/plugins/modules/device_credential_workflow_manager.py index 539367ab58..ab1c602cd7 100644 --- a/plugins/modules/device_credential_workflow_manager.py +++ b/plugins/modules/device_credential_workflow_manager.py @@ -1565,7 +1565,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_cli_ptr] \ .update({"password": item.get("password")}) else: - self.msg = "password is mandatory for udpating cli_credential " + str(have_cli_ptr) + self.msg = "password is mandatory for updating cli_credential " + str(have_cli_ptr) self.status = "failed" return self @@ -1719,7 +1719,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_httpsread_ptr] \ .update({"password": item.get("password")}) else: - self.msg = "password is mandatory for updating https_read " + str(have_httpsread_ptr) + self.msg = "The password is mandatory for updating https_read " + str(have_httpsread_ptr) self.status = "failed" return self for i in range(1, 5): @@ -1771,7 +1771,7 @@ def get_want_device_credentials(self, CredentialDetails): update_credential[update_httpswrite_ptr] \ .update({"password": item.get("password")}) else: - self.msg = "password is mandatory for updating https_write " + str(have_httpswrite_ptr) + self.msg = "The password is mandatory for updating https_write " + str(have_httpswrite_ptr) self.status = "failed" return self for i in range(1, 5): @@ -2514,7 +2514,7 @@ def verify_diff_merged(self, config): self.log("Successfully validated the assign device credential to site", "INFO") self.result.get("response")[0].get("assignCredential").update({"Validation": "Success"}) - self.msg = "Successfully validated the Global Device Credential and Assign Device Credential to Site." + self.msg = "Successfully validated the global device credential and assigned device credential to site." self.status = "success" return self @@ -2544,7 +2544,7 @@ def verify_diff_deleted(self, config): if have_global_credential_type is not None: for item in have_global_credential_type: if item is not None: - self.msg = "The configuration for deleting global device credentials " + \ + self.msg = "The configuration for deleting the global device credentials " + \ "is not being applied to the current configuration" self.status = "failed" return self From a332191fc9a7e447cff3753ad7c08242294519ff Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Thu, 25 Apr 2024 11:51:54 +0530 Subject: [PATCH 288/358] Instead of raising exception failed the status and show corresponding message on the console and log it as well. --- ...ents_and_notifications_workflow_manager.py | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/plugins/modules/events_and_notifications_workflow_manager.py b/plugins/modules/events_and_notifications_workflow_manager.py index 78f0bd184a..8c1c7b9bfe 100644 --- a/plugins/modules/events_and_notifications_workflow_manager.py +++ b/plugins/modules/events_and_notifications_workflow_manager.py @@ -734,9 +734,10 @@ def get_syslog_destination_in_ccc(self): return response except Exception as e: - error_message = "Error while getting the details of Syslog destination present in Cisco Catalyst Center: {0}".format(str(e)) - self.log(error_message, "ERROR") - raise Exception(error_message) + self.status = "failed" + self.msg = "Error while getting the details of Syslog destination present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(self.msg, "ERROR") + self.check_return_status() def get_syslog_destination_with_name(self, name): """ @@ -770,9 +771,10 @@ def get_syslog_destination_with_name(self, name): return syslog_details except Exception as e: - error_message = "Error while getting the details of Syslog destination with the name '{0}' from Cisco Catalyst Center: {1}".format(name, str(e)) - self.log(error_message, "ERROR") - raise Exception(error_message) + self.status = "failed" + self.msg = "Error while getting the details of Syslog destination with the name '{0}' from Cisco Catalyst Center: {1}".format(name, str(e)) + self.log(self.msg, "ERROR") + self.check_return_status() def syslog_dest_needs_update(self, syslog_details, syslog_details_in_ccc): """ @@ -968,9 +970,10 @@ def get_snmp_destination_in_ccc(self): return response except Exception as e: - error_message = "Error while getting the details of SNMP destination present in Cisco Catalyst Center: {0}".format(str(e)) - self.log(error_message, "ERROR") - raise Exception(error_message) + self.status = "failed" + self.msg = "Error while getting the details of SNMP destination present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(self.msg, "ERROR") + self.check_return_status() def collect_snmp_playbook_params(self, snmp_details): """ @@ -1106,10 +1109,11 @@ def add_snmp_destination(self, snmp_params): return self except Exception as e: - error_message = """Error while Adding the SNMP destination with the name '{0}' in Cisco Catalyst Center: + self.status = "failed" + self.msg = """Error while Adding the SNMP destination with the name '{0}' in Cisco Catalyst Center: {1}""".format(snmp_params.get('name'), str(e)) - self.log(error_message, "ERROR") - raise Exception(error_message) + self.log(self.msg, "ERROR") + self.check_return_status() def snmp_dest_needs_update(self, snmp_params, snmp_dest_detail_in_ccc): """ @@ -1258,9 +1262,10 @@ def get_rest_webhook_destination_in_ccc(self): return response except Exception as e: - error_message = "Error while getting the details of Webhook destination(s) present in Cisco Catalyst Center: {0}".format(str(e)) - self.log(error_message, "ERROR") - raise Exception(error_message) + self.status = "failed" + self.msg = "Error while getting the details of Webhook destination(s) present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(self.msg, "ERROR") + self.check_return_status() def collect_webhook_playbook_params(self, webhook_details): """ @@ -1508,9 +1513,10 @@ def get_email_destination_in_ccc(self): return response[0] except Exception as e: - error_message = "Error while getting the details of Email destination present in Cisco Catalyst Center: {0}".format(str(e)) - self.log(error_message, "ERROR") - raise Exception(error_message) + self.status = "failed" + self.msg = "Error while getting the details of Email destination present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(self.msg, "ERROR") + self.check_return_status() def collect_email_playbook_params(self, email_details): """ @@ -1740,9 +1746,10 @@ def get_itsm_settings_in_ccc(self): return response except Exception as e: - error_message = "Error while getting the details of ITSM Integration Settings present in Cisco Catalyst Center: {0}".format(str(e)) - self.log(error_message, "ERROR") - raise Exception(error_message) + self.status = "failed" + self.msg = "Error while getting the details of ITSM Integration Settings present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(self.msg, "ERROR") + self.check_return_status() def get_itsm_settings_by_id(self, itsm_id): """ @@ -1774,9 +1781,10 @@ def get_itsm_settings_by_id(self, itsm_id): return response except Exception as e: - error_message = "Error while getting the details of ITSM Integration Setting by id present in Cisco Catalyst Center: {0}".format(str(e)) - self.log(error_message, "ERROR") - raise Exception(error_message) + self.status = "failed" + self.msg = "Error while getting the details of ITSM Integration Setting by id present in Cisco Catalyst Center: {0}".format(str(e)) + self.log(self.msg, "ERROR") + self.check_return_status() def collect_itsm_playbook_params(self, itsm_details): """ From 4811e90e814f90fab1be15648f582e6bf3f21b75 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Thu, 25 Apr 2024 12:50:37 +0530 Subject: [PATCH 289/358] Added a new playbook and module for ISE RADIUS Integration --- ...se_radius_integration_workflow_manager.yml | 116 ++ ...ise_radius_integration_workflow_manager.py | 1466 +++++++++++++++++ tests/sanity/ignore-2.10.txt | 4 + tests/sanity/ignore-2.11.txt | 4 + tests/sanity/ignore-2.12.txt | 4 + tests/sanity/ignore-2.13.txt | 2 + tests/sanity/ignore-2.14.txt | 2 + tests/sanity/ignore-2.15.txt | 2 + tests/sanity/ignore-2.9.txt | 4 + 9 files changed, 1604 insertions(+) create mode 100644 playbooks/ise_radius_integration_workflow_manager.yml create mode 100644 plugins/modules/ise_radius_integration_workflow_manager.py diff --git a/playbooks/ise_radius_integration_workflow_manager.yml b/playbooks/ise_radius_integration_workflow_manager.yml new file mode 100644 index 0000000000..eba36a3c59 --- /dev/null +++ b/playbooks/ise_radius_integration_workflow_manager.yml @@ -0,0 +1,116 @@ +- hosts: dnac_servers + vars_files: + - credentials.yml + gather_facts: no + connection: local + tasks: + - name: Create an Authentication and Policy Server. + cisco.dnac.ise_radius_integration_workflow_manager: + dnac_host: "{{ dnac_host }}" + dnac_port: "{{ dnac_port }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + dnac_log_append: True + dnac_log_file_path: "{{ dnac_log_file_path }}" + state: merged + config_verify: True + config: + - authentication_policy_server: + server_type: AAA # [ISE, AAA] + server_ip_address: 10.0.0.20 + shared_secret: cisco + protocol: RADIUS_TACACS # [TACACS, RADIUS, RADIUS_TACACS] + encryption_scheme: KEYWRAP # KEYWRAP or RADSEC + message_key: dnacisesolutions1234 # For KEYWRAP, must be 20 char long + encryption_key: dnacsolutions123 # For KEYWRAP, must be 16 char long + authentication_port: 1800 + accounting_port: 1700 + port: 40 # For TACACS + retries: 3 # Range from 1 to 3 + timeout: 4 # Range from 2 to 20 + role: secondary + + - name: Delete Authentication and Policy Server. + cisco.dnac.ise_radius_integration_workflow_manager: + dnac_host: "{{ dnac_host }}" + dnac_port: "{{ dnac_port }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + dnac_log_append: True + dnac_log_file_path: "{{ dnac_log_file_path }}" + state: deleted + config_verify: True + config: + - authentication_policy_server: + server_ip_address: 10.0.0.20 + + - name: Create ISE Server. + cisco.dnac.ise_radius_integration_workflow_manager: + dnac_host: "{{ dnac_host }}" + dnac_port: "{{ dnac_port }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + dnac_log_append: True + dnac_log_file_path: "{{ dnac_log_file_path }}" + state: merged + config_verify: True + config: + - authentication_policy_server: + server_type: ISE # [ISE, AAA] + server_ip_address: 10.195.243.59 + shared_secret: cisco + protocol: RADIUS_TACACS # [TACACS, RADIUS, RADIUS_TACACS] + encryption_scheme: KEYWRAP # KEYWRAP or RADSEC + message_key: dnacisesolutions1234 # For KEYWRAP, must be 20 char long + encryption_key: dnacsolutions123 # For KEYWRAP, must be 16 char long + authentication_port: 1800 + accounting_port: 1700 + port: 40 # For TACACS + retries: 3 # Range from 1 to 3 + timeout: 4 # Range from 2 to 20 + role: primary + pxgrid_enabled: False # Avaliable for Cisco ISE only + use_dnac_cert_for_pxgrid: False + cisco_ise_dtos: # use this for creating the Cisco ISE Server + - user_name: admin + password: abcdefgh + fqdn: abc.cisco.com + ip_address: 10.195.243.59 + subscriber_name: abc + description: CISCO ISE + # ssh_key: + # external_cisco_ise_ip_addr_dtos: + # - external_cisco_ise_ip_addresses: + # - external_ip_address: + # ise_type: + trusted_server: True + + - name: Delete an ISE Server. + cisco.dnac.ise_radius_integration_workflow_manager: + dnac_host: "{{ dnac_host }}" + dnac_port: "{{ dnac_port }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + dnac_log_append: True + dnac_log_file_path: "{{ dnac_log_file_path }}" + state: deleted + config_verify: True + config: + - authentication_policy_server: + server_ip_address: 10.195.243.59 diff --git a/plugins/modules/ise_radius_integration_workflow_manager.py b/plugins/modules/ise_radius_integration_workflow_manager.py new file mode 100644 index 0000000000..3bbe5c31f2 --- /dev/null +++ b/plugins/modules/ise_radius_integration_workflow_manager.py @@ -0,0 +1,1466 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (c) 2024, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +"""Ansible module to operate the Authentication and Policy Servers in Cisco Catalyst Center.""" +from __future__ import absolute_import, division, print_function + +__metaclass__ = type +__author__ = ['Muthu Rakesh, Madhan Sankaranarayanan'] + +DOCUMENTATION = r""" +--- +module: ise_radius_integration_workflow_manager +short_description: Resource module for Authentication and Policy Servers +description: +- Manage operations on Authentication and Policy Servers. +- API to create Authentication and Policy Server Access Configuration. +- API to update Authentication and Policy Server Access Configuration. +- API to delete Authentication and Policy Server Access Configuration. +version_added: '6.13.0' +extends_documentation_fragment: + - cisco.dnac.workflow_manager_params +author: Muthu Rakesh (@MUTHU-RAKESH-27) + Madhan Sankaranarayanan (@madhansansel) +options: + config_verify: + description: Set to True to verify the Cisco Catalyst Center after applying the playbook config. + type: bool + default: False + state: + description: The state of Cisco Catalyst Center after module completion. + type: str + choices: [ merged, deleted ] + default: merged + config: + description: + - List of details of Authentication and Policy Servers being managed. + type: list + elements: dict + required: true + suboptions: + authentication_policy_server: + description: Manages the Authentication and Policy Servers. + type: dict + suboptions: + server_type: + description: + - Type of the Authentication and Policy Server. + - ISE for Cisco ISE servers. + - AAA for Non-Cisco ISE servers. + type: str + choices: [ AAA, ISE ] + default: AAA + server_ip_address: + description: Ip Address of the Authentication and Policy Server. + type: str + required: True + shared_secret: + description: + - Shared secret between devices and authentication and policy server. + - Shared secret key length should be from 4 to 10. + - Shared secret is a Read-Only parameter. + type: str + protocol: + description: + - Type of protocol for authentication and policy server. + - RADIUS provides centralized services (AAA) for users in remote access scenarios. + - TACACS focuses on access control and administrative authentication for network devices. + type: str + choices: [ TACACS, RADIUS, RADIUS_TACACS] + default: TACACS + encryption_scheme: + description: + - Type of encryption scheme for additional security. + - Updation of encryption scheme is not possible. + - > + KEYWRAP is used for securely wrapping and unwrapping encryption keys, + ensuring their confidentiality during transmission or storage. + - > + RADSEC is an extension of RADIUS that provides secure communication + between RADIUS clients and servers over TLS/SSL. Enhances enhancing the + confidentiality and integrity of authentication and accounting data exchange. + type: str + choices: [KEYWRAP, RADSEC] + message_key: + description: + - Message key used to encrypt shared secret. + - Updation of message key is not possible. + - Required when encryption_scheme is provided. + - > + When ASCII format is selected, Message Authentication Code Key may contain + alphanumeric and special characters. Key must be 20 char long. + type: str + encryption_key: + description: + - Encryption key used to encrypt shared secret. + - Updation of encryption scheme is not possible. + - Required when encryption_scheme is provided. + - > + When ASCII format is selected, Encryption Key may contain + alphanumeric and special characters. Key must be 16 char long. + type: str + authentication_port: + description: + - Authentication port of RADIUS server. + - Updation of authentication port is not possible. + - Authentication port should be from 1 to 65535. + type: str + default: "1812" + accounting_port: + description: + - Accounting port of RADIUS server. + - Updation of accounting port is not possible. + - Accounting port should be from 1 to 65535. + type: str + default: "1813" + port: + description: + - Port of TACACS server. + - Updation of port is not possible. + - Port should be from 1 to 65535. + type: str + default: "49" + retries: + description: + - Number of communication retries between devices and authentication and policy server. + - Retries should be from 1 to 3. + type: str + default: "3" + timeout: + description: + - Number of seconds before timing out between devices and authentication and policy server. + - Timeout should be from 2 to 20. + type: str + default: "4" + role: + description: + - Role of authentication and policy server. + - Updation of role is not possible + type: str + default: secondary + pxgrid_enabled: + description: + - Set True to enable the Pxgrid and False to disable the Pxgrid. + - Pxgrid is available only for the Cisco ISE Servers. + - > + PxGrid facilitates seamless integration and information sharing across products, + enhancing threat detection and response capabilities within the network ecosystem. + type: bool + default: True + use_dnac_cert_for_pxgrid: + description: Set True to use the Cisco Catalyst Center certificate for the Pxgrid. + type: bool + default: False + cisco_ise_dtos: + description: + - List of Cisco ISE Data Transfer Objects (DTOs). + - Required when server_type is set to ISE. + type: list + elements: dict + suboptions: + user_name: + description: + - User name of the Cisco ISE server. + - Required for passing the cisco_ise_dtos. + type: str + password: + description: + - Password of the Cisco ISE server. + - Required for passing the cisco_ise_dtos. + type: str + fqdn: + description: + - Fully-qualified domain name of the Cisco ISE server. + - Required for passing the cisco_ise_dtos. + type: str + ip_address: + description: + - IP Address of the Cisco ISE Server. + - Required for passing the cisco_ise_dtos. + type: str + subscriber_name: + description: + - Subscriber name of the Cisco ISE server. + - Required for passing the cisco_ise_dtos. + type: str + description: + description: Description about the Cisco ISE server. + type: str + ssh_key: + description: SSH key of the Cisco ISE server. + type: str + external_cisco_ise_ip_addr_dtos: + description: External Cisco ISE Ip address data transfer objects for future use. + type: list + elements: dict + suboptions: + external_cisco_ise_ip_addresses: + description: External Cisco ISE Ip addresses. + type: list + elements: dict + suboptions: + external_ip_address: + description: External Cisco ISE Ip address. + type: str + ise_type: + description: Type of the Authentication and Policy Server. + type: str + trusted_server: + description: + - Indicates whether the certificate is trustworthy for the server. + - Serves as a validation of its authenticity and reliability in secure connections. + type: bool +requirements: +- dnacentersdk == 2.7.0 +- python >= 3.5 +notes: + - SDK Method used are + system_settings.SystemSettings.add_authentication_and_policy_server_access_configuration, + system_settings.SystemSettings.edit_authentication_and_policy_server_access_configuration, + system_settings.SystemSettings.accept_cisco_ise_server_certificate_for_cisco_ise_server_integration, + system_settings.SystemSettings.delete_authentication_and_policy_server_access_configuration, + + - Paths used are + post /dna/intent/api/v1/authentication-policy-servers, + put /dna/intent/api/v1/authentication-policy-servers/${id}, + put /dna/intent/api/v1/integrate-ise/${id}, + delete /dna/intent/api/v1/authentication-policy-servers/${id} + +""" + +EXAMPLES = r""" +- name: Create an AAA server. + cisco.dnac.ise_radius_integration_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + state: merged + config_verify: True + config: + - authentication_policy_server: + server_type: string + server_ip_address: string + shared_secret: string + protocol: string + encryption_scheme: string + message_key: string + encryption_key: string + authentication_port: string + accounting_port: string + port: string + retries: string + timeout: string + role: string + +- name: Create an Cisco ISE server. + cisco.dnac.ise_radius_integration_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + state: merged + config_verify: True + config: + - authentication_policy_server: + server_type: string + server_ip_address: string + shared_secret: string + protocol: string + encryption_scheme: string + message_key: string + encryption_key: string + authentication_port: string + accounting_port: string + port: string + retries: string + timeout: string + role: string + use_dnac_cert_for_pxgrid: False + pxgrid_enabled: True + cisco_ise_dtos: + - user_name: string + password: string + fqdn: string + ip_address: string + subscriber_name: string + description: string + +- name: Update an AAA server. + cisco.dnac.ise_radius_integration_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + state: merged + config_verify: True + config: + - authentication_policy_server: + server_type: string + server_ip_address: string + protocol: string + authentication_port: string + accounting_port: string + port: string + retries: string + timeout: string + role: string + +- name: Update an Cisco ISE server. + cisco.dnac.ise_radius_integration_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + state: merged + config_verify: True + config: + - authentication_policy_server: + server_type: string + server_ip_address: string + protocol: string + authentication_port: string + accounting_port: string + port: string + retries: string + timeout: string + role: string + use_dnac_cert_for_pxgrid: False + pxgrid_enabled: True + cisco_ise_dtos: + - user_name: string + password: string + fqdn: string + ip_address: string + subscriber_name: string + description: string + +- name: Delete an Authentication and Policy server. + cisco.dnac.ise_radius_integration_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" + state: merged + config_verify: True + config: + - authentication_policy_server: + server_ip_address: string +""" + +RETURN = r""" +# Case_1: Successful creation of Authentication and Policy Server. +response_1: + description: A dictionary or list with the response returned by the Cisco Catalyst Center Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } + +# Case_2: Successful updation of Authentication and Policy Server. +response_2: + description: A dictionary or list with the response returned by the Cisco Catalyst Center Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } + +# Case_3: Successful creation/updation of network +response_3: + description: A dictionary or list with the response returned by the Cisco Catalyst Center Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" + +import copy +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.dnac.plugins.module_utils.dnac import ( + DnacBase, + validate_list_of_dicts, + get_dict_result, + dnac_compare_equality, +) + + +class IseRadiusIntegration(DnacBase): + """Class containing member attributes for ise_radius_integration_workflow_manager module""" + + def __init__(self, module): + super().__init__(module) + self.result["response"] = [ + {"authenticationPolicyServer": {"response": {}, "msg": {}}} + ] + self.authentication_policy_server_obj_params = \ + self.get_obj_params("authenticationPolicyServer") + + def validate_input(self): + """ + Checks if the configuration parameters provided in the playbook + meet the expected structure and data types, + as defined in the 'temp_spec' dictionary. + + Parameters: + None + + Returns: + self + + """ + + if not self.config: + self.msg = "config not available in playbook for validation" + self.status = "success" + return self + + # temp_spec is the specification for the expected structure of configuration parameters + temp_spec = { + "authentication_policy_server": { + "type": "dict", + "server_type": {"type": 'string', "choices": ["AAA", "ISE"]}, + "server_ip_address": {"type": 'string'}, + "shared_secret": {"type": 'string'}, + "protocol": {"type": 'string', "choices": ["TACACS", "RADIUS", "RADIUS_TACACS"]}, + "encryption_scheme": {"type": 'string'}, + "message_key": {"type": 'string'}, + "encryption_key": {"type": 'string'}, + "authentication_port": {"type": 'string'}, + "accounting_port": {"type": 'string'}, + "port": {"type": 'string'}, + "retries": {"type": 'string'}, + "timeout": {"type": 'string'}, + "role": {"type": 'string'}, + "pxgrid_enabled": {"type": 'bool'}, + "use_dnac_cert_for_pxgrid": {"type": 'bool'}, + "cisco_ise_dtos": { + "type": 'list', + "user_name": {"type": 'string'}, + "password": {"type": 'string'}, + "fqdn": {"type": 'string'}, + "ip_address": {"type": 'string'}, + "subscriber_name": {"type": 'string'}, + "description": {"type": 'string'}, + "ssh_key": {"type": 'string'}, + }, + "external_cisco_ise_ip_addr_dtos": { + "type": 'list', + "external_cisco_ise_ip_addresses": { + "type": 'list', + "external_ip_address": {"type": 'string'}, + }, + "ise_type": {"type": 'string'}, + } + } + } + + # Validate playbook params against the specification (temp_spec) + valid_temp, invalid_params = validate_list_of_dicts(self.config, temp_spec) + if invalid_params: + self.msg = "Invalid parameters in playbook: {0}".format("\n".join(invalid_params)) + self.status = "failed" + return self + + self.validated_config = valid_temp + self.log("Successfully validated playbook config params: {0}".format(valid_temp), "INFO") + self.msg = "Successfully validated input from the playbook" + self.status = "success" + return self + + def requires_update(self, have, want, obj_params): + """ + Check if the template config given requires update by comparing + current information wih the requested information. + + This method compares the current global pool, reserve pool, + or network details from Cisco Catalyst Center with the user-provided details + from the playbook, using a specified schema for comparison. + + Parameters: + have (dict) - Current information from the Cisco Catalyst Center + (global pool, reserve pool, network details) + want (dict) - Users provided information from the playbook + obj_params (list of tuples) - A list of parameter mappings specifying which + Cisco Catalyst Center parameters (dnac_param) + correspond to the user-provided + parameters (ansible_param). + + Returns: + bool - True if any parameter specified in obj_params differs between + current_obj and requested_obj, indicating that an update is required. + False if all specified parameters are equal. + + """ + + current_obj = have + requested_obj = want + self.log("Current State (have): {0}".format(current_obj), "DEBUG") + self.log("Desired State (want): {0}".format(requested_obj), "DEBUG") + + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def get_obj_params(self, get_object): + """ + Get the required comparison obj_params value + + Parameters: + get_object (str) - identifier for the required obj_params + + Returns: + obj_params (list) - obj_params value for comparison. + """ + + try: + obj_params = [] + if get_object == "authenticationPolicyServer": + obj_params = [ + ("pxgridEnabled", "pxgridEnabled"), + ("useDnacCertForPxgrid", "useDnacCertForPxgrid"), + ("protocol", "protocol"), + ("retries", "retries"), + ("timeoutSeconds", "timeoutSeconds"), + ("externalCiscoIseIpAddrDtos", "externalCiscoIseIpAddrDtos") + ] + else: + raise ValueError("Received an unexpected value for 'get_object': {0}" + .format(get_object)) + except Exception as msg: + self.log("Received exception: {0}".format(msg), "CRITICAL") + + return obj_params + + def get_auth_server_params(self, auth_server_info): + """ + Process Authentication and Policy Server params from playbook data for + Authentication and Policy Server config in Cisco Catalyst Center. + + Parameters: + auth_server_info (dict) - Cisco Catalyst Center data containing + information about the Authentication and Policy Server. + + Returns: + dict or None - Processed Authentication and Policy Server data in a format suitable + for Cisco Catalyst Center configuration, or None if auth_server_info is empty. + """ + + if not auth_server_info: + self.log("Authentication and Policy Server data is empty", "INFO") + return None + + self.log("Authentication and Policy Server Details: {0}".format(auth_server_info), "DEBUG") + auth_server = { + "authenticationPort": auth_server_info.get("authenticationPort"), + "accountingPort": auth_server_info.get("accountingPort"), + "isIseEnabled": auth_server_info.get("iseEnabled"), + "ipAddress": auth_server_info.get("ipAddress"), + "pxgridEnabled": auth_server_info.get("pxgridEnabled"), + "useDnacCertForPxgrid": auth_server_info.get("useDnacCertForPxgrid"), + "port": auth_server_info.get("port"), + "protocol": auth_server_info.get("protocol"), + "retries": str(auth_server_info.get("retries")), + "role": auth_server_info.get("role"), + "timeoutSeconds": str(auth_server_info.get("timeoutSeconds")), + "encryptionScheme": auth_server_info.get("encryptionScheme") + } + self.log("Formated Authentication and Policy Server details: {0}" + .format(auth_server), "DEBUG") + if auth_server.get("isIseEnabled") is True: + auth_server_ise_info = auth_server_info.get("ciscoIseDtos") + auth_server.update({"ciscoIseDtos": []}) + for ise_credential in auth_server_ise_info: + auth_server.get("ciscoIseDtos").append({ + "userName": ise_credential.get("userName"), + "fqdn": ise_credential.get("fqdn"), + "ipAddress": ise_credential.get("ipAddress"), + "subscriberName": ise_credential.get("subscriberName"), + "description": ise_credential.get("description") + }) + + return auth_server + + def auth_server_exists(self, ipAddress): + """ + Check if the Authentication and Policy Server with the given ipAddress exists + + Parameters: + ipAddress (str) - The ipAddress of the Authentication and + Policy Server to check for existence. + + Returns: + dict - A dictionary containing information about the + Authentication and Policy Server's existence: + - 'exists' (bool): True if the Authentication and Policy Server exists, False otherwise. + - 'id' (str or None): The ID of the Authentication and Policy Server if it exists + or None if it doesn't. + - 'details' (dict or None): Details of the Authentication and Policy Server if it exists + else None. + """ + + AuthServer = { + "exists": False, + "details": None, + "id": None + } + response = self.dnac._exec( + family="system_settings", + function='get_authentication_and_policy_servers', + ) + if not isinstance(response, dict): + self.log("Failed to retrieve the Authentication and Policy Server details - " + "Response is not a dictionary", "CRITICAL") + return AuthServer + + all_auth_server_details = response.get("response") + auth_server_details = get_dict_result(all_auth_server_details, "ipAddress", ipAddress) + self.log("Authentication and Policy Server Ip Address: {0}" + .format(ipAddress), "DEBUG") + self.log("Authentication and Policy Server details: {0}" + .format(auth_server_details), "DEBUG") + if not auth_server_details: + self.log("Global pool {0} does not exist".format(ipAddress), "INFO") + return AuthServer + AuthServer.update({"exists": True}) + AuthServer.update({"id": auth_server_details.get("instanceUuid")}) + AuthServer["details"] = self.get_auth_server_params(auth_server_details) + + self.log("Formatted global pool details: {0}".format(AuthServer), "DEBUG") + return AuthServer + + def get_have_authentication_policy_server(self, config): + """ + Get the current Authentication and Policy Server information from + Cisco Catalyst Center based on the provided playbook details. + check this API using check_return_status. + + Parameters: + config (dict) - Playbook details containing + Authentication and Policy Server configuration. + + Returns: + self - The current object with updated + Authentication and Policy Server information. + """ + + AuthServer = { + "exists": False, + "details": None, + "id": None + } + authentication_policy_server = config.get("authentication_policy_server") + if authentication_policy_server is None: + self.msg = "authentication_policy_server in config is missing in the playbook" + self.status = "failed" + return self + + ipAddress = authentication_policy_server.get("server_ip_address") + if ipAddress is None: + self.msg = "Mandatory Parameter server_ip_address required" + self.status = "failed" + return self + + AuthServer = self.auth_server_exists(ipAddress) + self.log("Authentication and Policy Server exists: {0}" + .format(AuthServer.get("exists")), "DEBUG") + self.log("Authentication and Policy Server details: {0}" + .format(AuthServer.get("details")), "DEBUG") + self.log("Authentication and Policy Server Id: {0}" + .format(AuthServer.get("id")), "DEBUG") + self.have.update({"authenticationPolicyServer": AuthServer}) + self.msg = "Collecting the Authentication and Policy Server " + \ + "details from the Cisco Catalyst Center." + self.status = "success" + return self + + def get_have(self, config): + """ + Get the current Authentication and Policy Server details from Cisco Catalyst Center + + Parameters: + config (dict) - Playbook details containing + Authentication and Policy Server configuration. + + Returns: + self - The current object with updated + Authentication and Policy Server information. + """ + + if config.get("authentication_policy_server") is not None: + self.get_have_authentication_policy_server(config).check_return_status() + + self.log("Current State (have): {0}".format(self.have), "INFO") + self.msg = "Successfully retrieved the details from the Cisco Catalyst Center" + self.status = "success" + return self + + def get_want_authentication_policy_server(self, auth_policy_server): + """ + Get all the Authentication Policy Server information from playbook + Set the status and the msg before returning from the API + Check the return value of the API with check_return_status() + + Parameters: + auth_policy_server (dict) - Playbook authentication policy server details + containing IpAddress, authentication port, accounting port, Cisco ISE Details, + protocol, port, retries, role, timeout seconds, encryption details. + + Returns: + self - The current object with updated desired Authentication Policy Server information. + """ + + auth_server = {} + trusted_server = False + auth_server_exists = self.have.get("authenticationPolicyServer").get("exists") + server_type = auth_policy_server.get("server_type") + if server_type not in ["ISE", "AAA", None]: + self.msg = "server_type should either be ISE or AAA but not {0}.".format(server_type) + self.status = "failed" + return self + + if server_type == "ISE": + auth_server.update({"isIseEnabled": True}) + else: + auth_server.update({"isIseEnabled": False}) + + auth_server.update({"ipAddress": auth_policy_server.get("server_ip_address")}) + + shared_secret = auth_policy_server.get("shared_secret") + if not (shared_secret or auth_server_exists): + self.msg = "shared_secret is mandatory parameter" + self.status = "failed" + return self + + if not (4 <= len(shared_secret) <= 10) or shared_secret.isspace(): + self.msg = "shared_secret should character should be between 4 to 100." + self.status = "failed" + return self + + auth_server.update({"sharedSecret": shared_secret}) + + protocol = auth_policy_server.get("protocol") + if protocol not in ["RADIUS", "TACACS", "RADIUS_TACACS", None]: + self.msg = "protocol should either be ['RADIUS', 'TACACS', 'RADIUS_TACACS']." + \ + "It should not be {0}".format(protocol) + self.status = "failed" + return self + + if protocol is not None: + auth_server.update({"protocol": protocol}) + else: + auth_server.update({"protocol": "RADIUS"}) + + encryption_scheme = str(auth_policy_server.get("encryption_scheme")) + if encryption_scheme not in ["KEYWRAP", "RADSEC", None]: + self.msg = "encryption_scheme should be in ['KEYWRAP', 'RADSEC']. " + \ + "It should not be {0}.".format(encryption_scheme) + self.status = "failed" + return self + + if encryption_scheme: + auth_server.update({"encryptionScheme": encryption_scheme}) + + if encryption_scheme == "KEYWRAP": + message_key = str(auth_policy_server.get("message_key")) + if not message_key: + self.msg = "message_key should not be empty if encryption_scheme is 'KEYWRAP'." + self.status = "failed" + return self + + if len(message_key) != 20: + self.msg = "message_key should be exactly 20 character." + self.status = "failed" + return self + + auth_server.update({"messageKey": message_key}) + + encryption_key = auth_policy_server.get("encryption_key") + if not encryption_key: + self.msg = "encryption_key should not be empty if encryption_scheme is 'KEYWRAP'." + self.status = "failed" + return self + + if len(encryption_key) != 16: + self.msg = "encryption_key should be exactly 16 characters." + self.status = "failed" + return self + + auth_server.update({"encryptionKey": encryption_key}) + + authentication_port = int(auth_policy_server.get("authentication_port")) + if not 1 <= int(authentication_port) <= 65535: + self.msg = "authentication_port should be from 1 to 65535." + self.status = "failed" + return self + + if authentication_port: + auth_server.update({"authenticationPort": authentication_port}) + else: + auth_server.update({"authenticationPort": "1812"}) + + accounting_port = int(auth_policy_server.get("accounting_port")) + if not 1 <= int(accounting_port) <= 65535: + self.msg = "accounting_port should be from 1 to 65535." + self.status = "failed" + return self + + if accounting_port: + auth_server.update({"accountingPort": accounting_port}) + else: + auth_server.update({"accountingPort": "1813"}) + + port = int(auth_policy_server.get("port")) + if port: + auth_server.update({"port": port}) + else: + auth_server.update({"port": "49"}) + + retries = str(auth_policy_server.get("retries")) + if not retries.isdigit(): + self.msg = "retries should contain only from 0-9." + self.status = "failed" + return self + + if not 1 <= int(retries) <= 3: + self.msg = "retries should be from 1 to 3." + self.status = "failed" + return self + + if retries: + auth_server.update({"retries": retries}) + else: + auth_server.update({"retries": "3"}) + + timeout = str(auth_policy_server.get("timeout")) + if not timeout.isdigit(): + self.msg = "timeout should contain only from 0-9." + self.status = "failed" + return self + + if not 2 <= int(timeout) <= 20: + self.msg = "timeout should be from 2 to 20." + self.status = "failed" + return self + + if timeout: + auth_server.update({"timeoutSeconds": timeout}) + else: + auth_server.update({"timeoutSeconds": "4"}) + + role = auth_policy_server.get("role") + if role: + auth_server.update({"role": role}) + else: + auth_server.update({"role": "secondary"}) + + if auth_server.get("isIseEnabled"): + pxgrid_enabled = auth_policy_server.get("pxgrid_enabled") + if pxgrid_enabled: + auth_server.update({"pxgridEnabled": pxgrid_enabled}) + else: + auth_server.update({"pxgridEnabled": True}) + + use_dnac_cert_for_pxgrid = auth_policy_server.get("use_dnac_cert_for_pxgrid") + if use_dnac_cert_for_pxgrid: + auth_server.update({"useDnacCertForPxgrid": use_dnac_cert_for_pxgrid}) + else: + auth_server.update({"useDnacCertForPxgrid": False}) + + cisco_ise_dtos = auth_policy_server.get("cisco_ise_dtos") + if not cisco_ise_dtos: + self.msg = "Mandatory parameter cisco_ise_dtos " + \ + "required when server_type is 'ISE'." + self.status = "failed" + return self + + auth_server.update({"ciscoIseDtos": []}) + position_ise_creds = 0 + for ise_credential in cisco_ise_dtos: + auth_server.get("ciscoIseDtos").append({}) + user_name = ise_credential.get("user_name") + if not user_name: + self.msg = "Mandatory parameter user_name required for ISE." + self.status = "failed" + return self + + auth_server.get("ciscoIseDtos")[position_ise_creds].update({ + "userName": user_name + }) + + password = ise_credential.get("password") + if not password: + self.msg = "Mandatory paramter password required for ISE." + self.status = "failed" + return self + + if not 4 <= len(password) <= 127: + self.msg = "" + self.status = "failed" + return self + + auth_server.get("ciscoIseDtos")[position_ise_creds].update({ + "password": password + }) + + fqdn = ise_credential.get("fqdn") + if not fqdn: + self.msg = "Mandatory parameter required for ISE." + self.status = "failed" + return self + + auth_server.get("ciscoIseDtos")[position_ise_creds].update({"fqdn": fqdn}) + + ip_address = ise_credential.get("ip_address") + if not ip_address: + self.msg = "Mandatory parameter ip_address required for ISE." + self.status = "failed" + return self + + auth_server.get("ciscoIseDtos")[position_ise_creds].update({ + "ipAddress": ip_address + }) + + subscriber_name = ise_credential.get("subscriber_name") + if not subscriber_name: + self.msg = "Mandatory parameter subscriber_name required for ISE." + self.status = "failed" + return self + + auth_server.get("ciscoIseDtos")[position_ise_creds].update({ + "subscriberName": subscriber_name + }) + + description = ise_credential.get("description") + if description: + auth_server.get("ciscoIseDtos")[position_ise_creds].update({ + "description": description + }) + + ssh_key = str(ise_credential.get("ssh_key")) + if ssh_key: + auth_server.get("ciscoIseDtos")[position_ise_creds].update({ + "sshkey": ssh_key + }) + + position_ise_creds += 1 + + external_cisco_ise_ip_addr_dtos = auth_policy_server \ + .get("external_cisco_ise_ip_addr_dtos") + if external_cisco_ise_ip_addr_dtos: + auth_server.update({"externalCiscoIseIpAddrDtos": []}) + position_ise_addresses = 0 + for external_cisco_ise in external_cisco_ise_ip_addr_dtos: + external_cisco_ise_ip_addresses = external_cisco_ise \ + .get("external_cisco_ise_ip_addresses") + if external_cisco_ise_ip_addresses: + auth_server.get("externalCiscoIseIpAddrDtos").append({}) + auth_server.get("externalCiscoIseIpAddrDtos")[position_ise_addresses] \ + .update({"externalCiscoIseIpAddresses": []}) + position_ise_address = 0 + for external_ip_address in external_cisco_ise_ip_addresses: + auth_server.get("externalCiscoIseIpAddrDtos")[position_ise_addresses] \ + .get("externalCiscoIseIpAddresses").append({}) + auth_server.get("externalCiscoIseIpAddrDtos")[position_ise_addresses] \ + .get("externalCiscoIseIpAddresses")[position_ise_address].update({ + "externalIpAddress": external_ip_address.get("external_ip_address") + }) + position_ise_address += 1 + ise_type = external_cisco_ise.get("ise_type") + if ise_type: + auth_server.get("externalCiscoIseIpAddrDtos")[position_ise_addresses] \ + .update({"type": ise_type}) + position_ise_addresses += 1 + + if auth_policy_server.get("trusted_server"): + trusted_server = True + + self.log("Authentication and Policy Server playbook details: {0}" + .format(auth_server), "DEBUG") + self.want.update({"authenticationPolicyServer": auth_server}) + self.want.update({"trusted_server": trusted_server}) + self.msg = "Collecting the Authentication and Policy Server details from the playbook" + self.status = "success" + return self + + def get_want(self, config): + """ + Get all the Authentication Policy Server related information from playbook + + Parameters: + config (list of dict) - Playbook details + + Returns: + None + """ + + if config.get("authentication_policy_server"): + auth_policy_server = config.get("authentication_policy_server") + self.get_want_authentication_policy_server(auth_policy_server).check_return_status() + + self.log("Desired State (want): {0}".format(self.want), "INFO") + self.msg = "Successfully retrieved details from the playbook" + self.status = "success" + return self + + def accept_cisco_ise_server_certificate(self, ipAddress, trusted_server): + """ + Accept the Cisco ISE server certificate in Cisco Catalyst + Center provided in the playbook. + + Parameters: + ipAddress (str) - The Ip address of the Authentication and Policy Server to be deleted. + trusted_server (bool) - Indicates whether the certificate is trustworthy for the server. + + Returns: + None + """ + + try: + AuthServer = self.auth_server_exists(ipAddress) + if not AuthServer: + self.msg = "Error while retrieving the Authentication and Policy Server {0} \ + details.".format(ipAddress) + self.log(str(self.msg, "CRITICAL")) + self.status = "failed" + return self + + cisco_ise_id = AuthServer.get("id") + if not cisco_ise_id: + self.msg = "Error while retrieving the Authentication and Policy Server {0} id." \ + .format(ipAddress) + self.log(str(self.msg, "CRITICAL")) + self.status = "failed" + return self + + response = self.dnac._exec( + family="system_settings", + function="accept_cisco_ise_server_certificate_for_cisco_ise_server_integration", + params={ + "id": cisco_ise_id, + "isCertAcceptedByUser": trusted_server + }, + ) + self.log("Received API response for 'accept_cisco_ise_server_certificate_" + "for_cisco_ise_server_integration': {0}".format(response), "DEBUG") + except Exception as msg: + self.log("Exception occurred while accepting the certificate of {0}: {1}" + .format(ipAddress, msg)) + return None + return + + def format_payload_for_update(self, have_auth_server, want_auth_server): + """ + Format the parameter of the payload for updating the authentication and policy server + in accordance with the information in the Cisco Catalyst Ceter. + + Parameters: + have_auth_server (dict) - Authentication and policy server information from the Cisco Catalyst Center. + want_auth_server (dict) - Authentication and policy server information from the Playbook. + + Returns: + self - The current object with updated desired Authentication Policy Server information. + """ + + if want_auth_server.get("sharedSecret") is not None: + del want_auth_server["sharedSecret"] + if want_auth_server.get("encryptionScheme") is not None: + del want_auth_server["encryptionScheme"] + if want_auth_server.get("messageKey") is not None: + del want_auth_server["messageKey"] + if want_auth_server.get("encryptionKey") is not None: + del want_auth_server["encryptionKey"] + + update_params = ["authenticationPort", "accountingPort", "port", "role"] + for item in update_params: + have_auth_server_item = have_auth_server.get(item) + want_auth_server_item = want_auth_server.get(item) + if want_auth_server_item is None: + want_auth_server.update({item: have_auth_server_item}) + + elif have_auth_server_item != want_auth_server_item: + self.msg = "Update does not support modifying '{0}'. Here you are trying to update '{1}'." \ + .format(update_params, item) + self.status = "failed" + return self + + have_auth_server_protocol = have_auth_server.get("protocol") + want_auth_server_protocol = want_auth_server.get("protocol") + if have_auth_server_protocol != want_auth_server_protocol: + if want_auth_server_protocol != "RADIUS_TACACS": + self.msg = "'protocol' can only be updated to 'RADIUS_TACACS' not from '{0}' to '{1}'" \ + .format(have_auth_server_protocol, want_auth_server_protocol) + self.status = "failed" + return self + + self.log("Successfully formatted the parameter of the payload for updating the authentication and policy server.") + self.msg = "Successfully formatted the parameter of the payload for updating the authentication and policy server." + self.status = "success" + return self + + def update_auth_policy_server(self, ipAddress): + """ + Update/Create Authentication and Policy Server in Cisco + Catalyst Center with fields provided in playbook. + + Parameters: + ipAddress (str) - The Ip address of the Authentication and Policy Server to be deleted. + + Returns: + None + """ + + result_auth_server = self.result.get("response")[0].get("authenticationPolicyServer") + result_auth_server.get("response").update({ipAddress: {}}) + + # Check Authentication and Policy Server exist, if not create and return + is_ise_server = self.want.get("authenticationPolicyServer").get("isIseEnabled") + if not self.have.get("authenticationPolicyServer").get("exists"): + auth_server_params = self.want.get("authenticationPolicyServer") + self.log("Desired State for Authentication and Policy Server (want): {0}" + .format(auth_server_params), "DEBUG") + response = self.dnac._exec( + family="system_settings", + function="add_authentication_and_policy_server_access_configuration", + params=auth_server_params, + ) + if not is_ise_server: + validation_string = "successfully created aaa settings" + else: + validation_string = "operation sucessful" + + self.check_task_response_status(response, validation_string).check_return_status() + if is_ise_server: + trusted_server = self.want.get("trusted_server") + self.accept_cisco_ise_server_certificate(ipAddress, trusted_server) + + self.log("Successfully created Authentication and Policy Server '{0}'." + .format(ipAddress), "INFO") + result_auth_server.get("response").get(ipAddress) \ + .update({ + "authenticationPolicyServer Details": self.want + .get("authenticationPolicyServer") + }) + result_auth_server.get("msg").update({ + ipAddress: "Authentication and Policy Server Created Successfully" + }) + return + + # Authentication and Policy Server exists, check update is required + # Edit API not working, remove this + self.format_payload_for_update(self.have.get("authenticationPolicyServer").get("details"), + self.want.get("authenticationPolicyServer")).check_return_status() + if not self.requires_update(self.have.get("authenticationPolicyServer").get("details"), + self.want.get("authenticationPolicyServer"), + self.authentication_policy_server_obj_params): + self.log("Authentication and Policy Server '{0}' doesn't require an update" + .format(ipAddress), "INFO") + result_auth_server.get("response").get(ipAddress).update({ + "Cisco Catalyst Center params": + self.have.get("authenticationPolicyServer").get("details") + }) + result_auth_server.get("response").get(ipAddress).update({ + "Id": self.have.get("authenticationPolicyServer").get("id") + }) + result_auth_server.get("msg").update({ + ipAddress: "Authentication and Policy Server doesn't require an update" + }) + return + + self.log("Authentication and Policy Server requires update", "DEBUG") + + # Authenticaiton and Policy Server Exists + auth_server_params = copy.deepcopy(self.want.get("authenticationPolicyServer")) + auth_server_params.update({"id": self.have.get("authenticationPolicyServer").get("id")}) + self.log("Desired State for Authentication and Policy Server (want): {0}" + .format(auth_server_params), "DEBUG") + self.log("Current State for Authentication and Policy Server (have): {0}" + .format(self.have.get("authenticationPolicyServer").get("details")), "DEBUG") + response = self.dnac._exec( + family="system_settings", + function="edit_authentication_and_policy_server_access_configuration", + params=auth_server_params, + ) + validation_string = "successfully updated aaa settings" + self.check_task_response_status(response, validation_string).check_return_status() + self.log("Authentication and Policy Server '{0}' updated successfully" + .format(ipAddress), "INFO") + result_auth_server.get("response").get(ipAddress) \ + .update({"Id": self.have.get("authenticationPolicyServer").get("id")}) + result_auth_server.get("msg").update({ + ipAddress: "Authentication and Policy Server Updated Successfully" + }) + return + + def get_diff_merged(self, config): + """ + Update or create Authentication and Policy Server in + Cisco Catalyst Center based on the playbook details. + + Parameters: + config (list of dict) - Playbook details containing + Authentication and Policy Server information. + + Returns: + self + """ + + if config.get("authentication_policy_server") is not None: + ipAddress = config.get("authentication_policy_server").get("server_ip_address") + self.update_auth_policy_server(ipAddress) + + return self + + def delete_auth_policy_server(self, ipAddress): + """ + Delete a Authentication and Policy Server by server Ip address in Cisco Catalyst Center. + + Parameters: + ipAddress (str) - The Ip address of the Authentication and Policy Server to be deleted. + + Returns: + self + """ + + auth_server_exists = self.have.get("authenticationPolicyServer").get("exists") + result_auth_server = self.result.get("response")[0].get("authenticationPolicyServer") + if not auth_server_exists: + result_auth_server.get("response").update({ + ipAddress: "Authentication and Policy Server not found" + }) + self.msg = "Authentication and Policy Server not found." + self.status = "success" + return self + + response = self.dnac._exec( + family="system_settings", + function="delete_authentication_and_policy_server_access_configuration", + params={"id": self.have.get("authenticationPolicyServer").get("id")}, + ) + + self.log("Received API response for 'delete_authentication_and_" + "policy_server_access_configuration': {0}".format(response), "DEBUG") + + # Check the task status + validation_string = "successfully deleted aaa settings" + self.check_task_response_status(response, validation_string).check_return_status() + taskid = response.get("response").get("taskId") + + # Update result information + result_auth_server.get("response").update({ipAddress: {}}) + result_auth_server.get("response").get(ipAddress).update({"Task Id": taskid}) + result_auth_server.get("msg").update({ + ipAddress: "Authentication and Policy Server deleted successfully." + }) + self.msg = "Authentication and Policy Server - {0} deleted successfully.".format(ipAddress) + self.status = "success" + return self + + def get_diff_deleted(self, config): + """ + Delete Authentication and Policy Server from the Cisco Catalyst Center. + + Parameters: + config (list of dict) - Playbook details + + Returns: + self + """ + + if config.get("authentication_policy_server") is not None: + ipAddress = config.get("authentication_policy_server").get("server_ip_address") + self.delete_auth_policy_server(ipAddress).check_return_status() + + return self + + def verify_diff_merged(self, config): + """ + Validating the Cisco Catalyst Center configuration with the playbook details + when state is merged (Create/Update). + + Parameters: + config (dict) - Playbook details containing + Authentication and Policy Server configuration. + + Returns: + self + """ + + self.get_have(config) + self.log("Current State (have): {0}".format(self.have), "INFO") + self.log("Requested State (want): {0}".format(self.want), "INFO") + if config.get("authentication_policy_server") is not None: + self.log("Desired State of Authentication and Policy Server (want): {0}" + .format(self.want.get("authenticationPolicyServer")), "DEBUG") + self.log("Current State of Authentication and Policy Server (have): {0}" + .format(self.have.get("authenticationPolicyServer") + .get("details")), "DEBUG") + check_list = ["isIseEnabled", "ipAddress", "pxgridEnabled", + "useDnacCertForPxgrid", "port", "protocol", + "retries", "role", "timeoutSeconds", "encryptionScheme"] + auth_server_have = self.have.get("authenticationPolicyServer").get("details") + auth_server_want = self.want.get("authenticationPolicyServer") + for item in check_list: + if auth_server_have.get(item) and auth_server_want.get(item) and \ + auth_server_have.get(item) != auth_server_want.get(item): + self.msg = "Authentication and Policy Server " + \ + "Config is not applied to the Cisco Catalyst Center." + self.status = "failed" + return self + + self.log("Successfully validated Authentication and Policy Server '{0}'." + .format(self.want.get("authenticationPolicyServer").get("ipAddress")), "INFO") + self.result.get("response")[0].get("authenticationPolicyServer").update({ + "Validation": "Success" + }) + + self.msg = "Successfully validated the Authentication and Policy Server." + self.status = "success" + return self + + def verify_diff_deleted(self, config): + """ + Validating the Cisco Catalyst Center configuration with the playbook details + when state is deleted (delete). + + Parameters: + config (dict) - Playbook details containing + Authentication and Policy Server configuration. + + Returns: + self + """ + + self.get_have(config) + ipAddress = config.get("authentication_policy_server").get("server_ip_address") + self.log("Current State (have): {0}".format(self.have), "INFO") + self.log("Authentication and Policy Server deleted from the Cisco Catalyst Center: {0}" + .format(ipAddress), "INFO") + if config.get("authentication_policy_server") is not None: + auth_server_exists = self.have.get("authenticationPolicyServer").get("exists") + if auth_server_exists: + self.msg = "Authentication and Policy Server " + \ + "Config is not applied to the Cisco Catalyst Center." + self.status = "failed" + return self + + self.log("Successfully validated absence of Authentication and Policy Server '{0}'." + .format(config.get("authentication_policy_server").get("ip_address")), "INFO") + self.result.get("response")[0].get("authenticationPolicyServer").update({ + "Validation": "Success" + }) + + self.msg = "Successfully validated the absence of Authentication and Policy Server." + self.status = "success" + return self + + def reset_values(self): + """ + Reset all neccessary attributes to default values + + Parameters: + None + + Returns: + None + """ + + self.have.clear() + self.want.clear() + return + + +def main(): + """main entry point for module execution""" + + # Define the specification for module arguments + element_spec = { + "dnac_host": {"type": 'str', "required": True}, + "dnac_port": {"type": 'str', "default": '443'}, + "dnac_username": {"type": 'str', "default": 'admin', "aliases": ['user']}, + "dnac_password": {"type": 'str', "no_log": True}, + "dnac_verify": {"type": 'bool', "default": 'True'}, + "dnac_version": {"type": 'str', "default": '2.2.3.3'}, + "dnac_debug": {"type": 'bool', "default": False}, + "dnac_log": {"type": 'bool', "default": False}, + "dnac_log_level": {"type": 'str', "default": 'WARNING'}, + "dnac_log_file_path": {"type": 'str', "default": 'dnac.log'}, + "dnac_log_append": {"type": 'bool', "default": True}, + "config_verify": {"type": 'bool', "default": False}, + 'dnac_api_task_timeout': {'type': 'int', "default": 1200}, + 'dnac_task_poll_interval': {'type': 'int', "default": 2}, + "config": {"type": 'list', "required": True, "elements": 'dict'}, + "state": {"default": 'merged', "choices": ['merged', 'deleted']}, + "validate_response_schema": {"type": 'bool', "default": True}, + } + + # Create an AnsibleModule object with argument specifications + module = AnsibleModule(argument_spec=element_spec, supports_check_mode=False) + ccc_ise_radius = IseRadiusIntegration(module) + state = ccc_ise_radius.params.get("state") + config_verify = ccc_ise_radius.params.get("config_verify") + if state not in ccc_ise_radius.supported_states: + ccc_ise_radius.status = "invalid" + ccc_ise_radius.msg = "State {0} is invalid".format(state) + ccc_ise_radius.check_return_status() + + ccc_ise_radius.validate_input().check_return_status() + + for config in ccc_ise_radius.config: + ccc_ise_radius.reset_values() + ccc_ise_radius.get_have(config).check_return_status() + if state != "deleted": + ccc_ise_radius.get_want(config).check_return_status() + ccc_ise_radius.get_diff_state_apply[state](config).check_return_status() + if config_verify: + ccc_ise_radius.verify_diff_state_apply[state](config).check_return_status() + + module.exit_json(**ccc_ise_radius.result) + + +if __name__ == "__main__": + main() diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index 199ea4ac42..81bbb929cd 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -740,3 +740,7 @@ plugins/modules/template_workflow_manager.py compile-2.7!skip # Python 2.7 is no plugins/modules/template_workflow_manager.py compile-2.6!skip # Python 2.6 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py import-2.6!skip # Python 2.6 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py compile-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py compile-2.6!skip # Python 2.6 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py import-2.6!skip # Python 2.6 is not supported by the DNA Center SDK diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 91834bb50a..0b839978b0 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -1091,3 +1091,7 @@ plugins/modules/template_workflow_manager.py compile-2.7!skip # Python 2.7 is no plugins/modules/template_workflow_manager.py compile-2.6!skip # Python 2.6 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py import-2.6!skip # Python 2.6 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py compile-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py compile-2.6!skip # Python 2.6 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py import-2.6!skip # Python 2.6 is not supported by the DNA Center SDK diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 41aebb287f..36d5eb734e 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -38,3 +38,7 @@ plugins/modules/template_workflow_manager.py compile-2.7!skip # Python 2.7 is no plugins/modules/template_workflow_manager.py compile-2.6!skip # Python 2.6 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py import-2.6!skip # Python 2.6 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py compile-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py compile-2.6!skip # Python 2.6 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py import-2.6!skip # Python 2.6 is not supported by the DNA Center SDK diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index 29449f7cb2..3c31c2c4bc 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -18,3 +18,5 @@ plugins/modules/device_credential_workflow_manager.py compile-2.7!skip # Python plugins/modules/device_credential_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py compile-2.7!skip # Python 2.7 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py compile-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 29449f7cb2..3c31c2c4bc 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -18,3 +18,5 @@ plugins/modules/device_credential_workflow_manager.py compile-2.7!skip # Python plugins/modules/device_credential_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py compile-2.7!skip # Python 2.7 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py compile-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 29449f7cb2..3c31c2c4bc 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -18,3 +18,5 @@ plugins/modules/device_credential_workflow_manager.py compile-2.7!skip # Python plugins/modules/device_credential_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py compile-2.7!skip # Python 2.7 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py compile-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK diff --git a/tests/sanity/ignore-2.9.txt b/tests/sanity/ignore-2.9.txt index 199ea4ac42..81bbb929cd 100644 --- a/tests/sanity/ignore-2.9.txt +++ b/tests/sanity/ignore-2.9.txt @@ -740,3 +740,7 @@ plugins/modules/template_workflow_manager.py compile-2.7!skip # Python 2.7 is no plugins/modules/template_workflow_manager.py compile-2.6!skip # Python 2.6 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK plugins/modules/template_workflow_manager.py import-2.6!skip # Python 2.6 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py compile-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py compile-2.6!skip # Python 2.6 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py import-2.7!skip # Python 2.7 is not supported by the DNA Center SDK +plugins/modules/ise_radius_integration_workflow_manager.py import-2.6!skip # Python 2.6 is not supported by the DNA Center SDK From a300145baa0d67c214ca840595f42719a26a7f4b Mon Sep 17 00:00:00 2001 From: Abinash Date: Thu, 25 Apr 2024 11:30:02 +0000 Subject: [PATCH 290/358] Adding module for device config backup --- playbooks/configs_backup.yml | 39 ++ .../device_configs_backup_workflow_manager.py | 573 ++++++++++++++++++ 2 files changed, 612 insertions(+) create mode 100644 playbooks/configs_backup.yml create mode 100644 plugins/modules/device_configs_backup_workflow_manager.py diff --git a/playbooks/configs_backup.yml b/playbooks/configs_backup.yml new file mode 100644 index 0000000000..696e021843 --- /dev/null +++ b/playbooks/configs_backup.yml @@ -0,0 +1,39 @@ +--- +- name: Take running config backup of devices + hosts: localhost + connection: local + gather_facts: no + + vars_files: + - "{{ CLUSTERFILE }}" + + vars: + dnac_login: &dnac_login + dnac_host: "{{ dnac_host }}" + dnac_username: "{{ dnac_username }}" + dnac_password: "{{ dnac_password }}" + dnac_verify: "{{ dnac_verify }}" + dnac_port: "{{ dnac_port }}" + dnac_version: "{{ dnac_version }}" + dnac_debug: "{{ dnac_debug }}" + dnac_log_level: "DEBUG" + + tasks: + - name: Take backup of a wired 9500 switch + cisco.dnac.device_configs_backup_workflow_manager: + <<: *dnac_login + dnac_log: True + state: merged + config_verify: True + config: + - hostname: NY-BN-9500.cisco.local + file_path: /home/admin/madhan_ansible/collections/ansible_collections/cisco/dnac/playbooks/new_tmp + + - name: Take backup of all the switches + cisco.dnac.device_configs_backup_workflow_manager: + <<: *dnac_login + dnac_log: True + state: merged + config_verify: True + config: + - family: Switches and Hubs \ No newline at end of file diff --git a/plugins/modules/device_configs_backup_workflow_manager.py b/plugins/modules/device_configs_backup_workflow_manager.py new file mode 100644 index 0000000000..7173a31f69 --- /dev/null +++ b/plugins/modules/device_configs_backup_workflow_manager.py @@ -0,0 +1,573 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2024, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type +__author__ = ("Abinash Mishra, Madhan Sankaranarayanan") + +DOCUMENTATION = r""" +--- +module: device_configs_backup_workflow_manager +short_description: Resource module for device_configs_backup functions +description: +- Manage operation related to image importation, distribution, activation and tagging image as golden +version_added: '6.13.0' +extends_documentation_fragment: + - cisco.dnac.workflow_manager_params +author: Abinash Mishra (@abimishr) + Madhan Sankaranarayanan (@madhansansel) +options: + state: + description: The state of Cisco Catalyst Center after module completion. + type: str + choices: [ merged ] + default: merged + config: + description: + - List of details of device being managed. + type: list + elements: dict + required: true + suboptions: + hostname: + description: Hostname of the device as displayed on the inventory GUI of Cisco Catalyst Center + type: str + management_ip_address: + description: IP address of the device as displayed on the inventory GUI of Cisco Catalyst Center + type: str + mac_address: + description: Mac address of the device as displayed on the inventory GUI of Cisco Catalyst Center + type: str + serial_number: + description: Serial number of the device as displayed on the inventory GUI of Cisco Catalyst Center + type: str + family: + description: Family of the device(s) as displayed on the inventory GUI of Cisco Catalyst Center + type: str + type: + description: Specifies the type of the device(s) from the family, like Cisco Catalyst 9300 Switch or Cisco Catalyst 9500 Switch + type: str + series: + description: Specifies the series of the device(s) from the type, like Cisco Catalyst 9300 Series Switches + type: str + collection_status: + description: Specifies the collection status of the device(s) on the GUI of Cisco Catalyst Center + type: str + file_path: + description: Location of the path or folder where the configs need to be exported in local system. + type: str +requirements: + - dnacentersdk == 2.6.10 + - python >= 3.5 +notes: + - SDK Methods used are devices.Devices.get_device_list, + configuration_archive.ConfigurationsArchive.export_device_configurations, + task.Task.get_task_by_id + - Paths used are get /dna/intent/api/v1/network-device + post dna/intent/api/v1/network-device-archive/cleartext + get /dna/intent/api/v1/task/${taskId} + +""" + +EXAMPLES = r""" +- name: Take backup of a 9300 wired device + cisco.dnac.device_configs_backup_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log: True + dnac_log_level: "{{dnac_log_level}}" + state: merged + config: + - hostname: NY-BN-9500.cisco.local + management_ip_address: 205.1.1.4 + serial_number: F2AKI0082J + family: Switches and Hubs + type: Cisco Catalyst 9300 Switch + series: Cisco Catalyst 9300 Series Switches + collection_status: Managed + file_path: /home/admin/madhan_ansible/collections/ansible_collections/cisco/dnac/playbooks/new_tmp +""" + +RETURN = r""" +# Case_1: Successful creation and exportation of device configs +response_1: + description: A dictionary with with the response returned by the Cisco Catalyst Center Python SDK + returned: always + type: dict + sample: > + { + "response": + { + "response": String, + "version": String + }, + "msg": String + } + +# Case_2: Error while taking a device_configs_backup +response_2: + description: A string with the response returned by the Cisco Catalyst Center Python SDK + returned: always + type: list + sample: > + { + "response": [], + "msg": String + } +""" +# common approach when a module relies on optional dependencies that are not available during the validation process. +try: + import pyzipper + HAS_PYZIPPER = True +except ImportError: + HAS_PYZIPPER = False + pyzipper = None + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.dnac.plugins.module_utils.dnac import ( + DnacBase, + validate_list_of_dicts +) +from io import BytesIO +import random +import string +import re +import time +import pathlib +import time + + +class Device_configs_backup(DnacBase): + + """ + Class containing member attributes for device_configs_backup workflow_manager module + """ + def __init__(self, module): + super().__init__(module) + + def validate_input(self): + """ + Validate the fields provided in the playbook. Checks the + configuration provided in the playbook against a predefined + specification to ensure it adheres to the expected structure + and data types. + + Parameters: + - self: The instance of the class containing the 'config' attribute + to be validated. + Returns: + The method returns an instance of the class with updated attributes: + - self.msg: A message describing the validation result. + - self.status: The status of the validation (either 'success' or 'failed'). + - self.validated_config: If successful, a validated version of the + 'config' parameter. + Example: + To use this method, create an instance of the class and call + 'validate_input' on it.If the validation succeeds, 'self.status' + will be 'success'and 'self.validated_config' will contain the + validated configuration. If it fails, 'self.status' will be + 'failed', and 'self.msg' will describe the validation issues. + """ + + if not self.config: + self.msg = "config not available in playbook for validattion" + self.status = "success" + return self + + device_configs_backup_spec = { + 'hostname': {'type': 'str', 'required': False}, + 'management_ip_address': {'type': 'str', 'required': False}, + 'mac_address': {'type': 'str', 'required': False}, + 'serial_number': {'type': 'str', 'required': False}, + 'family': {'type': 'str', 'required': False}, + 'type': {'type': 'str', 'required': False}, + 'series': {'type': 'str', 'required': False}, + 'collection_status': {'type': 'str', 'required': False}, + 'file_path': {'type': 'str', 'required': False, 'default': 'tmp'} + } + # Validate device_configs_backup params + valid_device_configs_backup, invalid_params = validate_list_of_dicts( + self.config, device_configs_backup_spec + ) + if invalid_params: + self.msg = "Invalid parameters in playbook: {0}".format( + "\n".join(invalid_params)) + self.log(str(self.msg), "ERROR") + self.status = "failed" + return self + + self.validated_config = valid_device_configs_backup + self.msg = "Successfully validated playbook configuration parameters using 'validate_input': {0}".format(str(valid_device_configs_backup)) + self.status = "success" + return self + + def validate_ipv4_address(self): + """ + Validates the management ip adress passed by the user + """ + + ip_address = self.validated_config[0].get("management_ip_address") + + if ip_address: + if self.is_valid_ipv4(ip_address) is False: + msg = "IP address {0} is not valid".format(ip_address) + self.log(msg, "CRITICAL") + self.module.fail_json(msg=msg) + + self.log("Validated IP address collected for config collection is {0}".format(ip_address), "INFO") + + def get_have(self): + """ + Get the current device_configs_backup details + Args: + self: The instance of the class containing the 'config' attribute to be validated. + Returns: + The method returns an instance of the class with updated attributes: + - self. + Example: + Stored paramters are used to call the APIs to store the validated configs + """ + + have = {} + have = self.validated_config[0] + self.have = have + self.log("Parameters collected from get have api are {0}".format(self.have), "INFO") + return self + + def get_device_ids_list(self): + """ + Fethces the list of device ids from various paramters passed in the playbook + Args: + self: The instance of the class containing the 'config' attribute to be validated. + Returns: + dev_id_list: The list of device ids based on the parameters passed by the user + Example: + Stored paramters like management ip address/ family can be used to fetch the device ids + list + """ + + device_params = self.validated_config[0] + if device_params.get("file_password"): + if len(device_params) - 1 == 0: + msg = "Please provide atleast one device parameter as mentioned in the documentation to fetch device configs" + self.log(msg, "CRITICAL") + self.module.fail_json(msg=msg) + response = self.dnac_apply['exec']( + family="devices", + function='get_device_list', + params=device_params, + op_modifies=True + ) + self.log("Reponse collected from the API 'get_device_list' is {0}".format(str(response)), "DEBUG") + device_list = response.get("response") + + self.log("Length of the device list fetched from the API 'get_device_list' is {0}".format(str(device_list)), "INFO") + if len(device_list) == 0: + msg = "No devices with the given paramters couldn't be found in the inventory" + self.log(msg, "CRITICAL") + self.module.fail_json(msg=msg) + + dev_id_list = [id.get("id") for id in device_list] + self.log("Device Ids list collected is {0}".format(dev_id_list), "INFO") + return dev_id_list + + def password_generator(self): + """ + Creates a password that matches Cisco Catalyst Center's requirements + Min password length is 8 and it should contain atleast one lower case letter, + one uppercase letter, one digit and one special characters from -=\\\\;,./~!@#$%^&*()_+{}[]|:? + """ + + punctuation = "-=;,.~!@#$%^&*()_+{}[]|:?" + password_chars = punctuation + string.ascii_letters + string.digits + password_list = [ + random.choice(punctuation), + random.choice(string.ascii_uppercase), + random.choice(string.ascii_lowercase), + random.choice(string.digits), + random.choice(password_chars), + random.choice(password_chars), + random.choice(password_chars), + random.choice(password_chars), + ] + password = [] + while password_list: + password.append( + password_list.pop(random.randint(0, len(password_list) - 1)) + ) + password = "".join(password) + + self.log("File password is generated using the password generator API", "INFO") + return password + + def get_want(self): + """ + Get all device_configs_backup related informantion from the playbook and preprare it to call + the API to export the device configurations. + Args: + self: The instance of the class containing the 'config' attribute to be validated. + Returns: + The method returns an instance of the class with updated attributes: + - self.want: A dictionary of paramters obtained from the playbook + - self.msg: A message indicating all the paramters from the playbook are + collected + - self.status: Success + Example: + It stores all the paramters passed from the playbook for further processing + before calling the APIs + """ + + self.want = {} + + self.want["deviceId"] = self.get_device_ids_list() + self.want["password"] = self.password_generator() + + self.msg = "Successfully collected all parameters from playbook " + \ + "for comparison" + self.status = "success" + self.log(self.msg, "INFO") + return self + + def get_device_config(self): + """ + Cisco Catalyst Center creates a ZIP file by calling the export API + """ + + response = self.dnac_apply['exec']( + family="configuration_archive", + function='export_device_configurations', + params=self.want, + op_modifies=True + ) + response = response.get("response") + + self.log("Response collected from 'export_device_configurations' API is {0}".format(str(response)), "DEBUG") + if response.get("errorCode"): + msg = response.get("message") + self.log(msg, "CRITICAL") + self.module.fail_json(msg=msg) + + task_id = response.get("taskId") + self.log("Task Id of the task is {0}".format(task_id), "INFO") + return task_id + + def get_task_status(self, task_id=None): + """ + Monitor the status of a task of creation of dicovery in the Cisco Catalyst Center. + It checks the task status periodically until the task is no longer 'In Progress' + or other states. If the task encounters an error or fails, it immediately fails the + module and returns False. + + Parameters: + - task_id: The ID of the task to monitor. + + Returns: + - result: True if the task completed successfully, False otherwise. + With True it also returns additionalStatusURL + """ + + result = False + params = dict(task_id=task_id) + while True: + response = self.dnac_apply['exec']( + family="task", + function='get_task_by_id', + params=params, + op_modifies=True, + ) + response = response.response + + self.log("Response collected from 'get task by id' is {0}".format(response), "DEBUG") + if response.get('isError') or re.search( + 'failed', response.get('progress'), flags=re.IGNORECASE + ): + msg = 'Device backup task with id {0} has not completed - Reason: {1}'.format( + task_id, response.get("failureReason")) + self.log(msg, "CRITICAL") + self.module.fail_json(msg=msg) + return False + + self.log("Task status for the task id (before checking status) {0} is {1}".format(str(task_id), str(response)), "INFO") + progress = response.get('progress') + + if progress == "Device configuration Successfully exported as password protected ZIP.": + result = True + additionalStatusURL = response.get("additionalStatusURL") + self.log("The backup process process is completed", "INFO") + self.result.update(dict(backup_task=response)) + return (result, additionalStatusURL) + + self.log("The progress status is {0}, continue to check the status after 3 seconds. Putting into sleep for 3 seconds".format(progress), "INFO") + time.sleep(3) + + def download_file(self, additionalStatusURL=None): + """ + Downloading file and store locally + Using unzip path settings for directory + Paremetrs: + self: The instance of the class containing the 'config' attribute to be validated. + additionalStatusURL: This paramter is used to fetch the file id + + Returns: + - result: True if the file downloaded and uzipped, else False + """ + + self.log(f"Downloading: {additionalStatusURL}") + file_id = additionalStatusURL.split("/")[-1] + + try: + response = self.dnac._exec( + family="file", + function='download_a_file_by_fileid', + op_modifies=True, + params={"file_id": file_id}, + ) + self.log("Received API response from 'download_a_file_by_fileid': {0}".format(str(response)), "DEBUG") + except Exception as e: + self.log(f"File couldn't be downloaded: {e}", "INFO") + return False + + if isinstance(response, dict) and response.get("errorCode"): + self.log(response.get("message"), "CRITICAL") + self.module.fail_json(msg=response.get("message")) + + zip_data = BytesIO(response.data) + self.log("ZIP data collected is {0}".format(zip_data), "INFO") + + pathlib.Path(self.have.get("file_path")).mkdir(parents=True, exist_ok=True) + self.log("Unzipping file after completion of download", "INFO") + + try: + with pyzipper.AESZipFile(zip_data, 'r') as f: + f.pwd = bytes(self.want.get("password"), encoding="utf-8") + f.extractall(path=str(self.have.get("file_path"))) + except Exception as e: + self.log(f"Error in unzipping: {e}", "CRITICAL") + return False + + self.log("Unzipping complete", "INFO") + return True + + def get_diff_merged(self): + """ + Add to device_configs_backup database + Args: + self: An instance of a class used for interacting with Cisco Catalyst Center. + Returns: + object: An instance of the class with updated results and status + based on the processing of differences. + Description: + The function processes the differences and, depending on the + changes required, it may add, update,or resynchronize devices in + Cisco Catalyst Center. The updated results and status are stored in the + class instance for further use. + """ + + if self.have.get('management_ip_address'): + self.validate_ipv4_address() + task_id = self.get_device_config() + result, additionalStatusURL = self.get_task_status(task_id=task_id) + if result is True: + download_status = self.download_file(additionalStatusURL=additionalStatusURL) + if download_status is True: + self.result['response'] = task_id + self.result['msg'] = "Device configs got downloaded" + self.log(self.result['msg'], "INFO") + self.result['changed'] = True + return self + return self + + def verify_diff_merged(self): + """ + Verify the merged status(Creation/Updation) of Discovery in Cisco Catalyst Center. + Args: + - self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Return: + - self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Description: + This method checks the merged status of a configuration in Cisco Catalyst Center by + retrieving the current state (have) and desired state (want) of the configuration, + logs the states, and validates whether the specified device(s) exists in the DNA + Center configuration's Discovery Database. + """ + + self.log("Current State (have): {0}".format(str(self.have)), "INFO") + self.log("Desired State (want): {0}".format(str(self.want)), "INFO") + # Code to validate Cisco Catalyst Center config for merged state + window_seconds = 10 + current_time = time.time() + window_start_time = current_time - window_seconds + files_modified_within_window = [ + f.name for f in pathlib.Path(self.have.get("file_path")).iterdir() + if f.stat().st_mtime > window_start_time + ] + + if len(files_modified_within_window) > 0: + self.log("Backup has been taken in the following files {0}".format(str(files_modified_within_window)), "INFO") + else: + self.log("Backup has not been taken, please check", "WARNING") + + self.status = "success" + + return self + + +def main(): + + """ + main entry point for module execution + """ + + element_spec = {'dnac_host': {'required': True, 'type': 'str'}, + 'dnac_port': {'type': 'str', 'default': '443'}, + 'dnac_username': {'type': 'str', 'default': 'admin', 'aliases': ['user']}, + 'dnac_password': {'type': 'str', 'no_log': True}, + 'dnac_verify': {'type': 'bool', 'default': 'True'}, + 'dnac_version': {'type': 'str', 'default': '2.2.3.3'}, + 'dnac_debug': {'type': 'bool', 'default': False}, + 'dnac_log': {'type': 'bool', 'default': False}, + "dnac_log_level": {"type": 'str', "default": 'WARNING'}, + "dnac_log_file_path": {"type": 'str', "default": 'dnac.log'}, + "dnac_log_append": {"type": 'bool', "default": True}, + "config_verify": {"type": 'bool', "default": False}, + 'dnac_api_task_timeout': {'type': 'int', "default": 1200}, + 'dnac_task_poll_interval': {'type': 'int', "default": 2}, + 'validate_response_schema': {'type': 'bool', 'default': True}, + 'config': {'required': True, 'type': 'list', 'elements': 'dict'}, + 'state': {'default': 'merged', 'choices': ['merged']} + } + module = AnsibleModule(argument_spec=element_spec, + supports_check_mode=False) + ccc_device_configs_backup = Device_configs_backup(module) + config_verify = ccc_device_configs_backup.params.get("config_verify") + + state = ccc_device_configs_backup.params.get("state") + if state not in ccc_device_configs_backup.supported_states: + ccc_device_configs_backup.status = "invalid" + ccc_device_configs_backup.msg = "State {0} is invalid".format(state) + ccc_device_configs_backup.check_return_status() + + ccc_device_configs_backup.validate_input().check_return_status() + + for config in ccc_device_configs_backup.validated_config: + ccc_device_configs_backup.reset_values() + ccc_device_configs_backup.get_have().check_return_status() + ccc_device_configs_backup.get_want().check_return_status() + ccc_device_configs_backup.get_diff_state_apply[state]().check_return_status() + if config_verify: + ccc_device_configs_backup.verify_diff_state_apply[state]().check_return_status() + + module.exit_json(**ccc_device_configs_backup.result) + + +if __name__ == '__main__': + main() From 8331a571c9dd8d93832a947d68c0f0c1d5dce167 Mon Sep 17 00:00:00 2001 From: Abinash Date: Thu, 25 Apr 2024 11:39:09 +0000 Subject: [PATCH 291/358] Adding module for device config backup --- .../modules/device_configs_backup_workflow_manager.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/modules/device_configs_backup_workflow_manager.py b/plugins/modules/device_configs_backup_workflow_manager.py index 7173a31f69..30c641547d 100644 --- a/plugins/modules/device_configs_backup_workflow_manager.py +++ b/plugins/modules/device_configs_backup_workflow_manager.py @@ -21,6 +21,10 @@ author: Abinash Mishra (@abimishr) Madhan Sankaranarayanan (@madhansansel) options: + config_verify: + description: Set to True to verify the Cisco Catalyst Center config after applying the playbook config. + type: bool + default: False state: description: The state of Cisco Catalyst Center after module completion. type: str @@ -421,7 +425,7 @@ def download_file(self, additionalStatusURL=None): - result: True if the file downloaded and uzipped, else False """ - self.log(f"Downloading: {additionalStatusURL}") + self.log("Downloading: {0}".format(additionalStatusURL), "INFO") file_id = additionalStatusURL.split("/")[-1] try: @@ -433,7 +437,7 @@ def download_file(self, additionalStatusURL=None): ) self.log("Received API response from 'download_a_file_by_fileid': {0}".format(str(response)), "DEBUG") except Exception as e: - self.log(f"File couldn't be downloaded: {e}", "INFO") + self.log("File couldn't be downloaded: {0}".format(e), "INFO") return False if isinstance(response, dict) and response.get("errorCode"): @@ -451,7 +455,7 @@ def download_file(self, additionalStatusURL=None): f.pwd = bytes(self.want.get("password"), encoding="utf-8") f.extractall(path=str(self.have.get("file_path"))) except Exception as e: - self.log(f"Error in unzipping: {e}", "CRITICAL") + self.log("Error in unzipping: {0}".format(e), "CRITICAL") return False self.log("Unzipping complete", "INFO") From 97f1d9593b9e6d835f49a42e3dffb1c2d26b1018 Mon Sep 17 00:00:00 2001 From: Abinash Date: Thu, 25 Apr 2024 11:47:24 +0000 Subject: [PATCH 292/358] Adding module for device config backup --- plugins/modules/device_configs_backup_workflow_manager.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/modules/device_configs_backup_workflow_manager.py b/plugins/modules/device_configs_backup_workflow_manager.py index 30c641547d..8764c7bfaa 100644 --- a/plugins/modules/device_configs_backup_workflow_manager.py +++ b/plugins/modules/device_configs_backup_workflow_manager.py @@ -136,6 +136,11 @@ HAS_PYZIPPER = False pyzipper = None +try: + import pathlib +except ImportError: + pathlib = None + from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.dnac.plugins.module_utils.dnac import ( DnacBase, @@ -146,8 +151,6 @@ import string import re import time -import pathlib -import time class Device_configs_backup(DnacBase): From 1a28ce190ae0002cb21cb50d54ad03c6046067b9 Mon Sep 17 00:00:00 2001 From: System Administrator Date: Thu, 25 Apr 2024 08:55:03 -0600 Subject: [PATCH 293/358] update to 2.3.7.5 version --- Pipfile | 12 + changelogs/changelog.yaml | 33 + galaxy.yml | 2 +- playbooks/dnac.log | 0 .../application_policy_application_set.py | 234 +++ ...ation_policy_application_set_count_info.py | 89 ++ ...application_policy_application_set_info.py | 95 ++ plugins/action/application_sets.py | 10 +- plugins/action/application_sets_info.py | 4 +- plugins/action/applications.py | 14 +- plugins/action/applications_count_v2_info.py | 89 ++ plugins/action/applications_health_info.py | 8 +- plugins/action/applications_info.py | 6 +- plugins/action/applications_v2.py | 275 ++++ plugins/action/applications_v2_info.py | 95 ++ plugins/action/auth_token_create.py | 84 ++ .../action/authentication_policy_servers.py | 338 +++++ .../buildings_planned_access_points_info.py | 4 +- ...business_sda_hostonboarding_ssid_ippool.py | 5 +- plugins/action/cli_credential.py | 2 +- plugins/action/client_detail_info.py | 4 +- plugins/action/client_health_info.py | 2 +- plugins/action/client_proximity_info.py | 4 +- .../action/compliance_device_by_id_info.py | 4 - .../action/compliance_device_details_info.py | 4 +- plugins/action/compliance_device_info.py | 4 - .../action/configuration_template_deploy.py | 2 +- .../configuration_template_deploy_v2.py | 2 +- .../action/configuration_template_project.py | 2 +- .../action/device_configurations_export.py | 4 +- plugins/action/device_details_info.py | 6 +- plugins/action/device_health_info.py | 8 +- plugins/action/device_reboot_apreboot.py | 181 +++ plugins/action/discovery_summary_info.py | 2 +- plugins/action/dna_event_snmp_config_info.py | 97 ++ plugins/action/eox_status_device_info.py | 8 +- plugins/action/eox_status_summary_info.py | 4 +- plugins/action/event_artifact_info.py | 4 +- plugins/action/event_info.py | 4 +- .../action/event_series_audit_logs_info.py | 8 +- ...t_series_audit_logs_parent_records_info.py | 8 +- .../event_series_audit_logs_summary_info.py | 4 +- plugins/action/event_series_count_info.py | 4 +- plugins/action/event_series_info.py | 8 +- plugins/action/event_snmp_config.py | 240 ++++ plugins/action/event_snmp_config_info.py | 18 +- plugins/action/event_subscription.py | 8 +- .../event_subscription_details_email_info.py | 4 +- .../event_subscription_details_rest_info.py | 4 +- .../event_subscription_details_syslog_info.py | 4 +- .../action/event_subscription_email_info.py | 4 +- plugins/action/event_subscription_info.py | 4 +- .../action/event_subscription_rest_info.py | 4 +- .../action/event_subscription_syslog_info.py | 4 +- plugins/action/event_syslog_config.py | 2 +- plugins/action/event_syslog_config_info.py | 4 +- plugins/action/event_webhook_create.py | 2 + plugins/action/event_webhook_read_info.py | 97 ++ plugins/action/event_webhook_update.py | 2 + .../action/flexible_report_content_info.py | 100 ++ plugins/action/flexible_report_execute.py | 86 ++ .../action/flexible_report_executions_info.py | 89 ++ plugins/action/flexible_report_schedule.py | 195 +++ .../action/flexible_report_schedule_info.py | 98 ++ .../action/flexible_report_schedules_info.py | 87 ++ plugins/action/global_pool_info.py | 4 +- plugins/action/http_read_credential.py | 2 +- plugins/action/http_write_credential.py | 2 +- .../integration_settings_instances_itsm.py | 1 + ...ntegration_settings_itsm_instances_info.py | 87 ++ .../integration_settings_status_info.py | 87 ++ plugins/action/ise_integration_status_info.py | 87 ++ plugins/action/issues_info.py | 8 +- plugins/action/lan_automation_log_info.py | 4 +- .../action/lan_automation_sessions_info.py | 87 ++ plugins/action/lan_automation_status_info.py | 4 +- plugins/action/lan_automation_update.py | 88 ++ .../action/lan_automation_update_device.py | 92 ++ plugins/action/lan_automation_update_v2.py | 88 ++ plugins/action/lan_automation_v2.py | 86 ++ .../license_device_license_summary_info.py | 6 +- plugins/action/maps_export.py | 86 ++ plugins/action/maps_import.py | 85 ++ plugins/action/maps_import_perform.py | 86 ++ plugins/action/maps_import_start.py | 84 ++ plugins/action/maps_import_status_info.py | 89 ++ .../maps_supported_access_points_info.py | 87 ++ plugins/action/netconf_credential.py | 4 +- plugins/action/network_device.py | 7 +- plugins/action/network_device_config__info.py | 99 ++ .../action/network_device_config_task_info.py | 89 ++ .../network_device_config_write_memory.py | 86 ++ plugins/action/network_device_count_info.py | 8 + .../action/network_device_equipment_info.py | 2 +- plugins/action/network_device_export.py | 2 - ...network_device_insight_device_link_info.py | 99 ++ .../action/network_device_ip_address_info.py | 98 ++ ...etwork_device_management_address_update.py | 88 ++ .../network_device_user_defined_field.py | 1 + ...etwork_device_user_defined_field_delete.py | 87 ++ ...etwork_device_user_defined_field_update.py | 88 ++ .../network_devices_interfaces_query.py | 92 ++ plugins/action/network_v2.py | 2 + plugins/action/path_trace.py | 3 +- plugins/action/path_trace_info.py | 16 +- plugins/action/planned_access_points.py | 286 ++++ plugins/action/planned_access_points_info.py | 4 +- plugins/action/pnp_device.py | 47 +- plugins/action/pnp_device_authorize.py | 2 +- plugins/action/pnp_device_claim_to_site.py | 8 +- plugins/action/pnp_device_count_info.py | 6 - plugins/action/pnp_device_info.py | 6 - plugins/action/pnp_global_settings.py | 4 + plugins/action/pnp_server_profile_update.py | 26 +- plugins/action/pnp_workflow.py | 1 + plugins/action/reports.py | 4 + plugins/action/reserve_ip_subpool.py | 10 +- plugins/action/reserve_ip_subpool_info.py | 10 +- plugins/action/reserve_ip_subpool_update.py | 4 +- plugins/action/roles.py | 262 ++++ plugins/action/sda_anycast_gateways.py | 288 ++++ .../action/sda_anycast_gateways_count_info.py | 97 ++ plugins/action/sda_anycast_gateways_info.py | 103 ++ plugins/action/sda_authentication_profiles.py | 190 +++ .../sda_authentication_profiles_info.py | 91 ++ plugins/action/sda_extranet_policies.py | 267 ++++ .../sda_extranet_policies_count_info.py | 87 ++ plugins/action/sda_extranet_policies_info.py | 93 ++ .../sda_fabric_authentication_profile.py | 9 +- plugins/action/sda_fabric_border_device.py | 9 +- .../action/sda_fabric_control_plane_device.py | 1 + plugins/action/sda_fabric_devices.py | 280 ++++ .../action/sda_fabric_devices_count_info.py | 93 ++ plugins/action/sda_fabric_devices_info.py | 97 ++ .../sda_fabric_devices_layer2_handoffs.py | 265 ++++ ...bric_devices_layer2_handoffs_count_info.py | 91 ++ ...sda_fabric_devices_layer2_handoffs_info.py | 95 ++ ...ric_devices_layer2_handoffs_ip_transits.py | 283 ++++ ..._layer2_handoffs_ip_transits_count_info.py | 91 ++ ...evices_layer2_handoffs_ip_transits_info.py | 95 ++ ...ic_devices_layer2_handoffs_sda_transits.py | 266 ++++ ...layer2_handoffs_sda_transits_count_info.py | 91 ++ ...vices_layer2_handoffs_sda_transits_info.py | 95 ++ plugins/action/sda_fabric_edge_device.py | 1 + plugins/action/sda_fabric_site.py | 1 + plugins/action/sda_fabric_sites.py | 267 ++++ plugins/action/sda_fabric_sites_count_info.py | 87 ++ plugins/action/sda_fabric_sites_info.py | 95 ++ plugins/action/sda_fabric_zones.py | 266 ++++ plugins/action/sda_fabric_zones_count_info.py | 87 ++ plugins/action/sda_fabric_zones_info.py | 95 ++ plugins/action/sda_multicast.py | 1 + .../sda_port_assignment_for_access_point.py | 1 + .../sda_port_assignment_for_user_device.py | 1 + plugins/action/sda_port_assignments.py | 295 ++++ .../action/sda_port_assignments_count_info.py | 97 ++ plugins/action/sda_port_assignments_info.py | 101 ++ plugins/action/sda_provision_device.py | 1 + plugins/action/sda_provision_devices.py | 274 ++++ .../sda_provision_devices_count_info.py | 89 ++ plugins/action/sda_provision_devices_info.py | 97 ++ plugins/action/sda_site_member_member_info.py | 97 ++ plugins/action/sda_virtual_network.py | 1 + plugins/action/sda_virtual_network_ip_pool.py | 5 +- plugins/action/sda_virtual_network_v2.py | 1 + ...security_advisories_ids_per_device_info.py | 2 +- plugins/action/sensor.py | 40 +- plugins/action/sensor_test_template_edit.py | 54 +- plugins/action/site_count_v2_info.py | 89 ++ plugins/action/site_health_info.py | 8 +- plugins/action/site_membership_info.py | 4 +- plugins/action/site_v2_info.py | 97 ++ .../snmpv2_read_community_credential.py | 4 +- .../snmpv2_write_community_credential.py | 4 +- plugins/action/snmpv3_credential.py | 5 +- plugins/action/swim_import_local.py | 10 +- plugins/action/system_health_info.py | 4 +- .../system_performance_historical_info.py | 4 +- plugins/action/system_performance_info.py | 4 +- plugins/action/tag_count_info.py | 2 - plugins/action/tag_info.py | 4 +- plugins/action/tag_member.py | 19 +- plugins/action/tag_member_count_info.py | 2 - plugins/action/tag_member_info.py | 4 +- plugins/action/tag_membership.py | 4 +- .../action/topology_network_health_info.py | 2 +- plugins/action/transit_peer_network.py | 36 +- plugins/action/user.py | 69 +- plugins/action/user_info.py | 4 +- .../action/users_external_authentication.py | 179 +++ .../users_external_authentication_info.py | 87 ++ .../users_external_servers_aaa_attribute.py | 201 +++ ...ers_external_servers_aaa_attribute_info.py | 87 ++ .../wireless_accespoint_configuration.py | 8 +- ...reless_accesspoint_configuration_create.py | 140 ++ plugins/action/wireless_dynamic_interface.py | 25 +- plugins/action/wireless_enterprise_ssid.py | 65 + plugins/action/wireless_profile.py | 8 +- plugins/action/wireless_psk_override.py | 10 +- .../wireless_sensor_test_results_info.py | 4 +- ...t_configuration_details_by_task_id_info.py | 7 +- plugins/modules/app_policy_default_info.py | 5 +- plugins/modules/app_policy_info.py | 5 +- plugins/modules/app_policy_intent_create.py | 11 +- plugins/modules/app_policy_queuing_profile.py | 7 +- .../app_policy_queuing_profile_count_info.py | 5 +- .../app_policy_queuing_profile_info.py | 5 +- .../application_policy_application_set.py | 117 ++ ...ation_policy_application_set_count_info.py | 67 + ...application_policy_application_set_info.py | 101 ++ plugins/modules/application_sets.py | 13 +- .../modules/application_sets_count_info.py | 5 +- plugins/modules/application_sets_info.py | 9 +- plugins/modules/applications.py | 50 +- plugins/modules/applications_count_info.py | 7 +- plugins/modules/applications_count_v2_info.py | 67 + plugins/modules/applications_health_info.py | 13 +- plugins/modules/applications_info.py | 35 +- plugins/modules/applications_v2.py | 342 +++++ plugins/modules/applications_v2_info.py | 152 ++ plugins/modules/assign_device_to_site.py | 16 +- .../associate_site_to_network_profile.py | 5 +- plugins/modules/auth_token_create.py | 58 + .../authentication_import_certificate.py | 5 +- .../authentication_import_certificate_p12.py | 5 +- .../modules/authentication_policy_servers.py | 255 ++++ .../authentication_policy_servers_info.py | 17 +- .../buildings_planned_access_points_info.py | 9 +- ...business_sda_hostonboarding_ssid_ippool.py | 31 +- ...ess_sda_hostonboarding_ssid_ippool_info.py | 5 +- ...siness_sda_virtual_network_summary_info.py | 20 +- ...business_sda_wireless_controller_create.py | 11 +- ...business_sda_wireless_controller_delete.py | 4 +- plugins/modules/cli_credential.py | 23 +- plugins/modules/client_detail_info.py | 205 ++- .../modules/client_enrichment_details_info.py | 5 +- plugins/modules/client_health_info.py | 100 +- plugins/modules/client_proximity_info.py | 9 +- plugins/modules/command_runner_run_command.py | 16 +- plugins/modules/compliance_check_run.py | 15 +- .../modules/compliance_device_by_id_info.py | 98 +- .../compliance_device_details_count_info.py | 14 +- .../modules/compliance_device_details_info.py | 20 +- plugins/modules/compliance_device_info.py | 30 +- .../compliance_device_status_count_info.py | 11 +- plugins/modules/configuration_template.py | 5 +- .../modules/configuration_template_clone.py | 5 +- .../modules/configuration_template_create.py | 5 +- .../modules/configuration_template_deploy.py | 20 +- ...nfiguration_template_deploy_status_info.py | 5 +- .../configuration_template_deploy_v2.py | 20 +- .../configuration_template_export_project.py | 5 +- .../configuration_template_export_template.py | 5 +- .../configuration_template_import_project.py | 5 +- .../configuration_template_import_template.py | 5 +- .../modules/configuration_template_info.py | 9 +- .../modules/configuration_template_project.py | 818 +---------- .../configuration_template_project_info.py | 214 +-- .../configuration_template_version_create.py | 5 +- .../configuration_template_version_info.py | 5 +- .../credential_to_site_by_siteid_create_v2.py | 7 +- .../modules/device_configurations_export.py | 26 +- plugins/modules/device_credential_create.py | 13 +- plugins/modules/device_credential_delete.py | 9 +- plugins/modules/device_credential_info.py | 9 +- plugins/modules/device_credential_update.py | 9 +- plugins/modules/device_details_info.py | 129 +- .../modules/device_enrichment_details_info.py | 5 +- .../device_family_identifiers_details_info.py | 5 +- plugins/modules/device_health_info.py | 100 +- .../modules/device_interface_by_ip_info.py | 23 +- .../modules/device_interface_count_info.py | 11 +- plugins/modules/device_interface_info.py | 23 +- plugins/modules/device_interface_isis_info.py | 23 +- plugins/modules/device_interface_ospf_info.py | 23 +- plugins/modules/device_reboot_apreboot.py | 5 +- .../modules/device_reboot_apreboot_info.py | 7 +- plugins/modules/device_replacement.py | 34 +- .../modules/device_replacement_count_info.py | 7 +- plugins/modules/device_replacement_deploy.py | 9 +- plugins/modules/device_replacement_info.py | 11 +- .../disassociate_site_to_network_profile.py | 5 +- plugins/modules/discovery.py | 127 +- plugins/modules/discovery_count_info.py | 5 +- .../modules/discovery_device_count_info.py | 5 +- plugins/modules/discovery_device_info.py | 5 +- .../modules/discovery_device_range_info.py | 9 +- plugins/modules/discovery_info.py | 5 +- plugins/modules/discovery_job_info.py | 5 +- plugins/modules/discovery_range_delete.py | 10 +- plugins/modules/discovery_range_info.py | 11 +- plugins/modules/discovery_summary_info.py | 37 +- .../dna_command_runner_keywords_info.py | 5 +- plugins/modules/dna_event_snmp_config_info.py | 103 ++ plugins/modules/dnac_packages_info.py | 7 +- ...nacaap_management_execution_status_info.py | 9 +- plugins/modules/eox_status_device_info.py | 40 +- plugins/modules/eox_status_summary_info.py | 9 +- plugins/modules/event_api_status_info.py | 5 +- plugins/modules/event_artifact_count_info.py | 7 +- plugins/modules/event_artifact_info.py | 13 +- .../event_config_connector_types_info.py | 5 +- plugins/modules/event_count_info.py | 5 +- plugins/modules/event_email_config.py | 17 +- plugins/modules/event_email_config_create.py | 13 +- plugins/modules/event_email_config_info.py | 11 +- plugins/modules/event_email_config_update.py | 13 +- plugins/modules/event_info.py | 9 +- .../modules/event_series_audit_logs_info.py | 13 +- ...t_series_audit_logs_parent_records_info.py | 13 +- .../event_series_audit_logs_summary_info.py | 9 +- plugins/modules/event_series_count_info.py | 9 +- plugins/modules/event_series_info.py | 13 +- plugins/modules/event_snmp_config.py | 144 ++ plugins/modules/event_snmp_config_info.py | 84 +- plugins/modules/event_subscription.py | 5 +- .../modules/event_subscription_count_info.py | 5 +- .../event_subscription_details_email_info.py | 9 +- .../event_subscription_details_rest_info.py | 20 +- .../event_subscription_details_syslog_info.py | 9 +- plugins/modules/event_subscription_email.py | 8 +- .../modules/event_subscription_email_info.py | 9 +- plugins/modules/event_subscription_info.py | 9 +- plugins/modules/event_subscription_rest.py | 5 +- .../modules/event_subscription_rest_info.py | 9 +- plugins/modules/event_subscription_syslog.py | 5 +- .../modules/event_subscription_syslog_info.py | 9 +- plugins/modules/event_syslog_config.py | 13 +- plugins/modules/event_syslog_config_info.py | 11 +- plugins/modules/event_webhook_create.py | 9 +- plugins/modules/event_webhook_read_info.py | 112 ++ plugins/modules/event_webhook_update.py | 9 +- .../execute_suggested_actions_commands.py | 7 +- plugins/modules/file_import.py | 5 +- plugins/modules/file_info.py | 8 +- plugins/modules/file_namespace_files_info.py | 5 +- plugins/modules/file_namespaces_info.py | 5 +- .../modules/flexible_report_content_info.py | 72 + plugins/modules/flexible_report_execute.py | 70 + .../flexible_report_executions_info.py | 84 ++ plugins/modules/flexible_report_schedule.py | 65 + .../modules/flexible_report_schedule_info.py | 64 + .../modules/flexible_report_schedules_info.py | 69 + plugins/modules/global_credential_delete.py | 5 +- plugins/modules/global_credential_info.py | 9 +- plugins/modules/global_credential_update.py | 7 +- plugins/modules/global_credential_v2.py | 81 +- plugins/modules/global_credential_v2_info.py | 7 +- plugins/modules/global_pool.py | 5 +- plugins/modules/global_pool_info.py | 37 +- plugins/modules/golden_image_create.py | 5 +- plugins/modules/golden_tag_image_delete.py | 5 +- .../modules/golden_tag_image_details_info.py | 5 +- plugins/modules/http_read_credential.py | 26 +- plugins/modules/http_write_credential.py | 26 +- .../integration_settings_instances_itsm.py | 9 +- ...ntegration_settings_instances_itsm_info.py | 7 +- ...ntegration_settings_itsm_instances_info.py | 78 + .../integration_settings_status_info.py | 74 + plugins/modules/interface_info.py | 73 +- .../interface_network_device_detail_info.py | 31 +- .../modules/interface_network_device_info.py | 23 +- .../interface_network_device_range_info.py | 23 +- plugins/modules/interface_operation_create.py | 9 +- plugins/modules/interface_update.py | 13 +- .../modules/ise_integration_status_info.py | 74 + .../modules/issues_enrichment_details_info.py | 5 +- plugins/modules/issues_info.py | 31 +- plugins/modules/itsm_cmdb_sync_status_info.py | 5 +- .../itsm_integration_events_failed_info.py | 5 +- .../modules/itsm_integration_events_retry.py | 5 +- plugins/modules/lan_automation_count_info.py | 5 +- plugins/modules/lan_automation_create.py | 5 +- plugins/modules/lan_automation_delete.py | 5 +- ...an_automation_log_by_serial_number_info.py | 7 +- plugins/modules/lan_automation_log_info.py | 9 +- .../modules/lan_automation_sessions_info.py | 68 + plugins/modules/lan_automation_status_info.py | 18 +- plugins/modules/lan_automation_update.py | 78 + .../modules/lan_automation_update_device.py | 122 ++ plugins/modules/lan_automation_update_v2.py | 84 ++ plugins/modules/lan_automation_v2.py | 166 +++ plugins/modules/license_device_count_info.py | 13 +- .../modules/license_device_deregistration.py | 13 +- .../license_device_license_details_info.py | 116 +- .../license_device_license_summary_info.py | 114 +- .../modules/license_device_registration.py | 13 +- .../license_smart_account_details_info.py | 5 +- plugins/modules/license_term_details_info.py | 13 +- plugins/modules/license_usage_details_info.py | 31 +- .../modules/license_virtual_account_change.py | 13 +- .../license_virtual_account_details_info.py | 13 +- plugins/modules/maps_export.py | 66 + plugins/modules/maps_import.py | 61 + plugins/modules/maps_import_perform.py | 63 + plugins/modules/maps_import_start.py | 56 + plugins/modules/maps_import_status_info.py | 117 ++ .../maps_supported_access_points_info.py | 72 + plugins/modules/netconf_credential.py | 20 +- plugins/modules/network_create.py | 7 +- plugins/modules/network_device.py | 78 +- plugins/modules/network_device_by_ip_info.py | 19 +- .../network_device_by_serial_number_info.py | 21 +- .../network_device_chassis_details_info.py | 5 +- .../modules/network_device_config__info.py | 135 ++ .../network_device_config_count_info.py | 5 +- plugins/modules/network_device_config_info.py | 9 +- .../network_device_config_task_info.py | 82 ++ .../network_device_config_write_memory.py | 66 + plugins/modules/network_device_count_info.py | 35 +- .../modules/network_device_custom_prompt.py | 13 +- .../network_device_custom_prompt_info.py | 11 +- .../modules/network_device_equipment_info.py | 20 +- plugins/modules/network_device_export.py | 17 +- ...twork_device_functional_capability_info.py | 7 +- ...ork_device_global_polling_interval_info.py | 5 +- plugins/modules/network_device_info.py | 25 +- ...network_device_insight_device_link_info.py | 126 ++ .../network_device_interface_neighbor_info.py | 5 +- .../network_device_interface_poe_info.py | 5 +- ...ce_inventory_insight_link_mismatch_info.py | 5 +- .../modules/network_device_ip_address_info.py | 119 ++ ...rk_device_lexicographically_sorted_info.py | 14 +- .../network_device_linecard_details_info.py | 5 +- ...etwork_device_management_address_update.py | 69 + ...network_device_meraki_organization_info.py | 7 +- .../network_device_module_count_info.py | 9 +- plugins/modules/network_device_module_info.py | 9 +- plugins/modules/network_device_poe_info.py | 7 +- .../network_device_polling_interval_info.py | 5 +- plugins/modules/network_device_range_info.py | 19 +- .../network_device_register_for_wsa_info.py | 5 +- .../network_device_stack_details_info.py | 5 +- .../modules/network_device_summary_info.py | 5 +- ...ork_device_supervisor_card_details_info.py | 5 +- plugins/modules/network_device_sync.py | 9 +- plugins/modules/network_device_update_role.py | 11 +- .../network_device_user_defined_field.py | 7 +- ...etwork_device_user_defined_field_delete.py | 70 + .../network_device_user_defined_field_info.py | 9 +- ...etwork_device_user_defined_field_update.py | 81 ++ plugins/modules/network_device_vlan_info.py | 12 +- .../network_device_wireless_lan_info.py | 36 +- .../network_devices_interfaces_query.py | 35 + plugins/modules/network_info.py | 5 +- plugins/modules/path_trace.py | 11 +- plugins/modules/path_trace_info.py | 42 +- plugins/modules/planned_access_points.py | 313 ++++ plugins/modules/planned_access_points_info.py | 9 +- ...atform_nodes_configuration_summary_info.py | 5 +- .../modules/platform_release_summary_info.py | 5 +- plugins/modules/pnp_device.py | 1258 +---------------- plugins/modules/pnp_device_authorize.py | 11 +- plugins/modules/pnp_device_claim.py | 5 +- plugins/modules/pnp_device_claim_to_site.py | 29 +- plugins/modules/pnp_device_config_preview.py | 5 +- plugins/modules/pnp_device_count_info.py | 43 +- plugins/modules/pnp_device_history_info.py | 7 +- plugins/modules/pnp_device_import.py | 1003 +------------ plugins/modules/pnp_device_info.py | 49 +- plugins/modules/pnp_device_reset.py | 5 +- plugins/modules/pnp_device_unclaim.py | 7 +- plugins/modules/pnp_global_settings.py | 171 +-- plugins/modules/pnp_global_settings_info.py | 6 +- plugins/modules/pnp_server_profile_update.py | 86 +- .../modules/pnp_smart_account_domains_info.py | 5 +- plugins/modules/pnp_virtual_account_add.py | 5 +- .../modules/pnp_virtual_account_deregister.py | 5 +- .../pnp_virtual_account_devices_sync.py | 7 +- .../pnp_virtual_account_sync_result_info.py | 7 +- plugins/modules/pnp_virtual_accounts_info.py | 5 +- plugins/modules/pnp_workflow.py | 5 +- plugins/modules/pnp_workflow_count_info.py | 7 +- plugins/modules/pnp_workflow_info.py | 11 +- plugins/modules/projects_details_info.py | 5 +- plugins/modules/qos_device_interface.py | 5 +- plugins/modules/qos_device_interface_info.py | 5 +- .../qos_device_interface_info_count_info.py | 5 +- plugins/modules/reports.py | 9 +- plugins/modules/reports_executions_info.py | 5 +- plugins/modules/reports_info.py | 5 +- plugins/modules/reports_view_group_info.py | 5 +- .../modules/reports_view_group_view_info.py | 5 +- plugins/modules/reserve_ip_subpool.py | 23 +- plugins/modules/reserve_ip_subpool_create.py | 23 +- plugins/modules/reserve_ip_subpool_delete.py | 5 +- plugins/modules/reserve_ip_subpool_info.py | 36 +- plugins/modules/reserve_ip_subpool_update.py | 32 +- plugins/modules/role_permissions_info.py | 9 +- plugins/modules/roles.py | 127 ++ plugins/modules/roles_info.py | 11 +- plugins/modules/sda_anycast_gateways.py | 203 +++ .../sda_anycast_gateways_count_info.py | 89 ++ plugins/modules/sda_anycast_gateways_info.py | 122 ++ .../modules/sda_authentication_profiles.py | 96 ++ .../sda_authentication_profiles_info.py | 84 ++ plugins/modules/sda_device_info.py | 5 +- plugins/modules/sda_device_role_info.py | 18 +- plugins/modules/sda_extranet_policies.py | 140 ++ .../sda_extranet_policies_count_info.py | 64 + plugins/modules/sda_extranet_policies_info.py | 89 ++ .../sda_fabric_authentication_profile.py | 5 +- .../sda_fabric_authentication_profile_info.py | 31 +- plugins/modules/sda_fabric_border_device.py | 7 +- .../modules/sda_fabric_border_device_info.py | 5 +- .../sda_fabric_control_plane_device.py | 5 +- .../sda_fabric_control_plane_device_info.py | 5 +- plugins/modules/sda_fabric_devices.py | 215 +++ .../modules/sda_fabric_devices_count_info.py | 79 ++ plugins/modules/sda_fabric_devices_info.py | 108 ++ .../sda_fabric_devices_layer2_handoffs.py | 134 ++ ...bric_devices_layer2_handoffs_count_info.py | 74 + ...sda_fabric_devices_layer2_handoffs_info.py | 91 ++ ...ric_devices_layer2_handoffs_ip_transits.py | 209 +++ ..._layer2_handoffs_ip_transits_count_info.py | 74 + ...evices_layer2_handoffs_ip_transits_info.py | 98 ++ ...ic_devices_layer2_handoffs_sda_transits.py | 157 ++ ...layer2_handoffs_sda_transits_count_info.py | 74 + ...vices_layer2_handoffs_sda_transits_info.py | 92 ++ plugins/modules/sda_fabric_edge_device.py | 5 +- .../modules/sda_fabric_edge_device_info.py | 5 +- plugins/modules/sda_fabric_site.py | 5 +- plugins/modules/sda_fabric_site_info.py | 5 +- plugins/modules/sda_fabric_sites.py | 123 ++ .../modules/sda_fabric_sites_count_info.py | 64 + plugins/modules/sda_fabric_sites_info.py | 89 ++ plugins/modules/sda_fabric_zones.py | 120 ++ .../modules/sda_fabric_zones_count_info.py | 64 + plugins/modules/sda_fabric_zones_info.py | 88 ++ plugins/modules/sda_multicast.py | 5 +- plugins/modules/sda_multicast_info.py | 5 +- .../sda_port_assignment_for_access_point.py | 5 +- ...a_port_assignment_for_access_point_info.py | 5 +- .../sda_port_assignment_for_user_device.py | 5 +- ...da_port_assignment_for_user_device_info.py | 5 +- plugins/modules/sda_port_assignments.py | 188 +++ .../sda_port_assignments_count_info.py | 89 ++ plugins/modules/sda_port_assignments_info.py | 110 ++ plugins/modules/sda_provision_device.py | 5 +- plugins/modules/sda_provision_device_info.py | 5 +- plugins/modules/sda_provision_devices.py | 141 ++ .../sda_provision_devices_count_info.py | 69 + plugins/modules/sda_provision_devices_info.py | 93 ++ .../modules/sda_site_member_member_info.py | 141 ++ plugins/modules/sda_virtual_network.py | 5 +- plugins/modules/sda_virtual_network_info.py | 14 +- .../modules/sda_virtual_network_ip_pool.py | 5 +- .../sda_virtual_network_ip_pool_info.py | 9 +- plugins/modules/sda_virtual_network_v2.py | 5 +- .../modules/sda_virtual_network_v2_info.py | 9 +- .../security_advisories_devices_info.py | 5 +- ...security_advisories_ids_per_device_info.py | 34 +- plugins/modules/security_advisories_info.py | 34 +- .../security_advisories_per_device_info.py | 34 +- .../security_advisories_summary_info.py | 21 +- plugins/modules/sensor.py | 970 ++++++++++++- plugins/modules/sensor_info.py | 9 +- plugins/modules/sensor_test_run.py | 5 +- .../modules/sensor_test_template_duplicate.py | 272 +++- plugins/modules/sensor_test_template_edit.py | 1141 +++++++++++++-- plugins/modules/service_provider_create.py | 5 +- plugins/modules/service_provider_info.py | 9 +- .../service_provider_profile_delete.py | 5 +- plugins/modules/service_provider_update.py | 5 +- plugins/modules/service_provider_v2.py | 7 +- plugins/modules/service_provider_v2_info.py | 7 +- plugins/modules/site_assign_credential.py | 5 +- plugins/modules/site_count_info.py | 9 +- plugins/modules/site_count_v2_info.py | 67 + plugins/modules/site_create.py | 17 +- plugins/modules/site_delete.py | 7 +- plugins/modules/site_health_info.py | 116 +- plugins/modules/site_info.py | 17 +- plugins/modules/site_membership_info.py | 9 +- plugins/modules/site_update.py | 51 +- plugins/modules/site_v2_info.py | 112 ++ plugins/modules/snmp_properties.py | 5 +- plugins/modules/snmp_properties_info.py | 5 +- .../snmpv2_read_community_credential.py | 7 +- .../snmpv2_write_community_credential.py | 7 +- plugins/modules/snmpv3_credential.py | 29 +- plugins/modules/sp_profile_delete_v2.py | 9 +- plugins/modules/swim_image_details_info.py | 5 +- plugins/modules/swim_import_local.py | 5 +- plugins/modules/swim_import_via_url.py | 5 +- plugins/modules/swim_trigger_activation.py | 5 +- plugins/modules/swim_trigger_distribution.py | 5 +- plugins/modules/system_health_count_info.py | 5 +- plugins/modules/system_health_info.py | 9 +- .../system_performance_historical_info.py | 18 +- plugins/modules/system_performance_info.py | 14 +- plugins/modules/tag.py | 41 +- plugins/modules/tag_count_info.py | 10 +- plugins/modules/tag_info.py | 13 +- plugins/modules/tag_member.py | 16 +- plugins/modules/tag_member_count_info.py | 10 +- plugins/modules/tag_member_info.py | 13 +- plugins/modules/tag_member_type_info.py | 5 +- plugins/modules/tag_membership.py | 20 +- plugins/modules/task_count_info.py | 5 +- plugins/modules/task_info.py | 5 +- plugins/modules/task_operation_info.py | 11 +- plugins/modules/task_tree_info.py | 11 +- plugins/modules/template_preview.py | 5 +- plugins/modules/templates_details_info.py | 7 +- plugins/modules/topology_layer_2_info.py | 5 +- plugins/modules/topology_layer_3_info.py | 5 +- .../modules/topology_network_health_info.py | 30 +- plugins/modules/topology_physical_info.py | 5 +- plugins/modules/topology_site_info.py | 5 +- plugins/modules/topology_vlan_details_info.py | 7 +- plugins/modules/transit_peer_network.py | 17 +- plugins/modules/transit_peer_network_info.py | 11 +- plugins/modules/user.py | 35 +- .../modules/user_enrichment_details_info.py | 5 +- plugins/modules/user_info.py | 22 +- .../modules/users_external_authentication.py | 61 + .../users_external_authentication_info.py | 65 + .../users_external_servers_aaa_attribute.py | 84 ++ ...ers_external_servers_aaa_attribute_info.py | 65 + .../modules/users_external_servers_info.py | 13 +- .../wireless_accespoint_configuration.py | 81 +- ...reless_accesspoint_configuration_create.py | 328 +++++ ..._accesspoint_configuration_summary_info.py | 7 +- plugins/modules/wireless_dynamic_interface.py | 36 +- .../wireless_dynamic_interface_info.py | 5 +- plugins/modules/wireless_enterprise_ssid.py | 110 +- .../modules/wireless_enterprise_ssid_info.py | 16 +- plugins/modules/wireless_profile.py | 16 +- plugins/modules/wireless_profile_info.py | 5 +- .../wireless_provision_access_point.py | 10 +- .../wireless_provision_device_create.py | 28 +- .../wireless_provision_device_update.py | 32 +- ...ireless_provision_ssid_create_provision.py | 32 +- ...eless_provision_ssid_delete_reprovision.py | 11 +- plugins/modules/wireless_psk_override.py | 43 +- plugins/modules/wireless_rf_profile.py | 27 +- plugins/modules/wireless_rf_profile_info.py | 82 +- .../wireless_sensor_test_results_info.py | 134 +- 639 files changed, 25623 insertions(+), 6781 deletions(-) create mode 100644 Pipfile create mode 100644 playbooks/dnac.log create mode 100644 plugins/action/application_policy_application_set.py create mode 100644 plugins/action/application_policy_application_set_count_info.py create mode 100644 plugins/action/application_policy_application_set_info.py create mode 100644 plugins/action/applications_count_v2_info.py create mode 100644 plugins/action/applications_v2.py create mode 100644 plugins/action/applications_v2_info.py create mode 100644 plugins/action/auth_token_create.py create mode 100644 plugins/action/authentication_policy_servers.py create mode 100644 plugins/action/device_reboot_apreboot.py create mode 100644 plugins/action/dna_event_snmp_config_info.py create mode 100644 plugins/action/event_snmp_config.py create mode 100644 plugins/action/event_webhook_read_info.py create mode 100644 plugins/action/flexible_report_content_info.py create mode 100644 plugins/action/flexible_report_execute.py create mode 100644 plugins/action/flexible_report_executions_info.py create mode 100644 plugins/action/flexible_report_schedule.py create mode 100644 plugins/action/flexible_report_schedule_info.py create mode 100644 plugins/action/flexible_report_schedules_info.py create mode 100644 plugins/action/integration_settings_itsm_instances_info.py create mode 100644 plugins/action/integration_settings_status_info.py create mode 100644 plugins/action/ise_integration_status_info.py create mode 100644 plugins/action/lan_automation_sessions_info.py create mode 100644 plugins/action/lan_automation_update.py create mode 100644 plugins/action/lan_automation_update_device.py create mode 100644 plugins/action/lan_automation_update_v2.py create mode 100644 plugins/action/lan_automation_v2.py create mode 100644 plugins/action/maps_export.py create mode 100644 plugins/action/maps_import.py create mode 100644 plugins/action/maps_import_perform.py create mode 100644 plugins/action/maps_import_start.py create mode 100644 plugins/action/maps_import_status_info.py create mode 100644 plugins/action/maps_supported_access_points_info.py create mode 100644 plugins/action/network_device_config__info.py create mode 100644 plugins/action/network_device_config_task_info.py create mode 100644 plugins/action/network_device_config_write_memory.py create mode 100644 plugins/action/network_device_insight_device_link_info.py create mode 100644 plugins/action/network_device_ip_address_info.py create mode 100644 plugins/action/network_device_management_address_update.py create mode 100644 plugins/action/network_device_user_defined_field_delete.py create mode 100644 plugins/action/network_device_user_defined_field_update.py create mode 100644 plugins/action/network_devices_interfaces_query.py create mode 100644 plugins/action/planned_access_points.py create mode 100644 plugins/action/roles.py create mode 100644 plugins/action/sda_anycast_gateways.py create mode 100644 plugins/action/sda_anycast_gateways_count_info.py create mode 100644 plugins/action/sda_anycast_gateways_info.py create mode 100644 plugins/action/sda_authentication_profiles.py create mode 100644 plugins/action/sda_authentication_profiles_info.py create mode 100644 plugins/action/sda_extranet_policies.py create mode 100644 plugins/action/sda_extranet_policies_count_info.py create mode 100644 plugins/action/sda_extranet_policies_info.py create mode 100644 plugins/action/sda_fabric_devices.py create mode 100644 plugins/action/sda_fabric_devices_count_info.py create mode 100644 plugins/action/sda_fabric_devices_info.py create mode 100644 plugins/action/sda_fabric_devices_layer2_handoffs.py create mode 100644 plugins/action/sda_fabric_devices_layer2_handoffs_count_info.py create mode 100644 plugins/action/sda_fabric_devices_layer2_handoffs_info.py create mode 100644 plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits.py create mode 100644 plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py create mode 100644 plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits_info.py create mode 100644 plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits.py create mode 100644 plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py create mode 100644 plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits_info.py create mode 100644 plugins/action/sda_fabric_sites.py create mode 100644 plugins/action/sda_fabric_sites_count_info.py create mode 100644 plugins/action/sda_fabric_sites_info.py create mode 100644 plugins/action/sda_fabric_zones.py create mode 100644 plugins/action/sda_fabric_zones_count_info.py create mode 100644 plugins/action/sda_fabric_zones_info.py create mode 100644 plugins/action/sda_port_assignments.py create mode 100644 plugins/action/sda_port_assignments_count_info.py create mode 100644 plugins/action/sda_port_assignments_info.py create mode 100644 plugins/action/sda_provision_devices.py create mode 100644 plugins/action/sda_provision_devices_count_info.py create mode 100644 plugins/action/sda_provision_devices_info.py create mode 100644 plugins/action/sda_site_member_member_info.py create mode 100644 plugins/action/site_count_v2_info.py create mode 100644 plugins/action/site_v2_info.py create mode 100644 plugins/action/users_external_authentication.py create mode 100644 plugins/action/users_external_authentication_info.py create mode 100644 plugins/action/users_external_servers_aaa_attribute.py create mode 100644 plugins/action/users_external_servers_aaa_attribute_info.py create mode 100644 plugins/action/wireless_accesspoint_configuration_create.py create mode 100644 plugins/modules/application_policy_application_set.py create mode 100644 plugins/modules/application_policy_application_set_count_info.py create mode 100644 plugins/modules/application_policy_application_set_info.py create mode 100644 plugins/modules/applications_count_v2_info.py create mode 100644 plugins/modules/applications_v2.py create mode 100644 plugins/modules/applications_v2_info.py create mode 100644 plugins/modules/auth_token_create.py create mode 100644 plugins/modules/authentication_policy_servers.py create mode 100644 plugins/modules/dna_event_snmp_config_info.py create mode 100644 plugins/modules/event_snmp_config.py create mode 100644 plugins/modules/event_webhook_read_info.py create mode 100644 plugins/modules/flexible_report_content_info.py create mode 100644 plugins/modules/flexible_report_execute.py create mode 100644 plugins/modules/flexible_report_executions_info.py create mode 100644 plugins/modules/flexible_report_schedule.py create mode 100644 plugins/modules/flexible_report_schedule_info.py create mode 100644 plugins/modules/flexible_report_schedules_info.py create mode 100644 plugins/modules/integration_settings_itsm_instances_info.py create mode 100644 plugins/modules/integration_settings_status_info.py create mode 100644 plugins/modules/ise_integration_status_info.py create mode 100644 plugins/modules/lan_automation_sessions_info.py create mode 100644 plugins/modules/lan_automation_update.py create mode 100644 plugins/modules/lan_automation_update_device.py create mode 100644 plugins/modules/lan_automation_update_v2.py create mode 100644 plugins/modules/lan_automation_v2.py create mode 100644 plugins/modules/maps_export.py create mode 100644 plugins/modules/maps_import.py create mode 100644 plugins/modules/maps_import_perform.py create mode 100644 plugins/modules/maps_import_start.py create mode 100644 plugins/modules/maps_import_status_info.py create mode 100644 plugins/modules/maps_supported_access_points_info.py create mode 100644 plugins/modules/network_device_config__info.py create mode 100644 plugins/modules/network_device_config_task_info.py create mode 100644 plugins/modules/network_device_config_write_memory.py create mode 100644 plugins/modules/network_device_insight_device_link_info.py create mode 100644 plugins/modules/network_device_ip_address_info.py create mode 100644 plugins/modules/network_device_management_address_update.py create mode 100644 plugins/modules/network_device_user_defined_field_delete.py create mode 100644 plugins/modules/network_device_user_defined_field_update.py create mode 100644 plugins/modules/network_devices_interfaces_query.py create mode 100644 plugins/modules/planned_access_points.py create mode 100644 plugins/modules/roles.py create mode 100644 plugins/modules/sda_anycast_gateways.py create mode 100644 plugins/modules/sda_anycast_gateways_count_info.py create mode 100644 plugins/modules/sda_anycast_gateways_info.py create mode 100644 plugins/modules/sda_authentication_profiles.py create mode 100644 plugins/modules/sda_authentication_profiles_info.py create mode 100644 plugins/modules/sda_extranet_policies.py create mode 100644 plugins/modules/sda_extranet_policies_count_info.py create mode 100644 plugins/modules/sda_extranet_policies_info.py create mode 100644 plugins/modules/sda_fabric_devices.py create mode 100644 plugins/modules/sda_fabric_devices_count_info.py create mode 100644 plugins/modules/sda_fabric_devices_info.py create mode 100644 plugins/modules/sda_fabric_devices_layer2_handoffs.py create mode 100644 plugins/modules/sda_fabric_devices_layer2_handoffs_count_info.py create mode 100644 plugins/modules/sda_fabric_devices_layer2_handoffs_info.py create mode 100644 plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits.py create mode 100644 plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py create mode 100644 plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_info.py create mode 100644 plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py create mode 100644 plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py create mode 100644 plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py create mode 100644 plugins/modules/sda_fabric_sites.py create mode 100644 plugins/modules/sda_fabric_sites_count_info.py create mode 100644 plugins/modules/sda_fabric_sites_info.py create mode 100644 plugins/modules/sda_fabric_zones.py create mode 100644 plugins/modules/sda_fabric_zones_count_info.py create mode 100644 plugins/modules/sda_fabric_zones_info.py create mode 100644 plugins/modules/sda_port_assignments.py create mode 100644 plugins/modules/sda_port_assignments_count_info.py create mode 100644 plugins/modules/sda_port_assignments_info.py create mode 100644 plugins/modules/sda_provision_devices.py create mode 100644 plugins/modules/sda_provision_devices_count_info.py create mode 100644 plugins/modules/sda_provision_devices_info.py create mode 100644 plugins/modules/sda_site_member_member_info.py create mode 100644 plugins/modules/site_count_v2_info.py create mode 100644 plugins/modules/site_v2_info.py create mode 100644 plugins/modules/users_external_authentication.py create mode 100644 plugins/modules/users_external_authentication_info.py create mode 100644 plugins/modules/users_external_servers_aaa_attribute.py create mode 100644 plugins/modules/users_external_servers_aaa_attribute_info.py create mode 100644 plugins/modules/wireless_accesspoint_configuration_create.py diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000000..b53ecf4600 --- /dev/null +++ b/Pipfile @@ -0,0 +1,12 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +dnacentersdk = ">=2.6.0" + +[dev-packages] + +[requires] +python_version = "3.12" diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 81e4f43487..bc40e8d7bf 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -866,3 +866,36 @@ releases: - Adding support to importing a template using JSON file - Changes in discovery workflow manager modules relating to different states of the discovery job - Changes in inventory and swim workflow manager modules. + 6.14.0 + release_date: "2024-04-25" + changes: + release_summary: New Dna Center API version 2.3.7.5. + minor_changes: + - application_policy_application_set_count_info - new module + - application_policy_application_set_info - new module + - application_policy_application_set - new module + - applications_count_v2_info - new module + - applications_v2_info - new module + - applications_v2 - new module + - auth_token_create - new module + - authentication_policy_servers - new module + - device_reboot_apreboot - new module + - dna_event_snmp_config_info - new module + - event_snmp_config - new module + - event_webhook_read_info - new module + - flexible_report_content_info - new module + - flexible_report_execute - new module + - flexible_report_executions_info - new module + - flexible_report_schedule_info - new module + - flexible_report_schedule - new module + - integration_settings_itsm_instances_info - new module + - integration_settings_status_info - new module + - ise_integration_status_info - new module + - lan_automation_sessions_info - new module + - lan_automation_update_device - new module + - lan_automation_update_v2 - new module + - lan_automation_update - new module + - lan_automation_v2 - new module + - network_device_user_defined_field_delete - new module + - users_external_authentication - new module + - users_external_servers_aaa_attribute - new module diff --git a/galaxy.yml b/galaxy.yml index 9858ed672f..e07c825ab1 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dnac -version: 6.13.3 +version: 6.14.0 readme: README.md authors: - Rafael Campos diff --git a/playbooks/dnac.log b/playbooks/dnac.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/action/application_policy_application_set.py b/plugins/action/application_policy_application_set.py new file mode 100644 index 0000000000..171175d4a6 --- /dev/null +++ b/plugins/action/application_policy_application_set.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id"], True), + ("state", "present", ["payload"], True), + ("state", "absent", ["id"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ApplicationPolicyApplicationSet(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['attributes'] = self.new_object.get('attributes') + new_object_params['name'] = name or self.new_object.get('name') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.dnac.exec( + family="application_policy", + function="get_application_sets2", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + except Exception: + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + o_id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("name", "name"), + ("scalableGroupType", "scalableGroupType"), + ("defaultBusinessRelevance", "defaultBusinessRelevance"), + ("namespace", "namespace"), + ("qualifier", "qualifier"), + ("type", "type"), + ("scalableGroupExternalHandle", "scalableGroupExternalHandle"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="application_policy", + function="create_application_sets", + params=self.create_params(), + op_modifies=True, + ) + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="application_policy", + function="delete_application_set", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = ApplicationPolicyApplicationSet(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = prev_obj + dnac.object_present_and_different() + else: + response = prev_obj + dnac.object_already_present() + else: + response = obj.create() + dnac.object_created() + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/application_policy_application_set_count_info.py b/plugins/action/application_policy_application_set_count_info.py new file mode 100644 index 0000000000..3a0a27f675 --- /dev/null +++ b/plugins/action/application_policy_application_set_count_info.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + scalableGroupType=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + scalable_group_type=params.get("scalableGroupType"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="application_policy", + function='get_application_set_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/application_policy_application_set_info.py b/plugins/action/application_policy_application_set_info.py new file mode 100644 index 0000000000..360ffb79e5 --- /dev/null +++ b/plugins/action/application_policy_application_set_info.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + attributes=dict(type="str"), + name=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + attributes=params.get("attributes"), + name=params.get("name"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="application_policy", + function='get_application_sets2', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/application_sets.py b/plugins/action/application_sets.py index b1bc7f48bf..f6877a3313 100644 --- a/plugins/action/application_sets.py +++ b/plugins/action/application_sets.py @@ -37,6 +37,7 @@ required_if = [ ("state", "present", ["payload"], True), + ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] @@ -151,12 +152,15 @@ def create(self): return result def delete(self): - id = self.new_object.get("id") - name = self.new_object.get("name") + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") result = None result = self.dnac.exec( family="application_policy", - function="delete_application_set", + function="delete_application_set2", params=self.delete_all_params(), ) return result diff --git a/plugins/action/application_sets_info.py b/plugins/action/application_sets_info.py index 9e388f1ac8..870d0e3c1c 100644 --- a/plugins/action/application_sets_info.py +++ b/plugins/action/application_sets_info.py @@ -25,8 +25,8 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), name=dict(type="str"), headers=dict(type="dict"), )) diff --git a/plugins/action/applications.py b/plugins/action/applications.py index 81c404e886..cc378dc1b0 100644 --- a/plugins/action/applications.py +++ b/plugins/action/applications.py @@ -37,6 +37,7 @@ required_if = [ ("state", "present", ["payload"], True), + ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] @@ -79,7 +80,7 @@ def get_object_by_name(self, name): try: items = self.dnac.exec( family="application_policy", - function="get_applications", + function="get_applications2", params=self.get_all_params(name=name), ) if isinstance(items, dict): @@ -96,7 +97,7 @@ def get_object_by_id(self, id): try: items = self.dnac.exec( family="application_policy", - function="get_applications", + function="get_applications2", params=self.get_all_params(id=id), ) if isinstance(items, dict): @@ -175,12 +176,15 @@ def update(self): return result def delete(self): - id = self.new_object.get("id") - name = self.new_object.get("name") + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") result = None result = self.dnac.exec( family="application_policy", - function="delete_application", + function="delete_application2", params=self.delete_all_params(), ) return result diff --git a/plugins/action/applications_count_v2_info.py b/plugins/action/applications_count_v2_info.py new file mode 100644 index 0000000000..f8d2365693 --- /dev/null +++ b/plugins/action/applications_count_v2_info.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + scalableGroupType=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + scalable_group_type=params.get("scalableGroupType"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="application_policy", + function='get_application_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/applications_health_info.py b/plugins/action/applications_health_info.py index 31d101b24c..dcb74b44d4 100644 --- a/plugins/action/applications_health_info.py +++ b/plugins/action/applications_health_info.py @@ -28,11 +28,11 @@ siteId=dict(type="str"), deviceId=dict(type="str"), macAddress=dict(type="str"), - startTime=dict(type="int"), - endTime=dict(type="int"), + startTime=dict(type="float"), + endTime=dict(type="float"), applicationHealth=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), applicationName=dict(type="str"), headers=dict(type="dict"), )) diff --git a/plugins/action/applications_info.py b/plugins/action/applications_info.py index 8d12751750..5a1ccaf658 100644 --- a/plugins/action/applications_info.py +++ b/plugins/action/applications_info.py @@ -25,8 +25,8 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), name=dict(type="str"), headers=dict(type="dict"), )) @@ -85,7 +85,7 @@ def run(self, tmp=None, task_vars=None): response = dnac.exec( family="application_policy", - function='get_applications', + function='get_applications2', params=self.get_object(self._task.args), ) self._result.update(dict(dnac_response=response)) diff --git a/plugins/action/applications_v2.py b/plugins/action/applications_v2.py new file mode 100644 index 0000000000..3771bb0045 --- /dev/null +++ b/plugins/action/applications_v2.py @@ -0,0 +1,275 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id"], True), + ("state", "present", ["payload"], True), + ("state", "absent", ["id"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ApplicationsV2(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['attributes'] = self.new_object.get('attributes') + new_object_params['name'] = name or self.new_object.get('name') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="application_policy", + function="get_applications", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + except Exception: + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="application_policy", + function="get_applications", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + o_id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("id", "id"), + ("instanceId", "instanceId"), + ("displayName", "displayName"), + ("instanceVersion", "instanceVersion"), + ("indicativeNetworkIdentity", "indicativeNetworkIdentity"), + ("name", "name"), + ("namespace", "namespace"), + ("networkApplications", "networkApplications"), + ("networkIdentity", "networkIdentity"), + ("parentScalableGroup", "parentScalableGroup"), + ("qualifier", "qualifier"), + ("scalableGroupExternalHandle", "scalableGroupExternalHandle"), + ("scalableGroupType", "scalableGroupType"), + ("type", "type"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="application_policy", + function="create_applications", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="application_policy", + function="edit_applications", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="application_policy", + function="delete_application", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = ApplicationsV2(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + response = obj.create() + dnac.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/applications_v2_info.py b/plugins/action/applications_v2_info.py new file mode 100644 index 0000000000..394363c015 --- /dev/null +++ b/plugins/action/applications_v2_info.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + attributes=dict(type="str"), + name=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + attributes=params.get("attributes"), + name=params.get("name"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="application_policy", + function='get_applications', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/auth_token_create.py b/plugins/action/auth_token_create.py new file mode 100644 index 0000000000..64e868966f --- /dev/null +++ b/plugins/action/auth_token_create.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="authentication", + function='authentication_api', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/authentication_policy_servers.py b/plugins/action/authentication_policy_servers.py new file mode 100644 index 0000000000..ea97f45b36 --- /dev/null +++ b/plugins/action/authentication_policy_servers.py @@ -0,0 +1,338 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + authenticationPort=dict(type="int"), + accountingPort=dict(type="int"), + ciscoIseDtos=dict(type="list"), + ipAddress=dict(type="str"), + pxgridEnabled=dict(type="bool"), + useDnacCertForPxgrid=dict(type="bool"), + isIseEnabled=dict(type="bool"), + port=dict(type="int"), + protocol=dict(type="str"), + retries=dict(type="str"), + role=dict(type="str"), + sharedSecret=dict(type="str"), + timeoutSeconds=dict(type="str"), + encryptionScheme=dict(type="str"), + messageKey=dict(type="str"), + encryptionKey=dict(type="str"), + externalCiscoIseIpAddrDtos=dict(type="list"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id", "role"], True), + ("state", "absent", ["id", "role"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class AuthenticationPolicyServers(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + authenticationPort=params.get("authenticationPort"), + accountingPort=params.get("accountingPort"), + ciscoIseDtos=params.get("ciscoIseDtos"), + ipAddress=params.get("ipAddress"), + pxgridEnabled=params.get("pxgridEnabled"), + useDnacCertForPxgrid=params.get("useDnacCertForPxgrid"), + isIseEnabled=params.get("isIseEnabled"), + port=params.get("port"), + protocol=params.get("protocol"), + retries=params.get("retries"), + role=params.get("role"), + sharedSecret=params.get("sharedSecret"), + timeoutSeconds=params.get("timeoutSeconds"), + encryptionScheme=params.get("encryptionScheme"), + messageKey=params.get("messageKey"), + encryptionKey=params.get("encryptionKey"), + externalCiscoIseIpAddrDtos=params.get("externalCiscoIseIpAddrDtos"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['is_ise_enabled'] = self.new_object.get('isIseEnabled') or \ + self.new_object.get('is_ise_enabled') + new_object_params['state'] = self.new_object.get('state_') or \ + self.new_object.get('state') + new_object_params['role'] = self.new_object.get('role') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['authenticationPort'] = self.new_object.get('authenticationPort') + new_object_params['accountingPort'] = self.new_object.get('accountingPort') + new_object_params['ciscoIseDtos'] = self.new_object.get('ciscoIseDtos') + new_object_params['ipAddress'] = self.new_object.get('ipAddress') + new_object_params['pxgridEnabled'] = self.new_object.get('pxgridEnabled') + new_object_params['useDnacCertForPxgrid'] = self.new_object.get('useDnacCertForPxgrid') + new_object_params['isIseEnabled'] = self.new_object.get('isIseEnabled') + new_object_params['port'] = self.new_object.get('port') + new_object_params['protocol'] = self.new_object.get('protocol') + new_object_params['retries'] = self.new_object.get('retries') + new_object_params['role'] = self.new_object.get('role') + new_object_params['sharedSecret'] = self.new_object.get('sharedSecret') + new_object_params['timeoutSeconds'] = self.new_object.get('timeoutSeconds') + new_object_params['encryptionScheme'] = self.new_object.get('encryptionScheme') + new_object_params['messageKey'] = self.new_object.get('messageKey') + new_object_params['encryptionKey'] = self.new_object.get('encryptionKey') + new_object_params['externalCiscoIseIpAddrDtos'] = self.new_object.get('externalCiscoIseIpAddrDtos') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + new_object_params['authenticationPort'] = self.new_object.get('authenticationPort') + new_object_params['accountingPort'] = self.new_object.get('accountingPort') + new_object_params['ciscoIseDtos'] = self.new_object.get('ciscoIseDtos') + new_object_params['ipAddress'] = self.new_object.get('ipAddress') + new_object_params['pxgridEnabled'] = self.new_object.get('pxgridEnabled') + new_object_params['useDnacCertForPxgrid'] = self.new_object.get('useDnacCertForPxgrid') + new_object_params['isIseEnabled'] = self.new_object.get('isIseEnabled') + new_object_params['port'] = self.new_object.get('port') + new_object_params['protocol'] = self.new_object.get('protocol') + new_object_params['retries'] = self.new_object.get('retries') + new_object_params['role'] = self.new_object.get('role') + new_object_params['sharedSecret'] = self.new_object.get('sharedSecret') + new_object_params['timeoutSeconds'] = self.new_object.get('timeoutSeconds') + new_object_params['encryptionScheme'] = self.new_object.get('encryptionScheme') + new_object_params['messageKey'] = self.new_object.get('messageKey') + new_object_params['encryptionKey'] = self.new_object.get('encryptionKey') + new_object_params['externalCiscoIseIpAddrDtos'] = self.new_object.get('externalCiscoIseIpAddrDtos') + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="system_settings", + function="get_authentication_and_policy_servers", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + except Exception: + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="system_settings", + function="get_authentication_and_policy_servers", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("authenticationPort", "authenticationPort"), + ("accountingPort", "accountingPort"), + ("ciscoIseDtos", "ciscoIseDtos"), + ("ipAddress", "ipAddress"), + ("pxgridEnabled", "pxgridEnabled"), + ("useDnacCertForPxgrid", "useDnacCertForPxgrid"), + ("isIseEnabled", "isIseEnabled"), + ("port", "port"), + ("protocol", "protocol"), + ("retries", "retries"), + ("role", "role"), + ("sharedSecret", "sharedSecret"), + ("timeoutSeconds", "timeoutSeconds"), + ("encryptionScheme", "encryptionScheme"), + ("messageKey", "messageKey"), + ("encryptionKey", "encryptionKey"), + ("externalCiscoIseIpAddrDtos", "externalCiscoIseIpAddrDtos"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="system_settings", + function="add_authentication_and_policy_server_access_configuration", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="system_settings", + function="edit_authentication_and_policy_server_access_configuration", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="system_settings", + function="delete_authentication_and_policy_server_access_configuration", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = AuthenticationPolicyServers(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + response = obj.create() + dnac.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/buildings_planned_access_points_info.py b/plugins/action/buildings_planned_access_points_info.py index 1668873255..3c8647ac18 100644 --- a/plugins/action/buildings_planned_access_points_info.py +++ b/plugins/action/buildings_planned_access_points_info.py @@ -26,8 +26,8 @@ # Add arguments specific for this module argument_spec.update(dict( buildingId=dict(type="str"), - limit=dict(type="int"), - offset=dict(type="int"), + limit=dict(type="float"), + offset=dict(type="float"), radios=dict(type="bool"), headers=dict(type="dict"), )) diff --git a/plugins/action/business_sda_hostonboarding_ssid_ippool.py b/plugins/action/business_sda_hostonboarding_ssid_ippool.py index 0a9652a759..9eceec3cf3 100644 --- a/plugins/action/business_sda_hostonboarding_ssid_ippool.py +++ b/plugins/action/business_sda_hostonboarding_ssid_ippool.py @@ -22,6 +22,9 @@ dnac_compare_equality, get_dict_result, ) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) # Get common arguments specification argument_spec = dnac_argument_spec() @@ -32,7 +35,6 @@ scalableGroupName=dict(type="str"), ssidNames=dict(type="list"), siteNameHierarchy=dict(type="str"), - headers=dict(type="dict"), )) required_if = [ @@ -52,7 +54,6 @@ def __init__(self, params, dnac): scalableGroupName=params.get("scalableGroupName"), ssidNames=params.get("ssidNames"), siteNameHierarchy=params.get("siteNameHierarchy"), - headers=params.get("headers"), ) def get_all_params(self, name=None, id=None): diff --git a/plugins/action/cli_credential.py b/plugins/action/cli_credential.py index 2b42190fa3..d10c90049a 100644 --- a/plugins/action/cli_credential.py +++ b/plugins/action/cli_credential.py @@ -127,7 +127,7 @@ def exists(self): id_exists = False name_exists = False o_id = self.new_object.get("id") - name = self.new_object.get("username") or self.new_object.get("description") + name = self.new_object.get("description") or self.new_object.get("username") if o_id: prev_obj = self.get_object_by_id(o_id) id_exists = prev_obj is not None and isinstance(prev_obj, dict) diff --git a/plugins/action/client_detail_info.py b/plugins/action/client_detail_info.py index e09db53c86..59b7fd8bb9 100644 --- a/plugins/action/client_detail_info.py +++ b/plugins/action/client_detail_info.py @@ -25,8 +25,8 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - timestamp=dict(type="str"), macAddress=dict(type="str"), + timestamp=dict(type="float"), headers=dict(type="dict"), )) @@ -65,8 +65,8 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( - timestamp=params.get("timestamp"), mac_address=params.get("macAddress"), + timestamp=params.get("timestamp"), headers=params.get("headers"), ) return new_object diff --git a/plugins/action/client_health_info.py b/plugins/action/client_health_info.py index 87275b0360..1f8a652b1e 100644 --- a/plugins/action/client_health_info.py +++ b/plugins/action/client_health_info.py @@ -25,7 +25,7 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - timestamp=dict(type="str"), + timestamp=dict(type="float"), headers=dict(type="dict"), )) diff --git a/plugins/action/client_proximity_info.py b/plugins/action/client_proximity_info.py index b9a411856f..af505d52a9 100644 --- a/plugins/action/client_proximity_info.py +++ b/plugins/action/client_proximity_info.py @@ -26,8 +26,8 @@ # Add arguments specific for this module argument_spec.update(dict( username=dict(type="str"), - number_days=dict(type="int"), - time_resolution=dict(type="int"), + number_days=dict(type="float"), + time_resolution=dict(type="float"), headers=dict(type="dict"), )) diff --git a/plugins/action/compliance_device_by_id_info.py b/plugins/action/compliance_device_by_id_info.py index e2c684bfc3..e9e9397eee 100644 --- a/plugins/action/compliance_device_by_id_info.py +++ b/plugins/action/compliance_device_by_id_info.py @@ -29,8 +29,6 @@ category=dict(type="str"), complianceType=dict(type="str"), diffList=dict(type="bool"), - key=dict(type="str"), - value=dict(type="str"), headers=dict(type="dict"), )) @@ -73,8 +71,6 @@ def get_object(self, params): category=params.get("category"), compliance_type=params.get("complianceType"), diff_list=params.get("diffList"), - key=params.get("key"), - value=params.get("value"), headers=params.get("headers"), ) return new_object diff --git a/plugins/action/compliance_device_details_info.py b/plugins/action/compliance_device_details_info.py index 4fedf1aab5..44fbabc271 100644 --- a/plugins/action/compliance_device_details_info.py +++ b/plugins/action/compliance_device_details_info.py @@ -28,8 +28,8 @@ complianceType=dict(type="str"), complianceStatus=dict(type="str"), deviceUuid=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), headers=dict(type="dict"), )) diff --git a/plugins/action/compliance_device_info.py b/plugins/action/compliance_device_info.py index 25d2db9cb9..553523dd26 100644 --- a/plugins/action/compliance_device_info.py +++ b/plugins/action/compliance_device_info.py @@ -27,8 +27,6 @@ argument_spec.update(dict( complianceStatus=dict(type="str"), deviceUuid=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), headers=dict(type="dict"), )) @@ -69,8 +67,6 @@ def get_object(self, params): new_object = dict( compliance_status=params.get("complianceStatus"), device_uuid=params.get("deviceUuid"), - offset=params.get("offset"), - limit=params.get("limit"), headers=params.get("headers"), ) return new_object diff --git a/plugins/action/configuration_template_deploy.py b/plugins/action/configuration_template_deploy.py index 55b033a763..48ccdcf3ad 100644 --- a/plugins/action/configuration_template_deploy.py +++ b/plugins/action/configuration_template_deploy.py @@ -28,7 +28,7 @@ forcePushTemplate=dict(type="bool"), isComposite=dict(type="bool"), mainTemplateId=dict(type="str"), - memberTemplateDeploymentInfo=dict(type="str"), + memberTemplateDeploymentInfo=dict(type="list"), targetInfo=dict(type="list"), templateId=dict(type="str"), )) diff --git a/plugins/action/configuration_template_deploy_v2.py b/plugins/action/configuration_template_deploy_v2.py index 802c84d98b..fe1ec9b760 100644 --- a/plugins/action/configuration_template_deploy_v2.py +++ b/plugins/action/configuration_template_deploy_v2.py @@ -28,7 +28,7 @@ forcePushTemplate=dict(type="bool"), isComposite=dict(type="bool"), mainTemplateId=dict(type="str"), - memberTemplateDeploymentInfo=dict(type="str"), + memberTemplateDeploymentInfo=dict(type="list"), targetInfo=dict(type="list"), templateId=dict(type="str"), )) diff --git a/plugins/action/configuration_template_project.py b/plugins/action/configuration_template_project.py index e6e356aa0b..65017e94d1 100644 --- a/plugins/action/configuration_template_project.py +++ b/plugins/action/configuration_template_project.py @@ -37,7 +37,7 @@ id=dict(type="str"), lastUpdateTime=dict(type="int"), name=dict(type="str"), - templates=dict(type="dict"), + templates=dict(type="list"), projectId=dict(type="str"), )) diff --git a/plugins/action/device_configurations_export.py b/plugins/action/device_configurations_export.py index 20c129b992..665bcbf41e 100644 --- a/plugins/action/device_configurations_export.py +++ b/plugins/action/device_configurations_export.py @@ -25,8 +25,8 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - deviceId=dict(type="list"), password=dict(type="str", no_log=True), + deviceId=dict(type="str"), )) required_if = [] @@ -64,8 +64,8 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( - deviceId=params.get("deviceId"), password=params.get("password"), + deviceId=params.get("deviceId"), ) return new_object diff --git a/plugins/action/device_details_info.py b/plugins/action/device_details_info.py index 7a743804c0..4c64f60f98 100644 --- a/plugins/action/device_details_info.py +++ b/plugins/action/device_details_info.py @@ -25,9 +25,9 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - timestamp=dict(type="str"), - searchBy=dict(type="str"), + timestamp=dict(type="float"), identifier=dict(type="str"), + searchBy=dict(type="str"), headers=dict(type="dict"), )) @@ -67,8 +67,8 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( timestamp=params.get("timestamp"), - search_by=params.get("searchBy"), identifier=params.get("identifier"), + search_by=params.get("searchBy"), headers=params.get("headers"), ) return new_object diff --git a/plugins/action/device_health_info.py b/plugins/action/device_health_info.py index 68bd65bfec..5bae85ad7c 100644 --- a/plugins/action/device_health_info.py +++ b/plugins/action/device_health_info.py @@ -28,10 +28,10 @@ deviceRole=dict(type="str"), siteId=dict(type="str"), health=dict(type="str"), - startTime=dict(type="int"), - endTime=dict(type="int"), - limit=dict(type="int"), - offset=dict(type="int"), + startTime=dict(type="float"), + endTime=dict(type="float"), + limit=dict(type="float"), + offset=dict(type="float"), headers=dict(type="dict"), )) diff --git a/plugins/action/device_reboot_apreboot.py b/plugins/action/device_reboot_apreboot.py new file mode 100644 index 0000000000..70a7b3e621 --- /dev/null +++ b/plugins/action/device_reboot_apreboot.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + apMacAddresses=dict(type="list"), +)) + +required_if = [ +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DeviceRebootApreboot(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + apMacAddresses=params.get("apMacAddresses"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['parent_task_id'] = self.new_object.get('parentTaskId') or \ + self.new_object.get('parent_task_id') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['apMacAddresses'] = self.new_object.get('apMacAddresses') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.dnac.exec( + family="wireless", + function="get_access_point_reboot_task_result", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + except Exception: + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("apMacAddresses", "apMacAddresses"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="wireless", + function="reboot_access_points", + params=self.create_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = DeviceRebootApreboot(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = prev_obj + dnac.object_present_and_different() + else: + response = prev_obj + dnac.object_already_present() + else: + response = obj.create() + dnac.object_created() + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/discovery_summary_info.py b/plugins/action/discovery_summary_info.py index 9b64187b2a..4e4b9741aa 100644 --- a/plugins/action/discovery_summary_info.py +++ b/plugins/action/discovery_summary_info.py @@ -80,7 +80,7 @@ def get_object(self, params): ip_address=params.get("ipAddress"), ping_status=params.get("pingStatus"), snmp_status=params.get("snmpStatus"), - cli_status=params.get("cliStatus"), + clistatus=params.get("cliStatus"), netconf_status=params.get("netconfStatus"), http_status=params.get("httpStatus"), headers=params.get("headers"), diff --git a/plugins/action/dna_event_snmp_config_info.py b/plugins/action/dna_event_snmp_config_info.py new file mode 100644 index 0000000000..19ad20c2dd --- /dev/null +++ b/plugins/action/dna_event_snmp_config_info.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + configId=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + sortBy=dict(type="str"), + order=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + config_id=params.get("configId"), + offset=params.get("offset"), + limit=params.get("limit"), + sort_by=params.get("sortBy"), + order=params.get("order"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="event_management", + function='get_snmp_destination', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/eox_status_device_info.py b/plugins/action/eox_status_device_info.py index 06ef71e8bd..40d675cce1 100644 --- a/plugins/action/eox_status_device_info.py +++ b/plugins/action/eox_status_device_info.py @@ -82,8 +82,8 @@ def run(self, tmp=None, task_vars=None): id = self._task.args.get("deviceId") if id: response = dnac.exec( - family="eo_x", - function='get_eo_x_details_per_device', + family="eox", + function='get_eox_details_per_device', params=self.get_object(self._task.args), ) self._result.update(dict(dnac_response=response)) @@ -91,8 +91,8 @@ def run(self, tmp=None, task_vars=None): return self._result if not id: response = dnac.exec( - family="eo_x", - function='get_eo_x_status_for_all_devices', + family="eox", + function='get_eox_status_for_all_devices', params=self.get_object(self._task.args), ) self._result.update(dict(dnac_response=response)) diff --git a/plugins/action/eox_status_summary_info.py b/plugins/action/eox_status_summary_info.py index 5b449d6623..db8934816d 100644 --- a/plugins/action/eox_status_summary_info.py +++ b/plugins/action/eox_status_summary_info.py @@ -78,8 +78,8 @@ def run(self, tmp=None, task_vars=None): dnac = DNACSDK(params=self._task.args) response = dnac.exec( - family="eo_x", - function='get_eo_x_summary', + family="eox", + function='get_eox_summary', params=self.get_object(self._task.args), ) self._result.update(dict(dnac_response=response)) diff --git a/plugins/action/event_artifact_info.py b/plugins/action/event_artifact_info.py index 4376fd4f0a..beef1e6a9b 100644 --- a/plugins/action/event_artifact_info.py +++ b/plugins/action/event_artifact_info.py @@ -27,8 +27,8 @@ argument_spec.update(dict( eventIds=dict(type="str"), tags=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), search=dict(type="str"), diff --git a/plugins/action/event_info.py b/plugins/action/event_info.py index d22c13f363..f7bcd07c79 100644 --- a/plugins/action/event_info.py +++ b/plugins/action/event_info.py @@ -27,8 +27,8 @@ argument_spec.update(dict( eventId=dict(type="str"), tags=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), headers=dict(type="dict"), diff --git a/plugins/action/event_series_audit_logs_info.py b/plugins/action/event_series_audit_logs_info.py index a2f85bacd7..6bd1bd2f39 100644 --- a/plugins/action/event_series_audit_logs_info.py +++ b/plugins/action/event_series_audit_logs_info.py @@ -41,10 +41,10 @@ deviceId=dict(type="str"), isSystemEvents=dict(type="bool"), description=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), - startTime=dict(type="int"), - endTime=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), + startTime=dict(type="float"), + endTime=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), headers=dict(type="dict"), diff --git a/plugins/action/event_series_audit_logs_parent_records_info.py b/plugins/action/event_series_audit_logs_parent_records_info.py index b9839c20fd..ffd36b1fea 100644 --- a/plugins/action/event_series_audit_logs_parent_records_info.py +++ b/plugins/action/event_series_audit_logs_parent_records_info.py @@ -40,10 +40,10 @@ deviceId=dict(type="str"), isSystemEvents=dict(type="bool"), description=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), - startTime=dict(type="int"), - endTime=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), + startTime=dict(type="float"), + endTime=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), headers=dict(type="dict"), diff --git a/plugins/action/event_series_audit_logs_summary_info.py b/plugins/action/event_series_audit_logs_summary_info.py index 42d15ac742..47e4576a18 100644 --- a/plugins/action/event_series_audit_logs_summary_info.py +++ b/plugins/action/event_series_audit_logs_summary_info.py @@ -42,8 +42,8 @@ deviceId=dict(type="str"), isSystemEvents=dict(type="bool"), description=dict(type="str"), - startTime=dict(type="int"), - endTime=dict(type="int"), + startTime=dict(type="float"), + endTime=dict(type="float"), headers=dict(type="dict"), )) diff --git a/plugins/action/event_series_count_info.py b/plugins/action/event_series_count_info.py index 8e6372c923..5951fd1196 100644 --- a/plugins/action/event_series_count_info.py +++ b/plugins/action/event_series_count_info.py @@ -26,8 +26,8 @@ # Add arguments specific for this module argument_spec.update(dict( eventIds=dict(type="str"), - startTime=dict(type="int"), - endTime=dict(type="int"), + startTime=dict(type="float"), + endTime=dict(type="float"), category=dict(type="str"), type=dict(type="str"), severity=dict(type="str"), diff --git a/plugins/action/event_series_info.py b/plugins/action/event_series_info.py index 8722bc05a8..31d06b5bb4 100644 --- a/plugins/action/event_series_info.py +++ b/plugins/action/event_series_info.py @@ -26,16 +26,16 @@ # Add arguments specific for this module argument_spec.update(dict( eventIds=dict(type="str"), - startTime=dict(type="int"), - endTime=dict(type="int"), + startTime=dict(type="float"), + endTime=dict(type="float"), category=dict(type="str"), type=dict(type="str"), severity=dict(type="str"), domain=dict(type="str"), subDomain=dict(type="str"), source=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), tags=dict(type="str"), diff --git a/plugins/action/event_snmp_config.py b/plugins/action/event_snmp_config.py new file mode 100644 index 0000000000..d2d3593b18 --- /dev/null +++ b/plugins/action/event_snmp_config.py @@ -0,0 +1,240 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + name=dict(type="str"), + description=dict(type="str"), + ipAddress=dict(type="str"), + port=dict(type="str"), + snmpVersion=dict(type="str"), + community=dict(type="str"), + userName=dict(type="str"), + snmpMode=dict(type="str"), + snmpAuthType=dict(type="str"), + authPassword=dict(type="str", no_log=True), + snmpPrivacyType=dict(type="str"), + privacyPassword=dict(type="str", no_log=True), + configId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class EventSnmpConfig(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + name=params.get("name"), + description=params.get("description"), + ipAddress=params.get("ipAddress"), + port=params.get("port"), + snmpVersion=params.get("snmpVersion"), + community=params.get("community"), + userName=params.get("userName"), + snmpMode=params.get("snmpMode"), + snmpAuthType=params.get("snmpAuthType"), + authPassword=params.get("authPassword"), + snmpPrivacyType=params.get("snmpPrivacyType"), + privacyPassword=params.get("privacyPassword"), + configId=params.get("configId"), + ) + + def create_params(self): + new_object_params = {} + new_object_params['name'] = self.new_object.get('name') + new_object_params['description'] = self.new_object.get('description') + new_object_params['ipAddress'] = self.new_object.get('ipAddress') + new_object_params['port'] = self.new_object.get('port') + new_object_params['snmpVersion'] = self.new_object.get('snmpVersion') + new_object_params['community'] = self.new_object.get('community') + new_object_params['userName'] = self.new_object.get('userName') + new_object_params['snmpMode'] = self.new_object.get('snmpMode') + new_object_params['snmpAuthType'] = self.new_object.get('snmpAuthType') + new_object_params['authPassword'] = self.new_object.get('authPassword') + new_object_params['snmpPrivacyType'] = self.new_object.get('snmpPrivacyType') + new_object_params['privacyPassword'] = self.new_object.get('privacyPassword') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['configId'] = self.new_object.get('configId') + new_object_params['name'] = self.new_object.get('name') + new_object_params['description'] = self.new_object.get('description') + new_object_params['ipAddress'] = self.new_object.get('ipAddress') + new_object_params['port'] = self.new_object.get('port') + new_object_params['snmpVersion'] = self.new_object.get('snmpVersion') + new_object_params['community'] = self.new_object.get('community') + new_object_params['userName'] = self.new_object.get('userName') + new_object_params['snmpMode'] = self.new_object.get('snmpMode') + new_object_params['snmpAuthType'] = self.new_object.get('snmpAuthType') + new_object_params['authPassword'] = self.new_object.get('authPassword') + new_object_params['snmpPrivacyType'] = self.new_object.get('snmpPrivacyType') + new_object_params['privacyPassword'] = self.new_object.get('privacyPassword') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name and get all + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("description", "description"), + ("ipAddress", "ipAddress"), + ("port", "port"), + ("snmpVersion", "snmpVersion"), + ("community", "community"), + ("userName", "userName"), + ("snmpMode", "snmpMode"), + ("snmpAuthType", "snmpAuthType"), + ("authPassword", "authPassword"), + ("snmpPrivacyType", "snmpPrivacyType"), + ("privacyPassword", "privacyPassword"), + ("configId", "configId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="event_management", + function="create_snmp_destination", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.dnac.exec( + family="event_management", + function="update_snmp_destination", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = EventSnmpConfig(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + response = obj.create() + dnac.object_created() + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/event_snmp_config_info.py b/plugins/action/event_snmp_config_info.py index 1bc024081f..cbd01f851f 100644 --- a/plugins/action/event_snmp_config_info.py +++ b/plugins/action/event_snmp_config_info.py @@ -25,11 +25,6 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - configId=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), - sortBy=dict(type="str"), - order=dict(type="str"), headers=dict(type="dict"), )) @@ -68,11 +63,6 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( - config_id=params.get("configId"), - offset=params.get("offset"), - limit=params.get("limit"), - sort_by=params.get("sortBy"), - order=params.get("order"), headers=params.get("headers"), ) return new_object @@ -87,11 +77,9 @@ def run(self, tmp=None, task_vars=None): dnac = DNACSDK(params=self._task.args) - response = dnac.exec( - family="event_management", - function='get_snmp_destination', - params=self.get_object(self._task.args), - ) + # NOTE: Does not have a get all method or it is in another action + response = None + dnac.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") self._result.update(dict(dnac_response=response)) self._result.update(dnac.exit_json()) return self._result diff --git a/plugins/action/event_subscription.py b/plugins/action/event_subscription.py index 52db4e8ad2..bb444e268c 100644 --- a/plugins/action/event_subscription.py +++ b/plugins/action/event_subscription.py @@ -37,6 +37,7 @@ required_if = [ ("state", "present", ["payload"], True), + ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] @@ -183,8 +184,11 @@ def update(self): return result def delete(self): - id = self.new_object.get("id") - name = self.new_object.get("name") + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") result = None result = self.dnac.exec( family="event_management", diff --git a/plugins/action/event_subscription_details_email_info.py b/plugins/action/event_subscription_details_email_info.py index 2ece6f956b..9681e5362a 100644 --- a/plugins/action/event_subscription_details_email_info.py +++ b/plugins/action/event_subscription_details_email_info.py @@ -27,8 +27,8 @@ argument_spec.update(dict( name=dict(type="str"), instanceId=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), headers=dict(type="dict"), diff --git a/plugins/action/event_subscription_details_rest_info.py b/plugins/action/event_subscription_details_rest_info.py index 9c73213176..147aaaa8d4 100644 --- a/plugins/action/event_subscription_details_rest_info.py +++ b/plugins/action/event_subscription_details_rest_info.py @@ -27,8 +27,8 @@ argument_spec.update(dict( name=dict(type="str"), instanceId=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), headers=dict(type="dict"), diff --git a/plugins/action/event_subscription_details_syslog_info.py b/plugins/action/event_subscription_details_syslog_info.py index fbec9c6ad7..27b88b23d7 100644 --- a/plugins/action/event_subscription_details_syslog_info.py +++ b/plugins/action/event_subscription_details_syslog_info.py @@ -27,8 +27,8 @@ argument_spec.update(dict( name=dict(type="str"), instanceId=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), headers=dict(type="dict"), diff --git a/plugins/action/event_subscription_email_info.py b/plugins/action/event_subscription_email_info.py index 9e5f52866e..93b4762e22 100644 --- a/plugins/action/event_subscription_email_info.py +++ b/plugins/action/event_subscription_email_info.py @@ -26,8 +26,8 @@ # Add arguments specific for this module argument_spec.update(dict( eventIds=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), domain=dict(type="str"), diff --git a/plugins/action/event_subscription_info.py b/plugins/action/event_subscription_info.py index c5dc8d6f6c..7470087206 100644 --- a/plugins/action/event_subscription_info.py +++ b/plugins/action/event_subscription_info.py @@ -26,8 +26,8 @@ # Add arguments specific for this module argument_spec.update(dict( eventIds=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), headers=dict(type="dict"), diff --git a/plugins/action/event_subscription_rest_info.py b/plugins/action/event_subscription_rest_info.py index 0466392604..f8c69c1683 100644 --- a/plugins/action/event_subscription_rest_info.py +++ b/plugins/action/event_subscription_rest_info.py @@ -26,8 +26,8 @@ # Add arguments specific for this module argument_spec.update(dict( eventIds=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), domain=dict(type="str"), diff --git a/plugins/action/event_subscription_syslog_info.py b/plugins/action/event_subscription_syslog_info.py index d79db09534..c8338dffb4 100644 --- a/plugins/action/event_subscription_syslog_info.py +++ b/plugins/action/event_subscription_syslog_info.py @@ -26,8 +26,8 @@ # Add arguments specific for this module argument_spec.update(dict( eventIds=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), domain=dict(type="str"), diff --git a/plugins/action/event_syslog_config.py b/plugins/action/event_syslog_config.py index e4aae36bbe..366d56718e 100644 --- a/plugins/action/event_syslog_config.py +++ b/plugins/action/event_syslog_config.py @@ -36,7 +36,7 @@ description=dict(type="str"), host=dict(type="str"), protocol=dict(type="str"), - port=dict(type="str"), + port=dict(type="int"), )) required_if = [ diff --git a/plugins/action/event_syslog_config_info.py b/plugins/action/event_syslog_config_info.py index bcef02393f..02c304e9bf 100644 --- a/plugins/action/event_syslog_config_info.py +++ b/plugins/action/event_syslog_config_info.py @@ -28,8 +28,8 @@ configId=dict(type="str"), name=dict(type="str"), protocol=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), sortBy=dict(type="str"), order=dict(type="str"), headers=dict(type="dict"), diff --git a/plugins/action/event_webhook_create.py b/plugins/action/event_webhook_create.py index de2b925147..ddbadcae42 100644 --- a/plugins/action/event_webhook_create.py +++ b/plugins/action/event_webhook_create.py @@ -32,6 +32,7 @@ method=dict(type="str"), trustCert=dict(type="bool"), headers=dict(type="list"), + isProxyRoute=dict(type="bool"), )) required_if = [] @@ -76,6 +77,7 @@ def get_object(self, params): method=params.get("method"), trustCert=params.get("trustCert"), headers=params.get("headers"), + isProxyRoute=params.get("isProxyRoute"), ) return new_object diff --git a/plugins/action/event_webhook_read_info.py b/plugins/action/event_webhook_read_info.py new file mode 100644 index 0000000000..9bb609a072 --- /dev/null +++ b/plugins/action/event_webhook_read_info.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + webhookIds=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + sortBy=dict(type="str"), + order=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + webhook_ids=params.get("webhookIds"), + offset=params.get("offset"), + limit=params.get("limit"), + sort_by=params.get("sortBy"), + order=params.get("order"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="event_management", + function='get_webhook_destination', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/event_webhook_update.py b/plugins/action/event_webhook_update.py index d11bc98a04..772b5e263a 100644 --- a/plugins/action/event_webhook_update.py +++ b/plugins/action/event_webhook_update.py @@ -32,6 +32,7 @@ method=dict(type="str"), trustCert=dict(type="bool"), headers=dict(type="list"), + isProxyRoute=dict(type="bool"), )) required_if = [] @@ -76,6 +77,7 @@ def get_object(self, params): method=params.get("method"), trustCert=params.get("trustCert"), headers=params.get("headers"), + isProxyRoute=params.get("isProxyRoute"), ) return new_object diff --git a/plugins/action/flexible_report_content_info.py b/plugins/action/flexible_report_content_info.py new file mode 100644 index 0000000000..ec95a02b73 --- /dev/null +++ b/plugins/action/flexible_report_content_info.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + reportId=dict(type="str"), + executionId=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + report_id=params.get("reportId"), + execution_id=params.get("executionId"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + id = self._task.args.get("reportId") + if id: + response = dnac.exec( + family="reports", + function='download_flexible_report', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result + if not id: + # NOTE: Does not have a get all method or it is in another action + response = None + dnac.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/flexible_report_execute.py b/plugins/action/flexible_report_execute.py new file mode 100644 index 0000000000..b2c481e10e --- /dev/null +++ b/plugins/action/flexible_report_execute.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + reportId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + report_id=params.get("reportId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="reports", + function='executing_the_flexible_report', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/flexible_report_executions_info.py b/plugins/action/flexible_report_executions_info.py new file mode 100644 index 0000000000..7340ddcd9d --- /dev/null +++ b/plugins/action/flexible_report_executions_info.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + reportId=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + report_id=params.get("reportId"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="reports", + function='get_execution_id_by_report_id', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/flexible_report_schedule.py b/plugins/action/flexible_report_schedule.py new file mode 100644 index 0000000000..f328936ebf --- /dev/null +++ b/plugins/action/flexible_report_schedule.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + schedule=dict(type="dict"), + reportId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["reportId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class FlexibleReportSchedule(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + schedule=params.get("schedule"), + report_id=params.get("reportId"), + ) + + def update_by_id_params(self): + new_object_params = {} + new_object_params['schedule'] = self.new_object.get('schedule') + new_object_params['reportId'] = self.new_object.get('reportId') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name and get all + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.dnac.exec( + family="reports", + function="get_flexible_report_schedule_by_report_id", + params={"report_id": id} + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'report_id', id) + except Exception: + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get("report_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("reportId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(report_id=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("schedule", "schedule"), + ("reportId", "report_id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("report_id") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("reportId") + if id_: + self.new_object.update(dict(report_id=id_)) + result = self.dnac.exec( + family="reports", + function="update_schedule_of_flexible_report", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = FlexibleReportSchedule(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + dnac.fail_json("Object does not exists, plugin only has update") + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/flexible_report_schedule_info.py b/plugins/action/flexible_report_schedule_info.py new file mode 100644 index 0000000000..cf11f213cb --- /dev/null +++ b/plugins/action/flexible_report_schedule_info.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + reportId=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + report_id=params.get("reportId"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + id = self._task.args.get("reportId") + if id: + response = dnac.exec( + family="reports", + function='get_flexible_report_schedule_by_report_id', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result + if not id: + # NOTE: Does not have a get all method or it is in another action + response = None + dnac.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/flexible_report_schedules_info.py b/plugins/action/flexible_report_schedules_info.py new file mode 100644 index 0000000000..15565a03ac --- /dev/null +++ b/plugins/action/flexible_report_schedules_info.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="reports", + function='get_all_flexible_report_schedules', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/global_pool_info.py b/plugins/action/global_pool_info.py index 56c0161a08..3045942814 100644 --- a/plugins/action/global_pool_info.py +++ b/plugins/action/global_pool_info.py @@ -25,8 +25,8 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), headers=dict(type="dict"), )) diff --git a/plugins/action/http_read_credential.py b/plugins/action/http_read_credential.py index c73050be86..1d1ac0acd2 100644 --- a/plugins/action/http_read_credential.py +++ b/plugins/action/http_read_credential.py @@ -130,7 +130,7 @@ def exists(self): id_exists = False name_exists = False o_id = self.new_object.get("id") - name = self.new_object.get("username") or self.new_object.get("description") + name = self.new_object.get("description") or self.new_object.get("username") if o_id: prev_obj = self.get_object_by_id(o_id) id_exists = prev_obj is not None and isinstance(prev_obj, dict) diff --git a/plugins/action/http_write_credential.py b/plugins/action/http_write_credential.py index 7ae396a1b7..5a63c0d5e5 100644 --- a/plugins/action/http_write_credential.py +++ b/plugins/action/http_write_credential.py @@ -130,7 +130,7 @@ def exists(self): id_exists = False name_exists = False o_id = self.new_object.get("id") - name = self.new_object.get("username") or self.new_object.get("description") + name = self.new_object.get("description") or self.new_object.get("username") if o_id: prev_obj = self.get_object_by_id(o_id) id_exists = prev_obj is not None and isinstance(prev_obj, dict) diff --git a/plugins/action/integration_settings_instances_itsm.py b/plugins/action/integration_settings_instances_itsm.py index 1b12af772f..0575dc457d 100644 --- a/plugins/action/integration_settings_instances_itsm.py +++ b/plugins/action/integration_settings_instances_itsm.py @@ -77,6 +77,7 @@ def update_by_id_params(self): new_object_params['description'] = self.new_object.get('description') new_object_params['data'] = self.new_object.get('data') new_object_params['dypName'] = self.new_object.get('dypName') + new_object_params['instanceId'] = self.new_object.get('instanceId') return new_object_params def get_object_by_name(self, name): diff --git a/plugins/action/integration_settings_itsm_instances_info.py b/plugins/action/integration_settings_itsm_instances_info.py new file mode 100644 index 0000000000..f8360f9c79 --- /dev/null +++ b/plugins/action/integration_settings_itsm_instances_info.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="itsm_integration", + function='get_all_itsm_integration_settings', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/integration_settings_status_info.py b/plugins/action/integration_settings_status_info.py new file mode 100644 index 0000000000..2673531b9e --- /dev/null +++ b/plugins/action/integration_settings_status_info.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="itsm_integration", + function='get_itsm_integration_status', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/ise_integration_status_info.py b/plugins/action/ise_integration_status_info.py new file mode 100644 index 0000000000..40bb9e2f79 --- /dev/null +++ b/plugins/action/ise_integration_status_info.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="system_settings", + function='cisco_ise_server_integration_status', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/issues_info.py b/plugins/action/issues_info.py index ab158f9e7e..288681100d 100644 --- a/plugins/action/issues_info.py +++ b/plugins/action/issues_info.py @@ -25,14 +25,14 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - startTime=dict(type="int"), - endTime=dict(type="int"), + startTime=dict(type="float"), + endTime=dict(type="float"), siteId=dict(type="str"), deviceId=dict(type="str"), macAddress=dict(type="str"), priority=dict(type="str"), - aiDriven=dict(type="str"), issueStatus=dict(type="str"), + aiDriven=dict(type="str"), headers=dict(type="dict"), )) @@ -77,8 +77,8 @@ def get_object(self, params): device_id=params.get("deviceId"), mac_address=params.get("macAddress"), priority=params.get("priority"), - ai_driven=params.get("aiDriven"), issue_status=params.get("issueStatus"), + ai_driven=params.get("aiDriven"), headers=params.get("headers"), ) return new_object diff --git a/plugins/action/lan_automation_log_info.py b/plugins/action/lan_automation_log_info.py index dfa702581c..dc9caf604f 100644 --- a/plugins/action/lan_automation_log_info.py +++ b/plugins/action/lan_automation_log_info.py @@ -25,8 +25,8 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), id=dict(type="str"), headers=dict(type="dict"), )) diff --git a/plugins/action/lan_automation_sessions_info.py b/plugins/action/lan_automation_sessions_info.py new file mode 100644 index 0000000000..5a9a7119d4 --- /dev/null +++ b/plugins/action/lan_automation_sessions_info.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="lan_automation", + function='lan_automation_active_sessions', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/lan_automation_status_info.py b/plugins/action/lan_automation_status_info.py index 073cfb275f..e380bd5fbc 100644 --- a/plugins/action/lan_automation_status_info.py +++ b/plugins/action/lan_automation_status_info.py @@ -25,8 +25,8 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), id=dict(type="str"), headers=dict(type="dict"), )) diff --git a/plugins/action/lan_automation_update.py b/plugins/action/lan_automation_update.py new file mode 100644 index 0000000000..0a30414e1e --- /dev/null +++ b/plugins/action/lan_automation_update.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + payload=dict(type="list"), + id=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + payload=params.get("payload"), + id=params.get("id"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="lan_automation", + function='lan_automation_stop_and_update_devices', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/lan_automation_update_device.py b/plugins/action/lan_automation_update_device.py new file mode 100644 index 0000000000..30ec6ef880 --- /dev/null +++ b/plugins/action/lan_automation_update_device.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + loopbackUpdateDeviceList=dict(type="list"), + linkUpdate=dict(type="dict"), + hostnameUpdateDevices=dict(type="list"), + feature=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + loopbackUpdateDeviceList=params.get("loopbackUpdateDeviceList"), + linkUpdate=params.get("linkUpdate"), + hostnameUpdateDevices=params.get("hostnameUpdateDevices"), + feature=params.get("feature"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="lan_automation", + function='lan_automation_device_update', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/lan_automation_update_v2.py b/plugins/action/lan_automation_update_v2.py new file mode 100644 index 0000000000..acd4c98120 --- /dev/null +++ b/plugins/action/lan_automation_update_v2.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + payload=dict(type="list"), + id=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + payload=params.get("payload"), + id=params.get("id"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="lan_automation", + function='lan_automation_stop_and_update_devices_v2', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/lan_automation_v2.py b/plugins/action/lan_automation_v2.py new file mode 100644 index 0000000000..2c538a873b --- /dev/null +++ b/plugins/action/lan_automation_v2.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + payload=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + payload=params.get("payload"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="lan_automation", + function='lan_automation_start_v2', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/license_device_license_summary_info.py b/plugins/action/license_device_license_summary_info.py index af82708cae..03544a2bf2 100644 --- a/plugins/action/license_device_license_summary_info.py +++ b/plugins/action/license_device_license_summary_info.py @@ -25,15 +25,15 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - page_number=dict(type="int"), + page_number=dict(type="float"), order=dict(type="str"), sort_by=dict(type="str"), dna_level=dict(type="str"), device_type=dict(type="str"), - limit=dict(type="int"), + limit=dict(type="float"), registration_status=dict(type="str"), virtual_account_name=dict(type="str"), - smart_account_id=dict(type="int"), + smart_account_id=dict(type="str"), device_uuid=dict(type="str"), headers=dict(type="dict"), )) diff --git a/plugins/action/maps_export.py b/plugins/action/maps_export.py new file mode 100644 index 0000000000..108cfd5031 --- /dev/null +++ b/plugins/action/maps_export.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + siteHierarchyUuid=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + site_hierarchy_uuid=params.get("siteHierarchyUuid"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sites", + function='export_map_archive', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/maps_import.py b/plugins/action/maps_import.py new file mode 100644 index 0000000000..de9e4dc2c2 --- /dev/null +++ b/plugins/action/maps_import.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + importContextUuid=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + import_context_uuid=params.get("importContextUuid"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sites", + function="import_map_archive_cancel_an_import", + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/maps_import_perform.py b/plugins/action/maps_import_perform.py new file mode 100644 index 0000000000..e6ab782a08 --- /dev/null +++ b/plugins/action/maps_import_perform.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + importContextUuid=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + import_context_uuid=params.get("importContextUuid"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sites", + function='import_map_archive_perform_import', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/maps_import_start.py b/plugins/action/maps_import_start.py new file mode 100644 index 0000000000..5bc2a1c6c8 --- /dev/null +++ b/plugins/action/maps_import_start.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sites", + function='import_map_archive_start_import', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/maps_import_status_info.py b/plugins/action/maps_import_status_info.py new file mode 100644 index 0000000000..bfb88e7d3d --- /dev/null +++ b/plugins/action/maps_import_status_info.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + importContextUuid=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + import_context_uuid=params.get("importContextUuid"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sites", + function='import_map_archive_import_status', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/maps_supported_access_points_info.py b/plugins/action/maps_supported_access_points_info.py new file mode 100644 index 0000000000..d4d9913876 --- /dev/null +++ b/plugins/action/maps_supported_access_points_info.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sites", + function='maps_supported_access_points', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/netconf_credential.py b/plugins/action/netconf_credential.py index 5ea30373d9..4312a58343 100644 --- a/plugins/action/netconf_credential.py +++ b/plugins/action/netconf_credential.py @@ -95,7 +95,7 @@ def get_object_by_name(self, name): if isinstance(items, dict): if 'response' in items: items = items.get('response') - result = get_dict_result(items, 'description', name) + result = get_dict_result(items, 'description', name) or get_dict_result(items, 'username', name) except Exception: result = None return result @@ -121,7 +121,7 @@ def exists(self): id_exists = False name_exists = False o_id = self.new_object.get("id") - name = self.new_object.get("username") or self.new_object.get("description") + name = self.new_object.get("description") or self.new_object.get("username") if o_id: prev_obj = self.get_object_by_id(o_id) id_exists = prev_obj is not None and isinstance(prev_obj, dict) diff --git a/plugins/action/network_device.py b/plugins/action/network_device.py index 650f0cc827..38a99c6b13 100644 --- a/plugins/action/network_device.py +++ b/plugins/action/network_device.py @@ -56,9 +56,9 @@ snmpUserName=dict(type="str"), snmpVersion=dict(type="str"), type=dict(type="str"), - updateMgmtIPaddressList=dict(type="list"), userName=dict(type="str"), id=dict(type="str"), + updateMgmtIPaddressList=dict(type="list"), cleanConfig=dict(type="bool"), )) @@ -100,9 +100,9 @@ def __init__(self, params, dnac): snmpUserName=params.get("snmpUserName"), snmpVersion=params.get("snmpVersion"), type=params.get("type"), - updateMgmtIPaddressList=params.get("updateMgmtIPaddressList"), userName=params.get("userName"), id=params.get("id"), + updateMgmtIPaddressList=params.get("updateMgmtIPaddressList"), clean_config=params.get("cleanConfig"), managementIpAddress=params.get("managementIpAddress"), ) @@ -188,7 +188,6 @@ def create_params(self): new_object_params['snmpUserName'] = self.new_object.get('snmpUserName') new_object_params['snmpVersion'] = self.new_object.get('snmpVersion') new_object_params['type'] = self.new_object.get('type') - new_object_params['updateMgmtIPaddressList'] = self.new_object.get('updateMgmtIPaddressList') new_object_params['userName'] = self.new_object.get('userName') return new_object_params @@ -316,9 +315,9 @@ def requires_update(self, current_obj): ("snmpUserName", "snmpUserName"), ("snmpVersion", "snmpVersion"), ("type", "type"), - ("updateMgmtIPaddressList", "updateMgmtIPaddressList"), ("userName", "userName"), ("id", "id"), + ("updateMgmtIPaddressList", "updateMgmtIPaddressList"), ("cleanConfig", "clean_config"), ] # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params diff --git a/plugins/action/network_device_config__info.py b/plugins/action/network_device_config__info.py new file mode 100644 index 0000000000..52a1b32534 --- /dev/null +++ b/plugins/action/network_device_config__info.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + deviceId=dict(type="str"), + fileType=dict(type="str"), + createdTime=dict(type="str"), + createdBy=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + device_id=params.get("deviceId"), + file_type=params.get("fileType"), + created_time=params.get("createdTime"), + created_by=params.get("createdBy"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="configuration_archive", + function='get_configuration_archive_details', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/network_device_config_task_info.py b/plugins/action/network_device_config_task_info.py new file mode 100644 index 0000000000..d9231ba352 --- /dev/null +++ b/plugins/action/network_device_config_task_info.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + parentTaskId=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + parent_task_id=params.get("parentTaskId"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="configuration_archive", + function='get_config_task_details', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/network_device_config_write_memory.py b/plugins/action/network_device_config_write_memory.py new file mode 100644 index 0000000000..1f145f04f4 --- /dev/null +++ b/plugins/action/network_device_config_write_memory.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + deviceId=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + deviceId=params.get("deviceId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="configuration_archive", + function='commit_device_configuration', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/network_device_count_info.py b/plugins/action/network_device_count_info.py index b2e2ad364e..79424c86a8 100644 --- a/plugins/action/network_device_count_info.py +++ b/plugins/action/network_device_count_info.py @@ -26,6 +26,10 @@ # Add arguments specific for this module argument_spec.update(dict( deviceId=dict(type="str"), + hostname=dict(type="list"), + managementIpAddress=dict(type="list"), + macAddress=dict(type="list"), + locationName=dict(type="list"), headers=dict(type="dict"), )) @@ -65,6 +69,10 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( device_id=params.get("deviceId"), + hostname=params.get("hostname"), + management_ip_address=params.get("managementIpAddress"), + mac_address=params.get("macAddress"), + location_name=params.get("locationName"), headers=params.get("headers"), ) return new_object diff --git a/plugins/action/network_device_equipment_info.py b/plugins/action/network_device_equipment_info.py index 2365b8a116..96235401fd 100644 --- a/plugins/action/network_device_equipment_info.py +++ b/plugins/action/network_device_equipment_info.py @@ -83,7 +83,7 @@ def run(self, tmp=None, task_vars=None): response = dnac.exec( family="devices", - function='return_power_supply_fan_details_for_the_given_device', + function='get_the_details_of_physical_components_of_the_given_device', params=self.get_object(self._task.args), ) self._result.update(dict(dnac_response=response)) diff --git a/plugins/action/network_device_export.py b/plugins/action/network_device_export.py index ed7447eec7..d130203a2d 100644 --- a/plugins/action/network_device_export.py +++ b/plugins/action/network_device_export.py @@ -26,7 +26,6 @@ # Add arguments specific for this module argument_spec.update(dict( deviceUuids=dict(type="list"), - id=dict(type="str"), operationEnum=dict(type="str"), parameters=dict(type="list"), password=dict(type="str", no_log=True), @@ -68,7 +67,6 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( deviceUuids=params.get("deviceUuids"), - id=params.get("id"), operationEnum=params.get("operationEnum"), parameters=params.get("parameters"), password=params.get("password"), diff --git a/plugins/action/network_device_insight_device_link_info.py b/plugins/action/network_device_insight_device_link_info.py new file mode 100644 index 0000000000..63cdcd94bd --- /dev/null +++ b/plugins/action/network_device_insight_device_link_info.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + siteId=dict(type="str"), + offset=dict(type="int"), + limit=dict(type="int"), + category=dict(type="str"), + sortBy=dict(type="str"), + order=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + site_id=params.get("siteId"), + offset=params.get("offset"), + limit=params.get("limit"), + category=params.get("category"), + sort_by=params.get("sortBy"), + order=params.get("order"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="devices", + function='inventory_insight_device_link_mismatch', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/network_device_ip_address_info.py b/plugins/action/network_device_ip_address_info.py new file mode 100644 index 0000000000..a766c17dc3 --- /dev/null +++ b/plugins/action/network_device_ip_address_info.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + ipAddress=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + ip_address=params.get("ipAddress"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + id = self._task.args.get("ipAddress") + if id: + response = dnac.exec( + family="devices", + function='get_network_device_by_ip', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result + if not id: + # NOTE: Does not have a get all method or it is in another action + response = None + dnac.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/network_device_management_address_update.py b/plugins/action/network_device_management_address_update.py new file mode 100644 index 0000000000..ab9d7c6704 --- /dev/null +++ b/plugins/action/network_device_management_address_update.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + newIP=dict(type="str"), + deviceid=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + newIP=params.get("newIP"), + deviceid=params.get("deviceid"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="devices", + function='update_device_management_address', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/network_device_user_defined_field.py b/plugins/action/network_device_user_defined_field.py index 724221ee90..9f1c83f14c 100644 --- a/plugins/action/network_device_user_defined_field.py +++ b/plugins/action/network_device_user_defined_field.py @@ -75,6 +75,7 @@ def update_by_id_params(self): new_object_params = {} new_object_params['name'] = self.new_object.get('name') new_object_params['description'] = self.new_object.get('description') + new_object_params['id'] = self.new_object.get('id') return new_object_params def get_object_by_name(self, name): diff --git a/plugins/action/network_device_user_defined_field_delete.py b/plugins/action/network_device_user_defined_field_delete.py new file mode 100644 index 0000000000..b1ac8e643f --- /dev/null +++ b/plugins/action/network_device_user_defined_field_delete.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + name=dict(type="str"), + deviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + name=params.get("name"), + device_id=params.get("deviceId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="devices", + function="remove_user_defined_field_from_device", + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/network_device_user_defined_field_update.py b/plugins/action/network_device_user_defined_field_update.py new file mode 100644 index 0000000000..81ffddaaf8 --- /dev/null +++ b/plugins/action/network_device_user_defined_field_update.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + payload=dict(type="list"), + deviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + payload=params.get("payload"), + device_id=params.get("deviceId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="devices", + function='add_user_defined_field_to_device', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/network_devices_interfaces_query.py b/plugins/action/network_devices_interfaces_query.py new file mode 100644 index 0000000000..d5e2d49012 --- /dev/null +++ b/plugins/action/network_devices_interfaces_query.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + startTime=dict(type="int"), + endTime=dict(type="int"), + query=dict(type="dict"), + deviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + startTime=params.get("startTime"), + endTime=params.get("endTime"), + query=params.get("query"), + device_id=params.get("deviceId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="devices", + # No function + # Metadata: {'type': 'c', 'look_by': '', 'urls': ['/dna/intent/api/v2/networkDevices/{deviceId}/interfaces/query'], 'tag': 'Devices', 'version_added': '6.14.0', 'get_all': 'get_device_interface_stats_info', 'operation_id_list': ['get:GetDeviceInterfaceStatsInfo'], 'description': 'get:This API returns the Interface Stats for the given Device Id. Please refer to the Feature tab for the Request Body usage and the API filtering support.\n', 'method_url': 'get:post /dna/intent/api/v2/networkDevices/{deviceId}/interfaces/query,\n'} + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/network_v2.py b/plugins/action/network_v2.py index c1d4d0c1c2..f9087cbf00 100644 --- a/plugins/action/network_v2.py +++ b/plugins/action/network_v2.py @@ -60,11 +60,13 @@ def get_all_params(self, name=None, id=None): def create_params(self): new_object_params = {} new_object_params['settings'] = self.new_object.get('settings') + new_object_params['siteId'] = self.new_object.get('siteId') return new_object_params def update_by_id_params(self): new_object_params = {} new_object_params['settings'] = self.new_object.get('settings') + new_object_params['siteId'] = self.new_object.get('siteId') return new_object_params def get_object_by_name(self, name): diff --git a/plugins/action/path_trace.py b/plugins/action/path_trace.py index 133122616a..ce5793b1fa 100644 --- a/plugins/action/path_trace.py +++ b/plugins/action/path_trace.py @@ -20,6 +20,7 @@ DNACSDK, dnac_argument_spec, dnac_compare_equality, + get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( InconsistentParameters, @@ -117,7 +118,7 @@ def get_object_by_name(self, name): try: items = self.dnac.exec( family="path_trace", - function="retrives_all_previous_pathtraces_summary", + function="retrieves_all_previous_pathtraces_summary", params=self.get_all_params(name=name), ) if isinstance(items, dict): diff --git a/plugins/action/path_trace_info.py b/plugins/action/path_trace_info.py index be9d0dbc26..079046eeb4 100644 --- a/plugins/action/path_trace_info.py +++ b/plugins/action/path_trace_info.py @@ -28,16 +28,16 @@ periodicRefresh=dict(type="bool"), sourceIP=dict(type="str"), destIP=dict(type="str"), - sourcePort=dict(type="str"), - destPort=dict(type="str"), - gtCreateTime=dict(type="str"), - ltCreateTime=dict(type="str"), + sourcePort=dict(type="float"), + destPort=dict(type="float"), + gtCreateTime=dict(type="float"), + ltCreateTime=dict(type="float"), protocol=dict(type="str"), status=dict(type="str"), taskId=dict(type="str"), - lastUpdateTime=dict(type="str"), - limit=dict(type="int"), - offset=dict(type="int"), + lastUpdateTime=dict(type="float"), + limit=dict(type="float"), + offset=dict(type="float"), order=dict(type="str"), sortBy=dict(type="str"), flowAnalysisId=dict(type="str"), @@ -122,7 +122,7 @@ def run(self, tmp=None, task_vars=None): if not id: response = dnac.exec( family="path_trace", - function='retrives_all_previous_pathtraces_summary', + function='retrieves_all_previous_pathtraces_summary', params=self.get_object(self._task.args), ) self._result.update(dict(dnac_response=response)) diff --git a/plugins/action/planned_access_points.py b/plugins/action/planned_access_points.py new file mode 100644 index 0000000000..180b2fea3b --- /dev/null +++ b/plugins/action/planned_access_points.py @@ -0,0 +1,286 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + attributes=dict(type="dict"), + isSensor=dict(type="bool"), + location=dict(type="dict"), + position=dict(type="dict"), + radioCount=dict(type="int"), + radios=dict(type="list"), + floorId=dict(type="str"), + plannedAccessPointUuid=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["floorId", "plannedAccessPointUuid"], True), + ("state", "absent", ["floorId", "plannedAccessPointUuid"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class PlannedAccessPoints(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + attributes=params.get("attributes"), + isSensor=params.get("isSensor"), + location=params.get("location"), + position=params.get("position"), + radioCount=params.get("radioCount"), + radios=params.get("radios"), + floor_id=params.get("floorId"), + planned_access_point_uuid=params.get("plannedAccessPointUuid"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['limit'] = self.new_object.get('limit') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['radios'] = self.new_object.get('radios') + new_object_params['floor_id'] = self.new_object.get('floorId') or \ + self.new_object.get('floor_id') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['attributes'] = self.new_object.get('attributes') + new_object_params['isSensor'] = self.new_object.get('isSensor') + new_object_params['location'] = self.new_object.get('location') + new_object_params['position'] = self.new_object.get('position') + new_object_params['radioCount'] = self.new_object.get('radioCount') + new_object_params['radios'] = self.new_object.get('radios') + new_object_params['floorId'] = self.new_object.get('floorId') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['floor_id'] = self.new_object.get('floor_id') + new_object_params['planned_access_point_uuid'] = self.new_object.get('planned_access_point_uuid') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['attributes'] = self.new_object.get('attributes') + new_object_params['isSensor'] = self.new_object.get('isSensor') + new_object_params['location'] = self.new_object.get('location') + new_object_params['position'] = self.new_object.get('position') + new_object_params['radioCount'] = self.new_object.get('radioCount') + new_object_params['radios'] = self.new_object.get('radios') + new_object_params['floorId'] = self.new_object.get('floorId') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="devices", + function="get_planned_access_points_for_floor", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + except Exception: + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="devices", + function="get_planned_access_points_for_floor", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get("planned_access_point_uuid") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("plannedAccessPointUuid") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(planned_access_point_uuid=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("attributes", "attributes"), + ("isSensor", "isSensor"), + ("location", "location"), + ("position", "position"), + ("radioCount", "radioCount"), + ("radios", "radios"), + ("floorId", "floor_id"), + ("plannedAccessPointUuid", "planned_access_point_uuid"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="devices", + function="create_planned_access_point_for_floor", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.dnac.exec( + family="devices", + function="update_planned_access_point_for_floor", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("planned_access_point_uuid") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("plannedAccessPointUuid") + if id_: + self.new_object.update(dict(planned_access_point_uuid=id_)) + result = self.dnac.exec( + family="devices", + function="delete_planned_access_point_for_floor", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = PlannedAccessPoints(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + response = obj.create() + dnac.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/planned_access_points_info.py b/plugins/action/planned_access_points_info.py index 86cd1a87b4..328bd1c63a 100644 --- a/plugins/action/planned_access_points_info.py +++ b/plugins/action/planned_access_points_info.py @@ -26,8 +26,8 @@ # Add arguments specific for this module argument_spec.update(dict( floorId=dict(type="str"), - limit=dict(type="int"), - offset=dict(type="int"), + limit=dict(type="float"), + offset=dict(type="float"), radios=dict(type="bool"), headers=dict(type="dict"), )) diff --git a/plugins/action/pnp_device.py b/plugins/action/pnp_device.py index ec9c0f36ae..5acf0f3c7c 100644 --- a/plugins/action/pnp_device.py +++ b/plugins/action/pnp_device.py @@ -31,15 +31,7 @@ # Add arguments specific for this module argument_spec.update(dict( state=dict(type="str", default="present", choices=["present", "absent"]), - _id=dict(type="str"), deviceInfo=dict(type="dict"), - runSummaryList=dict(type="list"), - systemResetWorkflow=dict(type="dict"), - systemWorkflow=dict(type="dict"), - tenantId=dict(type="str"), - version=dict(type="int"), - workflow=dict(type="dict"), - workflowParameters=dict(type="dict"), id=dict(type="str"), )) @@ -56,15 +48,7 @@ class PnpDevice(object): def __init__(self, params, dnac): self.dnac = dnac self.new_object = dict( - _id=params.get("_id"), deviceInfo=params.get("deviceInfo"), - runSummaryList=params.get("runSummaryList"), - systemResetWorkflow=params.get("systemResetWorkflow"), - systemWorkflow=params.get("systemWorkflow"), - tenantId=params.get("tenantId"), - version=params.get("version"), - workflow=params.get("workflow"), - workflowParameters=params.get("workflowParameters"), id=params.get("id"), ) @@ -81,17 +65,11 @@ def get_all_params(self, name=None, id=None): self.new_object.get('state') new_object_params['onb_state'] = self.new_object.get('onbState') or \ self.new_object.get('onb_state') - new_object_params['cm_state'] = self.new_object.get('cmState') or \ - self.new_object.get('cm_state') new_object_params['name'] = name or self.new_object.get('name') new_object_params['pid'] = self.new_object.get('pid') new_object_params['source'] = self.new_object.get('source') - new_object_params['project_id'] = self.new_object.get('projectId') or \ - self.new_object.get('project_id') new_object_params['workflow_id'] = self.new_object.get('workflowId') or \ self.new_object.get('workflow_id') - new_object_params['project_name'] = self.new_object.get('projectName') or \ - self.new_object.get('project_name') new_object_params['workflow_name'] = self.new_object.get('workflowName') or \ self.new_object.get('workflow_name') new_object_params['smart_account_id'] = self.new_object.get('smartAccountId') or \ @@ -109,15 +87,7 @@ def get_all_params(self, name=None, id=None): def create_params(self): new_object_params = {} - new_object_params['_id'] = self.new_object.get('_id') new_object_params['deviceInfo'] = self.new_object.get('deviceInfo') - new_object_params['runSummaryList'] = self.new_object.get('runSummaryList') - new_object_params['systemResetWorkflow'] = self.new_object.get('systemResetWorkflow') - new_object_params['systemWorkflow'] = self.new_object.get('systemWorkflow') - new_object_params['tenantId'] = self.new_object.get('tenantId') - new_object_params['version'] = self.new_object.get('version') - new_object_params['workflow'] = self.new_object.get('workflow') - new_object_params['workflowParameters'] = self.new_object.get('workflowParameters') return new_object_params def delete_by_id_params(self): @@ -127,15 +97,8 @@ def delete_by_id_params(self): def update_by_id_params(self): new_object_params = {} - new_object_params['_id'] = self.new_object.get('_id') + new_object_params['id'] = self.new_object.get('id') new_object_params['deviceInfo'] = self.new_object.get('deviceInfo') - new_object_params['runSummaryList'] = self.new_object.get('runSummaryList') - new_object_params['systemResetWorkflow'] = self.new_object.get('systemResetWorkflow') - new_object_params['systemWorkflow'] = self.new_object.get('systemWorkflow') - new_object_params['tenantId'] = self.new_object.get('tenantId') - new_object_params['version'] = self.new_object.get('version') - new_object_params['workflow'] = self.new_object.get('workflow') - new_object_params['workflowParameters'] = self.new_object.get('workflowParameters') new_object_params['id'] = self.new_object.get('id') return new_object_params @@ -206,15 +169,7 @@ def requires_update(self, current_obj): requested_obj = self.new_object obj_params = [ - ("_id", "_id"), ("deviceInfo", "deviceInfo"), - ("runSummaryList", "runSummaryList"), - ("systemResetWorkflow", "systemResetWorkflow"), - ("systemWorkflow", "systemWorkflow"), - ("tenantId", "tenantId"), - ("version", "version"), - ("workflow", "workflow"), - ("workflowParameters", "workflowParameters"), ("id", "id"), ] # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params diff --git a/plugins/action/pnp_device_authorize.py b/plugins/action/pnp_device_authorize.py index 2e6f18aca4..140b06bf8f 100644 --- a/plugins/action/pnp_device_authorize.py +++ b/plugins/action/pnp_device_authorize.py @@ -76,7 +76,7 @@ def run(self, tmp=None, task_vars=None): dnac = DNACSDK(params=self._task.args) response = dnac.exec( - family="cisco_dna_center_system", + family="device_onboarding_pnp", function='authorize_device', op_modifies=True, params=self.get_object(self._task.args), diff --git a/plugins/action/pnp_device_claim_to_site.py b/plugins/action/pnp_device_claim_to_site.py index 6bceab4a17..33e1ccb034 100644 --- a/plugins/action/pnp_device_claim_to_site.py +++ b/plugins/action/pnp_device_claim_to_site.py @@ -34,8 +34,8 @@ staticIP=dict(type="str"), subnetMask=dict(type="str"), gateway=dict(type="str"), - vlanID=dict(type="str"), - interfaceName=dict(type="str"), + vlanId=dict(type="str"), + ipInterfaceName=dict(type="str"), sensorProfile=dict(type="str"), )) @@ -83,8 +83,8 @@ def get_object(self, params): staticIP=params.get("staticIP"), subnetMask=params.get("subnetMask"), gateway=params.get("gateway"), - vlanID=params.get("vlanID"), - interfaceName=params.get("interfaceName"), + vlanId=params.get("vlanId"), + ipInterfaceName=params.get("ipInterfaceName"), sensorProfile=params.get("sensorProfile"), ) return new_object diff --git a/plugins/action/pnp_device_count_info.py b/plugins/action/pnp_device_count_info.py index 933b8bd0ca..a43bf56827 100644 --- a/plugins/action/pnp_device_count_info.py +++ b/plugins/action/pnp_device_count_info.py @@ -28,13 +28,10 @@ serialNumber=dict(type="list"), state_=dict(type="list"), onbState=dict(type="list"), - cmState=dict(type="list"), name=dict(type="list"), pid=dict(type="list"), source=dict(type="list"), - projectId=dict(type="list"), workflowId=dict(type="list"), - projectName=dict(type="list"), workflowName=dict(type="list"), smartAccountId=dict(type="list"), virtualAccountId=dict(type="list"), @@ -80,13 +77,10 @@ def get_object(self, params): serial_number=params.get("serialNumber"), state=params.get("state_"), onb_state=params.get("onbState"), - cm_state=params.get("cmState"), name=params.get("name"), pid=params.get("pid"), source=params.get("source"), - project_id=params.get("projectId"), workflow_id=params.get("workflowId"), - project_name=params.get("projectName"), workflow_name=params.get("workflowName"), smart_account_id=params.get("smartAccountId"), virtual_account_id=params.get("virtualAccountId"), diff --git a/plugins/action/pnp_device_info.py b/plugins/action/pnp_device_info.py index 529736179f..b0d567c208 100644 --- a/plugins/action/pnp_device_info.py +++ b/plugins/action/pnp_device_info.py @@ -32,13 +32,10 @@ serialNumber=dict(type="list"), state_=dict(type="list"), onbState=dict(type="list"), - cmState=dict(type="list"), name=dict(type="list"), pid=dict(type="list"), source=dict(type="list"), - projectId=dict(type="list"), workflowId=dict(type="list"), - projectName=dict(type="list"), workflowName=dict(type="list"), smartAccountId=dict(type="list"), virtualAccountId=dict(type="list"), @@ -92,13 +89,10 @@ def get_object(self, params): serial_number=params.get("serialNumber"), state=params.get("state_"), onb_state=params.get("onbState"), - cm_state=params.get("cmState"), name=params.get("name"), pid=params.get("pid"), source=params.get("source"), - project_id=params.get("projectId"), workflow_id=params.get("workflowId"), - project_name=params.get("projectName"), workflow_name=params.get("workflowName"), smart_account_id=params.get("smartAccountId"), virtual_account_id=params.get("virtualAccountId"), diff --git a/plugins/action/pnp_global_settings.py b/plugins/action/pnp_global_settings.py index 681e25e204..7cd5247223 100644 --- a/plugins/action/pnp_global_settings.py +++ b/plugins/action/pnp_global_settings.py @@ -20,6 +20,10 @@ DNACSDK, dnac_argument_spec, dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, ) # Get common arguments specification diff --git a/plugins/action/pnp_server_profile_update.py b/plugins/action/pnp_server_profile_update.py index 209812d6db..2414b69b8c 100644 --- a/plugins/action/pnp_server_profile_update.py +++ b/plugins/action/pnp_server_profile_update.py @@ -25,19 +25,10 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - autoSyncPeriod=dict(type="int"), - ccoUser=dict(type="str"), - expiry=dict(type="int"), - lastSync=dict(type="int"), - profile=dict(type="dict"), smartAccountId=dict(type="str"), - syncResult=dict(type="dict"), - syncResultStr=dict(type="str"), - syncStartTime=dict(type="int"), - syncStatus=dict(type="str"), - tenantId=dict(type="str"), - token=dict(type="str"), virtualAccountId=dict(type="str"), + profile=dict(type="dict"), + ccoUser=dict(type="str"), )) required_if = [] @@ -75,19 +66,10 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( - autoSyncPeriod=params.get("autoSyncPeriod"), - ccoUser=params.get("ccoUser"), - expiry=params.get("expiry"), - lastSync=params.get("lastSync"), - profile=params.get("profile"), smartAccountId=params.get("smartAccountId"), - syncResult=params.get("syncResult"), - syncResultStr=params.get("syncResultStr"), - syncStartTime=params.get("syncStartTime"), - syncStatus=params.get("syncStatus"), - tenantId=params.get("tenantId"), - token=params.get("token"), virtualAccountId=params.get("virtualAccountId"), + profile=params.get("profile"), + ccoUser=params.get("ccoUser"), ) return new_object diff --git a/plugins/action/pnp_workflow.py b/plugins/action/pnp_workflow.py index 7a42ea0d9e..868106c710 100644 --- a/plugins/action/pnp_workflow.py +++ b/plugins/action/pnp_workflow.py @@ -149,6 +149,7 @@ def update_by_id_params(self): new_object_params['useState'] = self.new_object.get('useState') new_object_params['version'] = self.new_object.get('version') new_object_params['id'] = self.new_object.get('id') + new_object_params['id'] = self.new_object.get('id') return new_object_params def get_object_by_name(self, name): diff --git a/plugins/action/reports.py b/plugins/action/reports.py index 28f656870e..decf205458 100644 --- a/plugins/action/reports.py +++ b/plugins/action/reports.py @@ -38,6 +38,7 @@ view=dict(type="dict"), viewGroupId=dict(type="str"), viewGroupVersion=dict(type="str"), + dataCategory=dict(type="str"), reportId=dict(type="str"), )) @@ -61,6 +62,7 @@ def __init__(self, params, dnac): view=params.get("view"), viewGroupId=params.get("viewGroupId"), viewGroupVersion=params.get("viewGroupVersion"), + dataCategory=params.get("dataCategory"), report_id=params.get("reportId"), ) @@ -80,6 +82,7 @@ def create_params(self): new_object_params['view'] = self.new_object.get('view') new_object_params['viewGroupId'] = self.new_object.get('viewGroupId') new_object_params['viewGroupVersion'] = self.new_object.get('viewGroupVersion') + new_object_params['dataCategory'] = self.new_object.get('dataCategory') return new_object_params def delete_by_id_params(self): @@ -157,6 +160,7 @@ def requires_update(self, current_obj): ("view", "view"), ("viewGroupId", "viewGroupId"), ("viewGroupVersion", "viewGroupVersion"), + ("dataCategory", "dataCategory"), ("reportId", "report_id"), ] # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params diff --git a/plugins/action/reserve_ip_subpool.py b/plugins/action/reserve_ip_subpool.py index 22ea8edae3..152438824c 100644 --- a/plugins/action/reserve_ip_subpool.py +++ b/plugins/action/reserve_ip_subpool.py @@ -98,6 +98,12 @@ def get_all_params(self, name=None, id=None): self.new_object.get('site_id') new_object_params['offset'] = self.new_object.get('offset') new_object_params['limit'] = self.new_object.get('limit') + new_object_params['ignore_inherited_groups'] = self.new_object.get('ignoreInheritedGroups') or \ + self.new_object.get('ignore_inherited_groups') + new_object_params['pool_usage'] = self.new_object.get('poolUsage') or \ + self.new_object.get('pool_usage') + new_object_params['group_name'] = self.new_object.get('groupName') or \ + self.new_object.get('group_name') return new_object_params def create_params(self): @@ -122,6 +128,7 @@ def create_params(self): new_object_params['ipv4TotalHost'] = self.new_object.get('ipv4TotalHost') new_object_params['ipv6TotalHost'] = self.new_object.get('ipv6TotalHost') new_object_params['slaacSupport'] = self.new_object.get('slaacSupport') + new_object_params['siteId'] = self.new_object.get('siteId') new_object_params['site_id'] = self.new_object.get('site_id') return new_object_params @@ -140,12 +147,13 @@ def update_by_id_params(self): new_object_params['ipv6Prefix'] = self.new_object.get('ipv6Prefix') new_object_params['ipv6PrefixLength'] = self.new_object.get('ipv6PrefixLength') new_object_params['ipv6Subnet'] = self.new_object.get('ipv6Subnet') + new_object_params['ipv6TotalHost'] = self.new_object.get('ipv6TotalHost') new_object_params['ipv6GateWay'] = self.new_object.get('ipv6GateWay') new_object_params['ipv6DhcpServers'] = self.new_object.get('ipv6DhcpServers') new_object_params['ipv6DnsServers'] = self.new_object.get('ipv6DnsServers') - new_object_params['ipv6TotalHost'] = self.new_object.get('ipv6TotalHost') new_object_params['slaacSupport'] = self.new_object.get('slaacSupport') new_object_params['ipv4GateWay'] = self.new_object.get('ipv4GateWay') + new_object_params['siteId'] = self.new_object.get('siteId') new_object_params['id'] = self.new_object.get('id') new_object_params['site_id'] = self.new_object.get('site_id') return new_object_params diff --git a/plugins/action/reserve_ip_subpool_info.py b/plugins/action/reserve_ip_subpool_info.py index c704db1ef9..bcf946a930 100644 --- a/plugins/action/reserve_ip_subpool_info.py +++ b/plugins/action/reserve_ip_subpool_info.py @@ -26,8 +26,11 @@ # Add arguments specific for this module argument_spec.update(dict( siteId=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), + ignoreInheritedGroups=dict(type="str"), + poolUsage=dict(type="str"), + groupName=dict(type="str"), headers=dict(type="dict"), )) @@ -69,6 +72,9 @@ def get_object(self, params): site_id=params.get("siteId"), offset=params.get("offset"), limit=params.get("limit"), + ignore_inherited_groups=params.get("ignoreInheritedGroups"), + pool_usage=params.get("poolUsage"), + group_name=params.get("groupName"), headers=params.get("headers"), ) return new_object diff --git a/plugins/action/reserve_ip_subpool_update.py b/plugins/action/reserve_ip_subpool_update.py index 4d2f8bf582..c3ef0accc3 100644 --- a/plugins/action/reserve_ip_subpool_update.py +++ b/plugins/action/reserve_ip_subpool_update.py @@ -33,10 +33,10 @@ ipv6Prefix=dict(type="bool"), ipv6PrefixLength=dict(type="int"), ipv6Subnet=dict(type="str"), + ipv6TotalHost=dict(type="int"), ipv6GateWay=dict(type="str"), ipv6DhcpServers=dict(type="list"), ipv6DnsServers=dict(type="list"), - ipv6TotalHost=dict(type="int"), slaacSupport=dict(type="bool"), ipv4GateWay=dict(type="str"), siteId=dict(type="str"), @@ -86,10 +86,10 @@ def get_object(self, params): ipv6Prefix=params.get("ipv6Prefix"), ipv6PrefixLength=params.get("ipv6PrefixLength"), ipv6Subnet=params.get("ipv6Subnet"), + ipv6TotalHost=params.get("ipv6TotalHost"), ipv6GateWay=params.get("ipv6GateWay"), ipv6DhcpServers=params.get("ipv6DhcpServers"), ipv6DnsServers=params.get("ipv6DnsServers"), - ipv6TotalHost=params.get("ipv6TotalHost"), slaacSupport=params.get("slaacSupport"), ipv4GateWay=params.get("ipv4GateWay"), site_id=params.get("siteId"), diff --git a/plugins/action/roles.py b/plugins/action/roles.py new file mode 100644 index 0000000000..38b6ba42ae --- /dev/null +++ b/plugins/action/roles.py @@ -0,0 +1,262 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + role=dict(type="str"), + description=dict(type="str"), + resourceTypes=dict(type="list"), + roleId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["role", "roleId"], True), + ("state", "absent", ["role", "roleId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class Roles(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + role=params.get("role"), + description=params.get("description"), + resourceTypes=params.get("resourceTypes"), + roleId=params.get("roleId"), + role_id=params.get("roleId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['role'] = self.new_object.get('role') + new_object_params['description'] = self.new_object.get('description') + new_object_params['resourceTypes'] = self.new_object.get('resourceTypes') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['role_id'] = self.new_object.get('role_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['roleId'] = self.new_object.get('roleId') + new_object_params['description'] = self.new_object.get('description') + new_object_params['resourceTypes'] = self.new_object.get('resourceTypes') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="userand_roles", + function="get_roles_api", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + except Exception: + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="userand_roles", + function="get_roles_api", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get("role_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("roleId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(role_id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("role", "role"), + ("description", "description"), + ("resourceTypes", "resourceTypes"), + ("roleId", "roleId"), + ("roleId", "role_id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="userand_roles", + function="add_role_api", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.dnac.exec( + family="userand_roles", + function="update_role_api", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("role_id") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("roleId") + if id_: + self.new_object.update(dict(role_id=id_)) + result = self.dnac.exec( + family="userand_roles", + function="delete_role_api", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = Roles(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + response = obj.create() + dnac.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_anycast_gateways.py b/plugins/action/sda_anycast_gateways.py new file mode 100644 index 0000000000..15cdd3d3d2 --- /dev/null +++ b/plugins/action/sda_anycast_gateways.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, + AnsibleSDAException, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id"], True), + ("state", "present", ["payload"], True), + ("state", "absent", ["id"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class SdaAnycastGateways(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['id'] = id or self.new_object.get('id') + new_object_params['fabric_id'] = self.new_object.get('fabricId') or \ + self.new_object.get('fabric_id') + new_object_params['virtual_network_name'] = self.new_object.get('virtualNetworkName') or \ + self.new_object.get('virtual_network_name') + new_object_params['ip_pool_name'] = self.new_object.get('ipPoolName') or \ + self.new_object.get('ip_pool_name') + new_object_params['vlan_name'] = self.new_object.get('vlanName') or \ + self.new_object.get('vlan_name') + new_object_params['vlan_id'] = self.new_object.get('vlanId') or \ + self.new_object.get('vlan_id') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def get_object_by_name(self, name, is_absent=False): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_anycast_gateways", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + if isinstance(items, dict) and items.get("status") == "failed": + if is_absent: + raise AnsibleSDAException(response=items) + result = None + return result + result = get_dict_result(items, 'name', name) + except Exception: + if is_absent: + raise + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_anycast_gateways", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self, is_absent=False): + name = self.new_object.get("name") + prev_obj = self.get_object_by_name(name, is_absent=is_absent) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("id", "id"), + ("fabricId", "fabricId"), + ("virtualNetworkName", "virtualNetworkName"), + ("ipPoolName", "ipPoolName"), + ("tcpMssAdjustment", "tcpMssAdjustment"), + ("vlanName", "vlanName"), + ("vlanId", "vlanId"), + ("trafficType", "trafficType"), + ("poolType", "poolType"), + ("securityGroupName", "securityGroupName"), + ("isCriticalPool", "isCriticalPool"), + ("isLayer2FloodingEnabled", "isLayer2FloodingEnabled"), + ("isWirelessPool", "isWirelessPool"), + ("isIpDirectedBroadcast", "isIpDirectedBroadcast"), + ("isIntraSubnetRoutingEnabled", "isIntraSubnetRoutingEnabled"), + ("isMultipleIpToMacAddresses", "isMultipleIpToMacAddresses"), + ("isSupplicantBasedExtendedNodeOnboarding", "isSupplicantBasedExtendedNodeOnboarding"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="sda", + function="add_anycast_gateways", + params=self.create_params(), + op_modifies=True, + ) + if isinstance(result, dict): + if 'response' in result: + result = result.get('response') + if isinstance(result, dict) and result.get("status") == "failed": + raise AnsibleSDAException(response=result) + return result + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="sda", + function="update_anycast_gateways", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="sda", + function="delete_anycast_gateway_by_id", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = SdaAnycastGateways(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + try: + response = obj.create() + dnac.object_created() + except AnsibleSDAException as e: + dnac.fail_json("Could not create object {e}".format(e=e._response)) + + elif state == "absent": + try: + (obj_exists, prev_obj) = obj.exists(is_absent=True) + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + except AnsibleSDAException as e: + dnac.fail_json("Could not get object to be delete {e}".format(e=e._response)) + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_anycast_gateways_count_info.py b/plugins/action/sda_anycast_gateways_count_info.py new file mode 100644 index 0000000000..f33187d702 --- /dev/null +++ b/plugins/action/sda_anycast_gateways_count_info.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + virtualNetworkName=dict(type="str"), + ipPoolName=dict(type="str"), + vlanName=dict(type="str"), + vlanId=dict(type="int"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + virtual_network_name=params.get("virtualNetworkName"), + ip_pool_name=params.get("ipPoolName"), + vlan_name=params.get("vlanName"), + vlan_id=params.get("vlanId"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_anycast_gateway_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_anycast_gateways_info.py b/plugins/action/sda_anycast_gateways_info.py new file mode 100644 index 0000000000..7e13dde41f --- /dev/null +++ b/plugins/action/sda_anycast_gateways_info.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + id=dict(type="str"), + fabricId=dict(type="str"), + virtualNetworkName=dict(type="str"), + ipPoolName=dict(type="str"), + vlanName=dict(type="str"), + vlanId=dict(type="int"), + offset=dict(type="int"), + limit=dict(type="int"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + id=params.get("id"), + fabric_id=params.get("fabricId"), + virtual_network_name=params.get("virtualNetworkName"), + ip_pool_name=params.get("ipPoolName"), + vlan_name=params.get("vlanName"), + vlan_id=params.get("vlanId"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_anycast_gateways', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_authentication_profiles.py b/plugins/action/sda_authentication_profiles.py new file mode 100644 index 0000000000..73a6176686 --- /dev/null +++ b/plugins/action/sda_authentication_profiles.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, + AnsibleSDAException, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + payload=dict(type="list"), +)) + +required_if = [ + ("state", "present", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class SdaAuthenticationProfiles(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['fabric_id'] = self.new_object.get('fabricId') or \ + self.new_object.get('fabric_id') + new_object_params['authentication_profile_name'] = self.new_object.get('authenticationProfileName') or \ + self.new_object.get('authentication_profile_name') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def get_object_by_name(self, name, is_absent=False): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.dnac.exec( + family="sda", + function="get_authentication_profiles", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + if isinstance(items, dict) and items.get("status") == "failed": + if is_absent: + raise AnsibleSDAException(response=items) + result = None + return result + result = get_dict_result(items, 'name', name) + except Exception: + if is_absent: + raise + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self, is_absent=False): + name = self.new_object.get("name") + prev_obj = self.get_object_by_name(name, is_absent=is_absent) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("id", "id"), + ("fabricId", "fabricId"), + ("authenticationProfileName", "authenticationProfileName"), + ("authenticationOrder", "authenticationOrder"), + ("dot1xToMabFallbackTimeout", "dot1xToMabFallbackTimeout"), + ("wakeOnLan", "wakeOnLan"), + ("numberOfHosts", "numberOfHosts"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="sda", + function="update_authentication_profile", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = SdaAuthenticationProfiles(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + dnac.fail_json("Object does not exists, plugin only has update") + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_authentication_profiles_info.py b/plugins/action/sda_authentication_profiles_info.py new file mode 100644 index 0000000000..cb7a4a143a --- /dev/null +++ b/plugins/action/sda_authentication_profiles_info.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + authenticationProfileName=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + authentication_profile_name=params.get("authenticationProfileName"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_authentication_profiles', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_extranet_policies.py b/plugins/action/sda_extranet_policies.py new file mode 100644 index 0000000000..e83a322570 --- /dev/null +++ b/plugins/action/sda_extranet_policies.py @@ -0,0 +1,267 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, + AnsibleSDAException, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id"], True), + ("state", "present", ["payload"], True), + ("state", "absent", ["id"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class SdaExtranetPolicies(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['extranet_policy_name'] = self.new_object.get('extranetPolicyName') or \ + self.new_object.get('extranet_policy_name') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def get_object_by_name(self, name, is_absent=False): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_extranet_policies", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + if isinstance(items, dict) and items.get("status") == "failed": + if is_absent: + raise AnsibleSDAException(response=items) + result = None + return result + result = get_dict_result(items, 'name', name) + except Exception: + if is_absent: + raise + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_extranet_policies", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self, is_absent=False): + name = self.new_object.get("name") + prev_obj = self.get_object_by_name(name, is_absent=is_absent) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("id", "id"), + ("extranetPolicyName", "extranetPolicyName"), + ("fabricIds", "fabricIds"), + ("providerVirtualNetworkName", "providerVirtualNetworkName"), + ("subscriberVirtualNetworkNames", "subscriberVirtualNetworkNames"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="sda", + function="add_extranet_policy", + params=self.create_params(), + op_modifies=True, + ) + if isinstance(result, dict): + if 'response' in result: + result = result.get('response') + if isinstance(result, dict) and result.get("status") == "failed": + raise AnsibleSDAException(response=result) + return result + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="sda", + function="update_extranet_policy", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="sda", + function="delete_extranet_policy_by_id", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = SdaExtranetPolicies(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + try: + response = obj.create() + dnac.object_created() + except AnsibleSDAException as e: + dnac.fail_json("Could not create object {e}".format(e=e._response)) + + elif state == "absent": + try: + (obj_exists, prev_obj) = obj.exists(is_absent=True) + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + except AnsibleSDAException as e: + dnac.fail_json("Could not get object to be delete {e}".format(e=e._response)) + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_extranet_policies_count_info.py b/plugins/action/sda_extranet_policies_count_info.py new file mode 100644 index 0000000000..b880f0edda --- /dev/null +++ b/plugins/action/sda_extranet_policies_count_info.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_extranet_policy_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_extranet_policies_info.py b/plugins/action/sda_extranet_policies_info.py new file mode 100644 index 0000000000..ebb3b4e121 --- /dev/null +++ b/plugins/action/sda_extranet_policies_info.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + extranetPolicyName=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + extranet_policy_name=params.get("extranetPolicyName"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_extranet_policies', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_authentication_profile.py b/plugins/action/sda_fabric_authentication_profile.py index 91a1f3ae5a..f367da227a 100644 --- a/plugins/action/sda_fabric_authentication_profile.py +++ b/plugins/action/sda_fabric_authentication_profile.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) @@ -37,6 +38,7 @@ required_if = [ ("state", "present", ["payload"], True), + ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] @@ -159,8 +161,11 @@ def update(self): return result def delete(self): - id = self.new_object.get("id") - name = self.new_object.get("name") + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") result = None result = self.dnac.exec( family="sda", diff --git a/plugins/action/sda_fabric_border_device.py b/plugins/action/sda_fabric_border_device.py index ab907f8088..31cf6e9160 100644 --- a/plugins/action/sda_fabric_border_device.py +++ b/plugins/action/sda_fabric_border_device.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) @@ -37,6 +38,7 @@ required_if = [ ("state", "present", ["payload"], True), + ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] @@ -144,8 +146,11 @@ def create(self): return result def delete(self): - id = self.new_object.get("id") - name = self.new_object.get("name") + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") result = None result = self.dnac.exec( family="sda", diff --git a/plugins/action/sda_fabric_control_plane_device.py b/plugins/action/sda_fabric_control_plane_device.py index c2df756d5a..1bb2fd0716 100644 --- a/plugins/action/sda_fabric_control_plane_device.py +++ b/plugins/action/sda_fabric_control_plane_device.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_fabric_devices.py b/plugins/action/sda_fabric_devices.py new file mode 100644 index 0000000000..810ebca76f --- /dev/null +++ b/plugins/action/sda_fabric_devices.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, + AnsibleSDAException, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + deviceRoles=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id"], True), + ("state", "present", ["payload"], True), + ("state", "absent", ["id"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class SdaFabricDevices(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + device_roles=params.get("deviceRoles"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['fabric_id'] = self.new_object.get('fabricId') or \ + self.new_object.get('fabric_id') + new_object_params['network_device_id'] = self.new_object.get('networkDeviceId') or \ + self.new_object.get('network_device_id') + new_object_params['device_roles'] = self.new_object.get('deviceRoles') or \ + self.new_object.get('device_roles') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def get_object_by_name(self, name, is_absent=False): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_devices", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + if isinstance(items, dict) and items.get("status") == "failed": + if is_absent: + raise AnsibleSDAException(response=items) + result = None + return result + result = get_dict_result(items, 'name', name) + except Exception: + if is_absent: + raise + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_devices", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self, is_absent=False): + name = self.new_object.get("name") + prev_obj = self.get_object_by_name(name, is_absent=is_absent) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("id", "id"), + ("networkDeviceId", "networkDeviceId"), + ("fabricId", "fabricId"), + ("deviceRoles", "deviceRoles"), + ("borderDeviceSettings", "borderDeviceSettings"), + ("fabricId", "fabric_id"), + ("networkDeviceId", "network_device_id"), + ("deviceRoles", "device_roles"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="sda", + function="add_fabric_devices", + params=self.create_params(), + op_modifies=True, + ) + if isinstance(result, dict): + if 'response' in result: + result = result.get('response') + if isinstance(result, dict) and result.get("status") == "failed": + raise AnsibleSDAException(response=result) + return result + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="sda", + function="update_fabric_devices", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="sda", + function="delete_a_fabric_device_by_id", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = SdaFabricDevices(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + try: + response = obj.create() + dnac.object_created() + except AnsibleSDAException as e: + dnac.fail_json("Could not create object {e}".format(e=e._response)) + + elif state == "absent": + try: + (obj_exists, prev_obj) = obj.exists(is_absent=True) + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + except AnsibleSDAException as e: + dnac.fail_json("Could not get object to be delete {e}".format(e=e._response)) + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_devices_count_info.py b/plugins/action/sda_fabric_devices_count_info.py new file mode 100644 index 0000000000..f61f179faf --- /dev/null +++ b/plugins/action/sda_fabric_devices_count_info.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + deviceRoles=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + device_roles=params.get("deviceRoles"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_devices_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_devices_info.py b/plugins/action/sda_fabric_devices_info.py new file mode 100644 index 0000000000..503be554a2 --- /dev/null +++ b/plugins/action/sda_fabric_devices_info.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + deviceRoles=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + device_roles=params.get("deviceRoles"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_devices', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs.py b/plugins/action/sda_fabric_devices_layer2_handoffs.py new file mode 100644 index 0000000000..284e0c4606 --- /dev/null +++ b/plugins/action/sda_fabric_devices_layer2_handoffs.py @@ -0,0 +1,265 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, + AnsibleSDAException, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id"], True), + ("state", "present", ["payload"], True), + ("state", "absent", ["id"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class SdaFabricDevicesLayer2Handoffs(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['fabric_id'] = self.new_object.get('fabricId') or \ + self.new_object.get('fabric_id') + new_object_params['network_device_id'] = self.new_object.get('networkDeviceId') or \ + self.new_object.get('network_device_id') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def get_object_by_name(self, name, is_absent=False): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_devices_layer2_handoffs", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + if isinstance(items, dict) and items.get("status") == "failed": + if is_absent: + raise AnsibleSDAException(response=items) + result = None + return result + result = get_dict_result(items, 'name', name) + except Exception: + if is_absent: + raise + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_devices_layer2_handoffs", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self, is_absent=False): + name = self.new_object.get("name") + prev_obj = self.get_object_by_name(name, is_absent=is_absent) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("networkDeviceId", "networkDeviceId"), + ("fabricId", "fabricId"), + ("interfaceName", "interfaceName"), + ("internalVlanId", "internalVlanId"), + ("externalVlanId", "externalVlanId"), + ("fabricId", "fabric_id"), + ("networkDeviceId", "network_device_id"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="sda", + function="add_fabric_devices_layer2_handoffs", + params=self.create_params(), + op_modifies=True, + ) + if isinstance(result, dict): + if 'response' in result: + result = result.get('response') + if isinstance(result, dict) and result.get("status") == "failed": + raise AnsibleSDAException(response=result) + return result + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + # NOTE: Does not have update method. What do we do? + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="sda", + function="delete_fabric_device_layer2_handoff_by_id", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = SdaFabricDevicesLayer2Handoffs(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + try: + response = obj.create() + dnac.object_created() + except AnsibleSDAException as e: + dnac.fail_json("Could not create object {e}".format(e=e._response)) + + elif state == "absent": + try: + (obj_exists, prev_obj) = obj.exists(is_absent=True) + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + except AnsibleSDAException as e: + dnac.fail_json("Could not get object to be delete {e}".format(e=e._response)) + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs_count_info.py b/plugins/action/sda_fabric_devices_layer2_handoffs_count_info.py new file mode 100644 index 0000000000..60d88025bd --- /dev/null +++ b/plugins/action/sda_fabric_devices_layer2_handoffs_count_info.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_devices_layer2_handoffs_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs_info.py b/plugins/action/sda_fabric_devices_layer2_handoffs_info.py new file mode 100644 index 0000000000..fd3e8f8f81 --- /dev/null +++ b/plugins/action/sda_fabric_devices_layer2_handoffs_info.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_devices_layer2_handoffs', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits.py b/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits.py new file mode 100644 index 0000000000..67469c79fc --- /dev/null +++ b/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits.py @@ -0,0 +1,283 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, + AnsibleSDAException, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id"], True), + ("state", "present", ["payload"], True), + ("state", "absent", ["id"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class SdaFabricDevicesLayer2HandoffsIpTransits(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['fabric_id'] = self.new_object.get('fabricId') or \ + self.new_object.get('fabric_id') + new_object_params['network_device_id'] = self.new_object.get('networkDeviceId') or \ + self.new_object.get('network_device_id') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def get_object_by_name(self, name, is_absent=False): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_devices_layer3_handoffs_with_ip_transit", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + if isinstance(items, dict) and items.get("status") == "failed": + if is_absent: + raise AnsibleSDAException(response=items) + result = None + return result + result = get_dict_result(items, 'name', name) + except Exception: + if is_absent: + raise + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_devices_layer3_handoffs_with_ip_transit", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self, is_absent=False): + name = self.new_object.get("name") + prev_obj = self.get_object_by_name(name, is_absent=is_absent) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("id", "id"), + ("networkDeviceId", "networkDeviceId"), + ("fabricId", "fabricId"), + ("transitNetworkId", "transitNetworkId"), + ("interfaceName", "interfaceName"), + ("externalConnectivityIpPoolName", "externalConnectivityIpPoolName"), + ("virtualNetworkName", "virtualNetworkName"), + ("vlanId", "vlanId"), + ("tcpMssAdjustment", "tcpMssAdjustment"), + ("localIpAddress", "localIpAddress"), + ("remoteIpAddress", "remoteIpAddress"), + ("localIpv6Address", "localIpv6Address"), + ("remoteIpv6Address", "remoteIpv6Address"), + ("fabricId", "fabric_id"), + ("networkDeviceId", "network_device_id"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="sda", + function="add_fabric_devices_layer3_handoffs_with_ip_transit", + params=self.create_params(), + op_modifies=True, + ) + if isinstance(result, dict): + if 'response' in result: + result = result.get('response') + if isinstance(result, dict) and result.get("status") == "failed": + raise AnsibleSDAException(response=result) + return result + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="sda", + function="update_fabric_devices_layer3_handoffs_with_ip_transit", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="sda", + function="delete_fabric_device_layer3_handoff_with_ip_transit_by_id", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = SdaFabricDevicesLayer2HandoffsIpTransits(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + try: + response = obj.create() + dnac.object_created() + except AnsibleSDAException as e: + dnac.fail_json("Could not create object {e}".format(e=e._response)) + + elif state == "absent": + try: + (obj_exists, prev_obj) = obj.exists(is_absent=True) + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + except AnsibleSDAException as e: + dnac.fail_json("Could not get object to be delete {e}".format(e=e._response)) + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py b/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py new file mode 100644 index 0000000000..bab5146752 --- /dev/null +++ b/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_devices_layer3_handoffs_with_ip_transit_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits_info.py b/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits_info.py new file mode 100644 index 0000000000..dd843a5001 --- /dev/null +++ b/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits_info.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_devices_layer3_handoffs_with_ip_transit', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits.py b/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits.py new file mode 100644 index 0000000000..46c1f73fcc --- /dev/null +++ b/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, + AnsibleSDAException, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["payload"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class SdaFabricDevicesLayer2HandoffsSdaTransits(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['fabric_id'] = self.new_object.get('fabricId') or \ + self.new_object.get('fabric_id') + new_object_params['network_device_id'] = self.new_object.get('networkDeviceId') or \ + self.new_object.get('network_device_id') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_all_params(self): + new_object_params = {} + new_object_params['fabric_id'] = self.new_object.get('fabric_id') + new_object_params['network_device_id'] = self.new_object.get('network_device_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def get_object_by_name(self, name, is_absent=False): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_devices_layer3_handoffs_with_sda_transit", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + if isinstance(items, dict) and items.get("status") == "failed": + if is_absent: + raise AnsibleSDAException(response=items) + result = None + return result + result = get_dict_result(items, 'name', name) + except Exception: + if is_absent: + raise + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_devices_layer3_handoffs_with_sda_transit", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self, is_absent=False): + name = self.new_object.get("name") + prev_obj = self.get_object_by_name(name, is_absent=is_absent) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("networkDeviceId", "networkDeviceId"), + ("fabricId", "fabricId"), + ("transitNetworkId", "transitNetworkId"), + ("affinityIdPrime", "affinityIdPrime"), + ("affinityIdDecider", "affinityIdDecider"), + ("connectedToInternet", "connectedToInternet"), + ("isMulticastOverTransitEnabled", "isMulticastOverTransitEnabled"), + ("fabricId", "fabric_id"), + ("networkDeviceId", "network_device_id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="sda", + function="add_fabric_devices_layer3_handoffs_with_sda_transit", + params=self.create_params(), + op_modifies=True, + ) + if isinstance(result, dict): + if 'response' in result: + result = result.get('response') + if isinstance(result, dict) and result.get("status") == "failed": + raise AnsibleSDAException(response=result) + return result + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="sda", + function="update_fabric_devices_layer3_handoffs_with_sda_transit", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="sda", + function="delete_fabric_device_layer3_handoffs_with_sda_transit", + params=self.delete_all_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = SdaFabricDevicesLayer2HandoffsSdaTransits(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + try: + response = obj.create() + dnac.object_created() + except AnsibleSDAException as e: + dnac.fail_json("Could not create object {e}".format(e=e._response)) + + elif state == "absent": + try: + (obj_exists, prev_obj) = obj.exists(is_absent=True) + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + except AnsibleSDAException as e: + dnac.fail_json("Could not get object to be delete {e}".format(e=e._response)) + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py b/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py new file mode 100644 index 0000000000..4a46b53b5d --- /dev/null +++ b/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_devices_layer3_handoffs_with_sda_transit_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits_info.py b/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits_info.py new file mode 100644 index 0000000000..556e656c6d --- /dev/null +++ b/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits_info.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_devices_layer3_handoffs_with_sda_transit', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_edge_device.py b/plugins/action/sda_fabric_edge_device.py index 84bd9ed571..d51e6f00b2 100644 --- a/plugins/action/sda_fabric_edge_device.py +++ b/plugins/action/sda_fabric_edge_device.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_fabric_site.py b/plugins/action/sda_fabric_site.py index 47af152760..2b1be14c47 100644 --- a/plugins/action/sda_fabric_site.py +++ b/plugins/action/sda_fabric_site.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_fabric_sites.py b/plugins/action/sda_fabric_sites.py new file mode 100644 index 0000000000..ce95fe893c --- /dev/null +++ b/plugins/action/sda_fabric_sites.py @@ -0,0 +1,267 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, + AnsibleSDAException, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id"], True), + ("state", "present", ["payload"], True), + ("state", "absent", ["id"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class SdaFabricSites(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['id'] = id or self.new_object.get('id') + new_object_params['site_id'] = self.new_object.get('siteId') or \ + self.new_object.get('site_id') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def get_object_by_name(self, name, is_absent=False): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_sites", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + if isinstance(items, dict) and items.get("status") == "failed": + if is_absent: + raise AnsibleSDAException(response=items) + result = None + return result + result = get_dict_result(items, 'name', name) + except Exception: + if is_absent: + raise + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_sites", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self, is_absent=False): + name = self.new_object.get("name") + prev_obj = self.get_object_by_name(name, is_absent=is_absent) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("id", "id"), + ("siteId", "siteId"), + ("authenticationProfileName", "authenticationProfileName"), + ("isPubSubEnabled", "isPubSubEnabled"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="sda", + function="add_fabric_site", + params=self.create_params(), + op_modifies=True, + ) + if isinstance(result, dict): + if 'response' in result: + result = result.get('response') + if isinstance(result, dict) and result.get("status") == "failed": + raise AnsibleSDAException(response=result) + return result + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="sda", + function="update_fabric_site", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="sda", + function="delete_fabric_site_by_id", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = SdaFabricSites(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + try: + response = obj.create() + dnac.object_created() + except AnsibleSDAException as e: + dnac.fail_json("Could not create object {e}".format(e=e._response)) + + elif state == "absent": + try: + (obj_exists, prev_obj) = obj.exists(is_absent=True) + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + except AnsibleSDAException as e: + dnac.fail_json("Could not get object to be delete {e}".format(e=e._response)) + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_sites_count_info.py b/plugins/action/sda_fabric_sites_count_info.py new file mode 100644 index 0000000000..28d6845717 --- /dev/null +++ b/plugins/action/sda_fabric_sites_count_info.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_site_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_sites_info.py b/plugins/action/sda_fabric_sites_info.py new file mode 100644 index 0000000000..9bea361ed8 --- /dev/null +++ b/plugins/action/sda_fabric_sites_info.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + id=dict(type="str"), + siteId=dict(type="str"), + offset=dict(type="int"), + limit=dict(type="int"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + id=params.get("id"), + site_id=params.get("siteId"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_sites', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_zones.py b/plugins/action/sda_fabric_zones.py new file mode 100644 index 0000000000..158a1edb52 --- /dev/null +++ b/plugins/action/sda_fabric_zones.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, + AnsibleSDAException, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id"], True), + ("state", "present", ["payload"], True), + ("state", "absent", ["id"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class SdaFabricZones(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['id'] = id or self.new_object.get('id') + new_object_params['site_id'] = self.new_object.get('siteId') or \ + self.new_object.get('site_id') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def get_object_by_name(self, name, is_absent=False): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_zones", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + if isinstance(items, dict) and items.get("status") == "failed": + if is_absent: + raise AnsibleSDAException(response=items) + result = None + return result + result = get_dict_result(items, 'name', name) + except Exception: + if is_absent: + raise + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_fabric_zones", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self, is_absent=False): + name = self.new_object.get("name") + prev_obj = self.get_object_by_name(name, is_absent=is_absent) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("id", "id"), + ("siteId", "siteId"), + ("authenticationProfileName", "authenticationProfileName"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="sda", + function="add_fabric_zone", + params=self.create_params(), + op_modifies=True, + ) + if isinstance(result, dict): + if 'response' in result: + result = result.get('response') + if isinstance(result, dict) and result.get("status") == "failed": + raise AnsibleSDAException(response=result) + return result + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="sda", + function="update_fabric_zone", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="sda", + function="delete_fabric_zone_by_id", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = SdaFabricZones(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + try: + response = obj.create() + dnac.object_created() + except AnsibleSDAException as e: + dnac.fail_json("Could not create object {e}".format(e=e._response)) + + elif state == "absent": + try: + (obj_exists, prev_obj) = obj.exists(is_absent=True) + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + except AnsibleSDAException as e: + dnac.fail_json("Could not get object to be delete {e}".format(e=e._response)) + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_zones_count_info.py b/plugins/action/sda_fabric_zones_count_info.py new file mode 100644 index 0000000000..28b84a9c08 --- /dev/null +++ b/plugins/action/sda_fabric_zones_count_info.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_zone_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_fabric_zones_info.py b/plugins/action/sda_fabric_zones_info.py new file mode 100644 index 0000000000..c1e5a10165 --- /dev/null +++ b/plugins/action/sda_fabric_zones_info.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + id=dict(type="str"), + siteId=dict(type="str"), + offset=dict(type="int"), + limit=dict(type="int"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + id=params.get("id"), + site_id=params.get("siteId"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_fabric_zones', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_multicast.py b/plugins/action/sda_multicast.py index 60c6b68abd..9a56d53a28 100644 --- a/plugins/action/sda_multicast.py +++ b/plugins/action/sda_multicast.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_port_assignment_for_access_point.py b/plugins/action/sda_port_assignment_for_access_point.py index 0cdfd8bf5a..5ea494ed9a 100644 --- a/plugins/action/sda_port_assignment_for_access_point.py +++ b/plugins/action/sda_port_assignment_for_access_point.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_port_assignment_for_user_device.py b/plugins/action/sda_port_assignment_for_user_device.py index 3c2a0728a2..02c99ae152 100644 --- a/plugins/action/sda_port_assignment_for_user_device.py +++ b/plugins/action/sda_port_assignment_for_user_device.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_port_assignments.py b/plugins/action/sda_port_assignments.py new file mode 100644 index 0000000000..baebcf2e13 --- /dev/null +++ b/plugins/action/sda_port_assignments.py @@ -0,0 +1,295 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, + AnsibleSDAException, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + interfaceName=dict(type="str"), + dataVlanName=dict(type="str"), + voiceVlanName=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id"], True), + ("state", "present", ["payload"], True), + ("state", "absent", ["id"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class SdaPortAssignments(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + interface_name=params.get("interfaceName"), + data_vlan_name=params.get("dataVlanName"), + voice_vlan_name=params.get("voiceVlanName"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['fabric_id'] = self.new_object.get('fabricId') or \ + self.new_object.get('fabric_id') + new_object_params['network_device_id'] = self.new_object.get('networkDeviceId') or \ + self.new_object.get('network_device_id') + new_object_params['interface_name'] = self.new_object.get('interfaceName') or \ + self.new_object.get('interface_name') + new_object_params['data_vlan_name'] = self.new_object.get('dataVlanName') or \ + self.new_object.get('data_vlan_name') + new_object_params['voice_vlan_name'] = self.new_object.get('voiceVlanName') or \ + self.new_object.get('voice_vlan_name') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def get_object_by_name(self, name, is_absent=False): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_port_assignments", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + if isinstance(items, dict) and items.get("status") == "failed": + if is_absent: + raise AnsibleSDAException(response=items) + result = None + return result + result = get_dict_result(items, 'name', name) + except Exception: + if is_absent: + raise + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_port_assignments", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self, is_absent=False): + name = self.new_object.get("name") + prev_obj = self.get_object_by_name(name, is_absent=is_absent) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("id", "id"), + ("fabricId", "fabricId"), + ("networkDeviceId", "networkDeviceId"), + ("interfaceName", "interfaceName"), + ("connectedDeviceType", "connectedDeviceType"), + ("dataVlanName", "dataVlanName"), + ("voiceVlanName", "voiceVlanName"), + ("authenticateTemplateName", "authenticateTemplateName"), + ("scalableGroupName", "scalableGroupName"), + ("interfaceDescription", "interfaceDescription"), + ("fabricId", "fabric_id"), + ("networkDeviceId", "network_device_id"), + ("interfaceName", "interface_name"), + ("dataVlanName", "data_vlan_name"), + ("voiceVlanName", "voice_vlan_name"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="sda", + function="add_port_assignments", + params=self.create_params(), + op_modifies=True, + ) + if isinstance(result, dict): + if 'response' in result: + result = result.get('response') + if isinstance(result, dict) and result.get("status") == "failed": + raise AnsibleSDAException(response=result) + return result + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="sda", + function="update_port_assignments", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="sda", + function="delete_port_assignment_by_id", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = SdaPortAssignments(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + try: + response = obj.create() + dnac.object_created() + except AnsibleSDAException as e: + dnac.fail_json("Could not create object {e}".format(e=e._response)) + + elif state == "absent": + try: + (obj_exists, prev_obj) = obj.exists(is_absent=True) + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + except AnsibleSDAException as e: + dnac.fail_json("Could not get object to be delete {e}".format(e=e._response)) + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_port_assignments_count_info.py b/plugins/action/sda_port_assignments_count_info.py new file mode 100644 index 0000000000..1552d0b04b --- /dev/null +++ b/plugins/action/sda_port_assignments_count_info.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + interfaceName=dict(type="str"), + dataVlanName=dict(type="str"), + voiceVlanName=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + interface_name=params.get("interfaceName"), + data_vlan_name=params.get("dataVlanName"), + voice_vlan_name=params.get("voiceVlanName"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_port_assignment_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_port_assignments_info.py b/plugins/action/sda_port_assignments_info.py new file mode 100644 index 0000000000..58d5080e60 --- /dev/null +++ b/plugins/action/sda_port_assignments_info.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + fabricId=dict(type="str"), + networkDeviceId=dict(type="str"), + interfaceName=dict(type="str"), + dataVlanName=dict(type="str"), + voiceVlanName=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + fabric_id=params.get("fabricId"), + network_device_id=params.get("networkDeviceId"), + interface_name=params.get("interfaceName"), + data_vlan_name=params.get("dataVlanName"), + voice_vlan_name=params.get("voiceVlanName"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_port_assignments', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_provision_device.py b/plugins/action/sda_provision_device.py index d9215cb0d0..53092c86a7 100644 --- a/plugins/action/sda_provision_device.py +++ b/plugins/action/sda_provision_device.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_provision_devices.py b/plugins/action/sda_provision_devices.py new file mode 100644 index 0000000000..85b8046064 --- /dev/null +++ b/plugins/action/sda_provision_devices.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, + AnsibleSDAException, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + payload=dict(type="list"), + networkDeviceId=dict(type="str"), + siteId=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id"], True), + ("state", "present", ["payload"], True), + ("state", "absent", ["id"], True), + ("state", "absent", ["payload"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class SdaProvisionDevices(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + payload=params.get("payload"), + network_device_id=params.get("networkDeviceId"), + site_id=params.get("siteId"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + new_object_params['id'] = id or self.new_object.get('id') + new_object_params['network_device_id'] = self.new_object.get('networkDeviceId') or \ + self.new_object.get('network_device_id') + new_object_params['site_id'] = self.new_object.get('siteId') or \ + self.new_object.get('site_id') + new_object_params['offset'] = self.new_object.get('offset') + new_object_params['limit'] = self.new_object.get('limit') + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + new_object_params['payload'] = self.new_object.get('payload') + return new_object_params + + def get_object_by_name(self, name, is_absent=False): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_provisioned_devices", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + if isinstance(items, dict) and items.get("status") == "failed": + if is_absent: + raise AnsibleSDAException(response=items) + result = None + return result + result = get_dict_result(items, 'name', name) + except Exception: + if is_absent: + raise + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="sda", + function="get_provisioned_devices", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None + return result + + def exists(self, is_absent=False): + name = self.new_object.get("name") + prev_obj = self.get_object_by_name(name, is_absent=is_absent) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + + obj_params = [ + ("id", "id"), + ("siteId", "siteId"), + ("networkDeviceId", "networkDeviceId"), + ("networkDeviceId", "network_device_id"), + ("siteId", "site_id"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="sda", + function="provision_devices", + params=self.create_params(), + op_modifies=True, + ) + if isinstance(result, dict): + if 'response' in result: + result = result.get('response') + if isinstance(result, dict) and result.get("status") == "failed": + raise AnsibleSDAException(response=result) + return result + + def update(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + result = self.dnac.exec( + family="sda", + function="re_provision_devices", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + def delete(self): + requested_obj = self.new_object.get('payload') + if requested_obj and len(requested_obj) > 0: + requested_obj = requested_obj[0] + id = self.new_object.get("id") or requested_obj.get("id") + name = self.new_object.get("name") or requested_obj.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.dnac.exec( + family="sda", + function="delete_provisioned_device_by_id", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = SdaProvisionDevices(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + dnac.object_updated() + else: + response = prev_obj + dnac.object_already_present() + else: + try: + response = obj.create() + dnac.object_created() + except AnsibleSDAException as e: + dnac.fail_json("Could not create object {e}".format(e=e._response)) + + elif state == "absent": + try: + (obj_exists, prev_obj) = obj.exists(is_absent=True) + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + except AnsibleSDAException as e: + dnac.fail_json("Could not get object to be delete {e}".format(e=e._response)) + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_provision_devices_count_info.py b/plugins/action/sda_provision_devices_count_info.py new file mode 100644 index 0000000000..3e36f931db --- /dev/null +++ b/plugins/action/sda_provision_devices_count_info.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + siteId=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + site_id=params.get("siteId"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_provisioned_devices_count', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_provision_devices_info.py b/plugins/action/sda_provision_devices_info.py new file mode 100644 index 0000000000..b06f1252e7 --- /dev/null +++ b/plugins/action/sda_provision_devices_info.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + id=dict(type="str"), + networkDeviceId=dict(type="str"), + siteId=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + id=params.get("id"), + network_device_id=params.get("networkDeviceId"), + site_id=params.get("siteId"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sda", + function='get_provisioned_devices', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_site_member_member_info.py b/plugins/action/sda_site_member_member_info.py new file mode 100644 index 0000000000..cc1bca386e --- /dev/null +++ b/plugins/action/sda_site_member_member_info.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + id=dict(type="str"), + offset=dict(type="str"), + limit=dict(type="str"), + memberType=dict(type="str"), + level=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + id=params.get("id"), + offset=params.get("offset"), + limit=params.get("limit"), + member_type=params.get("memberType"), + level=params.get("level"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sites", + function='get_devices_that_are_assigned_to_a_site', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/sda_virtual_network.py b/plugins/action/sda_virtual_network.py index 5f8405abab..a116f29949 100644 --- a/plugins/action/sda_virtual_network.py +++ b/plugins/action/sda_virtual_network.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_virtual_network_ip_pool.py b/plugins/action/sda_virtual_network_ip_pool.py index 674f550183..69bb4561d8 100644 --- a/plugins/action/sda_virtual_network_ip_pool.py +++ b/plugins/action/sda_virtual_network_ip_pool.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) @@ -77,14 +78,14 @@ def __init__(self, params, dnac): isCommonPool=params.get("isCommonPool"), isBridgeModeVm=params.get("isBridgeModeVm"), poolType=params.get("poolType"), + site_name_hierarchy=params.get("siteNameHierarchy"), virtual_network_name=params.get("virtualNetworkName"), ip_pool_name=params.get("ipPoolName"), ) def get_all_params(self, name=None, id=None): new_object_params = {} - new_object_params['site_name_hierarchy'] = self.new_object.get('site_name_hierarchy') or \ - self.new_object.get('siteNameHierarchy') + new_object_params['siteNameHierarchy'] = self.new_object.get('site_name_hierarchy') new_object_params['virtual_network_name'] = self.new_object.get('virtualNetworkName') or \ self.new_object.get('virtual_network_name') new_object_params['ip_pool_name'] = self.new_object.get('ipPoolName') or \ diff --git a/plugins/action/sda_virtual_network_v2.py b/plugins/action/sda_virtual_network_v2.py index 45c66872d8..2410e2a326 100644 --- a/plugins/action/sda_virtual_network_v2.py +++ b/plugins/action/sda_virtual_network_v2.py @@ -23,6 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/security_advisories_ids_per_device_info.py b/plugins/action/security_advisories_ids_per_device_info.py index eebfa56275..c298066b8f 100644 --- a/plugins/action/security_advisories_ids_per_device_info.py +++ b/plugins/action/security_advisories_ids_per_device_info.py @@ -83,7 +83,7 @@ def run(self, tmp=None, task_vars=None): if id: response = dnac.exec( family="security_advisories", - function='get_advisory_ids_per_device', + function='get_advisory_device_detail', params=self.get_object(self._task.args), ) self._result.update(dict(dnac_response=response)) diff --git a/plugins/action/sensor.py b/plugins/action/sensor.py index 7972398347..7d2df435d0 100644 --- a/plugins/action/sensor.py +++ b/plugins/action/sensor.py @@ -31,11 +31,17 @@ # Add arguments specific for this module argument_spec.update(dict( state=dict(type="str", default="present", choices=["present", "absent"]), - ssids=dict(type="list"), name=dict(type="str"), + version=dict(type="int"), + modelVersion=dict(type="int"), connection=dict(type="str"), + ssids=dict(type="list"), + profiles=dict(type="list"), + encryptionMode=dict(type="str"), + runNow=dict(type="str"), + locationInfoList=dict(type="list"), + sensors=dict(type="list"), apCoverage=dict(type="list"), - modelVersion=dict(type="int"), templateName=dict(type="str"), )) @@ -52,11 +58,17 @@ class Sensor(object): def __init__(self, params, dnac): self.dnac = dnac self.new_object = dict( - ssids=params.get("ssids"), name=params.get("name"), + version=params.get("version"), + modelVersion=params.get("modelVersion"), connection=params.get("connection"), + ssids=params.get("ssids"), + profiles=params.get("profiles"), + encryptionMode=params.get("encryptionMode"), + runNow=params.get("runNow"), + locationInfoList=params.get("locationInfoList"), + sensors=params.get("sensors"), apCoverage=params.get("apCoverage"), - modelVersion=params.get("modelVersion"), template_name=params.get("templateName"), ) @@ -68,11 +80,17 @@ def get_all_params(self, name=None, id=None): def create_params(self): new_object_params = {} - new_object_params['ssids'] = self.new_object.get('ssids') new_object_params['name'] = self.new_object.get('name') + new_object_params['version'] = self.new_object.get('version') + new_object_params['modelVersion'] = self.new_object.get('modelVersion') new_object_params['connection'] = self.new_object.get('connection') + new_object_params['ssids'] = self.new_object.get('ssids') + new_object_params['profiles'] = self.new_object.get('profiles') + new_object_params['encryptionMode'] = self.new_object.get('encryptionMode') + new_object_params['runNow'] = self.new_object.get('runNow') + new_object_params['locationInfoList'] = self.new_object.get('locationInfoList') + new_object_params['sensors'] = self.new_object.get('sensors') new_object_params['apCoverage'] = self.new_object.get('apCoverage') - new_object_params['modelVersion'] = self.new_object.get('modelVersion') return new_object_params def delete_all_params(self): @@ -127,11 +145,17 @@ def requires_update(self, current_obj): requested_obj = self.new_object obj_params = [ - ("ssids", "ssids"), ("name", "name"), + ("version", "version"), + ("modelVersion", "modelVersion"), ("connection", "connection"), + ("ssids", "ssids"), + ("profiles", "profiles"), + ("encryptionMode", "encryptionMode"), + ("runNow", "runNow"), + ("locationInfoList", "locationInfoList"), + ("sensors", "sensors"), ("apCoverage", "apCoverage"), - ("modelVersion", "modelVersion"), ("templateName", "template_name"), ] # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params diff --git a/plugins/action/sensor_test_template_edit.py b/plugins/action/sensor_test_template_edit.py index 5e75c953b1..9b3a8d200f 100644 --- a/plugins/action/sensor_test_template_edit.py +++ b/plugins/action/sensor_test_template_edit.py @@ -26,8 +26,33 @@ # Add arguments specific for this module argument_spec.update(dict( templateName=dict(type="str"), + name=dict(type="str"), + _id=dict(type="str"), + version=dict(type="int"), + modelVersion=dict(type="int"), + startTime=dict(type="int"), + lastModifiedTime=dict(type="int"), + numAssociatedSensor=dict(type="int"), + location=dict(type="str"), + siteHierarchy=dict(type="str"), + status=dict(type="str"), + connection=dict(type="str"), + actionInProgress=dict(type="str"), + frequency=dict(type="dict"), + rssiThreshold=dict(type="int"), + numNeighborAPThreshold=dict(type="int"), + scheduleInDays=dict(type="int"), + wlans=dict(type="list"), + ssids=dict(type="list"), + profiles=dict(type="list"), + testScheduleMode=dict(type="str"), + showWlcUpgradeBanner=dict(type="bool"), + radioAsSensorRemoved=dict(type="bool"), + encryptionMode=dict(type="str"), + runNow=dict(type="str"), locationInfoList=dict(type="list"), - schedule=dict(type="dict"), + sensors=dict(type="list"), + apCoverage=dict(type="list"), )) required_if = [] @@ -66,8 +91,33 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( templateName=params.get("templateName"), + name=params.get("name"), + _id=params.get("_id"), + version=params.get("version"), + modelVersion=params.get("modelVersion"), + startTime=params.get("startTime"), + lastModifiedTime=params.get("lastModifiedTime"), + numAssociatedSensor=params.get("numAssociatedSensor"), + location=params.get("location"), + siteHierarchy=params.get("siteHierarchy"), + status=params.get("status"), + connection=params.get("connection"), + actionInProgress=params.get("actionInProgress"), + frequency=params.get("frequency"), + rssiThreshold=params.get("rssiThreshold"), + numNeighborAPThreshold=params.get("numNeighborAPThreshold"), + scheduleInDays=params.get("scheduleInDays"), + wlans=params.get("wlans"), + ssids=params.get("ssids"), + profiles=params.get("profiles"), + testScheduleMode=params.get("testScheduleMode"), + showWlcUpgradeBanner=params.get("showWlcUpgradeBanner"), + radioAsSensorRemoved=params.get("radioAsSensorRemoved"), + encryptionMode=params.get("encryptionMode"), + runNow=params.get("runNow"), locationInfoList=params.get("locationInfoList"), - schedule=params.get("schedule"), + sensors=params.get("sensors"), + apCoverage=params.get("apCoverage"), ) return new_object diff --git a/plugins/action/site_count_v2_info.py b/plugins/action/site_count_v2_info.py new file mode 100644 index 0000000000..8f74ffe04e --- /dev/null +++ b/plugins/action/site_count_v2_info.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + id=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + id=params.get("id"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sites", + function='get_site_count_v2', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/site_health_info.py b/plugins/action/site_health_info.py index 7a38d07db8..adf65e0821 100644 --- a/plugins/action/site_health_info.py +++ b/plugins/action/site_health_info.py @@ -25,10 +25,10 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - timestamp=dict(type="str"), siteType=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), + timestamp=dict(type="float"), headers=dict(type="dict"), )) @@ -67,10 +67,10 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( - timestamp=params.get("timestamp"), site_type=params.get("siteType"), offset=params.get("offset"), limit=params.get("limit"), + timestamp=params.get("timestamp"), headers=params.get("headers"), ) return new_object diff --git a/plugins/action/site_membership_info.py b/plugins/action/site_membership_info.py index 7c5ec8467f..445783fac6 100644 --- a/plugins/action/site_membership_info.py +++ b/plugins/action/site_membership_info.py @@ -26,8 +26,8 @@ # Add arguments specific for this module argument_spec.update(dict( siteId=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), deviceFamily=dict(type="str"), serialNumber=dict(type="str"), headers=dict(type="dict"), diff --git a/plugins/action/site_v2_info.py b/plugins/action/site_v2_info.py new file mode 100644 index 0000000000..de6f8d2504 --- /dev/null +++ b/plugins/action/site_v2_info.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + groupNameHierarchy=dict(type="str"), + id=dict(type="str"), + type=dict(type="str"), + offset=dict(type="str"), + limit=dict(type="str"), + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + group_name_hierarchy=params.get("groupNameHierarchy"), + id=params.get("id"), + type=params.get("type"), + offset=params.get("offset"), + limit=params.get("limit"), + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="sites", + function='get_site_v2', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/snmpv2_read_community_credential.py b/plugins/action/snmpv2_read_community_credential.py index cda2e0c06e..917e96d3ee 100644 --- a/plugins/action/snmpv2_read_community_credential.py +++ b/plugins/action/snmpv2_read_community_credential.py @@ -89,7 +89,7 @@ def get_object_by_name(self, name): if isinstance(items, dict): if 'response' in items: items = items.get('response') - result = get_dict_result(items, 'description', name) + result = get_dict_result(items, 'description', name) or get_dict_result(items, 'username', name) except Exception: result = None return result @@ -115,7 +115,7 @@ def exists(self): id_exists = False name_exists = False o_id = self.new_object.get("id") - name = self.new_object.get("username") or self.new_object.get("description") + name = self.new_object.get("description") or self.new_object.get("username") if o_id: prev_obj = self.get_object_by_id(o_id) id_exists = prev_obj is not None and isinstance(prev_obj, dict) diff --git a/plugins/action/snmpv2_write_community_credential.py b/plugins/action/snmpv2_write_community_credential.py index 2ff190d75a..e1244b8689 100644 --- a/plugins/action/snmpv2_write_community_credential.py +++ b/plugins/action/snmpv2_write_community_credential.py @@ -89,7 +89,7 @@ def get_object_by_name(self, name): if isinstance(items, dict): if 'response' in items: items = items.get('response') - result = get_dict_result(items, 'description', name) + result = get_dict_result(items, 'description', name) or get_dict_result(items, 'username', name) except Exception: result = None return result @@ -115,7 +115,7 @@ def exists(self): id_exists = False name_exists = False o_id = self.new_object.get("id") - name = self.new_object.get("username") or self.new_object.get("description") + name = self.new_object.get("description") or self.new_object.get("username") if o_id: prev_obj = self.get_object_by_id(o_id) id_exists = prev_obj is not None and isinstance(prev_obj, dict) diff --git a/plugins/action/snmpv3_credential.py b/plugins/action/snmpv3_credential.py index 3130877154..480c82e66d 100644 --- a/plugins/action/snmpv3_credential.py +++ b/plugins/action/snmpv3_credential.py @@ -137,7 +137,7 @@ def exists(self): id_exists = False name_exists = False o_id = self.new_object.get("id") - name = self.new_object.get("username") or self.new_object.get("description") + name = self.new_object.get("description") or self.new_object.get("username") if o_id: prev_obj = self.get_object_by_id(o_id) id_exists = prev_obj is not None and isinstance(prev_obj, dict) @@ -167,9 +167,6 @@ def requires_update(self, current_obj): ("snmpMode", "snmpMode"), ("username", "username"), ] - - print("requested_obj: ", requested_obj) - print("current_obj: ", current_obj) # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params # If any does not have eq params, it requires update return any(not dnac_compare_equality(current_obj.get(dnac_param), diff --git a/plugins/action/swim_import_local.py b/plugins/action/swim_import_local.py index b5e3b8a6c9..57946e44e0 100644 --- a/plugins/action/swim_import_local.py +++ b/plugins/action/swim_import_local.py @@ -20,7 +20,6 @@ DNACSDK, dnac_argument_spec, ) -import os # Get common arguements specification argument_spec = dnac_argument_spec() @@ -42,8 +41,7 @@ class ActionModule(ActionBase): def __init__(self, *args, **kwargs): if not ANSIBLE_UTILS_IS_INSTALLED: - raise AnsibleActionFail( - "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") super(ActionModule, self).__init__(*args, **kwargs) self._supports_async = False self._supports_check_mode = False @@ -72,12 +70,8 @@ def get_object(self, params): is_third_party=params.get("isThirdParty"), third_party_vendor=params.get("thirdPartyVendor"), third_party_image_family=params.get("thirdPartyImageFamily"), - third_party_application_type=params.get( - "thirdPartyApplicationType"), + third_party_application_type=params.get("thirdPartyApplicationType"), file_path=params.get("filePath"), - multipart_fields={'file': (os.path.basename(params.get( - "filePath")), open(params.get("filePath"), 'rb'))}, - multipart_monitor_callback=None ) return new_object diff --git a/plugins/action/system_health_info.py b/plugins/action/system_health_info.py index 28683d23b0..6c97265c28 100644 --- a/plugins/action/system_health_info.py +++ b/plugins/action/system_health_info.py @@ -28,8 +28,8 @@ summary=dict(type="bool"), domain=dict(type="str"), subdomain=dict(type="str"), - limit=dict(type="int"), - offset=dict(type="int"), + limit=dict(type="float"), + offset=dict(type="float"), headers=dict(type="dict"), )) diff --git a/plugins/action/system_performance_historical_info.py b/plugins/action/system_performance_historical_info.py index 287c72245c..27eab29637 100644 --- a/plugins/action/system_performance_historical_info.py +++ b/plugins/action/system_performance_historical_info.py @@ -26,8 +26,8 @@ # Add arguments specific for this module argument_spec.update(dict( kpi=dict(type="str"), - startTime=dict(type="int"), - endTime=dict(type="int"), + startTime=dict(type="float"), + endTime=dict(type="float"), headers=dict(type="dict"), )) diff --git a/plugins/action/system_performance_info.py b/plugins/action/system_performance_info.py index b05406cbf6..3535f9fb6b 100644 --- a/plugins/action/system_performance_info.py +++ b/plugins/action/system_performance_info.py @@ -27,8 +27,8 @@ argument_spec.update(dict( kpi=dict(type="str"), function=dict(type="str"), - startTime=dict(type="int"), - endTime=dict(type="int"), + startTime=dict(type="float"), + endTime=dict(type="float"), headers=dict(type="dict"), )) diff --git a/plugins/action/tag_count_info.py b/plugins/action/tag_count_info.py index 03827a43d8..6766d9a9ed 100644 --- a/plugins/action/tag_count_info.py +++ b/plugins/action/tag_count_info.py @@ -28,7 +28,6 @@ name=dict(type="str"), nameSpace=dict(type="str"), attributeName=dict(type="str"), - level=dict(type="str"), size=dict(type="str"), systemTag=dict(type="str"), headers=dict(type="dict"), @@ -72,7 +71,6 @@ def get_object(self, params): name=params.get("name"), name_space=params.get("nameSpace"), attribute_name=params.get("attributeName"), - level=params.get("level"), size=params.get("size"), system_tag=params.get("systemTag"), headers=params.get("headers"), diff --git a/plugins/action/tag_info.py b/plugins/action/tag_info.py index 773cc8858b..acd9b93b4a 100644 --- a/plugins/action/tag_info.py +++ b/plugins/action/tag_info.py @@ -29,8 +29,8 @@ additionalInfo_nameSpace=dict(type="str"), additionalInfo_attributes=dict(type="str"), level=dict(type="str"), - offset=dict(type="int"), - limit=dict(type="int"), + offset=dict(type="float"), + limit=dict(type="float"), size=dict(type="str"), field=dict(type="str"), sortBy=dict(type="str"), diff --git a/plugins/action/tag_member.py b/plugins/action/tag_member.py index 54ae99e177..54682fc7fc 100644 --- a/plugins/action/tag_member.py +++ b/plugins/action/tag_member.py @@ -32,7 +32,7 @@ argument_spec.update(dict( state=dict(type="str", default="present", choices=["present", "absent"]), payload=dict(type="dict"), - object=dict(type="str"), + memberType=dict(type="list"), id=dict(type="str"), memberId=dict(type="str"), )) @@ -51,17 +51,17 @@ def __init__(self, params, dnac): self.dnac = dnac self.new_object = dict( payload=params.get("payload"), - object=params.get("object"), + memberType=params.get("memberType"), id=params.get("id"), member_id=params.get("memberId"), - member_type=params.get("memberType"), ) def create_params(self): new_object_params = {} new_object_params['payload'] = self.new_object.get('payload') new_object_params['id'] = self.new_object.get('id') - new_object_params['object'] = self.new_object.get('object') + new_object_params['memberType'] = self.new_object.get('memberType') + new_object_params['id'] = self.new_object.get('id') return new_object_params def delete_by_id_params(self): @@ -82,8 +82,7 @@ def get_object_by_id(self, id): items = self.dnac.exec( family="tag", function="get_tag_members_by_id", - params={"id": id, "memberType": self.new_object.get( - 'member_type'), } + params={"id": id} ) if isinstance(items, dict): if 'response' in items: @@ -110,8 +109,7 @@ def exists(self): _id = prev_obj.get("id") _id = _id or prev_obj.get("memberId") if id_exists and name_exists and o_id != _id: - raise InconsistentParameters( - "The 'id' and 'name' params don't refer to the same object") + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") if _id: self.new_object.update(dict(id=_id)) self.new_object.update(dict(member_id=_id)) @@ -124,7 +122,7 @@ def requires_update(self, current_obj): requested_obj = self.new_object obj_params = [ - ("object", "object"), + ("memberType", "memberType"), ("id", "id"), ("memberId", "member_id"), ] @@ -167,8 +165,7 @@ def delete(self): class ActionModule(ActionBase): def __init__(self, *args, **kwargs): if not ANSIBLE_UTILS_IS_INSTALLED: - raise AnsibleActionFail( - "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") super(ActionModule, self).__init__(*args, **kwargs) self._supports_async = False self._supports_check_mode = False diff --git a/plugins/action/tag_member_count_info.py b/plugins/action/tag_member_count_info.py index f3457c0676..93287adc65 100644 --- a/plugins/action/tag_member_count_info.py +++ b/plugins/action/tag_member_count_info.py @@ -28,7 +28,6 @@ id=dict(type="str"), memberType=dict(type="str"), memberAssociationType=dict(type="str"), - level=dict(type="str"), headers=dict(type="dict"), )) @@ -70,7 +69,6 @@ def get_object(self, params): id=params.get("id"), member_type=params.get("memberType"), member_association_type=params.get("memberAssociationType"), - level=params.get("level"), headers=params.get("headers"), ) return new_object diff --git a/plugins/action/tag_member_info.py b/plugins/action/tag_member_info.py index e90f5551ec..36c3640864 100644 --- a/plugins/action/tag_member_info.py +++ b/plugins/action/tag_member_info.py @@ -27,8 +27,8 @@ argument_spec.update(dict( id=dict(type="str"), memberType=dict(type="str"), - offset=dict(type="str"), - limit=dict(type="str"), + offset=dict(type="float"), + limit=dict(type="float"), memberAssociationType=dict(type="str"), level=dict(type="str"), headers=dict(type="dict"), diff --git a/plugins/action/tag_membership.py b/plugins/action/tag_membership.py index 451501f948..bb7b8a8b74 100644 --- a/plugins/action/tag_membership.py +++ b/plugins/action/tag_membership.py @@ -25,7 +25,7 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - memberToTags=dict(type="list"), + memberToTags=dict(type="dict"), memberType=dict(type="str"), )) @@ -79,7 +79,7 @@ def run(self, tmp=None, task_vars=None): response = dnac.exec( family="tag", - function='updates_tag_membership', + function='update_tag_membership', op_modifies=True, params=self.get_object(self._task.args), ) diff --git a/plugins/action/topology_network_health_info.py b/plugins/action/topology_network_health_info.py index d8a8e75da3..5b64f0398e 100644 --- a/plugins/action/topology_network_health_info.py +++ b/plugins/action/topology_network_health_info.py @@ -25,7 +25,7 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - timestamp=dict(type="str"), + timestamp=dict(type="float"), headers=dict(type="dict"), )) diff --git a/plugins/action/transit_peer_network.py b/plugins/action/transit_peer_network.py index a15848230a..cbcfe89103 100644 --- a/plugins/action/transit_peer_network.py +++ b/plugins/action/transit_peer_network.py @@ -23,7 +23,7 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - AnsibleSDAException, + InconsistentParameters, ) # Get common arguments specification @@ -74,7 +74,7 @@ def delete_all_params(self): new_object_params['transit_peer_network_name'] = self.new_object.get('transit_peer_network_name') return new_object_params - def get_object_by_name(self, name, is_absent=False): + def get_object_by_name(self, name): result = None # NOTE: Does not have a get by name method, using get all try: @@ -86,15 +86,8 @@ def get_object_by_name(self, name, is_absent=False): if isinstance(items, dict): if 'response' in items: items = items.get('response') - if isinstance(items, dict) and items.get("status") == "failed": - if is_absent: - raise AnsibleSDAException(response=items) - result = None - return result result = get_dict_result(items, 'name', name) except Exception: - if is_absent: - raise result = None return result @@ -103,10 +96,25 @@ def get_object_by_id(self, id): # NOTE: Does not have a get by id method or it is in another action return result - def exists(self, is_absent=False): - name = self.new_object.get("transitPeerNetworkName") - prev_obj = self.get_object_by_name(name, is_absent=is_absent) - it_exists = prev_obj is not None and isinstance(prev_obj, dict) and prev_obj.get("status") != "failed" + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) return (it_exists, prev_obj) def requires_update(self, current_obj): @@ -198,7 +206,7 @@ def run(self, tmp=None, task_vars=None): response = obj.create() dnac.object_created() elif state == "absent": - (obj_exists, prev_obj) = obj.exists(is_absent=True) + (obj_exists, prev_obj) = obj.exists() if obj_exists: response = obj.delete() dnac.object_deleted() diff --git a/plugins/action/user.py b/plugins/action/user.py index 1896e57ffb..ea9b6930d5 100644 --- a/plugins/action/user.py +++ b/plugins/action/user.py @@ -30,7 +30,7 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - state=dict(type="str", default="present", choices=["present"]), + state=dict(type="str", default="present", choices=["present", "absent"]), firstName=dict(type="str"), lastName=dict(type="str"), username=dict(type="str"), @@ -41,6 +41,8 @@ )) required_if = [ + ("state", "present", ["userId"], True), + ("state", "absent", ["userId"], True), ] required_one_of = [] mutually_exclusive = [] @@ -58,12 +60,15 @@ def __init__(self, params, dnac): email=params.get("email"), roleList=params.get("roleList"), userId=params.get("userId"), + user_id=params.get("userId"), ) def get_all_params(self, name=None, id=None): new_object_params = {} new_object_params['invoke_source'] = self.new_object.get('invokeSource') or \ self.new_object.get('invoke_source') + new_object_params['auth_source'] = self.new_object.get('authSource') or \ + self.new_object.get('auth_source') return new_object_params def create_params(self): @@ -76,6 +81,11 @@ def create_params(self): new_object_params['roleList'] = self.new_object.get('roleList') return new_object_params + def delete_by_id_params(self): + new_object_params = {} + new_object_params['user_id'] = self.new_object.get('user_id') + return new_object_params + def update_all_params(self): new_object_params = {} new_object_params['firstName'] = self.new_object.get('firstName') @@ -88,10 +98,10 @@ def update_all_params(self): def get_object_by_name(self, name): result = None - # NOTE: Does not have a get by name method, using get all + # NOTE: Does not have a get by name method or it is in another action try: items = self.dnac.exec( - family="user_and_roles", + family="userand_roles", function="get_users_api", params=self.get_all_params(name=name), ) @@ -106,13 +116,26 @@ def get_object_by_name(self, name): def get_object_by_id(self, id): result = None # NOTE: Does not have a get by id method or it is in another action + try: + items = self.dnac.exec( + family="userand_roles", + function="get_users_api", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception: + result = None return result def exists(self): - prev_obj = None id_exists = False name_exists = False + prev_obj = None o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get("user_id") name = self.new_object.get("name") if o_id: prev_obj = self.get_object_by_id(o_id) @@ -122,10 +145,12 @@ def exists(self): name_exists = prev_obj is not None and isinstance(prev_obj, dict) if name_exists: _id = prev_obj.get("id") + _id = _id or prev_obj.get("userId") if id_exists and name_exists and o_id != _id: raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") if _id: self.new_object.update(dict(id=_id)) + self.new_object.update(dict(user_id=_id)) it_exists = prev_obj is not None and isinstance(prev_obj, dict) return (it_exists, prev_obj) @@ -139,8 +164,9 @@ def requires_update(self, current_obj): ("email", "email"), ("roleList", "roleList"), ("userId", "userId"), + ("userId", "user_id"), ] - # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params # If any does not have eq params, it requires update return any(not dnac_compare_equality(current_obj.get(dnac_param), requested_obj.get(ansible_param)) @@ -148,7 +174,7 @@ def requires_update(self, current_obj): def create(self): result = self.dnac.exec( - family="user_and_roles", + family="userand_roles", function="add_user_api", params=self.create_params(), op_modifies=True, @@ -160,13 +186,33 @@ def update(self): name = self.new_object.get("name") result = None result = self.dnac.exec( - family="user_and_roles", + family="userand_roles", function="update_user_api", params=self.update_all_params(), op_modifies=True, ) return result + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("user_id") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("userId") + if id_: + self.new_object.update(dict(user_id=id_)) + result = self.dnac.exec( + family="userand_roles", + function="delete_user_api", + params=self.delete_by_id_params(), + ) + return result + class ActionModule(ActionBase): def __init__(self, *args, **kwargs): @@ -207,6 +253,7 @@ def run(self, tmp=None, task_vars=None): state = self._task.args.get("state") response = None + if state == "present": (obj_exists, prev_obj) = obj.exists() if obj_exists: @@ -220,6 +267,14 @@ def run(self, tmp=None, task_vars=None): response = obj.create() dnac.object_created() + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + self._result.update(dict(dnac_response=response)) self._result.update(dnac.exit_json()) return self._result diff --git a/plugins/action/user_info.py b/plugins/action/user_info.py index 7a5906fcce..f923914062 100644 --- a/plugins/action/user_info.py +++ b/plugins/action/user_info.py @@ -26,6 +26,7 @@ # Add arguments specific for this module argument_spec.update(dict( invokeSource=dict(type="str"), + authSource=dict(type="str"), headers=dict(type="dict"), )) @@ -65,6 +66,7 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( invoke_source=params.get("invokeSource"), + auth_source=params.get("authSource"), headers=params.get("headers"), ) return new_object @@ -80,7 +82,7 @@ def run(self, tmp=None, task_vars=None): dnac = DNACSDK(params=self._task.args) response = dnac.exec( - family="user_and_roles", + family="userand_roles", function='get_users_api', params=self.get_object(self._task.args), ) diff --git a/plugins/action/users_external_authentication.py b/plugins/action/users_external_authentication.py new file mode 100644 index 0000000000..2c5ab3af7c --- /dev/null +++ b/plugins/action/users_external_authentication.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enable=dict(type="bool"), +)) + +required_if = [ +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class UsersExternalAuthentication(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + enable=params.get("enable"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['enable'] = self.new_object.get('enable') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.dnac.exec( + family="userand_roles", + function="get_external_authentication_setting_api", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + except Exception: + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enable", "enable"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="userand_roles", + function="manage_external_authentication_setting_api", + params=self.create_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = UsersExternalAuthentication(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = prev_obj + dnac.object_present_and_different() + else: + response = prev_obj + dnac.object_already_present() + else: + response = obj.create() + dnac.object_created() + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/users_external_authentication_info.py b/plugins/action/users_external_authentication_info.py new file mode 100644 index 0000000000..7332d1681a --- /dev/null +++ b/plugins/action/users_external_authentication_info.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="userand_roles", + function='get_external_authentication_setting_api', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/users_external_servers_aaa_attribute.py b/plugins/action/users_external_servers_aaa_attribute.py new file mode 100644 index 0000000000..ef9c3aceb2 --- /dev/null +++ b/plugins/action/users_external_servers_aaa_attribute.py @@ -0,0 +1,201 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, + dnac_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + attributeName=dict(type="str"), +)) + +required_if = [ +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class UsersExternalServersAaaAttribute(object): + def __init__(self, params, dnac): + self.dnac = dnac + self.new_object = dict( + attributeName=params.get("attributeName"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + return new_object_params + + def create_params(self): + new_object_params = {} + new_object_params['attributeName'] = self.new_object.get('attributeName') + return new_object_params + + def delete_all_params(self): + new_object_params = {} + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.dnac.exec( + family="userand_roles", + function="get_a_a_a_attribute_api", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + except Exception: + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters("The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("attributeName", "attributeName"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not dnac_compare_equality(current_obj.get(dnac_param), + requested_obj.get(ansible_param)) + for (dnac_param, ansible_param) in obj_params) + + def create(self): + result = self.dnac.exec( + family="userand_roles", + function="add_and_update_a_a_a_attribute_api", + params=self.create_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.dnac.exec( + family="userand_roles", + function="delete_a_a_a_attribute_api", + params=self.delete_all_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(self._task.args) + obj = UsersExternalServersAaaAttribute(self._task.args, dnac) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = prev_obj + dnac.object_present_and_different() + else: + response = prev_obj + dnac.object_already_present() + else: + response = obj.create() + dnac.object_created() + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + dnac.object_deleted() + else: + dnac.object_already_absent() + + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/users_external_servers_aaa_attribute_info.py b/plugins/action/users_external_servers_aaa_attribute_info.py new file mode 100644 index 0000000000..d0cc29d0a5 --- /dev/null +++ b/plugins/action/users_external_servers_aaa_attribute_info.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguments specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + headers=dict(type="dict"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + headers=params.get("headers"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(dnac_response={})) + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="userand_roles", + function='get_a_a_a_attribute_api', + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/wireless_accespoint_configuration.py b/plugins/action/wireless_accespoint_configuration.py index f99e312edb..45b2e78225 100644 --- a/plugins/action/wireless_accespoint_configuration.py +++ b/plugins/action/wireless_accespoint_configuration.py @@ -30,8 +30,6 @@ adminStatus=dict(type="bool"), configureApMode=dict(type="bool"), apMode=dict(type="int"), - configureApHeight=dict(type="bool"), - apHeight=dict(type="int"), configureFailoverPriority=dict(type="bool"), failoverPriority=dict(type="int"), configureLedStatus=dict(type="bool"), @@ -48,6 +46,7 @@ tertiaryControllerName=dict(type="str"), tertiaryIpAddress=dict(type="dict"), radioConfigurations=dict(type="list"), + isAssignedSiteAsLocation=dict(type="bool"), )) required_if = [] @@ -90,8 +89,6 @@ def get_object(self, params): adminStatus=params.get("adminStatus"), configureApMode=params.get("configureApMode"), apMode=params.get("apMode"), - configureApHeight=params.get("configureApHeight"), - apHeight=params.get("apHeight"), configureFailoverPriority=params.get("configureFailoverPriority"), failoverPriority=params.get("failoverPriority"), configureLedStatus=params.get("configureLedStatus"), @@ -108,6 +105,7 @@ def get_object(self, params): tertiaryControllerName=params.get("tertiaryControllerName"), tertiaryIpAddress=params.get("tertiaryIpAddress"), radioConfigurations=params.get("radioConfigurations"), + isAssignedSiteAsLocation=params.get("isAssignedSiteAsLocation"), ) return new_object @@ -121,7 +119,7 @@ def run(self, tmp=None, task_vars=None): response = dnac.exec( family="wireless", - function='configure_access_points', + function='configure_access_points_v1', op_modifies=True, params=self.get_object(self._task.args), ) diff --git a/plugins/action/wireless_accesspoint_configuration_create.py b/plugins/action/wireless_accesspoint_configuration_create.py new file mode 100644 index 0000000000..8778b67576 --- /dev/null +++ b/plugins/action/wireless_accesspoint_configuration_create.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( + DNACSDK, + dnac_argument_spec, +) + +# Get common arguements specification +argument_spec = dnac_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + apList=dict(type="list"), + configureAdminStatus=dict(type="bool"), + adminStatus=dict(type="bool"), + configureApMode=dict(type="bool"), + apMode=dict(type="int"), + configureFailoverPriority=dict(type="bool"), + failoverPriority=dict(type="int"), + configureLedStatus=dict(type="bool"), + ledStatus=dict(type="bool"), + configureLedBrightnessLevel=dict(type="bool"), + ledBrightnessLevel=dict(type="int"), + configureLocation=dict(type="bool"), + location=dict(type="str"), + configureHAController=dict(type="bool"), + primaryControllerName=dict(type="str"), + primaryIpAddress=dict(type="dict"), + secondaryControllerName=dict(type="str"), + secondaryIpAddress=dict(type="dict"), + tertiaryControllerName=dict(type="str"), + tertiaryIpAddress=dict(type="dict"), + radioConfigurations=dict(type="list"), + configureCleanAirSI24Ghz=dict(type="bool"), + cleanAirSI24=dict(type="bool"), + configureCleanAirSI5Ghz=dict(type="bool"), + cleanAirSI5=dict(type="bool"), + configureCleanAirSI6Ghz=dict(type="bool"), + cleanAirSI6=dict(type="bool"), + isAssignedSiteAsLocation=dict(type="bool"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + apList=params.get("apList"), + configureAdminStatus=params.get("configureAdminStatus"), + adminStatus=params.get("adminStatus"), + configureApMode=params.get("configureApMode"), + apMode=params.get("apMode"), + configureFailoverPriority=params.get("configureFailoverPriority"), + failoverPriority=params.get("failoverPriority"), + configureLedStatus=params.get("configureLedStatus"), + ledStatus=params.get("ledStatus"), + configureLedBrightnessLevel=params.get("configureLedBrightnessLevel"), + ledBrightnessLevel=params.get("ledBrightnessLevel"), + configureLocation=params.get("configureLocation"), + location=params.get("location"), + configureHAController=params.get("configureHAController"), + primaryControllerName=params.get("primaryControllerName"), + primaryIpAddress=params.get("primaryIpAddress"), + secondaryControllerName=params.get("secondaryControllerName"), + secondaryIpAddress=params.get("secondaryIpAddress"), + tertiaryControllerName=params.get("tertiaryControllerName"), + tertiaryIpAddress=params.get("tertiaryIpAddress"), + radioConfigurations=params.get("radioConfigurations"), + configureCleanAirSI24Ghz=params.get("configureCleanAirSI24Ghz"), + cleanAirSI24=params.get("cleanAirSI24"), + configureCleanAirSI5Ghz=params.get("configureCleanAirSI5Ghz"), + cleanAirSI5=params.get("cleanAirSI5"), + configureCleanAirSI6Ghz=params.get("configureCleanAirSI6Ghz"), + cleanAirSI6=params.get("cleanAirSI6"), + isAssignedSiteAsLocation=params.get("isAssignedSiteAsLocation"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + dnac = DNACSDK(params=self._task.args) + + response = dnac.exec( + family="wireless", + function='configure_access_points_v2', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(dnac_response=response)) + self._result.update(dnac.exit_json()) + return self._result diff --git a/plugins/action/wireless_dynamic_interface.py b/plugins/action/wireless_dynamic_interface.py index 51f458f572..416d665a0b 100644 --- a/plugins/action/wireless_dynamic_interface.py +++ b/plugins/action/wireless_dynamic_interface.py @@ -32,13 +32,10 @@ argument_spec.update(dict( state=dict(type="str", default="present", choices=["present", "absent"]), interfaceName=dict(type="str"), - vlanId=dict(type="int"), - headers=dict(type="dict"), + vlanId=dict(type="float"), )) required_if = [ - ("state", "present", ["interfaceName"], True), - ("state", "absent", ["interfaceName"], True), ] required_one_of = [] mutually_exclusive = [] @@ -51,7 +48,6 @@ def __init__(self, params, dnac): self.new_object = dict( interfaceName=params.get("interfaceName"), vlanId=params.get("vlanId"), - headers=params.get("headers"), interface_name=params.get("interfaceName"), ) @@ -66,7 +62,7 @@ def create_params(self): new_object_params['vlanId'] = self.new_object.get('vlanId') return new_object_params - def delete_by_name_params(self): + def delete_all_params(self): new_object_params = {} new_object_params['interface_name'] = self.new_object.get('interface_name') new_object_params['headers'] = self.new_object.get('headers') @@ -100,18 +96,12 @@ def exists(self): name_exists = False o_id = self.new_object.get("id") name = self.new_object.get("name") - name = name or self.new_object.get("interface_name") if o_id: prev_obj = self.get_object_by_id(o_id) id_exists = prev_obj is not None and isinstance(prev_obj, dict) if not id_exists and name: prev_obj = self.get_object_by_name(name) name_exists = prev_obj is not None and isinstance(prev_obj, dict) - if id_exists: - _name = prev_obj.get("name") - _name = _name or prev_obj.get("interfaceName") - if _name: - self.new_object.update(dict(interface_name=_name)) if name_exists: _id = prev_obj.get("id") if id_exists and name_exists and o_id != _id: @@ -147,20 +137,11 @@ def create(self): def delete(self): id = self.new_object.get("id") name = self.new_object.get("name") - name = name or self.new_object.get("interface_name") result = None - if not name: - prev_obj_id = self.get_object_by_id(id) - name_ = None - if prev_obj_id: - name_ = prev_obj_id.get("name") - name_ = name_ or prev_obj_id.get("interfaceName") - if name_: - self.new_object.update(dict(interface_name=name_)) result = self.dnac.exec( family="wireless", function="delete_dynamic_interface", - params=self.delete_by_name_params(), + params=self.delete_all_params(), ) return result diff --git a/plugins/action/wireless_enterprise_ssid.py b/plugins/action/wireless_enterprise_ssid.py index 7e2d129c06..4773b9bcca 100644 --- a/plugins/action/wireless_enterprise_ssid.py +++ b/plugins/action/wireless_enterprise_ssid.py @@ -50,6 +50,19 @@ enableNeighborList=dict(type="bool"), mfpClientProtection=dict(type="str"), nasOptions=dict(type="list"), + profileName=dict(type="str"), + policyProfileName=dict(type="str"), + aaaOverride=dict(type="bool"), + coverageHoleDetectionEnable=dict(type="bool"), + protectedManagementFrame=dict(type="str"), + multiPSKSettings=dict(type="list"), + clientRateLimit=dict(type="float"), + authKeyMgmt=dict(type="list"), + rsnCipherSuiteGcmp256=dict(type="bool"), + rsnCipherSuiteCcmp256=dict(type="bool"), + rsnCipherSuiteGcmp128=dict(type="bool"), + ghz6PolicyClientSteering=dict(type="bool"), + ghz24Policy=dict(type="str"), ssidName=dict(type="str"), )) @@ -85,6 +98,19 @@ def __init__(self, params, dnac): enableNeighborList=params.get("enableNeighborList"), mfpClientProtection=params.get("mfpClientProtection"), nasOptions=params.get("nasOptions"), + profileName=params.get("profileName"), + policyProfileName=params.get("policyProfileName"), + aaaOverride=params.get("aaaOverride"), + coverageHoleDetectionEnable=params.get("coverageHoleDetectionEnable"), + protectedManagementFrame=params.get("protectedManagementFrame"), + multiPSKSettings=params.get("multiPSKSettings"), + clientRateLimit=params.get("clientRateLimit"), + authKeyMgmt=params.get("authKeyMgmt"), + rsnCipherSuiteGcmp256=params.get("rsnCipherSuiteGcmp256"), + rsnCipherSuiteCcmp256=params.get("rsnCipherSuiteCcmp256"), + rsnCipherSuiteGcmp128=params.get("rsnCipherSuiteGcmp128"), + ghz6PolicyClientSteering=params.get("ghz6PolicyClientSteering"), + ghz24Policy=params.get("ghz24Policy"), ssid_name=params.get("ssidName"), ) @@ -115,6 +141,19 @@ def create_params(self): new_object_params['enableNeighborList'] = self.new_object.get('enableNeighborList') new_object_params['mfpClientProtection'] = self.new_object.get('mfpClientProtection') new_object_params['nasOptions'] = self.new_object.get('nasOptions') + new_object_params['profileName'] = self.new_object.get('profileName') + new_object_params['policyProfileName'] = self.new_object.get('policyProfileName') + new_object_params['aaaOverride'] = self.new_object.get('aaaOverride') + new_object_params['coverageHoleDetectionEnable'] = self.new_object.get('coverageHoleDetectionEnable') + new_object_params['protectedManagementFrame'] = self.new_object.get('protectedManagementFrame') + new_object_params['multiPSKSettings'] = self.new_object.get('multiPSKSettings') + new_object_params['clientRateLimit'] = self.new_object.get('clientRateLimit') + new_object_params['authKeyMgmt'] = self.new_object.get('authKeyMgmt') + new_object_params['rsnCipherSuiteGcmp256'] = self.new_object.get('rsnCipherSuiteGcmp256') + new_object_params['rsnCipherSuiteCcmp256'] = self.new_object.get('rsnCipherSuiteCcmp256') + new_object_params['rsnCipherSuiteGcmp128'] = self.new_object.get('rsnCipherSuiteGcmp128') + new_object_params['ghz6PolicyClientSteering'] = self.new_object.get('ghz6PolicyClientSteering') + new_object_params['ghz24Policy'] = self.new_object.get('ghz24Policy') return new_object_params def delete_by_name_params(self): @@ -143,6 +182,19 @@ def update_all_params(self): new_object_params['enableNeighborList'] = self.new_object.get('enableNeighborList') new_object_params['mfpClientProtection'] = self.new_object.get('mfpClientProtection') new_object_params['nasOptions'] = self.new_object.get('nasOptions') + new_object_params['profileName'] = self.new_object.get('profileName') + new_object_params['policyProfileName'] = self.new_object.get('policyProfileName') + new_object_params['aaaOverride'] = self.new_object.get('aaaOverride') + new_object_params['coverageHoleDetectionEnable'] = self.new_object.get('coverageHoleDetectionEnable') + new_object_params['protectedManagementFrame'] = self.new_object.get('protectedManagementFrame') + new_object_params['multiPSKSettings'] = self.new_object.get('multiPSKSettings') + new_object_params['clientRateLimit'] = self.new_object.get('clientRateLimit') + new_object_params['authKeyMgmt'] = self.new_object.get('authKeyMgmt') + new_object_params['rsnCipherSuiteGcmp256'] = self.new_object.get('rsnCipherSuiteGcmp256') + new_object_params['rsnCipherSuiteCcmp256'] = self.new_object.get('rsnCipherSuiteCcmp256') + new_object_params['rsnCipherSuiteGcmp128'] = self.new_object.get('rsnCipherSuiteGcmp128') + new_object_params['ghz6PolicyClientSteering'] = self.new_object.get('ghz6PolicyClientSteering') + new_object_params['ghz24Policy'] = self.new_object.get('ghz24Policy') return new_object_params def get_object_by_name(self, name): @@ -231,6 +283,19 @@ def requires_update(self, current_obj): ("enableNeighborList", "enableNeighborList"), ("mfpClientProtection", "mfpClientProtection"), ("nasOptions", "nasOptions"), + ("profileName", "profileName"), + ("policyProfileName", "policyProfileName"), + ("aaaOverride", "aaaOverride"), + ("coverageHoleDetectionEnable", "coverageHoleDetectionEnable"), + ("protectedManagementFrame", "protectedManagementFrame"), + ("multiPSKSettings", "multiPSKSettings"), + ("clientRateLimit", "clientRateLimit"), + ("authKeyMgmt", "authKeyMgmt"), + ("rsnCipherSuiteGcmp256", "rsnCipherSuiteGcmp256"), + ("rsnCipherSuiteCcmp256", "rsnCipherSuiteCcmp256"), + ("rsnCipherSuiteGcmp128", "rsnCipherSuiteGcmp128"), + ("ghz6PolicyClientSteering", "ghz6PolicyClientSteering"), + ("ghz24Policy", "ghz24Policy"), ("ssidName", "ssid_name"), ] # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params diff --git a/plugins/action/wireless_profile.py b/plugins/action/wireless_profile.py index b2b22fb8e4..9bdfadd9db 100644 --- a/plugins/action/wireless_profile.py +++ b/plugins/action/wireless_profile.py @@ -20,6 +20,7 @@ DNACSDK, dnac_argument_spec, dnac_compare_equality, + get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( InconsistentParameters, @@ -35,7 +36,7 @@ )) required_if = [ - ("state", "present", ["profileDetails"], True), + ("state", "present", ["wirelessProfileName"], True), ("state", "absent", ["wirelessProfileName"], True), ] required_one_of = [] @@ -53,7 +54,7 @@ def __init__(self, params, dnac): def get_all_params(self, name=None, id=None): new_object_params = {} - new_object_params['profile_name'] = name or self.new_object.get('wireless_profile_name') + new_object_params['profile_name'] = self.new_object.get('wireless_profile_name') return new_object_params def create_params(self): @@ -103,9 +104,6 @@ def exists(self): o_id = self.new_object.get("id") name = self.new_object.get("name") name = name or self.new_object.get("wireless_profile_name") - profile_details = self.new_object.get("profileDetails") - if profile_details and profile_details.get("name"): - name = name or profile_details.get("name") if o_id: prev_obj = self.get_object_by_id(o_id) id_exists = prev_obj is not None and isinstance(prev_obj, dict) diff --git a/plugins/action/wireless_psk_override.py b/plugins/action/wireless_psk_override.py index 6fe372d58b..1bf29f6e69 100644 --- a/plugins/action/wireless_psk_override.py +++ b/plugins/action/wireless_psk_override.py @@ -25,7 +25,10 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( - payload=dict(type="list"), + ssidName=dict(type="str"), + site=dict(type="str"), + passPhrase=dict(type="str"), + wlanProfileName=dict(type="str"), )) required_if = [] @@ -63,7 +66,10 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( - payload=params.get("payload"), + ssidName=params.get("ssidName"), + site=params.get("site"), + passPhrase=params.get("passPhrase"), + wlanProfileName=params.get("wlanProfileName"), ) return new_object diff --git a/plugins/action/wireless_sensor_test_results_info.py b/plugins/action/wireless_sensor_test_results_info.py index 5948fad3cb..26ff29cd87 100644 --- a/plugins/action/wireless_sensor_test_results_info.py +++ b/plugins/action/wireless_sensor_test_results_info.py @@ -26,8 +26,8 @@ # Add arguments specific for this module argument_spec.update(dict( siteId=dict(type="str"), - startTime=dict(type="int"), - endTime=dict(type="int"), + startTime=dict(type="float"), + endTime=dict(type="float"), testFailureBy=dict(type="str"), headers=dict(type="dict"), )) diff --git a/plugins/modules/accesspoint_configuration_details_by_task_id_info.py b/plugins/modules/accesspoint_configuration_details_by_task_id_info.py index 642034e5ca..165f9596dd 100644 --- a/plugins/modules/accesspoint_configuration_details_by_task_id_info.py +++ b/plugins/modules/accesspoint_configuration_details_by_task_id_info.py @@ -11,7 +11,7 @@ description: - Get Accesspoint Configuration Details By Task Id by id. - Users can query the access point configuration result using this intent API. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -24,8 +24,8 @@ - Task_id path parameter. Task id information of ap config. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless GetAccessPointConfigurationTaskResult description: Complete reference of the GetAccessPointConfigurationTaskResult API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/app_policy_default_info.py b/plugins/modules/app_policy_default_info.py index 921f7a095f..c14daa7e42 100644 --- a/plugins/modules/app_policy_default_info.py +++ b/plugins/modules/app_policy_default_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy GetApplicationPolicyDefault description: Complete reference of the GetApplicationPolicyDefault API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/app_policy_info.py b/plugins/modules/app_policy_info.py index 3479d1edee..27bc0c30b2 100644 --- a/plugins/modules/app_policy_info.py +++ b/plugins/modules/app_policy_info.py @@ -24,8 +24,8 @@ - PolicyScope query parameter. Policy scope name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy GetApplicationPolicy description: Complete reference of the GetApplicationPolicy API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/app_policy_intent_create.py b/plugins/modules/app_policy_intent_create.py index fd487ca0c4..09074c41d6 100644 --- a/plugins/modules/app_policy_intent_create.py +++ b/plugins/modules/app_policy_intent_create.py @@ -28,7 +28,8 @@ elements: dict suboptions: groupId: - description: Group id. + description: The site(s) ID where the Application QoS Policy will be + deployed. elements: str type: list ssid: @@ -124,7 +125,8 @@ elements: dict suboptions: groupId: - description: Group id. + description: The site(s) ID where the Application QoS Policy will be + deployed. elements: str type: list id: @@ -226,8 +228,8 @@ type: dict type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy ApplicationPolicyIntent description: Complete reference of the ApplicationPolicyIntent API. @@ -314,7 +316,6 @@ - idRef: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/app_policy_queuing_profile.py b/plugins/modules/app_policy_queuing_profile.py index 9260ffbf52..893e799ce5 100644 --- a/plugins/modules/app_policy_queuing_profile.py +++ b/plugins/modules/app_policy_queuing_profile.py @@ -75,7 +75,7 @@ type: str type: list type: - description: Type. + description: The allowed clause types are BANDWIDTH, DSCP_CUSTOMIZATION. type: str type: list description: @@ -89,8 +89,8 @@ type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy CreateApplicationPolicyQueuingProfile description: Complete reference of the CreateApplicationPolicyQueuingProfile API. @@ -183,7 +183,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/app_policy_queuing_profile_count_info.py b/plugins/modules/app_policy_queuing_profile_count_info.py index 2a3b2c4dff..ef68ca49b3 100644 --- a/plugins/modules/app_policy_queuing_profile_count_info.py +++ b/plugins/modules/app_policy_queuing_profile_count_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy GetApplicationPolicyQueuingProfileCount description: Complete reference of the GetApplicationPolicyQueuingProfileCount API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/app_policy_queuing_profile_info.py b/plugins/modules/app_policy_queuing_profile_info.py index bb89873a67..ac351cc887 100644 --- a/plugins/modules/app_policy_queuing_profile_info.py +++ b/plugins/modules/app_policy_queuing_profile_info.py @@ -24,8 +24,8 @@ - Name query parameter. Queuing profile name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy GetApplicationPolicyQueuingProfile description: Complete reference of the GetApplicationPolicyQueuingProfile API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/application_policy_application_set.py b/plugins/modules/application_policy_application_set.py new file mode 100644 index 0000000000..512eebe307 --- /dev/null +++ b/plugins/modules/application_policy_application_set.py @@ -0,0 +1,117 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: application_policy_application_set +short_description: Resource module for Application Policy Application Set +description: +- Manage operations create and delete of the resource Application Policy Application Set. +- Create new custom application set/s. +- Delete existing custom application set by id. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + id: + description: Id path parameter. Id of custom application set to delete. + type: str + payload: + description: Application Policy Application Set's payload. + elements: dict + suboptions: + defaultBusinessRelevance: + description: Default business relevance. + type: str + name: + description: Application Set name. + type: str + namespace: + description: Namespace, should be set to scalablegroup application. + type: str + qualifier: + description: Qualifier, should be set to application. + type: str + scalableGroupExternalHandle: + description: Scalable group external handle, should be set to application set + name. + type: str + scalableGroupType: + description: Scalable group type, should be set to APPLICATION_GROUP. + type: str + type: + description: Type, should be set to scalablegroup. + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Application Policy CreateApplicationSets + description: Complete reference of the CreateApplicationSets API. + link: https://developer.cisco.com/docs/dna-center/#!create-application-sets +- name: Cisco DNA Center documentation for Application Policy DeleteApplicationSet + description: Complete reference of the DeleteApplicationSet API. + link: https://developer.cisco.com/docs/dna-center/#!delete-application-set +notes: + - SDK Method used are + application_policy.ApplicationPolicy.create_application_sets, + application_policy.ApplicationPolicy.delete_application_set, + + - Paths used are + post /dna/intent/api/v2/application-policy-application-set, + delete /dna/intent/api/v2/application-policy-application-set/{id}, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.application_policy_application_set: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - defaultBusinessRelevance: string + name: string + namespace: string + qualifier: string + scalableGroupExternalHandle: string + scalableGroupType: string + type: string + +- name: Delete by id + cisco.dnac.application_policy_application_set: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/application_policy_application_set_count_info.py b/plugins/modules/application_policy_application_set_count_info.py new file mode 100644 index 0000000000..5c4bed86f8 --- /dev/null +++ b/plugins/modules/application_policy_application_set_count_info.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: application_policy_application_set_count_info +short_description: Information module for Application Policy Application Set Count +description: +- Get all Application Policy Application Set Count. +- Get the number of all existing application sets. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + scalableGroupType: + description: + - ScalableGroupType query parameter. Scalable group type to retrieve, valid value APPLICATION_GROUP. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Application Policy GetApplicationSetCount + description: Complete reference of the GetApplicationSetCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-application-set-count +notes: + - SDK Method used are + application_policy.ApplicationPolicy.get_application_set_count, + + - Paths used are + get /dna/intent/api/v2/application-policy-application-set-count, + +""" + +EXAMPLES = r""" +- name: Get all Application Policy Application Set Count + cisco.dnac.application_policy_application_set_count_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + scalableGroupType: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": 0, + "version": "string" + } +""" diff --git a/plugins/modules/application_policy_application_set_info.py b/plugins/modules/application_policy_application_set_info.py new file mode 100644 index 0000000000..8a2e7efa2b --- /dev/null +++ b/plugins/modules/application_policy_application_set_info.py @@ -0,0 +1,101 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: application_policy_application_set_info +short_description: Information module for Application Policy Application Set +description: +- Get all Application Policy Application Set. +- Get application set/s by offset/limit or by name. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + attributes: + description: + - Attributes query parameter. Attributes to retrieve, valid value applicationSet. + type: str + name: + description: + - Name query parameter. Application set name. + type: str + offset: + description: + - Offset query parameter. The starting point or index from where the paginated results should begin. + type: float + limit: + description: + - > + Limit query parameter. The limit which is the maximum number of items to include in a single page of + results, max value 500. + type: float +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Application Policy GetApplicationSets2 + description: Complete reference of the GetApplicationSets2 API. + link: https://developer.cisco.com/docs/dna-center/#!get-application-sets-2 +notes: + - SDK Method used are + application_policy.ApplicationPolicy.get_application_sets2, + + - Paths used are + get /dna/intent/api/v2/application-policy-application-set, + +""" + +EXAMPLES = r""" +- name: Get all Application Policy Application Set + cisco.dnac.application_policy_application_set_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + attributes: string + name: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "instanceId": 0, + "displayName": "string", + "instanceVersion": 0, + "defaultBusinessRelevance": "string", + "identitySource": { + "id": "string", + "type": "string" + }, + "name": "string", + "namespace": "string", + "scalableGroupExternalHandle": "string", + "scalableGroupType": "string", + "type": "string" + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/application_sets.py b/plugins/modules/application_sets.py index b4c5dd14c3..2955c40ef3 100644 --- a/plugins/modules/application_sets.py +++ b/plugins/modules/application_sets.py @@ -29,19 +29,19 @@ type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy CreateApplicationSet description: Complete reference of the CreateApplicationSet API. link: https://developer.cisco.com/docs/dna-center/#!create-application-set -- name: Cisco DNA Center documentation for Application Policy DeleteApplicationSet - description: Complete reference of the DeleteApplicationSet API. - link: https://developer.cisco.com/docs/dna-center/#!delete-application-set +- name: Cisco DNA Center documentation for Application Policy DeleteApplicationSet2 + description: Complete reference of the DeleteApplicationSet2 API. + link: https://developer.cisco.com/docs/dna-center/#!delete-application-set-2 notes: - SDK Method used are application_policy.ApplicationPolicy.create_application_set, - application_policy.ApplicationPolicy.delete_application_set, + application_policy.ApplicationPolicy.delete_application_set2, - Paths used are post /dna/intent/api/v1/application-policy-application-set, @@ -76,7 +76,6 @@ - name: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/application_sets_count_info.py b/plugins/modules/application_sets_count_info.py index bd6336fb7c..97b87f7dc6 100644 --- a/plugins/modules/application_sets_count_info.py +++ b/plugins/modules/application_sets_count_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy GetApplicationSetsCount description: Complete reference of the GetApplicationSetsCount API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/application_sets_info.py b/plugins/modules/application_sets_info.py index 168674c87f..fd0870bd20 100644 --- a/plugins/modules/application_sets_info.py +++ b/plugins/modules/application_sets_info.py @@ -22,18 +22,18 @@ offset: description: - Offset query parameter. - type: int + type: float limit: description: - Limit query parameter. - type: int + type: float name: description: - Name query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy GetApplicationSets description: Complete reference of the GetApplicationSets API. @@ -64,7 +64,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/applications.py b/plugins/modules/applications.py index 43c18a12bf..616a9c70b9 100644 --- a/plugins/modules/applications.py +++ b/plugins/modules/applications.py @@ -32,29 +32,6 @@ description: Id Ref. type: str type: dict - indicativeNetworkIdentity: - description: Applications's indicativeNetworkIdentity. - elements: dict - suboptions: - displayName: - description: DisplayName. - type: str - id: - description: Id. - type: str - lowerPort: - description: LowerPort. - type: int - ports: - description: Ports. - type: str - protocol: - description: Protocol. - type: str - upperPort: - description: UpperPort. - type: int - type: list name: description: Name. type: str @@ -133,22 +110,22 @@ type: list type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy CreateApplication description: Complete reference of the CreateApplication API. link: https://developer.cisco.com/docs/dna-center/#!create-application -- name: Cisco DNA Center documentation for Application Policy DeleteApplication - description: Complete reference of the DeleteApplication API. - link: https://developer.cisco.com/docs/dna-center/#!delete-application +- name: Cisco DNA Center documentation for Application Policy DeleteApplication2 + description: Complete reference of the DeleteApplication2 API. + link: https://developer.cisco.com/docs/dna-center/#!delete-application-2 - name: Cisco DNA Center documentation for Application Policy EditApplication description: Complete reference of the EditApplication API. link: https://developer.cisco.com/docs/dna-center/#!edit-application notes: - SDK Method used are application_policy.ApplicationPolicy.create_application, - application_policy.ApplicationPolicy.delete_application, + application_policy.ApplicationPolicy.delete_application2, application_policy.ApplicationPolicy.edit_application, - Paths used are @@ -172,13 +149,6 @@ payload: - applicationSet: idRef: string - indicativeNetworkIdentity: - - displayName: string - id: string - lowerPort: 0 - ports: string - protocol: string - upperPort: 0 name: string networkApplications: - appProtocol: string @@ -258,7 +228,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -266,7 +235,10 @@ type: dict sample: > { - "taskId": "string", - "url": "string" + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" } """ diff --git a/plugins/modules/applications_count_info.py b/plugins/modules/applications_count_info.py index cf4eb7d8de..dd6056ba1c 100644 --- a/plugins/modules/applications_count_info.py +++ b/plugins/modules/applications_count_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy GetApplicationsCount description: Complete reference of the GetApplicationsCount API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -57,7 +56,7 @@ type: dict sample: > { - "response": 0, + "response": "string", "version": "string" } """ diff --git a/plugins/modules/applications_count_v2_info.py b/plugins/modules/applications_count_v2_info.py new file mode 100644 index 0000000000..32cbe8554e --- /dev/null +++ b/plugins/modules/applications_count_v2_info.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: applications_count_v2_info +short_description: Information module for Applications Count V2 +description: +- Get all Applications Count V2. +- Get the number of all existing applications. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + scalableGroupType: + description: + - ScalableGroupType query parameter. Scalable group type to retrieve, valid value APPLICATION. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Application Policy GetApplicationCount + description: Complete reference of the GetApplicationCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-application-count +notes: + - SDK Method used are + application_policy.ApplicationPolicy.get_application_count, + + - Paths used are + get /dna/intent/api/v2/applications-count, + +""" + +EXAMPLES = r""" +- name: Get all Applications Count V2 + cisco.dnac.applications_count_v2_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + scalableGroupType: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": 0, + "version": "string" + } +""" diff --git a/plugins/modules/applications_health_info.py b/plugins/modules/applications_health_info.py index 883fd5398b..b136b346ba 100644 --- a/plugins/modules/applications_health_info.py +++ b/plugins/modules/applications_health_info.py @@ -36,11 +36,11 @@ startTime: description: - StartTime query parameter. Starting epoch time in milliseconds of time window. - type: int + type: float endTime: description: - EndTime query parameter. Ending epoch time in milliseconds of time window. - type: int + type: float applicationHealth: description: - > @@ -52,20 +52,20 @@ - > Offset query parameter. The offset of the first application in the returned data (optionally used with siteId only). - type: int + type: float limit: description: - > Limit query parameter. The max number of application entries in returned data 1, 1000 (optionally used with siteId only). - type: int + type: float applicationName: description: - ApplicationName query parameter. The name of the application to get information on. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Applications Applications description: Complete reference of the Applications API. @@ -102,7 +102,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/applications_info.py b/plugins/modules/applications_info.py index 6570ca75d4..5bedfcba9a 100644 --- a/plugins/modules/applications_info.py +++ b/plugins/modules/applications_info.py @@ -22,25 +22,25 @@ offset: description: - Offset query parameter. The offset of the first application to be returned. - type: int + type: float limit: description: - Limit query parameter. The maximum number of applications to be returned. - type: int + type: float name: description: - Name query parameter. Application's name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Application Policy GetApplications - description: Complete reference of the GetApplications API. - link: https://developer.cisco.com/docs/dna-center/#!get-applications +- name: Cisco DNA Center documentation for Application Policy GetApplications2 + description: Complete reference of the GetApplications2 API. + link: https://developer.cisco.com/docs/dna-center/#!get-applications-2 notes: - SDK Method used are - application_policy.ApplicationPolicy.get_applications, + application_policy.ApplicationPolicy.get_applications2, - Paths used are get /dna/intent/api/v1/applications, @@ -64,7 +64,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -76,16 +75,6 @@ { "id": "string", "name": "string", - "indicativeNetworkIdentity": [ - { - "id": "string", - "displayName": "string", - "lowerPort": 0, - "ports": "string", - "protocol": "string", - "upperPort": 0 - } - ], "networkApplications": [ { "id": "string", @@ -98,8 +87,8 @@ "helpString": "string", "longDescription": "string", "name": "string", - "popularity": 0, - "rank": 0, + "popularity": "string", + "rank": "string", "trafficClass": "string", "serverName": "string", "url": "string", @@ -111,10 +100,10 @@ { "id": "string", "displayName": "string", - "lowerPort": 0, + "lowerPort": "string", "ports": "string", "protocol": "string", - "upperPort": 0 + "upperPort": "string" } ], "applicationSet": { diff --git a/plugins/modules/applications_v2.py b/plugins/modules/applications_v2.py new file mode 100644 index 0000000000..262db5ab04 --- /dev/null +++ b/plugins/modules/applications_v2.py @@ -0,0 +1,342 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: applications_v2 +short_description: Resource module for Applications V2 +description: +- Manage operations create, update and delete of the resource Applications V2. +- Create new custom application/s. +- Delete existing custom application by id. +- Edit the attributes of an existing application. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + id: + description: Id path parameter. Id of custom application to delete. + type: str + payload: + description: Applications V2's payload. + elements: dict + suboptions: + displayName: + description: Display name. + type: str + id: + description: Application id. + type: str + indicativeNetworkIdentity: + description: Applications V2's indicativeNetworkIdentity. + elements: dict + suboptions: + displayName: + description: Display name. + type: str + id: + description: Id. + type: str + lowerPort: + description: Lower port. + type: float + ports: + description: Ports. + type: str + protocol: + description: Protocol. + type: str + upperPort: + description: Upper port. + type: float + type: list + instanceId: + description: Instance id. + type: int + instanceVersion: + description: Instance version. + type: float + name: + description: Application name. + type: str + namespace: + description: Namespace. + type: str + networkApplications: + description: Applications V2's networkApplications. + elements: dict + suboptions: + appProtocol: + description: App protocol. + type: str + applicationSubType: + description: Application sub type, LEARNED discovered application, NONE + nbar and custom application. + type: str + applicationType: + description: Application type, DEFAULT nbar application, DEFAULT_MODIFIED + nbar modified application, CUSTOM custom application. + type: str + categoryId: + description: Category id. + type: str + displayName: + description: Display name. + type: str + dscp: + description: Dscp. + type: str + engineId: + description: Engine id. + type: str + helpString: + description: Help string. + type: str + id: + description: Id. + type: str + ignoreConflict: + description: Ignore conflict, true or false. + type: bool + longDescription: + description: Long description. + type: str + name: + description: Application name. + type: str + popularity: + description: Popularity. + type: float + rank: + description: Rank, any value between 1 to 65535. + type: int + selectorId: + description: Selector id. + type: str + serverName: + description: Server name. + type: str + trafficClass: + description: Traffic class. + type: str + url: + description: Url. + type: str + type: list + networkIdentity: + description: Applications V2's networkIdentity. + elements: dict + suboptions: + displayName: + description: Display name. + type: str + id: + description: Id. + type: str + ipv4Subnet: + description: Ipv4 subnet. + elements: str + type: list + ipv6Subnet: + description: Ipv6 subnet. + elements: dict + type: list + lowerPort: + description: Lower port. + type: float + ports: + description: Ports. + type: str + protocol: + description: Protocol. + type: str + upperPort: + description: Upper port. + type: float + type: list + parentScalableGroup: + description: Applications V2's parentScalableGroup. + suboptions: + idRef: + description: Id reference to parent application set. + type: str + type: dict + qualifier: + description: Qualifier, valid value application. + type: str + scalableGroupExternalHandle: + description: Scalable group external handle, should be equal to Application + name. + type: str + scalableGroupType: + description: Scalable group type, valid value APPLICATION. + type: str + type: + description: Type, valid value scalablegroup. + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Application Policy CreateApplications + description: Complete reference of the CreateApplications API. + link: https://developer.cisco.com/docs/dna-center/#!create-applications +- name: Cisco DNA Center documentation for Application Policy DeleteApplication + description: Complete reference of the DeleteApplication API. + link: https://developer.cisco.com/docs/dna-center/#!delete-application +- name: Cisco DNA Center documentation for Application Policy EditApplications + description: Complete reference of the EditApplications API. + link: https://developer.cisco.com/docs/dna-center/#!edit-applications +notes: + - SDK Method used are + application_policy.ApplicationPolicy.create_applications, + application_policy.ApplicationPolicy.delete_application, + application_policy.ApplicationPolicy.edit_applications, + + - Paths used are + post /dna/intent/api/v2/applications, + delete /dna/intent/api/v2/applications/{id}, + put /dna/intent/api/v2/applications, + +""" + +EXAMPLES = r""" +- name: Update all + cisco.dnac.applications_v2: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - displayName: string + id: string + indicativeNetworkIdentity: + - displayName: string + id: string + lowerPort: 0 + ports: string + protocol: string + upperPort: 0 + instanceId: 0 + instanceVersion: 0 + name: string + namespace: string + networkApplications: + - appProtocol: string + applicationSubType: string + applicationType: string + categoryId: string + displayName: string + dscp: string + engineId: string + helpString: string + id: string + ignoreConflict: true + longDescription: string + name: string + popularity: 0 + rank: 0 + selectorId: string + serverName: string + trafficClass: string + url: string + networkIdentity: + - displayName: string + id: string + ipv4Subnet: + - string + ipv6Subnet: + - {} + lowerPort: 0 + ports: string + protocol: string + upperPort: 0 + parentScalableGroup: + idRef: string + qualifier: string + scalableGroupExternalHandle: string + scalableGroupType: string + type: string + +- name: Create + cisco.dnac.applications_v2: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - indicativeNetworkIdentity: + - ipv4Subnet: + - string + ipv6Subnet: + - string + lowerPort: 0 + ports: string + protocol: string + upperPort: 0 + name: string + networkApplications: + - appProtocol: string + applicationType: string + categoryId: string + dscp: string + engineId: 0 + helpString: string + ignoreConflict: true + rank: 0 + serverName: string + trafficClass: string + type: string + url: string + networkIdentity: + - ipv4Subnet: + - string + lowerPort: 0 + ports: string + protocol: string + upperPort: 0 + parentScalableGroup: + idRef: string + scalableGroupType: string + type: string + +- name: Delete by id + cisco.dnac.applications_v2: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/applications_v2_info.py b/plugins/modules/applications_v2_info.py new file mode 100644 index 0000000000..63cf3ad192 --- /dev/null +++ b/plugins/modules/applications_v2_info.py @@ -0,0 +1,152 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: applications_v2_info +short_description: Information module for Applications V2 +description: +- Get all Applications V2. +- Get application/s by offset/limit or by name. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + attributes: + description: + - Attributes query parameter. Attributes to retrieve, valid value application. + type: str + name: + description: + - Name query parameter. The application name. + type: str + offset: + description: + - Offset query parameter. The starting point or index from where the paginated results should begin. + type: float + limit: + description: + - > + Limit query parameter. The limit which is the maximum number of items to include in a single page of + results, max value 500. + type: float +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Application Policy GetApplications + description: Complete reference of the GetApplications API. + link: https://developer.cisco.com/docs/dna-center/#!get-applications +notes: + - SDK Method used are + application_policy.ApplicationPolicy.get_applications, + + - Paths used are + get /dna/intent/api/v2/applications, + +""" + +EXAMPLES = r""" +- name: Get all Applications V2 + cisco.dnac.applications_v2_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + attributes: string + name: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "instanceId": 0, + "displayName": "string", + "instanceVersion": 0, + "identitySource": { + "id": "string", + "type": "string" + }, + "indicativeNetworkIdentity": [ + { + "id": "string", + "displayName": "string", + "lowerPort": 0, + "ports": "string", + "protocol": "string", + "upperPort": 0 + } + ], + "name": "string", + "namespace": "string", + "networkApplications": [ + { + "id": "string", + "appProtocol": "string", + "applicationSubType": "string", + "applicationType": "string", + "categoryId": "string", + "displayName": "string", + "dscp": "string", + "engineId": "string", + "helpString": "string", + "longDescription": "string", + "name": "string", + "popularity": 0, + "rank": 0, + "selectorId": "string", + "serverName": "string", + "url": "string", + "trafficClass": "string" + } + ], + "networkIdentity": [ + { + "id": "string", + "displayName": "string", + "ipv4Subnet": [ + "string" + ], + "ipv6Subnet": [ + {} + ], + "lowerPort": 0, + "ports": "string", + "protocol": "string", + "upperPort": 0 + } + ], + "parentScalableGroup": { + "id": "string", + "idRef": "string" + }, + "qualifier": "string", + "scalableGroupExternalHandle": "string", + "scalableGroupType": "string", + "type": "string" + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/assign_device_to_site.py b/plugins/modules/assign_device_to_site.py index c1da97fe91..4f7d74d449 100644 --- a/plugins/modules/assign_device_to_site.py +++ b/plugins/modules/assign_device_to_site.py @@ -11,7 +11,7 @@ description: - Manage operation create of the resource Assign Device To Site. - Assigns unassigned devices to a site. This API does not move assigned devices to other sites. -version_added: '6.5.0' +version_added: '6.0.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -21,25 +21,26 @@ elements: dict suboptions: ip: - description: Device ip (eg 10.104.240.64). + description: Device IP. It can be either IPv4 or IPv6. IPV4 e.g., 10.104.240.64. + IPV6 e.g., 2001 420 284 2004 4 181 500 183. type: str type: list headers: description: Additional headers. type: dict siteId: - description: SiteId path parameter. Site id to which site the device to assign. + description: SiteId path parameter. Site Id where device(s) needs to be assigned. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for AssignDevicesToSite +- name: Cisco DNA Center documentation for Sites AssignDevicesToSite description: Complete reference of the AssignDevicesToSite API. link: https://developer.cisco.com/docs/dna-center/#!assign-devices-to-site notes: - SDK Method used are - ..assign_devices_to_site, + sites.Sites.assign_devices_to_site, - Paths used are post /dna/intent/api/v1/assign-device-to-site/{siteId}/device, @@ -62,7 +63,6 @@ siteId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/associate_site_to_network_profile.py b/plugins/modules/associate_site_to_network_profile.py index b018515566..41da5cbc87 100644 --- a/plugins/modules/associate_site_to_network_profile.py +++ b/plugins/modules/associate_site_to_network_profile.py @@ -23,8 +23,8 @@ description: SiteId path parameter. Site Id to be associated. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Site Design Associate description: Complete reference of the Associate API. @@ -52,7 +52,6 @@ siteId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/auth_token_create.py b/plugins/modules/auth_token_create.py new file mode 100644 index 0000000000..2b6d6ac1fd --- /dev/null +++ b/plugins/modules/auth_token_create.py @@ -0,0 +1,58 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: auth_token_create +short_description: Resource module for Auth Token Create +description: +- Manage operation create of the resource Auth Token Create. +- > + API to obtain an access token, which remains valid for 1 hour. The token obtained using this API is required to be + set as value to the X-Auth-Token HTTP Header for all API calls to Cisco DNA Center. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: {} +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Authentication AuthenticationAPI + description: Complete reference of the AuthenticationAPI API. + link: https://developer.cisco.com/docs/dna-center/#!authentication-api +notes: + - SDK Method used are + authentication.Authentication.authentication_api, + + - Paths used are + post /dna/system/api/v1/auth/token, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.auth_token_create: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "Token": "string" + } +""" diff --git a/plugins/modules/authentication_import_certificate.py b/plugins/modules/authentication_import_certificate.py index 15cb6d2b61..33cac61f14 100644 --- a/plugins/modules/authentication_import_certificate.py +++ b/plugins/modules/authentication_import_certificate.py @@ -30,8 +30,8 @@ description: PkPassword query parameter. Private Key Passsword. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Authentication Management ImportCertificate description: Complete reference of the ImportCertificate API. @@ -61,7 +61,6 @@ pkPassword: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/authentication_import_certificate_p12.py b/plugins/modules/authentication_import_certificate_p12.py index 23d98d2775..1fcfea2a1c 100644 --- a/plugins/modules/authentication_import_certificate_p12.py +++ b/plugins/modules/authentication_import_certificate_p12.py @@ -30,8 +30,8 @@ description: PkPassword query parameter. Private Key Passsword. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Authentication Management ImportCertificateP12 description: Complete reference of the ImportCertificateP12 API. @@ -61,7 +61,6 @@ pkPassword: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/authentication_policy_servers.py b/plugins/modules/authentication_policy_servers.py new file mode 100644 index 0000000000..a3d56e6180 --- /dev/null +++ b/plugins/modules/authentication_policy_servers.py @@ -0,0 +1,255 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: authentication_policy_servers +short_description: Resource module for Authentication Policy Servers +description: +- Manage operations create, update and delete of the resource Authentication Policy Servers. +- > + API to add AAA/ISE server access configuration. Protocol can be configured as either RADIUS OR TACACS OR + RADIUS_TACACS. If configuring Cisco ISE server, after configuration, use ‘Cisco ISE Server Integration Status' + Intent API to check the integration status. Based on integration status, if require use 'Accept Cisco ISE Server + Certificate for Cisco ISE Server Integration' Intent API to accept the Cisco ISE certificate for Cisco ISE server + integration, then use again ‘Cisco ISE Server Integration Status' Intent API to check the integration status. +- API to delete AAA/ISE server access configuration. +- > + API to edit AAA/ISE server access configuration. After edit, use ‘Cisco ISE Server Integration Status' Intent API + to check the integration status. +version_added: '3.1.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + accountingPort: + description: Accounting port of RADIUS server (readonly). The range is from 1 to + 65535. E.g. 1813. + type: int + authenticationPort: + description: Authentication port of RADIUS server (readonly). The range is from + 1 to 65535. E.g. 1812. + type: int + ciscoIseDtos: + description: Authentication Policy Servers's ciscoIseDtos. + elements: dict + suboptions: + description: + description: Description about the Cisco ISE server. + type: str + fqdn: + description: Fully-qualified domain name of the Cisco ISE server (readonly). + E.g. Xi-62.my.com. + type: str + ipAddress: + description: IP Address of the Cisco ISE Server (readonly). + type: str + password: + description: Password of the Cisco ISE server. + type: str + sshkey: + description: SSH key of the Cisco ISE server. + type: str + subscriberName: + description: Subscriber name of the Cisco ISE server (readonly). E.g. Pxgrid_client_1662589467. + type: str + userName: + description: User name of the Cisco ISE server. + type: str + type: list + encryptionKey: + description: Encryption key used to encrypt shared secret (readonly). + type: str + encryptionScheme: + description: Type of encryption scheme for additional security (readonly). + type: str + externalCiscoIseIpAddrDtos: + description: Authentication Policy Servers's externalCiscoIseIpAddrDtos. + elements: dict + suboptions: + externalCiscoIseIpAddresses: + description: Authentication Policy Servers's externalCiscoIseIpAddresses. + elements: dict + suboptions: + externalIpAddress: + description: External IP Address. + type: str + type: list + type: + description: Type. + type: str + type: list + id: + description: Id path parameter. Authentication and Policy Server Identifier. Use + 'Get Authentication and Policy Servers' intent API to find the identifier. + type: str + ipAddress: + description: IP address of authentication and policy server (readonly). + type: str + isIseEnabled: + description: Value true for Cisco ISE Server (readonly). Default value is false. + type: bool + messageKey: + description: Message key used to encrypt shared secret (readonly). + type: str + port: + description: Port of TACACS server (readonly). The range is from 1 to 65535. + type: int + protocol: + description: Type of protocol for authentication and policy server. If already saved + with RADIUS, can update to RADIUS_TACACS. If already saved with TACACS, can update + to RADIUS_TACACS. + type: str + pxgridEnabled: + description: Value true for enable, false for disable. Default value is true. + type: bool + retries: + description: Number of communication retries between devices and authentication + and policy server. The range is from 1 to 3. + type: str + role: + description: Role of authentication and policy server (readonly). E.g. Primary, + secondary. + type: str + sharedSecret: + description: Shared secret between devices and authentication and policy server + (readonly). + type: str + timeoutSeconds: + description: Number of seconds before timing out between devices and authentication + and policy server. The range is from 2 to 20. + type: str + useDnacCertForPxgrid: + description: Value true to use DNAC certificate for Pxgrid. Default value is false. + type: bool +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for System Settings AddAuthenticationAndPolicyServerAccessConfiguration + description: Complete reference of the AddAuthenticationAndPolicyServerAccessConfiguration API. + link: https://developer.cisco.com/docs/dna-center/#!add-authentication-and-policy-server-access-configuration +- name: Cisco DNA Center documentation for System Settings DeleteAuthenticationAndPolicyServerAccessConfiguration + description: Complete reference of the DeleteAuthenticationAndPolicyServerAccessConfiguration API. + link: https://developer.cisco.com/docs/dna-center/#!delete-authentication-and-policy-server-access-configuration +- name: Cisco DNA Center documentation for System Settings EditAuthenticationAndPolicyServerAccessConfiguration + description: Complete reference of the EditAuthenticationAndPolicyServerAccessConfiguration API. + link: https://developer.cisco.com/docs/dna-center/#!edit-authentication-and-policy-server-access-configuration +notes: + - SDK Method used are + system_settings.SystemSettings.add_authentication_and_policy_server_access_configuration, + system_settings.SystemSettings.delete_authentication_and_policy_server_access_configuration, + system_settings.SystemSettings.edit_authentication_and_policy_server_access_configuration, + + - Paths used are + post /dna/intent/api/v1/authentication-policy-servers, + delete /dna/intent/api/v1/authentication-policy-servers/{id}, + put /dna/intent/api/v1/authentication-policy-servers/{id}, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.authentication_policy_servers: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + accountingPort: 0 + authenticationPort: 0 + ciscoIseDtos: + - description: string + fqdn: string + ipAddress: string + password: string + sshkey: string + subscriberName: string + userName: string + encryptionKey: string + encryptionScheme: string + externalCiscoIseIpAddrDtos: + - externalCiscoIseIpAddresses: + - externalIpAddress: string + type: string + ipAddress: string + isIseEnabled: true + messageKey: string + port: 0 + protocol: string + pxgridEnabled: true + retries: string + role: string + sharedSecret: string + timeoutSeconds: string + useDnacCertForPxgrid: true + +- name: Delete by id + cisco.dnac.authentication_policy_servers: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +- name: Update by id + cisco.dnac.authentication_policy_servers: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + accountingPort: 0 + authenticationPort: 0 + ciscoIseDtos: + - description: string + fqdn: string + ipAddress: string + password: string + sshkey: string + subscriberName: string + userName: string + encryptionKey: string + encryptionScheme: string + externalCiscoIseIpAddrDtos: + - externalCiscoIseIpAddresses: + - externalIpAddress: string + type: string + id: string + ipAddress: string + isIseEnabled: true + messageKey: string + port: 0 + protocol: string + pxgridEnabled: true + retries: string + role: string + sharedSecret: string + timeoutSeconds: string + useDnacCertForPxgrid: true + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "taskId": "string", + "url": "string" + } +""" diff --git a/plugins/modules/authentication_policy_servers_info.py b/plugins/modules/authentication_policy_servers_info.py index d0366ecc2a..2f7f5a8307 100644 --- a/plugins/modules/authentication_policy_servers_info.py +++ b/plugins/modules/authentication_policy_servers_info.py @@ -11,7 +11,7 @@ description: - Get all Authentication Policy Servers. - API to get Authentication and Policy Servers. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -25,15 +25,15 @@ type: bool state_: description: - - State query parameter. Valid values are INPROGRESS, ACTIVE, DELETED, RBAC-FAILURE, FAILED. + - State query parameter. Valid values are ACTIVE, INACTIVE, RBAC_SUCCESS, RBAC_FAILURE, DELETED, FAILED, INPROGRESS. type: str role: description: - Role query parameter. Authentication and Policy Server Role (Example primary, secondary). type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for System Settings GetAuthenticationAndPolicyServers description: Complete reference of the GetAuthenticationAndPolicyServers API. @@ -64,7 +64,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -79,8 +78,8 @@ "protocol": "string", "role": "string", "port": 0, - "authenticationPort": "string", - "accountingPort": "string", + "authenticationPort": 0, + "accountingPort": 0, "retries": 0, "timeoutSeconds": 0, "isIseEnabled": true, @@ -115,7 +114,9 @@ "encryptionKey": "string", "useDnacCertForPxgrid": true, "iseEnabled": true, - "pxgridEnabled": true + "pxgridEnabled": true, + "rbacUuid": "string", + "multiDnacEnabled": true } ] """ diff --git a/plugins/modules/buildings_planned_access_points_info.py b/plugins/modules/buildings_planned_access_points_info.py index 20aaae21a1..e8e6646030 100644 --- a/plugins/modules/buildings_planned_access_points_info.py +++ b/plugins/modules/buildings_planned_access_points_info.py @@ -26,18 +26,18 @@ limit: description: - Limit query parameter. - type: int + type: float offset: description: - Offset query parameter. - type: int + type: float radios: description: - Radios query parameter. Inlcude planned radio details. type: bool requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetPlannedAccessPointsForBuilding description: Complete reference of the GetPlannedAccessPointsForBuilding API. @@ -69,7 +69,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/business_sda_hostonboarding_ssid_ippool.py b/plugins/modules/business_sda_hostonboarding_ssid_ippool.py index 53a47bdc98..348fcdc32c 100644 --- a/plugins/modules/business_sda_hostonboarding_ssid_ippool.py +++ b/plugins/modules/business_sda_hostonboarding_ssid_ippool.py @@ -10,16 +10,17 @@ short_description: Resource module for Business Sda Hostonboarding Ssid Ippool description: - Manage operations create and update of the resource Business Sda Hostonboarding Ssid Ippool. -- Add SSID to IP Pool Mapping. -- Update SSID to IP Pool Mapping. +- > + Update SSID mapping to a VLAN. The request does not need to include all the SSIDs currently mapped to a VLAN; it + can include only the SSIDs that require update. Note ECA is not supported. +- > + Update SSID mapping to a VLAN. The request does not need to include all the SSIDs currently mapped to a VLAN; it + can include only the SSIDs that require update. Note ECA is not supported. version_added: '4.0.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) options: - headers: - description: Additional headers. - type: dict scalableGroupName: description: Scalable Group Name. type: str @@ -34,8 +35,8 @@ description: VLAN Name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Fabric Wireless AddSSIDToIPPoolMapping description: Complete reference of the AddSSIDToIPPoolMapping API. @@ -65,7 +66,6 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" state: present - headers: '{{my_headers | from_json}}' scalableGroupName: string siteNameHierarchy: string ssidNames: @@ -89,18 +89,15 @@ vlanName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK returned: always - type: list + type: dict sample: > - [ - { - "executionId": "string", - "executionStatusURL": "string", - "message": "string" - } - ] + { + "executionId": "string", + "executionStatusUrl": "string", + "message": "string" + } """ diff --git a/plugins/modules/business_sda_hostonboarding_ssid_ippool_info.py b/plugins/modules/business_sda_hostonboarding_ssid_ippool_info.py index 7de5bd47ff..6454d4d115 100644 --- a/plugins/modules/business_sda_hostonboarding_ssid_ippool_info.py +++ b/plugins/modules/business_sda_hostonboarding_ssid_ippool_info.py @@ -28,8 +28,8 @@ - SiteNameHierarchy query parameter. Site Name Heirarchy. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Fabric Wireless GetSSIDToIPPoolMapping description: Complete reference of the GetSSIDToIPPoolMapping API. @@ -59,7 +59,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/business_sda_virtual_network_summary_info.py b/plugins/modules/business_sda_virtual_network_summary_info.py index beb749da61..8846c2614d 100644 --- a/plugins/modules/business_sda_virtual_network_summary_info.py +++ b/plugins/modules/business_sda_virtual_network_summary_info.py @@ -11,7 +11,7 @@ description: - Get all Business Sda Virtual Network Summary. - Get Virtual Network Summary. -version_added: '6.5.0' +version_added: '6.0.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -24,15 +24,15 @@ - SiteNameHierarchy query parameter. Complete fabric siteNameHierarchy Path. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for GetVirtualNetworkSummary +- name: Cisco DNA Center documentation for SDA GetVirtualNetworkSummary description: Complete reference of the GetVirtualNetworkSummary API. link: https://developer.cisco.com/docs/dna-center/#!get-virtual-network-summary notes: - SDK Method used are - ..get_virtual_network_summary, + sda.Sda.get_virtual_network_summary, - Paths used are get /dna/intent/api/v1/business/sda/virtual-network/summary, @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -65,11 +64,16 @@ "virtualNetworkCount": 0, "virtualNetworkSummary": [ { + "virtualNetworkContextId": "string", + "virtualNetworkId": "string", "siteNameHierarchy": "string", - "virtualNetworkName": "string" + "virtualNetworkName": "string", + "layer3Instance": 0, + "virtualNetworkStatus": "string" } ], "status": "string", - "description": "string" + "description": "string", + "executionId": "string" } """ diff --git a/plugins/modules/business_sda_wireless_controller_create.py b/plugins/modules/business_sda_wireless_controller_create.py index 9b1619f907..22f5c24497 100644 --- a/plugins/modules/business_sda_wireless_controller_create.py +++ b/plugins/modules/business_sda_wireless_controller_create.py @@ -17,14 +17,14 @@ author: Rafael Campos (@racampos) options: deviceName: - description: EWLC Device Name. + description: WLC Device Name. type: str siteNameHierarchy: - description: Site Name Hierarchy. + description: Fabric Site Name Hierarchy. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Fabric Wireless AddWLCToFabricDomain description: Complete reference of the AddWLCToFabricDomain API. @@ -53,7 +53,6 @@ siteNameHierarchy: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -62,7 +61,7 @@ sample: > { "executionId": "string", - "executionStatusURL": "string", + "executionStatusUrl": "string", "message": "string" } """ diff --git a/plugins/modules/business_sda_wireless_controller_delete.py b/plugins/modules/business_sda_wireless_controller_delete.py index 3231a6e233..1b08223c21 100644 --- a/plugins/modules/business_sda_wireless_controller_delete.py +++ b/plugins/modules/business_sda_wireless_controller_delete.py @@ -23,8 +23,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Fabric Wireless RemoveWLCFromFabricDomain description: Complete reference of the RemoveWLCFromFabricDomain API. diff --git a/plugins/modules/cli_credential.py b/plugins/modules/cli_credential.py index 9a7c0e4890..af6b8f9ffa 100644 --- a/plugins/modules/cli_credential.py +++ b/plugins/modules/cli_credential.py @@ -18,35 +18,35 @@ author: Rafael Campos (@racampos) options: comments: - description: Cli Credential's comments. + description: Comments to identify the CLI credential. type: str credentialType: - description: Cli Credential's credentialType. + description: Credential type to identify the application that uses the CLI credential. type: str description: - description: Cli Credential's description. + description: Description for CLI Credentials. type: str enablePassword: - description: Cli Credential's enablePassword. + description: CLI Enable Password. type: str id: - description: Cli Credential's id. + description: Id of the CLI Credential in UUID format. type: str instanceTenantId: - description: Cli Credential's instanceTenantId. + description: Deprecated. type: str instanceUuid: - description: Cli Credential's instanceUuid. + description: Deprecated. type: str password: - description: Cli Credential's password. + description: CLI Password. type: str username: - description: Cli Credential's username. + description: CLI Username. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery CreateCLICredentials description: Complete reference of the CreateCLICredentials API. @@ -107,7 +107,6 @@ username: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/client_detail_info.py b/plugins/modules/client_detail_info.py index 5cc6ca6d93..041b12d54c 100644 --- a/plugins/modules/client_detail_info.py +++ b/plugins/modules/client_detail_info.py @@ -19,17 +19,17 @@ headers: description: Additional headers. type: dict - timestamp: - description: - - Timestamp query parameter. Epoch time(in milliseconds) when the Client health data is required. - type: str macAddress: description: - MacAddress query parameter. MAC Address of the client. type: str + timestamp: + description: + - Timestamp query parameter. Epoch time(in milliseconds) when the Client health data is required. + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Clients GetClientDetail description: Complete reference of the GetClientDetail API. @@ -54,12 +54,11 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" headers: "{{my_headers | from_json}}" - timestamp: string macAddress: string + timestamp: 0 register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -70,12 +69,20 @@ "detail": { "id": "string", "connectionStatus": "string", + "tracked": "string", "hostType": "string", - "userId": {}, + "userId": "string", + "duid": "string", + "identifier": "string", "hostName": "string", - "hostOs": {}, - "hostVersion": {}, + "hostOs": "string", + "hostVersion": "string", "subType": "string", + "firmwareVersion": "string", + "deviceVendor": "string", + "deviceForm": "string", + "salesCode": "string", + "countryCode": "string", "lastUpdated": 0, "healthScore": [ { @@ -91,57 +98,129 @@ ], "authType": "string", "vlanId": 0, + "l3VirtualNetwork": "string", + "l2VirtualNetwork": "string", "vnid": 0, + "upnId": "string", + "upnName": "string", "ssid": "string", "frequency": "string", "channel": "string", - "apGroup": {}, - "location": {}, + "apGroup": "string", + "sgt": "string", + "location": "string", "clientConnection": "string", "connectedDevice": [ - {} + { + "type": "string", + "name": "string", + "mac": "string", + "id": "string", + "ip address": "string", + "mgmtIp": "string", + "band": "string", + "mode": "string" + } ], "issueCount": 0, "rssi": "string", - "avgRssi": {}, + "rssiThreshold": "string", + "rssiIsInclude": "string", + "avgRssi": "string", "snr": "string", - "avgSnr": {}, + "snrThreshold": "string", + "snrIsInclude": "string", + "avgSnr": "string", "dataRate": "string", "txBytes": "string", "rxBytes": "string", - "dnsSuccess": {}, - "dnsFailure": {}, + "dnsResponse": "string", + "dnsRequest": "string", "onboarding": { - "averageRunDuration": {}, - "maxRunDuration": {}, - "averageAssocDuration": {}, - "maxAssocDuration": {}, - "averageAuthDuration": {}, - "maxAuthDuration": {}, - "averageDhcpDuration": {}, - "maxDhcpDuration": {}, + "averageRunDuration": "string", + "maxRunDuration": "string", + "averageAssocDuration": "string", + "maxAssocDuration": "string", + "averageAuthDuration": "string", + "maxAuthDuration": "string", + "averageDhcpDuration": "string", + "maxDhcpDuration": "string", "aaaServerIp": "string", - "dhcpServerIp": {}, - "authDoneTime": {}, - "assocDoneTime": {}, - "dhcpDoneTime": {}, + "dhcpServerIp": "string", + "authDoneTime": 0, + "assocDoneTime": 0, + "dhcpDoneTime": 0, "assocRootcauseList": [ - {} + "string" ], "aaaRootcauseList": [ - {} + "string" ], "dhcpRootcauseList": [ - {} + "string" ], "otherRootcauseList": [ - {} + "string" + ], + "latestRootCauseList": [ + "string" ] }, "clientType": "string", - "onboardingTime": {}, - "port": {}, - "iosCapable": true + "onboardingTime": 0, + "port": "string", + "iosCapable": true, + "usage": 0, + "linkSpeed": 0, + "linkThreshold": "string", + "remoteEndDuplexMode": "string", + "txLinkError": 0, + "rxLinkError": 0, + "txRate": 0, + "rxRate": 0, + "rxRetryPct": "string", + "versionTime": 0, + "dot11Protocol": "string", + "slotId": 0, + "dot11ProtocolCapability": "string", + "privateMac": true, + "dhcpServerIp": "string", + "aaaServerIp": "string", + "aaaServerTransaction": 0, + "aaaServerFailedTransaction": 0, + "aaaServerSuccessTransaction": 0, + "aaaServerLatency": 0, + "aaaServerMABLatency": 0, + "aaaServerEAPLatency": 0, + "dhcpServerTransaction": 0, + "dhcpServerFailedTransaction": 0, + "dhcpServerSuccessTransaction": 0, + "dhcpServerLatency": 0, + "dhcpServerDOLatency": 0, + "dhcpServerRALatency": 0, + "maxRoamingDuration": "string", + "upnOwner": "string", + "connectedUpn": "string", + "connectedUpnOwner": "string", + "connectedUpnId": "string", + "isGuestUPNEndpoint": true, + "wlcName": "string", + "wlcUuid": "string", + "sessionDuration": "string", + "intelCapable": true, + "hwModel": "string", + "powerType": "string", + "modelName": "string", + "bridgeVMMode": "string", + "dhcpNakIp": "string", + "dhcpDeclineIp": "string", + "portDescription": "string", + "latencyVoice": 0, + "latencyVideo": 0, + "latencyBg": 0, + "latencyBe": 0, + "trustScore": "string", + "trustDetails": "string" }, "connectionInfo": { "hostType": "string", @@ -164,31 +243,61 @@ "id": "string", "description": "string", "deviceType": "string", - "platformId": {}, - "family": {}, + "platformId": "string", + "family": "string", "ip": "string", - "softwareVersion": {}, - "userId": {}, + "ipv6": [ + "string" + ], + "softwareVersion": "string", + "userId": "string", "nodeType": "string", - "radioFrequency": {}, - "clients": {}, - "count": {}, + "radioFrequency": "string", + "clients": 0, + "count": 0, "healthScore": 0, "level": 0, - "fabricGroup": {}, - "connectedDevice": {} + "fabricGroup": "string", + "fabricRole": [ + "string" + ], + "connectedDevice": "string", + "stackType": "string" } ], "links": [ { "source": "string", "linkStatus": "string", + "sourceLinkStatus": "string", + "targetLinkStatus": "string", "label": [ "string" ], "target": "string", - "id": {}, - "portUtilization": {} + "id": "string", + "portUtilization": 0, + "sourceInterfaceName": "string", + "targetInterfaceName": "string", + "sourceDuplexInfo": "string", + "targetDuplexInfo": "string", + "sourcePortMode": "string", + "targetPortMode": "string", + "sourceAdminStatus": "string", + "targetAdminStatus": "string", + "apRadioAdminStatus": "string", + "apRadioOperStatus": "string", + "sourcePortVLANInfo": "string", + "targetPortVLANInfo": "string", + "interfaceDetails": [ + { + "clientMacAddress": "string", + "connectedDeviceIntName": "string", + "duplex": "string", + "portMode": "string", + "adminStatus": "string" + } + ] } ] } diff --git a/plugins/modules/client_enrichment_details_info.py b/plugins/modules/client_enrichment_details_info.py index 54be2389af..48946934f2 100644 --- a/plugins/modules/client_enrichment_details_info.py +++ b/plugins/modules/client_enrichment_details_info.py @@ -22,8 +22,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Clients GetClientEnrichmentDetails description: Complete reference of the GetClientEnrichmentDetails API. @@ -51,7 +51,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/client_health_info.py b/plugins/modules/client_health_info.py index f036bb5bdb..a9930dcdf0 100644 --- a/plugins/modules/client_health_info.py +++ b/plugins/modules/client_health_info.py @@ -22,10 +22,10 @@ timestamp: description: - Timestamp query parameter. Epoch time(in milliseconds) when the Client health data is required. - type: str + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Clients GetOverallClientHealth description: Complete reference of the GetOverallClientHealth API. @@ -50,60 +50,58 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" headers: "{{my_headers | from_json}}" - timestamp: string + timestamp: 0 register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK returned: always - type: list - elements: dict + type: dict sample: > - [ - { - "siteId": "string", - "scoreDetail": [ - { - "scoreCategory": { - "scoreCategory": "string", - "value": "string" - }, - "scoreValue": 0, - "clientCount": 0, - "clientUniqueCount": 0, - "starttime": 0, - "endtime": 0, - "scoreList": [ - { - "scoreCategory": { - "scoreCategory": "string", - "value": "string" - }, - "scoreValue": 0, - "clientCount": 0, - "clientUniqueCount": 0, - "starttime": 0, - "endtime": 0, - "scoreList": [ - { - "scoreCategory": { - "scoreCategory": "string", - "value": "string" - }, - "scoreValue": 0, - "clientCount": 0, - "clientUniqueCount": {}, - "starttime": 0, - "endtime": 0 - } - ] - } - ] - } - ] - } - ] + { + "version": "string", + "response": [ + { + "siteId": "string", + "scoreDetail": [ + { + "scoreCategory": { + "scoreCategory": "string", + "value": "string" + }, + "scoreValue": 0, + "clientCount": 0, + "clientUniqueCount": 0, + "maintenanceAffectedClientCount": 0, + "randomMacCount": 0, + "duidCount": 0, + "starttime": 0, + "endtime": 0, + "connectedToUdnCount": 0, + "unconnectedToUdnCount": 0, + "scoreList": [ + { + "scoreCategory": { + "scoreCategory": "string", + "value": "string" + }, + "scoreValue": 0, + "clientCount": 0, + "clientUniqueCount": 0, + "maintenanceAffectedClientCount": 0, + "randomMacCount": 0, + "duidCount": 0, + "starttime": 0, + "endtime": 0, + "connectedToUdnCount": 0, + "unconnectedToUdnCount": 0 + } + ] + } + ] + } + ] + } """ diff --git a/plugins/modules/client_proximity_info.py b/plugins/modules/client_proximity_info.py index 7d30d7542e..d87ad0cbbb 100644 --- a/plugins/modules/client_proximity_info.py +++ b/plugins/modules/client_proximity_info.py @@ -32,16 +32,16 @@ - > Number_days query parameter. Number of days to track proximity until current date. Defaults and maximum up to 14 days. - type: int + type: float time_resolution: description: - > Time_resolution query parameter. Time interval (in minutes) to measure proximity. Defaults to 15 minutes with a minimum 5 minutes. - type: int + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Clients ClientProximity description: Complete reference of the ClientProximity API. @@ -72,7 +72,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/command_runner_run_command.py b/plugins/modules/command_runner_run_command.py index 5b12002ede..2ae6b29f85 100644 --- a/plugins/modules/command_runner_run_command.py +++ b/plugins/modules/command_runner_run_command.py @@ -17,25 +17,26 @@ author: Rafael Campos (@racampos) options: commands: - description: Command Runner Run Command's commands. + description: Commands to be executed. elements: str type: list description: - description: Command Runner Run Command's description. + description: Describe the details about the command request. type: str deviceUuids: - description: Command Runner Run Command's deviceUuids. + description: Device Id of the device. elements: str type: list name: - description: Command Runner Run Command's name. + description: Name of the the request like getshowrun , deviceinterfacestatusCli. type: str timeout: - description: Command Runner Run Command's timeout. + description: The timeout value in unit of second. If no timeout provided wait till + 300sec. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Command Runner RunReadOnlyCommandsOnDevicesToGetTheirRealTimeConfiguration description: Complete reference of the RunReadOnlyCommandsOnDevicesToGetTheirRealTimeConfiguration API. @@ -68,7 +69,6 @@ timeout: 0 """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/compliance_check_run.py b/plugins/modules/compliance_check_run.py index c244f41f85..d676aeaee7 100644 --- a/plugins/modules/compliance_check_run.py +++ b/plugins/modules/compliance_check_run.py @@ -17,19 +17,23 @@ author: Rafael Campos (@racampos) options: categories: - description: Compliance Check Run's categories. + description: Category can have any value among 'INTENT'(mapped to compliance types + NETWORK_SETTINGS,NETWORK_PROFILE,WORKFLOW,FABRIC,APPLICATION_VISIBILITY), 'RUNNING_CONFIG' + , 'IMAGE' , 'PSIRT' , 'EOX' , 'NETWORK_SETTINGS'. elements: str type: list deviceUuids: - description: Compliance Check Run's deviceUuids. + description: UUID of the device. elements: str type: list triggerFull: - description: TriggerFull flag. + description: If it is true then compliance will be triggered for all categories. + If it is false then compliance will be triggered for categories mentioned in categories + section . type: bool requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Compliance RunCompliance description: Complete reference of the RunCompliance API. @@ -60,7 +64,6 @@ triggerFull: true """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/compliance_device_by_id_info.py b/plugins/modules/compliance_device_by_id_info.py index 99d967c02a..afe6d944b4 100644 --- a/plugins/modules/compliance_device_by_id_info.py +++ b/plugins/modules/compliance_device_by_id_info.py @@ -21,33 +21,28 @@ type: dict deviceUuid: description: - - DeviceUuid path parameter. + - DeviceUuid path parameter. Device Id. type: str category: description: - - Category query parameter. ComplianceCategory can have any value among 'INTENT', 'RUNNING_CONFIG'. + - > + Category query parameter. Category can have any value among 'INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT' , + 'DESIGN_OOD' , 'EOX' , 'NETWORK_SETTINGS'. type: str complianceType: description: - > - ComplianceType query parameter. ComplianceType can have any value among 'NETWORK_DESIGN', 'NETWORK_PROFILE', - 'FABRIC', 'POLICY', 'RUNNING_CONFIG'. + ComplianceType query parameter. Specify "Compliance type(s)" separated by commas. The Compliance type can be + 'APPLICATION_VISIBILITY', 'EOX', 'FABRIC', 'IMAGE', 'NETWORK_PROFILE', 'NETWORK_SETTINGS', 'PSIRT', + 'RUNNING_CONFIG', 'WORKFLOW'. type: str diffList: description: - DiffList query parameter. Diff list pass true to fetch the diff list. type: bool - key: - description: - - Key query parameter. Extended attribute key. - type: str - value: - description: - - Value query parameter. Extended attribute value. - type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Compliance ComplianceDetailsOfDevice description: Complete reference of the ComplianceDetailsOfDevice API. @@ -75,13 +70,10 @@ category: string complianceType: string diffList: True - key: string - value: string deviceUuid: string register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -89,55 +81,63 @@ type: dict sample: > { - "deviceUuid": "string", - "version": "string", "response": [ { - "displayName": "string", + "deviceUuid": "string", "complianceType": "string", + "status": "string", + "state": "string", "lastSyncTime": 0, - "additionalDataURL": "string", + "lastUpdateTime": 0, "sourceInfoList": [ { + "name": "string", + "nameWithBusinessKey": "string", + "sourceEnum": "string", + "type": "string", + "appName": "string", "count": 0, - "displayName": "string", + "ackStatus": "string", + "businessKey": { + "resourceName": "string", + "businessKeyAttributes": {}, + "otherAttributes": { + "name": "string", + "cfsAttributes": { + "displayName": "string", + "appName": "string", + "description": "string", + "source": "string", + "type": "string" + } + } + }, "diffList": [ { - "displayName": "string", - "moveFromPath": "string", "op": "string", "configuredValue": "string", "intendedValue": "string", - "path": "string", + "moveFromPath": "string", "businessKey": "string", - "extendedAttributes": "string" + "path": "string", + "extendedAttributes": { + "attributeDisplayName": "string", + "path": "string", + "dataConverter": "string", + "type": "string" + }, + "ackStatus": "string", + "instanceUUID": "string", + "displayName": "string" } ], - "sourceEnum": "string", - "licenseAppName": "string", - "provisioningArea": "string", - "networkProfileName": "string", - "nameWithBusinessKey": "string", - "appName": "string", - "name": "string", - "type": "string", - "businessKey": { - "otherAttributes": { - "cfsAttributes": "string", - "name": "string" - }, - "resourceName": "string", - "businessKeyAttributes": "string" - } + "displayName": "string" } ], - "deviceUuid": "string", - "message": "string", - "state": "string", - "status": "string", - "category": "string", - "lastUpdateTime": 0 + "ackStatus": "string", + "version": "string" } - ] + ], + "deviceUuid": "string" } """ diff --git a/plugins/modules/compliance_device_details_count_info.py b/plugins/modules/compliance_device_details_count_info.py index a51939ed4d..30a7b590b6 100644 --- a/plugins/modules/compliance_device_details_count_info.py +++ b/plugins/modules/compliance_device_details_count_info.py @@ -22,18 +22,19 @@ complianceType: description: - > - ComplianceType query parameter. ComplianceType can have any value among 'NETWORK_PROFILE', 'IMAGE', - 'APPLICATION_VISIBILITY', 'FABRIC', 'PSIRT', 'RUNNING_CONFIG', 'WORKFLOW'. + ComplianceType query parameter. Specify "Compliance type(s)" separated by commas. The Compliance type can be + 'APPLICATION_VISIBILITY', 'EOX', 'FABRIC', 'IMAGE', 'NETWORK_PROFILE', 'NETWORK_SETTINGS', 'PSIRT', + 'RUNNING_CONFIG', 'WORKFLOW'. type: str complianceStatus: description: - > - ComplianceStatus query parameter. Compliance status can have value among 'COMPLIANT', 'NON_COMPLIANT', - 'IN_PROGRESS', 'NOT_AVAILABLE', 'NOT_APPLICABLE', 'ERROR'. + ComplianceStatus query parameter. Specify "Compliance status(es)" separated by commas. The Compliance status + can be 'COMPLIANT', 'NON_COMPLIANT', 'IN_PROGRESS', 'NOT_AVAILABLE', 'NOT_APPLICABLE', 'ERROR'. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Compliance GetComplianceDetailCount description: Complete reference of the GetComplianceDetailCount API. @@ -63,7 +64,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/compliance_device_details_info.py b/plugins/modules/compliance_device_details_info.py index bc06458f28..55980c744a 100644 --- a/plugins/modules/compliance_device_details_info.py +++ b/plugins/modules/compliance_device_details_info.py @@ -22,30 +22,31 @@ complianceType: description: - > - ComplianceType query parameter. ComplianceType can have any value among 'NETWORK_PROFILE', 'IMAGE', - 'APPLICATION_VISIBILITY', 'FABRIC', 'PSIRT', 'RUNNING_CONFIG', 'WORKFLOW'. + ComplianceType query parameter. Specify "Compliance type(s)" in commas. The Compliance type can be + 'NETWORK_PROFILE', 'IMAGE', 'FABRIC', 'APPLICATION_VISIBILITY', 'FABRIC', RUNNING_CONFIG', + 'NETWORK_SETTINGS', 'WORKFLOW' , 'EOX'. type: str complianceStatus: description: - > - ComplianceStatus query parameter. Compliance status can have value among 'COMPLIANT', 'NON_COMPLIANT', - 'IN_PROGRESS', 'NOT_AVAILABLE', 'NOT_APPLICABLE', 'ERROR'. + ComplianceStatus query parameter. Specify "Compliance status(es)" in commas. The Compliance status can be + 'COMPLIANT', 'NON_COMPLIANT', 'IN_PROGRESS', 'NOT_AVAILABLE', 'NOT_APPLICABLE', 'ERROR'. type: str deviceUuid: description: - - DeviceUuid query parameter. Comma separated deviceUuids. + - DeviceUuid query parameter. Comma separated "Device Id(s)". type: str offset: description: - Offset query parameter. Offset/starting row. - type: int + type: float limit: description: - Limit query parameter. Number of records to be retrieved. - type: int + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Compliance GetComplianceDetail description: Complete reference of the GetComplianceDetail API. @@ -78,7 +79,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/compliance_device_info.py b/plugins/modules/compliance_device_info.py index 38eaafb12c..60bdef0875 100644 --- a/plugins/modules/compliance_device_info.py +++ b/plugins/modules/compliance_device_info.py @@ -24,24 +24,16 @@ complianceStatus: description: - > - ComplianceStatus query parameter. Compliance status can be have value among - 'COMPLIANT','NON_COMPLIANT','IN_PROGRESS', 'ERROR'. + ComplianceStatus query parameter. Specify "Compliance status(es)" separated by commas. The Compliance status + can be 'COMPLIANT', 'NON_COMPLIANT', 'IN_PROGRESS', 'NOT_AVAILABLE', 'NOT_APPLICABLE', 'ERROR'. type: str deviceUuid: description: - - DeviceUuid query parameter. Comma separated deviceUuids. + - DeviceUuid query parameter. Comma separated 'Device Ids'. type: str - offset: - description: - - Offset query parameter. Offset/starting row. - type: int - limit: - description: - - Limit query parameter. Number of records to be retrieved. - type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Compliance DeviceComplianceStatus description: Complete reference of the DeviceComplianceStatus API. @@ -73,8 +65,6 @@ headers: "{{my_headers | from_json}}" complianceStatus: string deviceUuid: string - offset: 0 - limit: 0 register: result - name: Get Compliance Device by id @@ -91,7 +81,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -99,13 +88,12 @@ type: dict sample: > { - "version": "string", "response": { "deviceUuid": "string", "complianceStatus": "string", - "message": "string", - "scheduleTime": 0, - "lastUpdateTime": 0 - } + "lastUpdateTime": 0, + "scheduleTime": "string" + }, + "version": "string" } """ diff --git a/plugins/modules/compliance_device_status_count_info.py b/plugins/modules/compliance_device_status_count_info.py index 6c7897f94d..2a96751cfc 100644 --- a/plugins/modules/compliance_device_status_count_info.py +++ b/plugins/modules/compliance_device_status_count_info.py @@ -22,12 +22,12 @@ complianceStatus: description: - > - ComplianceStatus query parameter. Compliance status can have value among 'COMPLIANT', 'NON_COMPLIANT', - 'IN_PROGRESS', 'NOT_AVAILABLE', 'NOT_APPLICABLE', 'ERROR'. + ComplianceStatus query parameter. Specify "Compliance status(es)" separated by commas. The Compliance status + can be 'COMPLIANT', 'NON_COMPLIANT', 'IN_PROGRESS', 'NOT_AVAILABLE', 'NOT_APPLICABLE', 'ERROR'. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Compliance GetComplianceStatusCount description: Complete reference of the GetComplianceStatusCount API. @@ -56,7 +56,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -65,6 +64,6 @@ sample: > { "version": "string", - "response": 0 + "response": "string" } """ diff --git a/plugins/modules/configuration_template.py b/plugins/modules/configuration_template.py index 05e7acf351..95752c49bc 100644 --- a/plugins/modules/configuration_template.py +++ b/plugins/modules/configuration_template.py @@ -512,8 +512,8 @@ description: Current version of template. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates DeletesTheTemplate description: Complete reference of the DeletesTheTemplate API. @@ -713,7 +713,6 @@ templateId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_clone.py b/plugins/modules/configuration_template_clone.py index c21257ba40..3be0b8e3f1 100644 --- a/plugins/modules/configuration_template_clone.py +++ b/plugins/modules/configuration_template_clone.py @@ -28,8 +28,8 @@ description: TemplateId path parameter. UUID of the template to clone it. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates CreatesACloneOfTheGivenTemplate description: Complete reference of the CreatesACloneOfTheGivenTemplate API. @@ -58,7 +58,6 @@ templateId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_create.py b/plugins/modules/configuration_template_create.py index f5beee649b..708ebd26f6 100644 --- a/plugins/modules/configuration_template_create.py +++ b/plugins/modules/configuration_template_create.py @@ -508,8 +508,8 @@ description: Current version of template. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates CreateTemplate description: Complete reference of the CreateTemplate API. @@ -691,7 +691,6 @@ version: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_deploy.py b/plugins/modules/configuration_template_deploy.py index a1b1b5265b..c620a3378f 100644 --- a/plugins/modules/configuration_template_deploy.py +++ b/plugins/modules/configuration_template_deploy.py @@ -27,7 +27,8 @@ type: str memberTemplateDeploymentInfo: description: MemberTemplateDeploymentInfo. - type: str + elements: dict + type: list targetInfo: description: Configuration Template Deploy's targetInfo. elements: dict @@ -42,8 +43,10 @@ description: Template params/values to be provisioned. type: dict resourceParams: - description: Resource params to be provisioned. - type: dict + description: Resource params to be provisioned. Refer to features page for usage + details. + elements: dict + type: list type: description: Target type of device. type: str @@ -55,8 +58,8 @@ description: UUID of template to be provisioned. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates DeployTemplate description: Complete reference of the DeployTemplate API. @@ -83,18 +86,19 @@ forcePushTemplate: true isComposite: true mainTemplateId: string - memberTemplateDeploymentInfo: string + memberTemplateDeploymentInfo: + - {} targetInfo: - hostName: string id: string params: {} - resourceParams: {} + resourceParams: + - {} type: string versionedTemplateId: string templateId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_deploy_status_info.py b/plugins/modules/configuration_template_deploy_status_info.py index 46c7439eb5..256b3f548c 100644 --- a/plugins/modules/configuration_template_deploy_status_info.py +++ b/plugins/modules/configuration_template_deploy_status_info.py @@ -24,8 +24,8 @@ - DeploymentId path parameter. UUID of deployment to retrieve template deployment status. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates StatusOfTemplateDeployment description: Complete reference of the StatusOfTemplateDeployment API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_deploy_v2.py b/plugins/modules/configuration_template_deploy_v2.py index af7f1094d4..f6e2686070 100644 --- a/plugins/modules/configuration_template_deploy_v2.py +++ b/plugins/modules/configuration_template_deploy_v2.py @@ -27,7 +27,8 @@ type: str memberTemplateDeploymentInfo: description: MemberTemplateDeploymentInfo. - type: str + elements: dict + type: list targetInfo: description: Configuration Template Deploy V2's targetInfo. elements: dict @@ -42,8 +43,10 @@ description: Template params/values to be provisioned. type: dict resourceParams: - description: Resource params to be provisioned. - type: dict + description: Resource params to be provisioned. Refer to features page for usage + details. + elements: dict + type: list type: description: Target type of device. type: str @@ -55,8 +58,8 @@ description: UUID of template to be provisioned. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates DeployTemplateV2 description: Complete reference of the DeployTemplateV2 API. @@ -83,18 +86,19 @@ forcePushTemplate: true isComposite: true mainTemplateId: string - memberTemplateDeploymentInfo: string + memberTemplateDeploymentInfo: + - {} targetInfo: - hostName: string id: string params: {} - resourceParams: {} + resourceParams: + - {} type: string versionedTemplateId: string templateId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_export_project.py b/plugins/modules/configuration_template_export_project.py index f414750054..6d4a4d4eb6 100644 --- a/plugins/modules/configuration_template_export_project.py +++ b/plugins/modules/configuration_template_export_project.py @@ -21,8 +21,8 @@ elements: dict type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates ExportsTheProjectsForAGivenCriteria description: Complete reference of the ExportsTheProjectsForAGivenCriteria API. @@ -50,7 +50,6 @@ - {} """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_export_template.py b/plugins/modules/configuration_template_export_template.py index d460cef406..fa443a3325 100644 --- a/plugins/modules/configuration_template_export_template.py +++ b/plugins/modules/configuration_template_export_template.py @@ -21,8 +21,8 @@ elements: dict type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates ExportsTheTemplatesForAGivenCriteria description: Complete reference of the ExportsTheTemplatesForAGivenCriteria API. @@ -50,7 +50,6 @@ - {} """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_import_project.py b/plugins/modules/configuration_template_import_project.py index 37b2096e4e..8e0ca8089f 100644 --- a/plugins/modules/configuration_template_import_project.py +++ b/plugins/modules/configuration_template_import_project.py @@ -23,8 +23,8 @@ fails with 'Template already exists' error. type: bool requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates ImportsTheProjectsProvided description: Complete reference of the ImportsTheProjectsProvided API. @@ -51,7 +51,6 @@ doVersion: true """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_import_template.py b/plugins/modules/configuration_template_import_template.py index 7f9cf31f6b..5f3d0d8360 100644 --- a/plugins/modules/configuration_template_import_template.py +++ b/plugins/modules/configuration_template_import_template.py @@ -523,8 +523,8 @@ project. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates ImportsTheTemplatesProvided description: Complete reference of the ImportsTheTemplatesProvided API. @@ -709,7 +709,6 @@ projectName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_info.py b/plugins/modules/configuration_template_info.py index ad9e264cf9..dc472bf0cf 100644 --- a/plugins/modules/configuration_template_info.py +++ b/plugins/modules/configuration_template_info.py @@ -51,12 +51,12 @@ type: bool tags: description: - - Tags query parameter. Filter template(s) based on tags. + - Tags query parameter. Filter template(s) based on tags. elements: str type: list projectNames: description: - - ProjectNames query parameter. Filter template(s) based on project names. + - ProjectNames query parameter. Filter template(s) based on project names. elements: str type: list unCommitted: @@ -76,8 +76,8 @@ - LatestVersion query parameter. LatestVersion flag to get the latest versioned template. type: bool requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates GetsDetailsOfAGivenTemplate description: Complete reference of the GetsDetailsOfAGivenTemplate API. @@ -135,7 +135,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_project.py b/plugins/modules/configuration_template_project.py index 7678e283c8..f2c59a8ae2 100644 --- a/plugins/modules/configuration_template_project.py +++ b/plugins/modules/configuration_template_project.py @@ -50,504 +50,10 @@ templates: description: List of templates within the project. elements: dict - suboptions: - author: - description: Author of template. - type: str - composite: - description: Is it composite template. - type: bool - containingTemplates: - description: Configuration Template Project's containingTemplates. - elements: dict - suboptions: - composite: - description: Is it composite template. - type: bool - description: - description: Description of template. - type: str - deviceTypes: - description: Configuration Template Project's deviceTypes. - elements: dict - suboptions: - productFamily: - description: Device family. - type: str - productSeries: - description: Device series. - type: str - productType: - description: Device type. - type: str - type: list - id: - description: UUID of template. - type: str - language: - description: Template language (JINJA or VELOCITY). - type: str - name: - description: Name of template. - type: str - projectName: - description: Project name. - type: str - rollbackTemplateParams: - description: Configuration Template Project's rollbackTemplateParams. - elements: dict - suboptions: - binding: - description: Bind to source. - type: str - customOrder: - description: CustomOrder of template param. - type: int - dataType: - description: Datatype of template param. - type: str - defaultValue: - description: Default value of template param. - type: str - description: - description: Description of template param. - type: str - displayName: - description: Display name of param. - type: str - group: - description: Group. - type: str - id: - description: UUID of template param. - type: str - instructionText: - description: Instruction text for param. - type: str - key: - description: Key. - type: str - notParam: - description: Is it not a variable. - type: bool - order: - description: Order of template param. - type: int - paramArray: - description: Is it an array. - type: bool - parameterName: - description: Name of template param. - type: str - provider: - description: Provider. - type: str - range: - description: Configuration Template Project's range. - elements: dict - suboptions: - id: - description: UUID of range. - type: str - maxValue: - description: Max value of range. - type: int - minValue: - description: Min value of range. - type: int - type: list - required: - description: Is param required. - type: bool - selection: - description: Configuration Template Project's selection. - suboptions: - defaultSelectedValues: - description: Default selection values. - elements: str - type: list - id: - description: UUID of selection. - type: str - selectionType: - description: Type of selection(SINGLE_SELECT or MULTI_SELECT). - type: str - selectionValues: - description: Selection values. - type: dict - type: dict - type: list - tags: - description: Configuration Template Project's tags. - elements: dict - suboptions: - id: - description: UUID of tag. - type: str - name: - description: Name of tag. - type: str - type: list - templateContent: - description: Template content. - type: str - templateParams: - description: Configuration Template Project's templateParams. - elements: dict - suboptions: - binding: - description: Bind to source. - type: str - customOrder: - description: CustomOrder of template param. - type: int - dataType: - description: Datatype of template param. - type: str - defaultValue: - description: Default value of template param. - type: str - description: - description: Description of template param. - type: str - displayName: - description: Display name of param. - type: str - group: - description: Group. - type: str - id: - description: UUID of template param. - type: str - instructionText: - description: Instruction text for param. - type: str - key: - description: Key. - type: str - notParam: - description: Is it not a variable. - type: bool - order: - description: Order of template param. - type: int - paramArray: - description: Is it an array. - type: bool - parameterName: - description: Name of template param. - type: str - provider: - description: Provider. - type: str - range: - description: Configuration Template Project's range. - elements: dict - suboptions: - id: - description: UUID of range. - type: str - maxValue: - description: Max value of range. - type: int - minValue: - description: Min value of range. - type: int - type: list - required: - description: Is param required. - type: bool - selection: - description: Configuration Template Project's selection. - suboptions: - defaultSelectedValues: - description: Default selection values. - elements: str - type: list - id: - description: UUID of selection. - type: str - selectionType: - description: Type of selection(SINGLE_SELECT or MULTI_SELECT). - type: str - selectionValues: - description: Selection values. - type: dict - type: dict - type: list - version: - description: Current version of template. - type: str - type: list - createTime: - description: Create time of template. - type: int - customParamsOrder: - description: Custom Params Order. - type: bool - description: - description: Description of template. - type: str - deviceTypes: - description: Configuration Template Project's deviceTypes. - elements: dict - suboptions: - productFamily: - description: Device family. - type: str - productSeries: - description: Device series. - type: str - productType: - description: Device type. - type: str - type: list - failurePolicy: - description: Define failure policy if template provisioning fails. - type: str - id: - description: UUID of template. - type: str - language: - description: Template language (JINJA or VELOCITY). - type: str - lastUpdateTime: - description: Update time of template. - type: int - latestVersionTime: - description: Latest versioned template time. - type: int - name: - description: Name of template. - type: str - parentTemplateId: - description: Parent templateID. - type: str - projectId: - description: Project UUID. - type: str - projectName: - description: Project name. - type: str - rollbackTemplateContent: - description: Rollback template content. - type: str - rollbackTemplateParams: - description: Configuration Template Project's rollbackTemplateParams. - elements: dict - suboptions: - binding: - description: Bind to source. - type: str - customOrder: - description: CustomOrder of template param. - type: int - dataType: - description: Datatype of template param. - type: str - defaultValue: - description: Default value of template param. - type: str - description: - description: Description of template param. - type: str - displayName: - description: Display name of param. - type: str - group: - description: Group. - type: str - id: - description: UUID of template param. - type: str - instructionText: - description: Instruction text for param. - type: str - key: - description: Key. - type: str - notParam: - description: Is it not a variable. - type: bool - order: - description: Order of template param. - type: int - paramArray: - description: Is it an array. - type: bool - parameterName: - description: Name of template param. - type: str - provider: - description: Provider. - type: str - range: - description: Configuration Template Project's range. - elements: dict - suboptions: - id: - description: UUID of range. - type: str - maxValue: - description: Max value of range. - type: int - minValue: - description: Min value of range. - type: int - type: list - required: - description: Is param required. - type: bool - selection: - description: Configuration Template Project's selection. - suboptions: - defaultSelectedValues: - description: Default selection values. - elements: str - type: list - id: - description: UUID of selection. - type: str - selectionType: - description: Type of selection(SINGLE_SELECT or MULTI_SELECT). - type: str - selectionValues: - description: Selection values. - type: dict - type: dict - type: list - softwareType: - description: Applicable device software type. - type: str - softwareVariant: - description: Applicable device software variant. - type: str - softwareVersion: - description: Applicable device software version. - type: str - tags: - description: Configuration Template Project's tags. - elements: dict - suboptions: - id: - description: UUID of tag. - type: str - name: - description: Name of tag. - type: str - type: list - templateContent: - description: Template content. - type: str - templateParams: - description: Configuration Template Project's templateParams. - elements: dict - suboptions: - binding: - description: Bind to source. - type: str - customOrder: - description: CustomOrder of template param. - type: int - dataType: - description: Datatype of template param. - type: str - defaultValue: - description: Default value of template param. - type: str - description: - description: Description of template param. - type: str - displayName: - description: Display name of param. - type: str - group: - description: Group. - type: str - id: - description: UUID of template param. - type: str - instructionText: - description: Instruction text for param. - type: str - key: - description: Key. - type: str - notParam: - description: Is it not a variable. - type: bool - order: - description: Order of template param. - type: int - paramArray: - description: Is it an array. - type: bool - parameterName: - description: Name of template param. - type: str - provider: - description: Provider. - type: str - range: - description: Configuration Template Project's range. - elements: dict - suboptions: - id: - description: UUID of range. - type: str - maxValue: - description: Max value of range. - type: int - minValue: - description: Min value of range. - type: int - type: list - required: - description: Is param required. - type: bool - selection: - description: Configuration Template Project's selection. - suboptions: - defaultSelectedValues: - description: Default selection values. - elements: str - type: list - id: - description: UUID of selection. - type: str - selectionType: - description: Type of selection(SINGLE_SELECT or MULTI_SELECT). - type: str - selectionValues: - description: Selection values. - type: dict - type: dict - type: list - validationErrors: - description: Configuration Template Project's validationErrors. - suboptions: - rollbackTemplateErrors: - description: Validation or design conflicts errors of rollback template. - elements: dict - type: list - templateErrors: - description: Validation or design conflicts errors. - elements: dict - type: list - templateId: - description: UUID of template. - type: str - templateVersion: - description: Current version of template. - type: str - type: dict - version: - description: Current version of template. - type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates CreateProject description: Complete reference of the CreateProject API. @@ -591,164 +97,7 @@ - id: string name: string templates: - - author: string - composite: true - containingTemplates: - - composite: true - description: string - deviceTypes: - - productFamily: string - productSeries: string - productType: string - id: string - language: string - name: string - projectName: string - rollbackTemplateParams: - - binding: string - customOrder: 0 - dataType: string - defaultValue: string - description: string - displayName: string - group: string - id: string - instructionText: string - key: string - notParam: true - order: 0 - paramArray: true - parameterName: string - provider: string - range: - - id: string - maxValue: 0 - minValue: 0 - required: true - selection: - defaultSelectedValues: - - string - id: string - selectionType: string - selectionValues: {} - tags: - - id: string - name: string - templateContent: string - templateParams: - - binding: string - customOrder: 0 - dataType: string - defaultValue: string - description: string - displayName: string - group: string - id: string - instructionText: string - key: string - notParam: true - order: 0 - paramArray: true - parameterName: string - provider: string - range: - - id: string - maxValue: 0 - minValue: 0 - required: true - selection: - defaultSelectedValues: - - string - id: string - selectionType: string - selectionValues: {} - version: string - createTime: 0 - customParamsOrder: true - description: string - deviceTypes: - - productFamily: string - productSeries: string - productType: string - failurePolicy: string - id: string - language: string - lastUpdateTime: 0 - latestVersionTime: 0 - name: string - parentTemplateId: string - projectId: string - projectName: string - rollbackTemplateContent: string - rollbackTemplateParams: - - binding: string - customOrder: 0 - dataType: string - defaultValue: string - description: string - displayName: string - group: string - id: string - instructionText: string - key: string - notParam: true - order: 0 - paramArray: true - parameterName: string - provider: string - range: - - id: string - maxValue: 0 - minValue: 0 - required: true - selection: - defaultSelectedValues: - - string - id: string - selectionType: string - selectionValues: {} - softwareType: string - softwareVariant: string - softwareVersion: string - tags: - - id: string - name: string - templateContent: string - templateParams: - - binding: string - customOrder: 0 - dataType: string - defaultValue: string - description: string - displayName: string - group: string - id: string - instructionText: string - key: string - notParam: true - order: 0 - paramArray: true - parameterName: string - provider: string - range: - - id: string - maxValue: 0 - minValue: 0 - required: true - selection: - defaultSelectedValues: - - string - id: string - selectionType: string - selectionValues: {} - validationErrors: - rollbackTemplateErrors: - - {} - templateErrors: - - {} - templateId: string - templateVersion: string - version: string + - {} - name: Update all cisco.dnac.configuration_template_project: @@ -768,165 +117,7 @@ tags: - id: string name: string - templates: - - author: string - composite: true - containingTemplates: - - composite: true - description: string - deviceTypes: - - productFamily: string - productSeries: string - productType: string - id: string - language: string - name: string - projectName: string - rollbackTemplateParams: - - binding: string - customOrder: 0 - dataType: string - defaultValue: string - description: string - displayName: string - group: string - id: string - instructionText: string - key: string - notParam: true - order: 0 - paramArray: true - parameterName: string - provider: string - range: - - id: string - maxValue: 0 - minValue: 0 - required: true - selection: - defaultSelectedValues: - - string - id: string - selectionType: string - selectionValues: {} - tags: - - id: string - name: string - templateContent: string - templateParams: - - binding: string - customOrder: 0 - dataType: string - defaultValue: string - description: string - displayName: string - group: string - id: string - instructionText: string - key: string - notParam: true - order: 0 - paramArray: true - parameterName: string - provider: string - range: - - id: string - maxValue: 0 - minValue: 0 - required: true - selection: - defaultSelectedValues: - - string - id: string - selectionType: string - selectionValues: {} - version: string - createTime: 0 - customParamsOrder: true - description: string - deviceTypes: - - productFamily: string - productSeries: string - productType: string - failurePolicy: string - id: string - language: string - lastUpdateTime: 0 - latestVersionTime: 0 - name: string - parentTemplateId: string - projectId: string - projectName: string - rollbackTemplateContent: string - rollbackTemplateParams: - - binding: string - customOrder: 0 - dataType: string - defaultValue: string - description: string - displayName: string - group: string - id: string - instructionText: string - key: string - notParam: true - order: 0 - paramArray: true - parameterName: string - provider: string - range: - - id: string - maxValue: 0 - minValue: 0 - required: true - selection: - defaultSelectedValues: - - string - id: string - selectionType: string - selectionValues: {} - softwareType: string - softwareVariant: string - softwareVersion: string - tags: - - id: string - name: string - templateContent: string - templateParams: - - binding: string - customOrder: 0 - dataType: string - defaultValue: string - description: string - displayName: string - group: string - id: string - instructionText: string - key: string - notParam: true - order: 0 - paramArray: true - parameterName: string - provider: string - range: - - id: string - maxValue: 0 - minValue: 0 - required: true - selection: - defaultSelectedValues: - - string - id: string - selectionType: string - selectionValues: {} - validationErrors: - rollbackTemplateErrors: - - {} - templateErrors: - - {} - templateId: string - templateVersion: string - version: string + templates: {} - name: Delete by id cisco.dnac.configuration_template_project: @@ -941,7 +132,6 @@ projectId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_project_info.py b/plugins/modules/configuration_template_project_info.py index f200203db6..3846cc728d 100644 --- a/plugins/modules/configuration_template_project_info.py +++ b/plugins/modules/configuration_template_project_info.py @@ -34,8 +34,8 @@ - ProjectId path parameter. ProjectId(UUID) of project to get project details. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates GetsAListOfProjects description: Complete reference of the GetsAListOfProjects API. @@ -83,7 +83,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -102,213 +101,6 @@ "id": "string", "lastUpdateTime": 0, "name": "string", - "templates": [ - { - "tags": [ - { - "id": "string", - "name": "string" - } - ], - "author": "string", - "composite": true, - "containingTemplates": [ - { - "tags": [ - { - "id": "string", - "name": "string" - } - ], - "composite": true, - "description": "string", - "deviceTypes": [ - { - "productFamily": "string", - "productSeries": "string", - "productType": "string" - } - ], - "id": "string", - "language": "string", - "name": "string", - "projectName": "string", - "rollbackTemplateParams": [ - { - "binding": "string", - "customOrder": 0, - "dataType": "string", - "defaultValue": "string", - "description": "string", - "displayName": "string", - "group": "string", - "id": "string", - "instructionText": "string", - "key": "string", - "notParam": true, - "order": 0, - "paramArray": true, - "parameterName": "string", - "provider": "string", - "range": [ - { - "id": "string", - "maxValue": 0, - "minValue": 0 - } - ], - "required": true, - "selection": { - "defaultSelectedValues": [ - "string" - ], - "id": "string", - "selectionType": "string", - "selectionValues": {} - } - } - ], - "templateContent": "string", - "templateParams": [ - { - "binding": "string", - "customOrder": 0, - "dataType": "string", - "defaultValue": "string", - "description": "string", - "displayName": "string", - "group": "string", - "id": "string", - "instructionText": "string", - "key": "string", - "notParam": true, - "order": 0, - "paramArray": true, - "parameterName": "string", - "provider": "string", - "range": [ - { - "id": "string", - "maxValue": 0, - "minValue": 0 - } - ], - "required": true, - "selection": { - "defaultSelectedValues": [ - "string" - ], - "id": "string", - "selectionType": "string", - "selectionValues": {} - } - } - ], - "version": "string" - } - ], - "createTime": 0, - "customParamsOrder": true, - "description": "string", - "deviceTypes": [ - { - "productFamily": "string", - "productSeries": "string", - "productType": "string" - } - ], - "failurePolicy": "string", - "id": "string", - "language": "string", - "lastUpdateTime": 0, - "latestVersionTime": 0, - "name": "string", - "parentTemplateId": "string", - "projectId": "string", - "projectName": "string", - "rollbackTemplateContent": "string", - "rollbackTemplateParams": [ - { - "binding": "string", - "customOrder": 0, - "dataType": "string", - "defaultValue": "string", - "description": "string", - "displayName": "string", - "group": "string", - "id": "string", - "instructionText": "string", - "key": "string", - "notParam": true, - "order": 0, - "paramArray": true, - "parameterName": "string", - "provider": "string", - "range": [ - { - "id": "string", - "maxValue": 0, - "minValue": 0 - } - ], - "required": true, - "selection": { - "defaultSelectedValues": [ - "string" - ], - "id": "string", - "selectionType": "string", - "selectionValues": {} - } - } - ], - "softwareType": "string", - "softwareVariant": "string", - "softwareVersion": "string", - "templateContent": "string", - "templateParams": [ - { - "binding": "string", - "customOrder": 0, - "dataType": "string", - "defaultValue": "string", - "description": "string", - "displayName": "string", - "group": "string", - "id": "string", - "instructionText": "string", - "key": "string", - "notParam": true, - "order": 0, - "paramArray": true, - "parameterName": "string", - "provider": "string", - "range": [ - { - "id": "string", - "maxValue": 0, - "minValue": 0 - } - ], - "required": true, - "selection": { - "defaultSelectedValues": [ - "string" - ], - "id": "string", - "selectionType": "string", - "selectionValues": {} - } - } - ], - "validationErrors": { - "rollbackTemplateErrors": {}, - "templateErrors": {}, - "templateId": "string", - "templateVersion": "string" - }, - "version": "string" - } - ] + "templates": {} } """ diff --git a/plugins/modules/configuration_template_version_create.py b/plugins/modules/configuration_template_version_create.py index d0317ea84c..b95eb03548 100644 --- a/plugins/modules/configuration_template_version_create.py +++ b/plugins/modules/configuration_template_version_create.py @@ -23,8 +23,8 @@ description: UUID of template. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates VersionTemplate description: Complete reference of the VersionTemplate API. @@ -52,7 +52,6 @@ templateId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/configuration_template_version_info.py b/plugins/modules/configuration_template_version_info.py index 0dfdb8a930..2d148981f3 100644 --- a/plugins/modules/configuration_template_version_info.py +++ b/plugins/modules/configuration_template_version_info.py @@ -24,8 +24,8 @@ - TemplateId path parameter. TemplateId(UUID) to get list of versioned templates. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates GetsAllTheVersionsOfAGivenTemplate description: Complete reference of the GetsAllTheVersionsOfAGivenTemplate API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/credential_to_site_by_siteid_create_v2.py b/plugins/modules/credential_to_site_by_siteid_create_v2.py index 1ee9e33a91..68d88b5f09 100644 --- a/plugins/modules/credential_to_site_by_siteid_create_v2.py +++ b/plugins/modules/credential_to_site_by_siteid_create_v2.py @@ -11,7 +11,7 @@ description: - Manage operation create of the resource Credential To Site By Siteid Create V2. - API to assign Device Credential to a site. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -38,8 +38,8 @@ description: SNMPv3 Credential Id. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings AssignDeviceCredentialToSiteV2 description: Complete reference of the AssignDeviceCredentialToSiteV2 API. @@ -72,7 +72,6 @@ snmpV3Id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_configurations_export.py b/plugins/modules/device_configurations_export.py index 4d7ba14db0..c205a51608 100644 --- a/plugins/modules/device_configurations_export.py +++ b/plugins/modules/device_configurations_export.py @@ -17,15 +17,17 @@ author: Rafael Campos (@racampos) options: deviceId: - description: Device Id. - elements: str - type: list + description: UUIDs of the devices for which configurations need to be exported. + type: str password: - description: Password. + description: Password for the zip file to protect exported configurations. Must + contain, at minimum 8 characters, one lowercase letter, one uppercase letter, + one number, one special character(-=;,./~!@#$%^&*()_+{}| ?). It may not contain + white space or the characters <>. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Archive ExportDeviceConfigurations description: Complete reference of the ExportDeviceConfigurations API. @@ -49,12 +51,10 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" - deviceId: - - string + deviceId: string password: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -62,10 +62,10 @@ type: dict sample: > { + "version": "string", "response": { - "taskId": "string", - "url": "string" - }, - "version": "string" + "url": "string", + "taskId": "string" + } } """ diff --git a/plugins/modules/device_credential_create.py b/plugins/modules/device_credential_create.py index b26ec83a09..10662f946c 100644 --- a/plugins/modules/device_credential_create.py +++ b/plugins/modules/device_credential_create.py @@ -10,7 +10,9 @@ short_description: Resource module for Device Credential Create description: - Manage operation create of the resource Device Credential Create. -- API to create device credentials. +- > + API to create device credentials. This API has been deprecated and will not be available in a Cisco DNA Center + release after August 1st 2024 23 59 59 GMT. Please refer new Intent API Create Global Credentials V2. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module @@ -48,7 +50,7 @@ type: str port: description: Port for http read credential. - type: int + type: float username: description: User name of the http read credential. type: str @@ -65,7 +67,7 @@ type: str port: description: Port for http write credential. - type: int + type: float username: description: User name of the http write credential. type: str @@ -120,8 +122,8 @@ type: list type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings CreateDeviceCredentials description: Complete reference of the CreateDeviceCredentials API. @@ -177,7 +179,6 @@ username: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_credential_delete.py b/plugins/modules/device_credential_delete.py index 73d1449977..716bcfef0b 100644 --- a/plugins/modules/device_credential_delete.py +++ b/plugins/modules/device_credential_delete.py @@ -10,7 +10,9 @@ short_description: Resource module for Device Credential Delete description: - Manage operation delete of the resource Device Credential Delete. -- Delete device credential. +- > + Delete device credential. This API has been deprecated and will not be available in a Cisco DNA Center release + after August 1st 2024 23 59 59 GMT. Please refer new Intent API Delete Global Credentials V2. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module @@ -20,8 +22,8 @@ description: Id path parameter. Global credential id. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings DeleteDeviceCredential description: Complete reference of the DeleteDeviceCredential API. @@ -48,7 +50,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_credential_info.py b/plugins/modules/device_credential_info.py index 27175a6692..c0db3bbcff 100644 --- a/plugins/modules/device_credential_info.py +++ b/plugins/modules/device_credential_info.py @@ -10,7 +10,9 @@ short_description: Information module for Device Credential description: - Get all Device Credential. -- API to get device credential details. +- > + API to get device credential details. This API has been deprecated and will not be available in a Cisco DNA Center + release after August 1st 2024 23 59 59 GMT. Please refer new Intent API Get All Global Credentials V2. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -24,8 +26,8 @@ - SiteId query parameter. Site id to retrieve the credential details associated with the site. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings GetDeviceCredentialDetails description: Complete reference of the GetDeviceCredentialDetails API. @@ -54,7 +56,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_credential_update.py b/plugins/modules/device_credential_update.py index 7c5cafd5ba..5a25c48501 100644 --- a/plugins/modules/device_credential_update.py +++ b/plugins/modules/device_credential_update.py @@ -10,7 +10,9 @@ short_description: Resource module for Device Credential Update description: - Manage operation update of the resource Device Credential Update. -- API to update device credentials. +- > + API to update device credentials. This API has been deprecated and will not be available in a Cisco DNA Center + release after August 1st 2024 23 59 59 GMT. Please refer new Intent API Update Global Credentials V2. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module @@ -132,8 +134,8 @@ type: dict type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings UpdateDeviceCredentials description: Complete reference of the UpdateDeviceCredentials API. @@ -195,7 +197,6 @@ username: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_details_info.py b/plugins/modules/device_details_info.py index 05793acd29..bbf8396358 100644 --- a/plugins/modules/device_details_info.py +++ b/plugins/modules/device_details_info.py @@ -21,19 +21,19 @@ type: dict timestamp: description: - - Timestamp query parameter. Epoch time(in milliseconds) when the device data is required. - type: str - searchBy: + - Timestamp query parameter. UTC timestamp of device data in milliseconds. + type: float + identifier: description: - - SearchBy query parameter. MAC Address or Device Name value or UUID of the network device. + - Identifier query parameter. One of "macAddress", "nwDeviceName", "uuid" (case insensitive). type: str - identifier: + searchBy: description: - - Identifier query parameter. One of keywords macAddress or uuid or nwDeviceName. + - SearchBy query parameter. MAC Address, device name, or UUID of the network device. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDeviceDetail description: Complete reference of the GetDeviceDetail API. @@ -58,13 +58,12 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" headers: "{{my_headers | from_json}}" - timestamp: string - searchBy: string + timestamp: 0 identifier: string + searchBy: string register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -72,49 +71,91 @@ type: dict sample: > { - "HALastResetReason": "string", - "managementIpAddr": "string", - "HAPrimaryPowerStatus": "string", - "redundancyMode": "string", - "communicationState": "string", + "noiseScore": 0, + "policyTagName": "string", + "interferenceScore": 0, + "opState": "string", + "powerSaveMode": "string", + "mode": "string", + "resetReason": "string", + "nwDeviceRole": "string", + "protocol": "string", + "powerMode": "string", + "connectedTime": "string", + "ringStatus": true, + "ledFlashSeconds": "string", + "ip_addr_managementIpAddr": "string", + "stackType": "string", + "subMode": "string", + "serialNumber": "string", "nwDeviceName": "string", - "redundancyUnit": "string", - "platformId": "string", - "redundancyPeerState": "string", + "deviceGroupHierarchyId": "string", + "cpu": "string", + "utilization": "string", "nwDeviceId": "string", - "redundancyState": "string", - "nwDeviceRole": "string", + "siteHierarchyGraphId": "string", "nwDeviceFamily": "string", "macAddress": "string", - "collectionStatus": "string", + "homeApEnabled": "string", "deviceSeries": "string", - "osType": "string", - "clientCount": "string", - "HASecondaryPowerStatus": "string", + "collectionStatus": "string", + "utilizationScore": 0, + "maintenanceMode": true, + "interference": "string", "softwareVersion": "string", - "nwDeviceType": "string", + "tagIdList": [ + {} + ], + "powerType": "string", "overallHealth": 0, - "memoryScore": 0, - "cpuScore": 0, - "noiseScore": 0, - "utilizationScore": 0, - "airQualityScore": 0, - "interferenceScore": 0, - "wqeScore": 0, - "freeMbufScore": 0, - "packetPoolScore": 0, - "freeTimerScore": 0, + "managementIpAddr": "string", "memory": "string", - "cpu": "string", + "communicationState": "string", + "apType": "string", + "adminState": "string", "noise": "string", - "utilization": "string", + "icapCapability": "string", + "regulatoryDomain": "string", + "ethernetMac": "string", + "nwDeviceType": "string", "airQuality": "string", - "interference": "string", - "wqe": "string", - "freeMbuf": "string", - "packetPool": "string", - "freeTimer": "string", + "rfTagName": "string", + "siteTagName": "string", + "platformId": "string", + "upTime": "string", + "memoryScore": 0, + "powerSaveModeCapable": "string", + "powerProfile": "string", + "airQualityScore": 0, "location": "string", - "timestamp": "string" + "flexGroup": "string", + "lastBootTime": 0, + "powerCalendarProfile": "string", + "connectivityStatus": 0, + "ledFlashEnabled": "string", + "cpuScore": 0, + "avgTemperature": 0, + "maxTemperature": 0, + "haStatus": "string", + "osType": "string", + "timestamp": 0, + "apGroup": "string", + "redundancyMode": "string", + "featureFlagList": [ + "string" + ], + "freeMbufScore": 0, + "HALastResetReason": "string", + "wqeScore": 0, + "redundancyPeerStateDerived": "string", + "freeTimerScore": 0, + "redundancyPeerState": "string", + "redundancyStateDerived": "string", + "redundancyState": "string", + "packetPoolScore": 0, + "freeTimer": 0, + "packetPool": 0, + "wqe": 0, + "freeMbuf": 0 } """ diff --git a/plugins/modules/device_enrichment_details_info.py b/plugins/modules/device_enrichment_details_info.py index 37a46f792f..a825d5c9c5 100644 --- a/plugins/modules/device_enrichment_details_info.py +++ b/plugins/modules/device_enrichment_details_info.py @@ -22,8 +22,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDeviceEnrichmentDetails description: Complete reference of the GetDeviceEnrichmentDetails API. @@ -51,7 +51,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_family_identifiers_details_info.py b/plugins/modules/device_family_identifiers_details_info.py index 97736aa741..4210b61136 100644 --- a/plugins/modules/device_family_identifiers_details_info.py +++ b/plugins/modules/device_family_identifiers_details_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Software Image Management (SWIM) GetDeviceFamilyIdentifiers description: Complete reference of the GetDeviceFamilyIdentifiers API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_health_info.py b/plugins/modules/device_health_info.py index 7b0775f33e..dd604930b5 100644 --- a/plugins/modules/device_health_info.py +++ b/plugins/modules/device_health_info.py @@ -23,35 +23,35 @@ type: dict deviceRole: description: - - DeviceRole query parameter. The device role (One of CORE, ACCESS, DISTRIBUTION, ROUTER, WLC, AP). + - DeviceRole query parameter. CORE, ACCESS, DISTRIBUTION, ROUTER, WLC, or AP (case insensitive). type: str siteId: description: - - SiteId query parameter. Assurance site UUID value. + - SiteId query parameter. DNAC site UUID. type: str health: description: - - Health query parameter. The device overall health (One of POOR, FAIR, GOOD). + - Health query parameter. DNAC health catagory POOR, FAIR, or GOOD (case insensitive). type: str startTime: description: - StartTime query parameter. UTC epoch time in milliseconds. - type: int + type: float endTime: description: - - EndTime query parameter. UTC epoch time in miliseconds. - type: int + - EndTime query parameter. UTC epoch time in milliseconds. + type: float limit: description: - - Limit query parameter. Max number of device entries in the response (default to 50. Max at 1000). - type: int + - Limit query parameter. Max number of device entries in the response (default to 50. Max at 500). + type: float offset: description: - - Offset query parameter. The offset of the first device in the returned data. - type: int + - Offset query parameter. The offset of the first device in the returned data (Mutiple of 'limit' + 1). + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices Devices description: Complete reference of the Devices API. @@ -86,7 +86,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -98,51 +97,84 @@ "totalCount": 0, "response": [ { - "name": "string", - "model": "string", - "osVersion": "string", - "ipAddress": "string", - "overallHealth": 0, - "issueCount": 0, - "location": "string", - "deviceFamily": "string", "deviceType": "string", - "macAddress": "string", - "interfaceLinkErrHealth": 0, - "cpuUlitilization": 0, - "cpuHealth": 0, - "memoryUtilizationHealth": 0, - "memoryUtilization": 0, - "interDeviceLinkAvailHealth": 0, - "reachabilityHealth": "string", - "clientCount": { + "cpuUtilization": 0, + "overallHealth": 0, + "utilizationHealth": { "radio0": 0, "radio1": 0, + "radio2": 0, + "radio3": 0, "Ghz24": 0, "Ghz50": 0 }, - "interferenceHealth": { + "airQualityHealth": { "radio0": 0, "radio1": 0, + "radio2": 0, + "radio3": 0, "Ghz24": 0, "Ghz50": 0 }, + "ipAddress": "string", + "cpuHealth": 0, + "deviceFamily": "string", + "issueCount": 0, + "macAddress": "string", "noiseHealth": { + "radio0": 0, "radio1": 0, + "radio2": 0, + "radio3": 0, + "Ghz24": 0, "Ghz50": 0 }, - "airQualityHealth": { + "osVersion": "string", + "name": "string", + "interfaceLinkErrHealth": 0, + "memoryUtilization": 0, + "interDeviceLinkAvailHealth": 0, + "interferenceHealth": { "radio0": 0, "radio1": 0, + "radio2": 0, + "radio3": 0, "Ghz24": 0, "Ghz50": 0 }, - "utilizationHealth": { + "model": "string", + "location": "string", + "reachabilityHealth": "string", + "band": { + "radio0": "string", + "radio1": "string", + "radio2": "string", + "radio3": 0 + }, + "memoryUtilizationHealth": 0, + "clientCount": { "radio0": 0, "radio1": 0, + "radio2": 0, + "radio3": 0, "Ghz24": 0, "Ghz50": 0 - } + }, + "avgTemperature": 0, + "maxTemperature": 0, + "interDeviceLinkAvailFabric": 0, + "apCount": 0, + "freeTimerScore": 0, + "freeTimer": 0, + "packetPoolHealth": 0, + "packetPool": 0, + "freeMemoryBufferHealth": 0, + "freeMemoryBuffer": 0, + "wqePoolsHealth": 0, + "wqePools": 0, + "wanLinkUtilization": 0, + "cpuUlitilization": 0, + "uuid": "string" } ] } diff --git a/plugins/modules/device_interface_by_ip_info.py b/plugins/modules/device_interface_by_ip_info.py index df7223b150..d9ea17a249 100644 --- a/plugins/modules/device_interface_by_ip_info.py +++ b/plugins/modules/device_interface_by_ip_info.py @@ -24,8 +24,8 @@ - IpAddress path parameter. IP address of the interface. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetInterfaceByIP description: Complete reference of the GetInterfaceByIP API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -64,9 +63,24 @@ { "response": [ { + "addresses": [ + { + "address": { + "ipAddress": { + "address": "string" + }, + "ipMask": { + "address": "string" + }, + "isInverseMask": true + }, + "type": "string" + } + ], "adminStatus": "string", "className": "string", "description": "string", + "name": "string", "deviceId": "string", "duplex": "string", "id": "string", @@ -77,11 +91,14 @@ "ipv4Address": "string", "ipv4Mask": "string", "isisSupport": "string", + "lastOutgoingPacketTime": 0, + "lastIncomingPacketTime": 0, "lastUpdated": "string", "macAddress": "string", "mappedPhysicalInterfaceId": "string", "mappedPhysicalInterfaceName": "string", "mediaType": "string", + "mtu": "string", "nativeVlanId": "string", "ospfSupport": "string", "pid": "string", diff --git a/plugins/modules/device_interface_count_info.py b/plugins/modules/device_interface_count_info.py index 01d3361fbb..5f416c933b 100644 --- a/plugins/modules/device_interface_count_info.py +++ b/plugins/modules/device_interface_count_info.py @@ -20,12 +20,12 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Devices GetDeviceInterfaceCount - description: Complete reference of the GetDeviceInterfaceCount API. - link: https://developer.cisco.com/docs/dna-center/#!get-device-interface-count +- name: Cisco DNA Center documentation for Devices GetDeviceInterfaceCountForMultipleDevices + description: Complete reference of the GetDeviceInterfaceCountForMultipleDevices API. + link: https://developer.cisco.com/docs/dna-center/#!get-device-interface-count-for-multiple-devices notes: - SDK Method used are devices.Devices.get_device_interface_count, @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_interface_info.py b/plugins/modules/device_interface_info.py index 31b2bc4c64..983189ebfb 100644 --- a/plugins/modules/device_interface_info.py +++ b/plugins/modules/device_interface_info.py @@ -42,8 +42,8 @@ - Id path parameter. Interface ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetAllInterfaces description: Complete reference of the GetAllInterfaces API. @@ -93,7 +93,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -102,9 +101,24 @@ sample: > { "response": { + "addresses": [ + { + "address": { + "ipAddress": { + "address": "string" + }, + "ipMask": { + "address": "string" + }, + "isInverseMask": true + }, + "type": "string" + } + ], "adminStatus": "string", "className": "string", "description": "string", + "name": "string", "deviceId": "string", "duplex": "string", "id": "string", @@ -115,11 +129,14 @@ "ipv4Address": "string", "ipv4Mask": "string", "isisSupport": "string", + "lastOutgoingPacketTime": 0, + "lastIncomingPacketTime": 0, "lastUpdated": "string", "macAddress": "string", "mappedPhysicalInterfaceId": "string", "mappedPhysicalInterfaceName": "string", "mediaType": "string", + "mtu": "string", "nativeVlanId": "string", "ospfSupport": "string", "pid": "string", diff --git a/plugins/modules/device_interface_isis_info.py b/plugins/modules/device_interface_isis_info.py index 798c478215..2be160ae79 100644 --- a/plugins/modules/device_interface_isis_info.py +++ b/plugins/modules/device_interface_isis_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetISISInterfaces description: Complete reference of the GetISISInterfaces API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -59,9 +58,24 @@ { "response": [ { + "addresses": [ + { + "address": { + "ipAddress": { + "address": "string" + }, + "ipMask": { + "address": "string" + }, + "isInverseMask": true + }, + "type": "string" + } + ], "adminStatus": "string", "className": "string", "description": "string", + "name": "string", "deviceId": "string", "duplex": "string", "id": "string", @@ -72,11 +86,14 @@ "ipv4Address": "string", "ipv4Mask": "string", "isisSupport": "string", + "lastOutgoingPacketTime": 0, + "lastIncomingPacketTime": 0, "lastUpdated": "string", "macAddress": "string", "mappedPhysicalInterfaceId": "string", "mappedPhysicalInterfaceName": "string", "mediaType": "string", + "mtu": "string", "nativeVlanId": "string", "ospfSupport": "string", "pid": "string", diff --git a/plugins/modules/device_interface_ospf_info.py b/plugins/modules/device_interface_ospf_info.py index ed87a4b0cd..69e49d3e6d 100644 --- a/plugins/modules/device_interface_ospf_info.py +++ b/plugins/modules/device_interface_ospf_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetOSPFInterfaces description: Complete reference of the GetOSPFInterfaces API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -59,9 +58,24 @@ { "response": [ { + "addresses": [ + { + "address": { + "ipAddress": { + "address": "string" + }, + "ipMask": { + "address": "string" + }, + "isInverseMask": true + }, + "type": "string" + } + ], "adminStatus": "string", "className": "string", "description": "string", + "name": "string", "deviceId": "string", "duplex": "string", "id": "string", @@ -72,11 +86,14 @@ "ipv4Address": "string", "ipv4Mask": "string", "isisSupport": "string", + "lastOutgoingPacketTime": 0, + "lastIncomingPacketTime": 0, "lastUpdated": "string", "macAddress": "string", "mappedPhysicalInterfaceId": "string", "mappedPhysicalInterfaceName": "string", "mediaType": "string", + "mtu": "string", "nativeVlanId": "string", "ospfSupport": "string", "pid": "string", diff --git a/plugins/modules/device_reboot_apreboot.py b/plugins/modules/device_reboot_apreboot.py index 92e7c41ee0..e4c73707ff 100644 --- a/plugins/modules/device_reboot_apreboot.py +++ b/plugins/modules/device_reboot_apreboot.py @@ -21,8 +21,8 @@ elements: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless RebootAccessPoints description: Complete reference of the RebootAccessPoints API. @@ -51,7 +51,6 @@ - string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_reboot_apreboot_info.py b/plugins/modules/device_reboot_apreboot_info.py index c4e500062a..556038da9f 100644 --- a/plugins/modules/device_reboot_apreboot_info.py +++ b/plugins/modules/device_reboot_apreboot_info.py @@ -11,7 +11,7 @@ description: - Get all Device Reboot Apreboot. - Users can query the access point reboot status using this intent API. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -24,8 +24,8 @@ - ParentTaskId query parameter. Task id of ap reboot request. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless GetAccessPointRebootTaskResult description: Complete reference of the GetAccessPointRebootTaskResult API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_replacement.py b/plugins/modules/device_replacement.py index a5353ddd06..99a9bfa009 100644 --- a/plugins/modules/device_replacement.py +++ b/plugins/modules/device_replacement.py @@ -22,51 +22,52 @@ elements: dict suboptions: creationTime: - description: Device Replacement's creationTime. + description: Date and time of marking the device for replacement. type: int family: - description: Device Replacement's family. + description: Faulty device family. type: str faultyDeviceId: - description: Device Replacement's faultyDeviceId. + description: Unique identifier of the faulty device. type: str faultyDeviceName: - description: Device Replacement's faultyDeviceName. + description: Faulty device name. type: str faultyDevicePlatform: - description: Device Replacement's faultyDevicePlatform. + description: Faulty device platform. type: str faultyDeviceSerialNumber: - description: Device Replacement's faultyDeviceSerialNumber. + description: Faulty device serial number. type: str id: - description: Device Replacement's id. + description: Unique identifier of the device replacement resource. type: str neighbourDeviceId: - description: Device Replacement's neighbourDeviceId. + description: Unique identifier of the neighbor device to create the DHCP server. type: str networkReadinessTaskId: - description: Device Replacement's networkReadinessTaskId. + description: Unique identifier of network readiness task. type: str replacementDevicePlatform: - description: Device Replacement's replacementDevicePlatform. + description: Replacement device platform. type: str replacementDeviceSerialNumber: - description: Device Replacement's replacementDeviceSerialNumber. + description: Replacement device serial number. type: str replacementStatus: - description: Device Replacement's replacementStatus. + description: Device replacement status. Use NON-FAULTY to unmark the device + for replacement. type: str replacementTime: - description: Device Replacement's replacementTime. + description: Date and time of device replacement. type: int workflowId: - description: Device Replacement's workflowId. + description: Unique identifier of the device replacement workflow. type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Replacement MarkDeviceForReplacement description: Complete reference of the MarkDeviceForReplacement API. @@ -139,7 +140,6 @@ workflowId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_replacement_count_info.py b/plugins/modules/device_replacement_count_info.py index 8aae86979d..98c7f9257a 100644 --- a/plugins/modules/device_replacement_count_info.py +++ b/plugins/modules/device_replacement_count_info.py @@ -23,12 +23,12 @@ description: - > ReplacementStatus query parameter. Device Replacement status listREADY-FOR-REPLACEMENT, REPLACEMENT-IN- - PROGRESS, REPLACEMENT-SCHEDULED, REPLACED, ERROR. + PROGRESS, REPLACEMENT-SCHEDULED, REPLACED, ERROR. elements: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Replacement ReturnReplacementDevicesCount description: Complete reference of the ReturnReplacementDevicesCount API. @@ -57,7 +57,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_replacement_deploy.py b/plugins/modules/device_replacement_deploy.py index 81dfc92516..83b7b31352 100644 --- a/plugins/modules/device_replacement_deploy.py +++ b/plugins/modules/device_replacement_deploy.py @@ -19,14 +19,14 @@ author: Rafael Campos (@racampos) options: faultyDeviceSerialNumber: - description: Device Replacement Deploy's faultyDeviceSerialNumber. + description: Faulty device serial number. type: str replacementDeviceSerialNumber: - description: Device Replacement Deploy's replacementDeviceSerialNumber. + description: Replacement device serial number. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Replacement DeployDeviceReplacementWorkflow description: Complete reference of the DeployDeviceReplacementWorkflow API. @@ -54,7 +54,6 @@ replacementDeviceSerialNumber: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/device_replacement_info.py b/plugins/modules/device_replacement_info.py index 4dd9756d5f..49bdb7f7b5 100644 --- a/plugins/modules/device_replacement_info.py +++ b/plugins/modules/device_replacement_info.py @@ -46,7 +46,7 @@ description: - > ReplacementStatus query parameter. Device Replacement status READY-FOR-REPLACEMENT, REPLACEMENT-IN-PROGRESS, - REPLACEMENT-SCHEDULED, REPLACED, ERROR, NETWORK_READINESS_REQUESTED, NETWORK_READINESS_FAILED. + REPLACEMENT-SCHEDULED, REPLACED, ERROR, NETWORK_READINESS_REQUESTED, NETWORK_READINESS_FAILED. elements: str type: list family: @@ -71,8 +71,8 @@ - Limit query parameter. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Replacement ReturnListOfReplacementDevicesWithReplacementDetails description: Complete reference of the ReturnListOfReplacementDevicesWithReplacementDetails API. @@ -111,7 +111,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -134,7 +133,9 @@ "replacementDeviceSerialNumber": "string", "replacementStatus": "string", "replacementTime": 0, - "workflowId": "string" + "workflowId": "string", + "workflowFailedStep": "string", + "readinesscheckTaskId": "string" } ], "version": "string" diff --git a/plugins/modules/disassociate_site_to_network_profile.py b/plugins/modules/disassociate_site_to_network_profile.py index 2972ac7f20..e06c5e1986 100644 --- a/plugins/modules/disassociate_site_to_network_profile.py +++ b/plugins/modules/disassociate_site_to_network_profile.py @@ -23,8 +23,8 @@ description: SiteId path parameter. Site Id to be associated. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Site Design Disassociate description: Complete reference of the Disassociate API. @@ -52,7 +52,6 @@ siteId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/discovery.py b/plugins/modules/discovery.py index 94fca37e00..f688ed7329 100644 --- a/plugins/modules/discovery.py +++ b/plugins/modules/discovery.py @@ -22,200 +22,206 @@ author: Rafael Campos (@racampos) options: attributeInfo: - description: Discovery's attributeInfo. + description: Deprecated. type: dict cdpLevel: - description: Discovery's cdpLevel. + description: CDP level to which neighbor devices to be discovered. type: int deviceIds: - description: Discovery's deviceIds. + description: Ids of the devices discovered in a discovery. type: str discoveryCondition: - description: Discovery's discoveryCondition. + description: To indicate the discovery status. Available options Complete or In + Progress. type: str discoveryStatus: - description: Discovery's discoveryStatus. + description: Status of the discovery. Available options are active, inactive, edit. type: str discoveryType: - description: Discovery's discoveryType. + description: Type of the discovery. 'SINGLE', 'RANGE', 'MULTI RANGE', 'CDP', 'LLDP', + 'CIDR'. type: str enablePasswordList: - description: Discovery's enablePasswordList. + description: Enable Password of the devices to be discovered. type: str globalCredentialIdList: - description: Discovery's globalCredentialIdList. + description: List of global credential ids to be used. elements: str type: list httpReadCredential: description: Discovery's httpReadCredential. suboptions: comments: - description: Discovery's comments. + description: Comments to identify the credential. type: str credentialType: - description: Discovery's credentialType. + description: Credential type to identify the application that uses the credential. type: str description: - description: Discovery's description. + description: Description of the credential. type: str id: - description: Discovery's id. + description: Credential Id. type: str instanceTenantId: - description: Discovery's instanceTenantId. + description: Credential Tenant Id. type: str instanceUuid: - description: Discovery's instanceUuid. + description: Credential Id. type: str password: - description: Discovery's password. + description: HTTP(S) password. type: str port: - description: Discovery's port. + description: HTTP(S) port. type: int secure: - description: Secure flag. + description: Flag for HTTPS. type: bool username: - description: Discovery's username. + description: HTTP(S) username. type: str type: dict httpWriteCredential: description: Discovery's httpWriteCredential. suboptions: comments: - description: Discovery's comments. + description: Comments to identify the credential. type: str credentialType: - description: Discovery's credentialType. + description: Credential type to identify the application that uses the credential. type: str description: - description: Discovery's description. + description: Description of the credential. type: str id: - description: Discovery's id. + description: Credential Id. type: str instanceTenantId: - description: Discovery's instanceTenantId. + description: Credential Tenant Id. type: str instanceUuid: - description: Discovery's instanceUuid. + description: Credential Id. type: str password: - description: Discovery's password. + description: HTTP(S) password. type: str port: - description: Discovery's port. + description: HTTP(S) port. type: int secure: - description: Secure flag. + description: Flag for HTTPS. type: bool username: - description: Discovery's username. + description: HTTP(S) username. type: str type: dict id: - description: Discovery's id. + description: Unique Discovery Id. type: str ipAddressList: - description: Discovery's ipAddressList. + description: List of IP address of the devices to be discovered. type: str ipFilterList: - description: Discovery's ipFilterList. + description: IP addresses of the devices to be filtered. type: str isAutoCdp: - description: IsAutoCdp flag. + description: Flag to mention if CDP discovery or not. type: bool lldpLevel: - description: Discovery's lldpLevel. + description: LLDP level to which neighbor devices to be discovered. type: int name: - description: Discovery's name. + description: Name for the discovery. type: str netconfPort: - description: Discovery's netconfPort. + description: Netconf port on the device. Netconf will need valid sshv2 credentials + for it to work. type: str numDevices: - description: Discovery's numDevices. + description: Number of devices discovered in the discovery. type: int parentDiscoveryId: - description: Discovery's parentDiscoveryId. + description: Parent Discovery Id from which the discovery was initiated. type: str passwordList: - description: Discovery's passwordList. + description: Password of the devices to be discovered. type: str preferredMgmtIPMethod: - description: Discovery's preferredMgmtIPMethod. + description: Preferred management IP method. Available options are 'None' and 'UseLoopBack'. type: str protocolOrder: - description: Discovery's protocolOrder. + description: Order of protocol (ssh/telnet) in which device connection will be tried. + Ex 'telnet' only telnet; 'ssh,telnet' ssh with higher order than telnet. type: str retry: description: Number of times to try establishing connection to device. type: int retryCount: - description: Discovery's retryCount. + description: Number of times to try establishing connection to device. type: int snmpAuthPassphrase: - description: Discovery's snmpAuthPassphrase. + description: Auth passphrase for SNMP. type: str snmpAuthProtocol: - description: Discovery's snmpAuthProtocol. + description: SNMP auth protocol. SHA' or 'MD5'. type: str snmpMode: - description: Discovery's snmpMode. + description: Mode of SNMP. 'AUTHPRIV' or 'AUTHNOPRIV' or 'NOAUTHNOPRIV'. type: str snmpPrivPassphrase: - description: Discovery's snmpPrivPassphrase. + description: Passphrase for SNMP privacy. type: str snmpPrivProtocol: - description: Discovery's snmpPrivProtocol. + description: SNMP privacy protocol. 'AES128'. type: str snmpROCommunity: - description: Snmp RO community of the devices to be discovered. + description: SNMP RO community of the devices to be discovered. type: str snmpROCommunityDesc: - description: Description for Snmp RO community. + description: Description for SNMP RO community. type: str snmpRWCommunity: - description: Snmp RW community of the devices to be discovered. + description: SNMP RW community of the devices to be discovered. type: str snmpRWCommunityDesc: - description: Description for Snmp RW community. + description: Description for SNMP RW community. type: str snmpRoCommunity: - description: Discovery's snmpRoCommunity. + description: SNMP RO community of the devices to be discovered. type: str snmpRoCommunityDesc: - description: Discovery's snmpRoCommunityDesc. + description: Description for SNMP RO community. type: str snmpRwCommunity: - description: Discovery's snmpRwCommunity. + description: SNMP RW community of the devices to be discovered. type: str snmpRwCommunityDesc: - description: Discovery's snmpRwCommunityDesc. + description: Description for SNMP RW community. type: str snmpUserName: - description: Discovery's snmpUserName. + description: SNMP username of the device. type: str snmpVersion: description: Version of SNMP. V2 or v3. type: str timeOut: - description: Discovery's timeOut. + description: Time to wait for device response. type: int timeout: description: Time to wait for device response in seconds. type: int updateMgmtIp: - description: UpdateMgmtIp flag. + description: Updates Management IP if multiple IPs are available for a device. If + set to true, when a device is rediscovered with a different IP, the management + IP is updated. Default value is false. type: bool userNameList: - description: Discovery's userNameList. + description: Username of the devices to be discovered. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery StartDiscovery description: Complete reference of the StartDiscovery API. @@ -388,7 +394,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/discovery_count_info.py b/plugins/modules/discovery_count_info.py index 59f92499a0..abf5c9d0c8 100644 --- a/plugins/modules/discovery_count_info.py +++ b/plugins/modules/discovery_count_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery GetCountOfAllDiscoveryJobs description: Complete reference of the GetCountOfAllDiscoveryJobs API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/discovery_device_count_info.py b/plugins/modules/discovery_device_count_info.py index 51da8df803..4a73deeae0 100644 --- a/plugins/modules/discovery_device_count_info.py +++ b/plugins/modules/discovery_device_count_info.py @@ -30,8 +30,8 @@ - TaskId query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery GetDevicesDiscoveredById description: Complete reference of the GetDevicesDiscoveredById API. @@ -61,7 +61,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/discovery_device_info.py b/plugins/modules/discovery_device_info.py index 2bc42ae22b..2fde652725 100644 --- a/plugins/modules/discovery_device_info.py +++ b/plugins/modules/discovery_device_info.py @@ -30,8 +30,8 @@ - TaskId query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery GetDiscoveredNetworkDevicesByDiscoveryId description: Complete reference of the GetDiscoveredNetworkDevicesByDiscoveryId API. @@ -61,7 +61,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/discovery_device_range_info.py b/plugins/modules/discovery_device_range_info.py index ade1f28280..769d10b141 100644 --- a/plugins/modules/discovery_device_range_info.py +++ b/plugins/modules/discovery_device_range_info.py @@ -27,19 +27,19 @@ type: str startIndex: description: - - StartIndex path parameter. Start index. + - StartIndex path parameter. Starting index for the records. type: int recordsToReturn: description: - - RecordsToReturn path parameter. Number of records to return. + - RecordsToReturn path parameter. Number of records to fetch from the start index. type: int taskId: description: - TaskId query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery GetDiscoveredDevicesByRange description: Complete reference of the GetDiscoveredDevicesByRange API. @@ -71,7 +71,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/discovery_info.py b/plugins/modules/discovery_info.py index 68d1cc74f4..1973b581e4 100644 --- a/plugins/modules/discovery_info.py +++ b/plugins/modules/discovery_info.py @@ -24,8 +24,8 @@ - Id path parameter. Discovery ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery GetDiscoveryById description: Complete reference of the GetDiscoveryById API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/discovery_job_info.py b/plugins/modules/discovery_job_info.py index 2e6de4f14f..251b971c1c 100644 --- a/plugins/modules/discovery_job_info.py +++ b/plugins/modules/discovery_job_info.py @@ -44,8 +44,8 @@ - Id path parameter. Discovery ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery GetDiscoveryJobsByIP description: Complete reference of the GetDiscoveryJobsByIP API. @@ -98,7 +98,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/discovery_range_delete.py b/plugins/modules/discovery_range_delete.py index 876881242e..36b5d5e7eb 100644 --- a/plugins/modules/discovery_range_delete.py +++ b/plugins/modules/discovery_range_delete.py @@ -17,14 +17,15 @@ author: Rafael Campos (@racampos) options: recordsToDelete: - description: RecordsToDelete path parameter. Number of records to delete. + description: RecordsToDelete path parameter. Number of records to delete from the + starting index. type: int startIndex: - description: StartIndex path parameter. Start index. + description: StartIndex path parameter. Starting index for the records. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery DeleteDiscoveryBySpecifiedRange description: Complete reference of the DeleteDiscoveryBySpecifiedRange API. @@ -52,7 +53,6 @@ startIndex: 0 """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/discovery_range_info.py b/plugins/modules/discovery_range_info.py index c4fc60ba7e..eeac5d9261 100644 --- a/plugins/modules/discovery_range_info.py +++ b/plugins/modules/discovery_range_info.py @@ -10,7 +10,7 @@ short_description: Information module for Discovery Range description: - Get all Discovery Range. -- Returns the discovery by specified range. +- Returns the discoveries by specified range. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -21,15 +21,15 @@ type: dict startIndex: description: - - StartIndex path parameter. Start index. + - StartIndex path parameter. Starting index for the records. type: int recordsToReturn: description: - - RecordsToReturn path parameter. Number of records to return. + - RecordsToReturn path parameter. Number of records to fetch from the starting index. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery GetDiscoveriesByRange description: Complete reference of the GetDiscoveriesByRange API. @@ -59,7 +59,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/discovery_summary_info.py b/plugins/modules/discovery_summary_info.py index 9cff8b3ee8..38bc3f1809 100644 --- a/plugins/modules/discovery_summary_info.py +++ b/plugins/modules/discovery_summary_info.py @@ -11,8 +11,8 @@ description: - Get all Discovery Summary. - > - Returns the network devices from a discovery job based on given filters. Discovery ID can be obtained using the - "Get Discoveries by range" API. + Returns the devices discovered in the given discovery based on given filters. Discovery ID can be obtained using + the "Get Discoveries by range" API. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -31,45 +31,57 @@ type: str sortBy: description: - - SortBy query parameter. + - > + SortBy query parameter. Sort by field. Available values are pingStatus, cliStatus,snmpStatus, httpStatus and + netconfStatus. type: str sortOrder: description: - - SortOrder query parameter. + - SortOrder query parameter. Order of sorting based on sortBy. Available values are 'asc' and 'des'. type: str ipAddress: description: - - IpAddress query parameter. + - IpAddress query parameter. IP Address of the device. elements: str type: list pingStatus: description: - - PingStatus query parameter. + - > + PingStatus query parameter. Ping status for the IP during the job run. Available values are 'SUCCESS', + 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. elements: str type: list snmpStatus: description: - - SnmpStatus query parameter. + - > + SnmpStatus query parameter. SNMP status for the IP during the job run. Available values are 'SUCCESS', + 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. elements: str type: list cliStatus: description: - - CliStatus query parameter. + - > + CliStatus query parameter. CLI status for the IP during the job run. Available values are 'SUCCESS', + 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. elements: str type: list netconfStatus: description: - - NetconfStatus query parameter. + - > + NetconfStatus query parameter. NETCONF status for the IP during the job run. Available values are 'SUCCESS', + 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. elements: str type: list httpStatus: description: - - HttpStatus query parameter. + - > + HttpStatus query parameter. HTTP staus for the IP during the job run. Available values are 'SUCCESS', + 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. elements: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery GetNetworkDevicesFromDiscovery description: Complete reference of the GetNetworkDevicesFromDiscovery API. @@ -107,7 +119,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/dna_command_runner_keywords_info.py b/plugins/modules/dna_command_runner_keywords_info.py index 1e63e6b131..0e3873e8ed 100644 --- a/plugins/modules/dna_command_runner_keywords_info.py +++ b/plugins/modules/dna_command_runner_keywords_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Command Runner GetAllKeywordsOfCLIsAcceptedByCommandRunner description: Complete reference of the GetAllKeywordsOfCLIsAcceptedByCommandRunner API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/dna_event_snmp_config_info.py b/plugins/modules/dna_event_snmp_config_info.py new file mode 100644 index 0000000000..7a4241fb1f --- /dev/null +++ b/plugins/modules/dna_event_snmp_config_info.py @@ -0,0 +1,103 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: dna_event_snmp_config_info +short_description: Information module for Dna Event Snmp Config +description: +- Get all Dna Event Snmp Config. +- Get SNMP Destination. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + configId: + description: + - ConfigId query parameter. List of SNMP configurations. + type: str + offset: + description: + - Offset query parameter. The number of SNMP configuration's to offset in the resultset whose default value 0. + type: float + limit: + description: + - Limit query parameter. The number of SNMP configuration's to limit in the resultset whose default value 10. + type: float + sortBy: + description: + - SortBy query parameter. SortBy field name. + type: str + order: + description: + - Order query parameter. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Event Management GetSNMPDestination + description: Complete reference of the GetSNMPDestination API. + link: https://developer.cisco.com/docs/dna-center/#!get-snmp-destination +notes: + - SDK Method used are + event_management.EventManagement.get_snmp_destination, + + - Paths used are + get /dna/intent/api/v1/dna-event/snmp-config, + +""" + +EXAMPLES = r""" +- name: Get all Dna Event Snmp Config + cisco.dnac.dna_event_snmp_config_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + configId: string + offset: 0 + limit: 0 + sortBy: string + order: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: list + elements: dict + sample: > + [ + { + "version": "string", + "tenantId": "string", + "configId": "string", + "name": "string", + "description": "string", + "ipAddress": "string", + "port": 0, + "snmpVersion": "string", + "community": "string", + "userName": "string", + "snmpMode": "string", + "snmpAuthType": "string", + "authPassword": "string", + "snmpPrivacyType": "string", + "privacyPassword": "string" + } + ] +""" diff --git a/plugins/modules/dnac_packages_info.py b/plugins/modules/dnac_packages_info.py index ebc2481a5c..5328fb6ff2 100644 --- a/plugins/modules/dnac_packages_info.py +++ b/plugins/modules/dnac_packages_info.py @@ -11,7 +11,7 @@ description: - Get all Dnac Packages. - Provides information such as name, version of packages installed on the DNA center. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Platform CiscoDNACenterPackagesSummary description: Complete reference of the CiscoDNACenterPackagesSummary API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/dnacaap_management_execution_status_info.py b/plugins/modules/dnacaap_management_execution_status_info.py index 3fc122f4de..8972268c67 100644 --- a/plugins/modules/dnacaap_management_execution_status_info.py +++ b/plugins/modules/dnacaap_management_execution_status_info.py @@ -24,8 +24,8 @@ - ExecutionId path parameter. Execution Id of API. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Task GetBusinessAPIExecutionDetails description: Complete reference of the GetBusinessAPIExecutionDetails API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -71,7 +70,7 @@ "endTimeEpoch": 0, "timeDuration": 0, "status": "string", - "bapiError": "string", - "runtimeInstanceId": "string" + "runtimeInstanceId": "string", + "bapiError": "string" } """ diff --git a/plugins/modules/eox_status_device_info.py b/plugins/modules/eox_status_device_info.py index dc10734508..c8cdfe7a5f 100644 --- a/plugins/modules/eox_status_device_info.py +++ b/plugins/modules/eox_status_device_info.py @@ -13,7 +13,7 @@ - Get Eox Status Device by id. - Retrieves EoX details for a device. - Retrieves EoX status for all devices in the network. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -26,8 +26,8 @@ - DeviceId path parameter. Device instance UUID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for EoX GetEoXDetailsPerDevice description: Complete reference of the GetEoXDetailsPerDevice API. @@ -37,8 +37,8 @@ link: https://developer.cisco.com/docs/dna-center/#!get-eo-x-status-for-all-devices notes: - SDK Method used are - eo_x.EoX.get_eo_x_details_per_device, - eo_x.EoX.get_eo_x_status_for_all_devices, + eox.Eox.get_eox_details_per_device, + eox.Eox.get_eox_status_for_all_devices, - Paths used are get /dna/intent/api/v1/eox-status/device, @@ -73,7 +73,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -86,27 +85,30 @@ "alertCount": 0, "eoxDetails": [ { + "name": "string", "bulletinHeadline": "string", + "bulletinName": "string", "bulletinNumber": "string", "bulletinURL": "string", - "endOfHardwareNewServiceAttachmentDate": 0, - "endOfHardwareServiceContractRenewalDate": 0, - "endOfLastHardwareShipDate": 0, - "endOfLifeDate": 0, - "endOfLifeExternalAnnouncementDate": 0, - "endOfSaleDate": 0, - "endOfSignatureReleasesDate": 0, - "endOfSoftwareVulnerabilityOrSecuritySupportDate": 0, - "endOfSoftwareVulnerabilityOrSecuritySupportDateHw": 0, - "endOfSoftwareMaintenanceReleasesDate": 0, + "endOfHardwareNewServiceAttachmentDate": "string", + "endOfHardwareServiceContractRenewalDate": "string", + "endOfLastHardwareShipDate": "string", + "endOfLifeExternalAnnouncementDate": "string", + "endOfSignatureReleasesDate": "string", + "endOfSoftwareVulnerabilityOrSecuritySupportDate": "string", + "endOfSoftwareVulnerabilityOrSecuritySupportDateHw": "string", + "endOfSaleDate": "string", + "endOfLifeDate": "string", + "lastDateOfSupport": "string", + "endOfSoftwareMaintenanceReleasesDate": "string", "eoxAlertType": "string", - "lastDateOfSupport": 0, - "name": "string" + "eoXPhysicalType": "string", + "bulletinPID": "string" } ], "scanStatus": "string", "comments": [ - {} + "string" ], "lastScanTime": 0 }, diff --git a/plugins/modules/eox_status_summary_info.py b/plugins/modules/eox_status_summary_info.py index 26dc6d99d1..a77d84cf60 100644 --- a/plugins/modules/eox_status_summary_info.py +++ b/plugins/modules/eox_status_summary_info.py @@ -11,7 +11,7 @@ description: - Get all Eox Status Summary. - Retrieves EoX summary for all devices in the network. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -20,15 +20,15 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for EoX GetEoXSummary description: Complete reference of the GetEoXSummary API. link: https://developer.cisco.com/docs/dna-center/#!get-eo-x-summary notes: - SDK Method used are - eo_x.EoX.get_eo_x_summary, + eox.Eox.get_eox_summary, - Paths used are get /dna/intent/api/v1/eox-status/summary, @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_api_status_info.py b/plugins/modules/event_api_status_info.py index 8c6cf8d139..2583ec4ebf 100644 --- a/plugins/modules/event_api_status_info.py +++ b/plugins/modules/event_api_status_info.py @@ -24,8 +24,8 @@ - ExecutionId path parameter. Execution ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetStatusAPIForEvents description: Complete reference of the GetStatusAPIForEvents API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_artifact_count_info.py b/plugins/modules/event_artifact_count_info.py index fb7d3ab7db..d9c707967a 100644 --- a/plugins/modules/event_artifact_count_info.py +++ b/plugins/modules/event_artifact_count_info.py @@ -10,7 +10,7 @@ short_description: Information module for Event Artifact Count description: - Get all Event Artifact Count. -- Get the count of registered event artifacts with provided eventIds or tags as mandatory. +- Get the count of registered event artifacts. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management EventArtifactCount description: Complete reference of the EventArtifactCount API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_artifact_info.py b/plugins/modules/event_artifact_info.py index 196b1233c2..2e4bda28ed 100644 --- a/plugins/modules/event_artifact_info.py +++ b/plugins/modules/event_artifact_info.py @@ -30,11 +30,11 @@ offset: description: - Offset query parameter. Record start offset. - type: int + type: float limit: description: - Limit query parameter. # of records to return in result set. - type: int + type: float sortBy: description: - SortBy query parameter. Sort by field. @@ -48,8 +48,8 @@ - Search query parameter. Findd matches in name, description, eventId, type, category. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetEventArtifacts description: Complete reference of the GetEventArtifacts API. @@ -84,7 +84,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -128,6 +127,10 @@ "supportedConnectorTypes": [ "string" ], + "configs": { + "isAlert": true, + "isACKnowledgeable": true + }, "tenantId": "string" } ] diff --git a/plugins/modules/event_config_connector_types_info.py b/plugins/modules/event_config_connector_types_info.py index b30a9659a5..d0d29fd6eb 100644 --- a/plugins/modules/event_config_connector_types_info.py +++ b/plugins/modules/event_config_connector_types_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetConnectorTypes description: Complete reference of the GetConnectorTypes API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_count_info.py b/plugins/modules/event_count_info.py index 8643646556..f2fc3e3fb3 100644 --- a/plugins/modules/event_count_info.py +++ b/plugins/modules/event_count_info.py @@ -28,8 +28,8 @@ - Tags query parameter. The registered Tags should be provided. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management CountOfEvents description: Complete reference of the CountOfEvents API. @@ -59,7 +59,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_email_config.py b/plugins/modules/event_email_config.py index fd5fdb882f..b0d6740ac3 100644 --- a/plugins/modules/event_email_config.py +++ b/plugins/modules/event_email_config.py @@ -12,7 +12,7 @@ - Manage operations create and update of the resource Event Email Config. - Create Email Destination. - Update Email Destination. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -35,6 +35,9 @@ port: description: Port. type: str + smtpType: + description: SmtpType. + type: str userName: description: User Name. type: str @@ -51,6 +54,9 @@ port: description: Port. type: str + smtpType: + description: SmtpType. + type: str userName: description: User Name. type: str @@ -62,8 +68,8 @@ description: To Email. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management CreateEmailDestination description: Complete reference of the CreateEmailDestination API. @@ -99,11 +105,13 @@ hostName: string password: string port: string + smtpType: string userName: string secondarySMTPConfig: hostName: string password: string port: string + smtpType: string userName: string subject: string toEmail: string @@ -124,17 +132,18 @@ hostName: string password: string port: string + smtpType: string userName: string secondarySMTPConfig: hostName: string password: string port: string + smtpType: string userName: string subject: string toEmail: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_email_config_create.py b/plugins/modules/event_email_config_create.py index 4be4ec3628..f2ee47b163 100644 --- a/plugins/modules/event_email_config_create.py +++ b/plugins/modules/event_email_config_create.py @@ -34,6 +34,9 @@ port: description: Port. type: str + smtpType: + description: SmtpType. + type: str userName: description: User Name. type: str @@ -50,6 +53,9 @@ port: description: Port. type: str + smtpType: + description: SmtpType. + type: str userName: description: User Name. type: str @@ -61,8 +67,8 @@ description: To Email. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management CreateEmailDestination description: Complete reference of the CreateEmailDestination API. @@ -92,17 +98,18 @@ hostName: string password: string port: string + smtpType: string userName: string secondarySMTPConfig: hostName: string password: string port: string + smtpType: string userName: string subject: string toEmail: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_email_config_info.py b/plugins/modules/event_email_config_info.py index 272118cd79..14a1e37081 100644 --- a/plugins/modules/event_email_config_info.py +++ b/plugins/modules/event_email_config_info.py @@ -11,7 +11,7 @@ description: - Get all Event Email Config. - Get Email Destination. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetEmailDestination description: Complete reference of the GetEmailDestination API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -65,14 +64,14 @@ "port": "string", "userName": "string", "password": "string", - "security": "string" + "smtpType": "string" }, "secondarySMTPConfig": { "hostName": "string", "port": "string", "userName": "string", "password": "string", - "security": "string" + "smtpType": "string" }, "fromEmail": "string", "toEmail": "string", diff --git a/plugins/modules/event_email_config_update.py b/plugins/modules/event_email_config_update.py index c471ff807c..97cd325c75 100644 --- a/plugins/modules/event_email_config_update.py +++ b/plugins/modules/event_email_config_update.py @@ -34,6 +34,9 @@ port: description: Port. type: str + smtpType: + description: SmtpType. + type: str userName: description: User Name. type: str @@ -50,6 +53,9 @@ port: description: Port. type: str + smtpType: + description: SmtpType. + type: str userName: description: User Name. type: str @@ -61,8 +67,8 @@ description: To Email. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management UpdateEmailDestination description: Complete reference of the UpdateEmailDestination API. @@ -92,17 +98,18 @@ hostName: string password: string port: string + smtpType: string userName: string secondarySMTPConfig: hostName: string password: string port: string + smtpType: string userName: string subject: string toEmail: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_info.py b/plugins/modules/event_info.py index a3eafb2975..89bd0f5bbc 100644 --- a/plugins/modules/event_info.py +++ b/plugins/modules/event_info.py @@ -30,11 +30,11 @@ offset: description: - Offset query parameter. The number of Registries to offset in the resultset whose default value 0. - type: int + type: float limit: description: - Limit query parameter. The number of Registries to limit in the resultset whose default value 10. - type: int + type: float sortBy: description: - SortBy query parameter. SortBy field name. @@ -44,8 +44,8 @@ - Order query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetEvents description: Complete reference of the GetEvents API. @@ -79,7 +79,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_series_audit_logs_info.py b/plugins/modules/event_series_audit_logs_info.py index b5fa297d91..130acb05d9 100644 --- a/plugins/modules/event_series_audit_logs_info.py +++ b/plugins/modules/event_series_audit_logs_info.py @@ -92,23 +92,23 @@ offset: description: - Offset query parameter. Position of a particular Audit Log record in the data. - type: int + type: float limit: description: - Limit query parameter. Number of Audit Log records to be returned per page. - type: int + type: float startTime: description: - > StartTime query parameter. Start Time in milliseconds since Epoch Eg. 1597950637211 (when provided endTime is mandatory). - type: int + type: float endTime: description: - > EndTime query parameter. End Time in milliseconds since Epoch Eg. 1597961437211 (when provided startTime is mandatory). - type: int + type: float sortBy: description: - > @@ -122,8 +122,8 @@ values asc, desc. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetAuditLogRecords description: Complete reference of the GetAuditLogRecords API. @@ -173,7 +173,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_series_audit_logs_parent_records_info.py b/plugins/modules/event_series_audit_logs_parent_records_info.py index 26bd96d296..db0a6f1261 100644 --- a/plugins/modules/event_series_audit_logs_parent_records_info.py +++ b/plugins/modules/event_series_audit_logs_parent_records_info.py @@ -88,23 +88,23 @@ offset: description: - Offset query parameter. Position of a particular Audit Log record in the data. - type: int + type: float limit: description: - Limit query parameter. Number of Audit Log records to be returned per page. - type: int + type: float startTime: description: - > StartTime query parameter. Start Time in milliseconds since Epoch Eg. 1597950637211 (when provided endTime is mandatory). - type: int + type: float endTime: description: - > EndTime query parameter. End Time in milliseconds since Epoch Eg. 1597961437211 (when provided startTime is mandatory). - type: int + type: float sortBy: description: - > @@ -118,8 +118,8 @@ values asc, desc. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetAuditLogParentRecords description: Complete reference of the GetAuditLogParentRecords API. @@ -168,7 +168,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_series_audit_logs_summary_info.py b/plugins/modules/event_series_audit_logs_summary_info.py index 2e0d2e1331..ee86982ba6 100644 --- a/plugins/modules/event_series_audit_logs_summary_info.py +++ b/plugins/modules/event_series_audit_logs_summary_info.py @@ -98,16 +98,16 @@ - > StartTime query parameter. Start Time in milliseconds since Epoch Eg. 1597950637211 (when provided endTime is mandatory). - type: int + type: float endTime: description: - > EndTime query parameter. End Time in milliseconds since Epoch Eg. 1597961437211 (when provided startTime is mandatory). - type: int + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetAuditLogSummary description: Complete reference of the GetAuditLogSummary API. @@ -154,7 +154,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_series_count_info.py b/plugins/modules/event_series_count_info.py index ebd6576f04..d009a852cf 100644 --- a/plugins/modules/event_series_count_info.py +++ b/plugins/modules/event_series_count_info.py @@ -26,11 +26,11 @@ startTime: description: - StartTime query parameter. Start Time in milliseconds. - type: int + type: float endTime: description: - EndTime query parameter. End Time in milliseconds. - type: int + type: float category: description: - Category query parameter. @@ -56,8 +56,8 @@ - Source query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management CountOfNotifications description: Complete reference of the CountOfNotifications API. @@ -94,7 +94,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_series_info.py b/plugins/modules/event_series_info.py index 982aa0cbc3..6feb8bccc1 100644 --- a/plugins/modules/event_series_info.py +++ b/plugins/modules/event_series_info.py @@ -26,11 +26,11 @@ startTime: description: - StartTime query parameter. Start Time in milliseconds. - type: int + type: float endTime: description: - EndTime query parameter. End Time in milliseconds. - type: int + type: float category: description: - Category query parameter. @@ -58,11 +58,11 @@ offset: description: - Offset query parameter. Start Offset. - type: int + type: float limit: description: - Limit query parameter. # of records. - type: int + type: float sortBy: description: - SortBy query parameter. Sort By column. @@ -84,8 +84,8 @@ - SiteId query parameter. Site Id. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetNotifications description: Complete reference of the GetNotifications API. @@ -129,7 +129,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_snmp_config.py b/plugins/modules/event_snmp_config.py new file mode 100644 index 0000000000..a6cecc76ab --- /dev/null +++ b/plugins/modules/event_snmp_config.py @@ -0,0 +1,144 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: event_snmp_config +short_description: Resource module for Event Snmp Config +description: +- Manage operations create and update of the resource Event Snmp Config. +- Create SNMP Destination. +- Update SNMP Destination. +version_added: '3.1.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + authPassword: + description: Auth Password. + type: str + community: + description: Required only if snmpVersion is V2C. + type: str + configId: + description: Config Id. + type: str + description: + description: Description. + type: str + ipAddress: + description: Ip Address. + type: str + name: + description: Name. + type: str + port: + description: Port. + type: str + privacyPassword: + description: Privacy Password. + type: str + snmpAuthType: + description: Snmp Auth Type. + type: str + snmpMode: + description: If snmpVersion is V3 it is required and cannot be NONE. + type: str + snmpPrivacyType: + description: Snmp Privacy Type. + type: str + snmpVersion: + description: Snmp Version. + type: str + userName: + description: Required only if snmpVersion is V3. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Event Management CreateSNMPDestination + description: Complete reference of the CreateSNMPDestination API. + link: https://developer.cisco.com/docs/dna-center/#!create-snmp-destination +- name: Cisco DNA Center documentation for Event Management UpdateSNMPDestination + description: Complete reference of the UpdateSNMPDestination API. + link: https://developer.cisco.com/docs/dna-center/#!update-snmp-destination +notes: + - SDK Method used are + event_management.EventManagement.create_snmp_destination, + event_management.EventManagement.update_snmp_destination, + + - Paths used are + post /dna/intent/api/v1/event/snmp-config, + put /dna/intent/api/v1/event/snmp-config, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.event_snmp_config: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + authPassword: string + community: string + description: string + ipAddress: string + name: string + port: string + privacyPassword: string + snmpAuthType: string + snmpMode: string + snmpPrivacyType: string + snmpVersion: string + userName: string + +- name: Update all + cisco.dnac.event_snmp_config: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + authPassword: string + community: string + configId: string + description: string + ipAddress: string + name: string + port: string + privacyPassword: string + snmpAuthType: string + snmpMode: string + snmpPrivacyType: string + snmpVersion: string + userName: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "errorMessage": { + "errors": [ + {} + ] + }, + "apiStatus": "string", + "statusMessage": "string" + } +""" diff --git a/plugins/modules/event_snmp_config_info.py b/plugins/modules/event_snmp_config_info.py index b870816721..0f4065ef90 100644 --- a/plugins/modules/event_snmp_config_info.py +++ b/plugins/modules/event_snmp_config_info.py @@ -9,9 +9,7 @@ module: event_snmp_config_info short_description: Information module for Event Snmp Config description: -- Get all Event Snmp Config. -- Get SNMP Destination. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -19,93 +17,21 @@ headers: description: Additional headers. type: dict - configId: - description: - - ConfigId query parameter. List of SNMP configurations. - type: str - offset: - description: - - Offset query parameter. The number of SNMP configuration's to offset in the resultset whose default value 0. - type: int - limit: - description: - - Limit query parameter. The number of SNMP configuration's to limit in the resultset whose default value 10. - type: int - sortBy: - description: - - SortBy query parameter. SortBy field name. - type: str - order: - description: - - Order query parameter. - type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 -seealso: -- name: Cisco DNA Center documentation for Event Management GetSNMPDestination - description: Complete reference of the GetSNMPDestination API. - link: https://developer.cisco.com/docs/dna-center/#!get-snmp-destination +- dnacentersdk >= 2.4.9 +- python >= 3.5 notes: - - SDK Method used are - event_management.EventManagement.get_snmp_destination, - - Paths used are - get /dna/intent/api/v1/event/snmp-config, """ EXAMPLES = r""" -- name: Get all Event Snmp Config - cisco.dnac.event_snmp_config_info: - dnac_host: "{{dnac_host}}" - dnac_username: "{{dnac_username}}" - dnac_password: "{{dnac_password}}" - dnac_verify: "{{dnac_verify}}" - dnac_port: "{{dnac_port}}" - dnac_version: "{{dnac_version}}" - dnac_debug: "{{dnac_debug}}" - headers: "{{my_headers | from_json}}" - configId: string - offset: 0 - limit: 0 - sortBy: string - order: string - register: result - """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK returned: always type: dict - sample: > - { - "errorMessage": { - "errors": [ - "string" - ] - }, - "apiStatus": "string", - "statusMessage": [ - { - "version": "string", - "tenantId": "string", - "configId": "string", - "name": "string", - "description": "string", - "ipAddress": "string", - "port": 0, - "snmpVersion": "string", - "community": "string", - "userName": "string", - "snmpMode": "string", - "snmpAuthType": "string", - "authPassword": "string", - "snmpPrivacyType": "string", - "privacyPassword": "string" - } - ] - } + sample: + - {} """ diff --git a/plugins/modules/event_subscription.py b/plugins/modules/event_subscription.py index 0aca4d2dba..16d35cc004 100644 --- a/plugins/modules/event_subscription.py +++ b/plugins/modules/event_subscription.py @@ -94,8 +94,8 @@ description: Subscriptions query parameter. List of EventSubscriptionId's for removal. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management CreateEventSubscriptions description: Complete reference of the CreateEventSubscriptions API. @@ -207,7 +207,6 @@ version: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_subscription_count_info.py b/plugins/modules/event_subscription_count_info.py index daf1a6fdfe..3ccc77e3c9 100644 --- a/plugins/modules/event_subscription_count_info.py +++ b/plugins/modules/event_subscription_count_info.py @@ -24,8 +24,8 @@ - EventIds query parameter. List of subscriptions related to the respective eventIds. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management CountOfEventSubscriptions description: Complete reference of the CountOfEventSubscriptions API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_subscription_details_email_info.py b/plugins/modules/event_subscription_details_email_info.py index b6487d13fd..9a665be609 100644 --- a/plugins/modules/event_subscription_details_email_info.py +++ b/plugins/modules/event_subscription_details_email_info.py @@ -30,11 +30,11 @@ offset: description: - Offset query parameter. The number of Email Subscription detail's to offset in the resultset whose default value 0. - type: int + type: float limit: description: - Limit query parameter. The number of Email Subscription detail's to limit in the resultset whose default value 10. - type: int + type: float sortBy: description: - SortBy query parameter. SortBy field name. @@ -44,8 +44,8 @@ - Order query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetEmailSubscriptionDetails description: Complete reference of the GetEmailSubscriptionDetails API. @@ -79,7 +79,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_subscription_details_rest_info.py b/plugins/modules/event_subscription_details_rest_info.py index ee793eff1e..c6e8270896 100644 --- a/plugins/modules/event_subscription_details_rest_info.py +++ b/plugins/modules/event_subscription_details_rest_info.py @@ -32,13 +32,13 @@ - > Offset query parameter. The number of Rest/Webhook Subscription detail's to offset in the resultset whose default value 0. - type: int + type: float limit: description: - > Limit query parameter. The number of Rest/Webhook Subscription detail's to limit in the resultset whose default value 10. - type: int + type: float sortBy: description: - SortBy query parameter. SortBy field name. @@ -48,8 +48,8 @@ - Order query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetRestWebhookSubscriptionDetails description: Complete reference of the GetRestWebhookSubscriptionDetails API. @@ -83,7 +83,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -99,7 +98,7 @@ "connectorType": "string", "url": "string", "method": "string", - "trustCert": "string", + "trustCert": true, "headers": [ { "name": "string", @@ -111,7 +110,14 @@ ], "pathParams": [ "string" - ] + ], + "body": "string", + "connectTimeout": 0, + "readTimeout": 0, + "serviceName": "string", + "servicePort": "string", + "namespace": "string", + "proxyRoute": true } ] """ diff --git a/plugins/modules/event_subscription_details_syslog_info.py b/plugins/modules/event_subscription_details_syslog_info.py index 18e68fa779..bba66a02e8 100644 --- a/plugins/modules/event_subscription_details_syslog_info.py +++ b/plugins/modules/event_subscription_details_syslog_info.py @@ -32,11 +32,11 @@ - > Offset query parameter. The number of Syslog Subscription detail's to offset in the resultset whose default value 0. - type: int + type: float limit: description: - Limit query parameter. The number of Syslog Subscription detail's to limit in the resultset whose default value 10. - type: int + type: float sortBy: description: - SortBy query parameter. SortBy field name. @@ -46,8 +46,8 @@ - Order query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetSyslogSubscriptionDetails description: Complete reference of the GetSyslogSubscriptionDetails API. @@ -81,7 +81,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_subscription_email.py b/plugins/modules/event_subscription_email.py index 13dc4cfe8e..38c3153e55 100644 --- a/plugins/modules/event_subscription_email.py +++ b/plugins/modules/event_subscription_email.py @@ -72,7 +72,8 @@ elements: dict suboptions: instanceId: - description: (From Get Email Subscription Details --> pick InstanceId). + description: (From Get Email Subscription Details --> pick InstanceId if + available). type: str subscriptionDetails: description: Event Subscription Email's subscriptionDetails. @@ -106,8 +107,8 @@ type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management CreateEmailEventSubscription description: Complete reference of the CreateEmailEventSubscription API. @@ -214,7 +215,6 @@ version: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_subscription_email_info.py b/plugins/modules/event_subscription_email_info.py index 3eab8992b4..5697521d91 100644 --- a/plugins/modules/event_subscription_email_info.py +++ b/plugins/modules/event_subscription_email_info.py @@ -28,11 +28,11 @@ offset: description: - Offset query parameter. The number of Subscriptions's to offset in the resultset whose default value 0. - type: int + type: float limit: description: - Limit query parameter. The number of Subscriptions's to limit in the resultset whose default value 10. - type: int + type: float sortBy: description: - SortBy query parameter. SortBy field name. @@ -62,8 +62,8 @@ - Name query parameter. List of email subscriptions related to the respective name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetEmailEventSubscriptions description: Complete reference of the GetEmailEventSubscriptions API. @@ -101,7 +101,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_subscription_info.py b/plugins/modules/event_subscription_info.py index 9349d81e71..a627bb3fea 100644 --- a/plugins/modules/event_subscription_info.py +++ b/plugins/modules/event_subscription_info.py @@ -26,11 +26,11 @@ offset: description: - Offset query parameter. The number of Subscriptions's to offset in the resultset whose default value 0. - type: int + type: float limit: description: - Limit query parameter. The number of Subscriptions's to limit in the resultset whose default value 10. - type: int + type: float sortBy: description: - SortBy query parameter. SortBy field name. @@ -40,8 +40,8 @@ - Order query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetEventSubscriptions description: Complete reference of the GetEventSubscriptions API. @@ -74,7 +74,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_subscription_rest.py b/plugins/modules/event_subscription_rest.py index 81eea1f2eb..f0162b6ed4 100644 --- a/plugins/modules/event_subscription_rest.py +++ b/plugins/modules/event_subscription_rest.py @@ -90,8 +90,8 @@ type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management CreateRestWebhookEventSubscription description: Complete reference of the CreateRestWebhookEventSubscription API. @@ -186,7 +186,6 @@ version: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_subscription_rest_info.py b/plugins/modules/event_subscription_rest_info.py index 06e8dab617..809497c6b8 100644 --- a/plugins/modules/event_subscription_rest_info.py +++ b/plugins/modules/event_subscription_rest_info.py @@ -26,11 +26,11 @@ offset: description: - Offset query parameter. The number of Subscriptions's to offset in the resultset whose default value 0. - type: int + type: float limit: description: - Limit query parameter. The number of Subscriptions's to limit in the resultset whose default value 10. - type: int + type: float sortBy: description: - SortBy query parameter. SortBy field name. @@ -60,8 +60,8 @@ - Name query parameter. List of subscriptions related to the respective name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetRestWebhookEventSubscriptions description: Complete reference of the GetRestWebhookEventSubscriptions API. @@ -99,7 +99,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_subscription_syslog.py b/plugins/modules/event_subscription_syslog.py index aeff30dd35..243ffd625d 100644 --- a/plugins/modules/event_subscription_syslog.py +++ b/plugins/modules/event_subscription_syslog.py @@ -90,8 +90,8 @@ type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management CreateSyslogEventSubscription description: Complete reference of the CreateSyslogEventSubscription API. @@ -186,7 +186,6 @@ version: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_subscription_syslog_info.py b/plugins/modules/event_subscription_syslog_info.py index ef6ffb044c..9c193e266b 100644 --- a/plugins/modules/event_subscription_syslog_info.py +++ b/plugins/modules/event_subscription_syslog_info.py @@ -26,11 +26,11 @@ offset: description: - Offset query parameter. The number of Subscriptions's to offset in the resultset whose default value 0. - type: int + type: float limit: description: - Limit query parameter. The number of Subscriptions's to limit in the resultset whose default value 10. - type: int + type: float sortBy: description: - SortBy query parameter. SortBy field name. @@ -60,8 +60,8 @@ - Name query parameter. List of subscriptions related to the respective name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetSyslogEventSubscriptions description: Complete reference of the GetSyslogEventSubscriptions API. @@ -99,7 +99,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_syslog_config.py b/plugins/modules/event_syslog_config.py index 11c6d9508b..13f36b2d0a 100644 --- a/plugins/modules/event_syslog_config.py +++ b/plugins/modules/event_syslog_config.py @@ -12,7 +12,7 @@ - Manage operations create and update of the resource Event Syslog Config. - Create Syslog Destination. - Update Syslog Destination. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -31,13 +31,13 @@ type: str port: description: Port. - type: str + type: int protocol: description: Protocol. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management CreateSyslogDestination description: Complete reference of the CreateSyslogDestination API. @@ -71,7 +71,7 @@ description: string host: string name: string - port: string + port: 0 protocol: string - name: Create @@ -88,11 +88,10 @@ description: string host: string name: string - port: string + port: 0 protocol: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_syslog_config_info.py b/plugins/modules/event_syslog_config_info.py index a2e6009c82..d3f6a9c99b 100644 --- a/plugins/modules/event_syslog_config_info.py +++ b/plugins/modules/event_syslog_config_info.py @@ -11,7 +11,7 @@ description: - Get all Event Syslog Config. - Get Syslog Destination. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -34,11 +34,11 @@ offset: description: - Offset query parameter. The number of syslog configuration's to offset in the resultset whose default value 0. - type: int + type: float limit: description: - Limit query parameter. The number of syslog configuration's to limit in the resultset whose default value 10. - type: int + type: float sortBy: description: - SortBy query parameter. SortBy field name. @@ -48,8 +48,8 @@ - Order query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management GetSyslogDestination description: Complete reference of the GetSyslogDestination API. @@ -84,7 +84,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_webhook_create.py b/plugins/modules/event_webhook_create.py index 2859b76158..c32c9db292 100644 --- a/plugins/modules/event_webhook_create.py +++ b/plugins/modules/event_webhook_create.py @@ -36,6 +36,9 @@ description: Value. type: str type: list + isProxyRoute: + description: Is Proxy Route. + type: bool method: description: Method. type: str @@ -52,8 +55,8 @@ description: Required only for update webhook configuration. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management CreateWebhookDestination description: Complete reference of the CreateWebhookDestination API. @@ -83,6 +86,7 @@ encrypt: true name: string value: string + isProxyRoute: true method: string name: string trustCert: true @@ -90,7 +94,6 @@ webhookId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/event_webhook_read_info.py b/plugins/modules/event_webhook_read_info.py new file mode 100644 index 0000000000..21c50893e6 --- /dev/null +++ b/plugins/modules/event_webhook_read_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: event_webhook_read_info +short_description: Information module for Event Webhook Read +description: +- Get all Event Webhook Read. +- Get Webhook Destination. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + webhookIds: + description: + - WebhookIds query parameter. List of webhook configurations. + type: str + offset: + description: + - Offset query parameter. The number of webhook configuration's to offset in the resultset whose default value 0. + type: float + limit: + description: + - Limit query parameter. The number of webhook configuration's to limit in the resultset whose default value 10. + type: float + sortBy: + description: + - SortBy query parameter. SortBy field name. + type: str + order: + description: + - Order query parameter. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Event Management GetWebhookDestination + description: Complete reference of the GetWebhookDestination API. + link: https://developer.cisco.com/docs/dna-center/#!get-webhook-destination +notes: + - SDK Method used are + event_management.EventManagement.get_webhook_destination, + + - Paths used are + get /dna/intent/api/v1/event/webhook, + +""" + +EXAMPLES = r""" +- name: Get all Event Webhook Read + cisco.dnac.event_webhook_read_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + webhookIds: string + offset: 0 + limit: 0 + sortBy: string + order: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "errorMessage": { + "errors": [ + "string" + ] + }, + "apiStatus": "string", + "statusMessage": [ + { + "version": "string", + "tenantId": "string", + "webhookId": "string", + "name": "string", + "description": "string", + "url": "string", + "method": "string", + "trustCert": true, + "headers": [ + { + "name": "string", + "value": "string", + "defaultValue": "string", + "encrypt": true + } + ], + "isProxyRoute": true + } + ] + } +""" diff --git a/plugins/modules/event_webhook_update.py b/plugins/modules/event_webhook_update.py index 0c50462ed0..c3471193b8 100644 --- a/plugins/modules/event_webhook_update.py +++ b/plugins/modules/event_webhook_update.py @@ -36,6 +36,9 @@ description: Value. type: str type: list + isProxyRoute: + description: Is Proxy Route. + type: bool method: description: Method. type: str @@ -52,8 +55,8 @@ description: Required only for update webhook configuration. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Event Management UpdateWebhookDestination description: Complete reference of the UpdateWebhookDestination API. @@ -83,6 +86,7 @@ encrypt: true name: string value: string + isProxyRoute: true method: string name: string trustCert: true @@ -90,7 +94,6 @@ webhookId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/execute_suggested_actions_commands.py b/plugins/modules/execute_suggested_actions_commands.py index 43fce32030..24a0a0e133 100644 --- a/plugins/modules/execute_suggested_actions_commands.py +++ b/plugins/modules/execute_suggested_actions_commands.py @@ -14,7 +14,7 @@ This API triggers the execution of the suggested actions for an issue, given the Issue Id. It will return an execution Id. At the completion of the execution, the output of the commands associated with the suggested actions will be provided. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -27,8 +27,8 @@ description: Contains the actual value for the entity type that has been defined. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Issues ExecuteSuggestedActionsCommands description: Complete reference of the ExecuteSuggestedActionsCommands API. @@ -56,7 +56,6 @@ entity_value: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/file_import.py b/plugins/modules/file_import.py index f9909edddd..ec3ce7f075 100644 --- a/plugins/modules/file_import.py +++ b/plugins/modules/file_import.py @@ -23,8 +23,8 @@ description: NameSpace path parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for File UploadFile description: Complete reference of the UploadFile API. @@ -52,7 +52,6 @@ nameSpace: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/file_info.py b/plugins/modules/file_info.py index b9bdba4b9e..aec9a594f2 100644 --- a/plugins/modules/file_info.py +++ b/plugins/modules/file_info.py @@ -36,8 +36,8 @@ - The filename used to save the download file. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for File DownloadAFileByFileId description: Complete reference of the DownloadAFileByFileId API. @@ -63,13 +63,9 @@ dnac_debug: "{{dnac_debug}}" headers: "{{my_headers | from_json}}" fileId: string - dirPath: /tmp/downloads/Test-242.bin - saveFile: true - filename: string register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/file_namespace_files_info.py b/plugins/modules/file_namespace_files_info.py index 0e16dbc1af..cae4582a6a 100644 --- a/plugins/modules/file_namespace_files_info.py +++ b/plugins/modules/file_namespace_files_info.py @@ -24,8 +24,8 @@ - NameSpace path parameter. A listing of fileId's. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for File GetListOfFiles description: Complete reference of the GetListOfFiles API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/file_namespaces_info.py b/plugins/modules/file_namespaces_info.py index 8492681110..c781369634 100644 --- a/plugins/modules/file_namespaces_info.py +++ b/plugins/modules/file_namespaces_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for File GetListOfAvailableNamespaces description: Complete reference of the GetListOfAvailableNamespaces API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/flexible_report_content_info.py b/plugins/modules/flexible_report_content_info.py new file mode 100644 index 0000000000..502596e2de --- /dev/null +++ b/plugins/modules/flexible_report_content_info.py @@ -0,0 +1,72 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: flexible_report_content_info +short_description: Information module for Flexible Report Content +description: +- Get Flexible Report Content by id. +- > + This is used to download the flexible report. The API returns report content. Save the response to a file by + converting the response data as a blob and setting the file format available from content-disposition response + header. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + reportId: + description: + - ReportId path parameter. Id of the report. + type: str + executionId: + description: + - ExecutionId path parameter. Id of execution. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Reports DownloadFlexibleReport + description: Complete reference of the DownloadFlexibleReport API. + link: https://developer.cisco.com/docs/dna-center/#!download-flexible-report +notes: + - SDK Method used are + reports.Reports.download_flexible_report, + + - Paths used are + get /dna/data/api/v1/flexible-report/report/content/{reportId}/{executionId}, + +""" + +EXAMPLES = r""" +- name: Get Flexible Report Content by id + cisco.dnac.flexible_report_content_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + reportId: string + executionId: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: str + sample: > + "'string'" +""" diff --git a/plugins/modules/flexible_report_execute.py b/plugins/modules/flexible_report_execute.py new file mode 100644 index 0000000000..f10db659f8 --- /dev/null +++ b/plugins/modules/flexible_report_execute.py @@ -0,0 +1,70 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: flexible_report_execute +short_description: Resource module for Flexible Report Execute +description: +- Manage operation create of the resource Flexible Report Execute. +- This API is used for executing the report. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + reportId: + description: ReportId path parameter. Id of the Report. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Reports ExecutingTheFlexibleReport + description: Complete reference of the ExecutingTheFlexibleReport API. + link: https://developer.cisco.com/docs/dna-center/#!executing-the-flexible-report +notes: + - SDK Method used are + reports.Reports.executing_the_flexible_report, + + - Paths used are + post /dna/data/api/v1/flexible-report/report/{reportId}/execute, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.flexible_report_execute: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + reportId: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "executionId": "string", + "startTime": 0, + "endTime": 0, + "processStatus": {}, + "requestStatus": "string", + "errors": [ + "string" + ], + "warnings": [ + {} + ] + } +""" diff --git a/plugins/modules/flexible_report_executions_info.py b/plugins/modules/flexible_report_executions_info.py new file mode 100644 index 0000000000..14eaf06569 --- /dev/null +++ b/plugins/modules/flexible_report_executions_info.py @@ -0,0 +1,84 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: flexible_report_executions_info +short_description: Information module for Flexible Report Executions +description: +- Get all Flexible Report Executions. +- Get Execution Id by Report Id. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + reportId: + description: + - ReportId path parameter. Id of the report. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Reports GetExecutionIdByReportId + description: Complete reference of the GetExecutionIdByReportId API. + link: https://developer.cisco.com/docs/dna-center/#!get-execution-id-by-report-id +notes: + - SDK Method used are + reports.Reports.get_execution_id_by_report_id, + + - Paths used are + get /dna/data/api/v1/flexible-report/report/{reportId}/executions, + +""" + +EXAMPLES = r""" +- name: Get all Flexible Report Executions + cisco.dnac.flexible_report_executions_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + reportId: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "reportId": "string", + "reportName": "string", + "executions": [ + { + "executionId": "string", + "startTime": 0, + "endTime": 0, + "processStatus": "string", + "requestStatus": "string", + "errors": [ + "string" + ], + "warnings": [ + {} + ] + } + ], + "executionCount": 0, + "reportWasExecuted": true + } +""" diff --git a/plugins/modules/flexible_report_schedule.py b/plugins/modules/flexible_report_schedule.py new file mode 100644 index 0000000000..9d6e4ed8a5 --- /dev/null +++ b/plugins/modules/flexible_report_schedule.py @@ -0,0 +1,65 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: flexible_report_schedule +short_description: Resource module for Flexible Report Schedule +description: +- Manage operation update of the resource Flexible Report Schedule. +- Update schedule of flexible report. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + reportId: + description: ReportId path parameter. Id of the report. + type: str + schedule: + description: Schedule information. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Reports UpdateScheduleOfFlexibleReport + description: Complete reference of the UpdateScheduleOfFlexibleReport API. + link: https://developer.cisco.com/docs/dna-center/#!update-schedule-of-flexible-report +notes: + - SDK Method used are + reports.Reports.update_schedule_of_flexible_report, + + - Paths used are + put /dna/data/api/v1/flexible-report/schedule/{reportId}, + +""" + +EXAMPLES = r""" +- name: Update by id + cisco.dnac.flexible_report_schedule: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + reportId: string + schedule: {} + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "schedule": {} + } +""" diff --git a/plugins/modules/flexible_report_schedule_info.py b/plugins/modules/flexible_report_schedule_info.py new file mode 100644 index 0000000000..47f589a07a --- /dev/null +++ b/plugins/modules/flexible_report_schedule_info.py @@ -0,0 +1,64 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: flexible_report_schedule_info +short_description: Information module for Flexible Report Schedule +description: +- Get Flexible Report Schedule by id. +- Get flexible report schedule by report id. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + reportId: + description: + - ReportId path parameter. Id of the report. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Reports GetFlexibleReportScheduleByReportId + description: Complete reference of the GetFlexibleReportScheduleByReportId API. + link: https://developer.cisco.com/docs/dna-center/#!get-flexible-report-schedule-by-report-id +notes: + - SDK Method used are + reports.Reports.get_flexible_report_schedule_by_report_id, + + - Paths used are + get /dna/data/api/v1/flexible-report/schedule/{reportId}, + +""" + +EXAMPLES = r""" +- name: Get Flexible Report Schedule by id + cisco.dnac.flexible_report_schedule_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + reportId: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: + - {} +""" diff --git a/plugins/modules/flexible_report_schedules_info.py b/plugins/modules/flexible_report_schedules_info.py new file mode 100644 index 0000000000..46a7fe2fc7 --- /dev/null +++ b/plugins/modules/flexible_report_schedules_info.py @@ -0,0 +1,69 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: flexible_report_schedules_info +short_description: Information module for Flexible Report Schedules +description: +- Get all Flexible Report Schedules. +- Get all flexible report schedules. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Reports GetAllFlexibleReportSchedules + description: Complete reference of the GetAllFlexibleReportSchedules API. + link: https://developer.cisco.com/docs/dna-center/#!get-all-flexible-report-schedules +notes: + - SDK Method used are + reports.Reports.get_all_flexible_report_schedules, + + - Paths used are + get /dna/data/api/v1/flexible-report/schedules, + +""" + +EXAMPLES = r""" +- name: Get all Flexible Report Schedules + cisco.dnac.flexible_report_schedules_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: list + elements: dict + sample: > + [ + { + "reportId": "string", + "schedule": { + "type": "string", + "dateTime": 0 + }, + "reportName": "string" + } + ] +""" diff --git a/plugins/modules/global_credential_delete.py b/plugins/modules/global_credential_delete.py index 3dd9ad1d1d..34581241bb 100644 --- a/plugins/modules/global_credential_delete.py +++ b/plugins/modules/global_credential_delete.py @@ -20,8 +20,8 @@ description: GlobalCredentialId path parameter. ID of global-credential. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery DeleteGlobalCredentialsById description: Complete reference of the DeleteGlobalCredentialsById API. @@ -48,7 +48,6 @@ globalCredentialId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/global_credential_info.py b/plugins/modules/global_credential_info.py index 2d46ca10ff..2fd59e6407 100644 --- a/plugins/modules/global_credential_info.py +++ b/plugins/modules/global_credential_info.py @@ -29,19 +29,19 @@ type: str sortBy: description: - - SortBy query parameter. + - SortBy query parameter. Field to sort the results by. Sorts by 'instanceId' if no value is provided. type: str order: description: - - Order query parameter. + - Order query parameter. Order of sorting. 'asc' or 'des'. type: str id: description: - Id path parameter. Global Credential ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery GetCredentialSubTypeByCredentialId description: Complete reference of the GetCredentialSubTypeByCredentialId API. @@ -90,7 +90,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/global_credential_update.py b/plugins/modules/global_credential_update.py index 8f2ea144af..720273fea4 100644 --- a/plugins/modules/global_credential_update.py +++ b/plugins/modules/global_credential_update.py @@ -20,12 +20,12 @@ description: GlobalCredentialId path parameter. Global credential Uuid. type: str siteUuids: - description: Global Credential Update's siteUuids. + description: List of siteUuids where credential is to be updated. elements: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery UpdateGlobalCredentials description: Complete reference of the UpdateGlobalCredentials API. @@ -54,7 +54,6 @@ - string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/global_credential_v2.py b/plugins/modules/global_credential_v2.py index 2d27cca33d..5677ae7842 100644 --- a/plugins/modules/global_credential_v2.py +++ b/plugins/modules/global_credential_v2.py @@ -17,7 +17,7 @@ - > API to update device credentials. Multiple credentials can be passed at once, but only a single credential of a given type can be passed at once. Please refer sample Request Body for more information. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -26,57 +26,57 @@ description: Global Credential V2's cliCredential. suboptions: description: - description: Description. + description: Description for CLI credential. type: str enablePassword: - description: Enable Password. + description: CLI Enable Password. type: str id: - description: Id. + description: Id of the CLI Credential in UUID format. type: str password: - description: Password. + description: CLI Password. type: str username: - description: Username. + description: CLI Username. type: str type: dict httpsRead: description: Global Credential V2's httpsRead. suboptions: - id: - description: Id. + description: + description: Description for HTTP(S) Read Credentials. type: str - name: - description: Name. + id: + description: Id of the HTTP(S) Read Credential in UUID format. type: str password: - description: Password. + description: HTTP(S) Read Password. type: str port: - description: Port. + description: HTTP(S) Port. type: int username: - description: Username. + description: HTTP(S) Read Username. type: str type: dict httpsWrite: description: Global Credential V2's httpsWrite. suboptions: - id: - description: Id. + description: + description: Description for HTTP(S) Write Credentials. type: str - name: - description: Name. + id: + description: Id of the HTTP(S) Read Credential in UUID format. type: str password: - description: Password. + description: HTTP(S) Write Password. type: str port: - description: Port. + description: HTTP(S) Port. type: int username: - description: Username. + description: HTTP(S) Write Username. type: str type: dict id: @@ -86,59 +86,59 @@ description: Global Credential V2's snmpV2cRead. suboptions: description: - description: Description. + description: Description for Snmp RO community. type: str id: - description: Id. + description: Id of the SNMP Read Credential in UUID format. type: str readCommunity: - description: Read Community. + description: Snmp RO community. type: str type: dict snmpV2cWrite: description: Global Credential V2's snmpV2cWrite. suboptions: description: - description: Description. + description: Description for Snmp RW community. type: str id: - description: Id. + description: Id of the SNMP Write Credential in UUID format. type: str writeCommunity: - description: Write Community. + description: Snmp RW community. type: str type: dict snmpV3: description: Global Credential V2's snmpV3. suboptions: authPassword: - description: Auth Password. + description: Auth Password for SNMP V3. type: str authType: - description: Auth Type. + description: SNMP auth protocol. SHA' or 'MD5'. type: str description: - description: Description. + description: Description for Snmp V3 Credential. type: str id: - description: Id. + description: Id of the SNMP V3 Credential in UUID format. type: str privacyPassword: - description: Privacy Password. + description: Privacy Password for SNMP privacy. type: str privacyType: - description: Privacy Type. + description: SNMP privacy protocol. 'AES128','AES192','AES256'. type: str snmpMode: - description: Snmp Mode. + description: Mode of SNMP. 'AUTHPRIV' or 'AUTHNOPRIV' or 'NOAUTHNOPRIV'. type: str username: - description: Username. + description: SNMP V3 Username. type: str type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery CreateGlobalCredentialsV2 description: Complete reference of the CreateGlobalCredentialsV2 API. @@ -180,14 +180,14 @@ password: string username: string httpsRead: + description: string id: string - name: string password: string port: 0 username: string httpsWrite: + description: string id: string - name: string password: string port: 0 username: string @@ -225,12 +225,12 @@ password: string username: string httpsRead: - - name: string + - description: string password: string port: 0 username: string httpsWrite: - - name: string + - description: string password: string port: 0 username: string @@ -262,7 +262,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/global_credential_v2_info.py b/plugins/modules/global_credential_v2_info.py index 6b0bffd4db..37db95a46f 100644 --- a/plugins/modules/global_credential_v2_info.py +++ b/plugins/modules/global_credential_v2_info.py @@ -13,7 +13,7 @@ - > API to get device credentials' details. It fetches all global credentials of all types at once, without the need to pass any input parameters. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -22,8 +22,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery GetAllGlobalCredentialsV2 description: Complete reference of the GetAllGlobalCredentialsV2 API. @@ -51,7 +51,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/global_pool.py b/plugins/modules/global_pool.py index f52c316d6a..9f53f8cafa 100644 --- a/plugins/modules/global_pool.py +++ b/plugins/modules/global_pool.py @@ -48,8 +48,8 @@ type: list type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings CreateGlobalPool description: Complete reference of the CreateGlobalPool API. @@ -129,7 +129,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/global_pool_info.py b/plugins/modules/global_pool_info.py index 4d95ba9eac..7d8a908f11 100644 --- a/plugins/modules/global_pool_info.py +++ b/plugins/modules/global_pool_info.py @@ -10,7 +10,7 @@ short_description: Information module for Global Pool description: - Get all Global Pool. -- API to get global pool. +- API to get the global pool. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -21,15 +21,15 @@ type: dict offset: description: - - Offset query parameter. Offset/starting row. - type: int + - Offset query parameter. Offset/starting row. Indexed from 1. Default value of 1. + type: float limit: description: - - Limit query parameter. No of Global Pools to be retrieved. - type: int + - Limit query parameter. Number of Global Pools to be retrieved. Default is 25 if not specified. + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings GetGlobalPool description: Complete reference of the GetGlobalPool API. @@ -59,7 +59,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -76,20 +75,26 @@ "gateways": [ "string" ], - "createTime": "string", - "lastUpdateTime": "string", - "totalIpAddressCount": "string", - "usedIpAddressCount": "string", + "createTime": 0, + "lastUpdateTime": 0, + "totalIpAddressCount": 0, + "usedIpAddressCount": 0, "parentUuid": "string", "owner": "string", - "shared": "string", - "overlapping": "string", - "configureExternalDhcp": "string", + "shared": true, + "overlapping": true, + "configureExternalDhcp": true, "usedPercentage": "string", "clientOptions": {}, + "ipPoolType": "string", + "unavailableIpAddressCount": 0, + "availableIpAddressCount": 0, + "totalAssignableIpAddressCount": 0, "dnsServerIps": [ "string" ], + "hasSubpools": true, + "defaultAssignedIpAddressCount": 0, "context": [ { "owner": "string", @@ -97,7 +102,7 @@ "contextValue": "string" } ], - "ipv6": "string", + "ipv6": true, "id": "string", "ipPoolCidr": "string" } diff --git a/plugins/modules/golden_image_create.py b/plugins/modules/golden_image_create.py index 95385c59d8..91d7d7b222 100644 --- a/plugins/modules/golden_image_create.py +++ b/plugins/modules/golden_image_create.py @@ -30,8 +30,8 @@ description: SiteId in uuid format. For Global Site "-1" to be used. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Software Image Management (SWIM) TagAsGoldenImage description: Complete reference of the TagAsGoldenImage API. @@ -61,7 +61,6 @@ siteId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/golden_tag_image_delete.py b/plugins/modules/golden_tag_image_delete.py index 392165663b..e3010ea7c3 100644 --- a/plugins/modules/golden_tag_image_delete.py +++ b/plugins/modules/golden_tag_image_delete.py @@ -32,8 +32,8 @@ Global site. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Software Image Management (SWIM) RemoveGoldenTagForImage description: Complete reference of the RemoveGoldenTagForImage API. @@ -63,7 +63,6 @@ siteId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/golden_tag_image_details_info.py b/plugins/modules/golden_tag_image_details_info.py index c92ed95039..a6aebf1195 100644 --- a/plugins/modules/golden_tag_image_details_info.py +++ b/plugins/modules/golden_tag_image_details_info.py @@ -38,8 +38,8 @@ - ImageId path parameter. Image Id in uuid format. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Software Image Management (SWIM) GetGoldenTagStatusOfAnImage description: Complete reference of the GetGoldenTagStatusOfAnImage API. @@ -71,7 +71,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/http_read_credential.py b/plugins/modules/http_read_credential.py index 89a5f7f47f..a99555fc00 100644 --- a/plugins/modules/http_read_credential.py +++ b/plugins/modules/http_read_credential.py @@ -18,38 +18,39 @@ author: Rafael Campos (@racampos) options: comments: - description: Http Read Credential's comments. + description: Comments to identify the HTTP(S) Read credential. type: str credentialType: - description: Http Read Credential's credentialType. + description: Credential type to identify the application that uses the HTTP(S) Read + credential. type: str description: - description: Http Read Credential's description. + description: Description for HTTP(S) Read Credential. type: str id: - description: Http Read Credential's id. + description: Id of the HTTP(S) Read Credential in UUID format. type: str instanceTenantId: - description: Http Read Credential's instanceTenantId. + description: Deprecated. type: str instanceUuid: - description: Http Read Credential's instanceUuid. + description: Deprecated. type: str password: - description: Http Read Credential's password. + description: HTTP(S) Read Password. type: str port: - description: Http Read Credential's port. + description: HTTP(S) Port. Valid port should be in the range of 1 to 65535. type: int secure: - description: Secure flag. + description: Flag for HTTPS Read. type: bool username: - description: Http Read Credential's username. + description: HTTP(S) Read Username. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery CreateHTTPReadCredentials description: Complete reference of the CreateHTTPReadCredentials API. @@ -112,7 +113,6 @@ username: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/http_write_credential.py b/plugins/modules/http_write_credential.py index 611f40716d..d22a4d4207 100644 --- a/plugins/modules/http_write_credential.py +++ b/plugins/modules/http_write_credential.py @@ -18,38 +18,39 @@ author: Rafael Campos (@racampos) options: comments: - description: Http Write Credential's comments. + description: Comments to identify the HTTP(S) Write credential. type: str credentialType: - description: Http Write Credential's credentialType. + description: Credential type to identify the application that uses the HTTP(S) Write + credential. type: str description: - description: Http Write Credential's description. + description: Description for HTTP(S) Write Credential. type: str id: - description: Http Write Credential's id. + description: Id of the HTTP(S) Write Credential in UUID format. type: str instanceTenantId: - description: Http Write Credential's instanceTenantId. + description: Deprecated. type: str instanceUuid: - description: Http Write Credential's instanceUuid. + description: Deprecated. type: str password: - description: Http Write Credential's password. + description: HTTP(S) Write Password. type: str port: - description: Http Write Credential's port. + description: HTTP(S) Port. Valid port should be in the range of 1 to 65535. type: int secure: - description: Secure flag. + description: Flag for HTTPS Write. type: bool username: - description: Http Write Credential's username. + description: HTTP(S) Write Username. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery CreateHTTPWriteCredentials description: Complete reference of the CreateHTTPWriteCredentials API. @@ -112,7 +113,6 @@ username: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/integration_settings_instances_itsm.py b/plugins/modules/integration_settings_instances_itsm.py index 86fa8bd762..991dccb6b6 100644 --- a/plugins/modules/integration_settings_instances_itsm.py +++ b/plugins/modules/integration_settings_instances_itsm.py @@ -13,7 +13,7 @@ - Creates ITSM Integration setting. - Deletes the ITSM Integration setting. - Updates the ITSM Integration setting. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -39,7 +39,7 @@ description: Description of the setting instance. type: str dypName: - description: It should be ServiceNowConnection. + description: It can be ServiceNowConnection. type: str instanceId: description: InstanceId path parameter. Instance Id of the Integration setting instance. @@ -48,8 +48,8 @@ description: Name of the setting instance. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for ITSM Integration CreateITSMIntegrationSetting description: Complete reference of the CreateITSMIntegrationSetting API. @@ -126,7 +126,6 @@ instanceId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/integration_settings_instances_itsm_info.py b/plugins/modules/integration_settings_instances_itsm_info.py index 0519f5e5a1..f0c3958b90 100644 --- a/plugins/modules/integration_settings_instances_itsm_info.py +++ b/plugins/modules/integration_settings_instances_itsm_info.py @@ -11,7 +11,7 @@ description: - Get Integration Settings Instances Itsm by id. - Fetches ITSM Integration setting by ID. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -24,8 +24,8 @@ - InstanceId path parameter. Instance Id of the Integration setting instance. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for ITSM Integration GetITSMIntegrationSettingById description: Complete reference of the GetITSMIntegrationSettingById API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/integration_settings_itsm_instances_info.py b/plugins/modules/integration_settings_itsm_instances_info.py new file mode 100644 index 0000000000..dd81cd6b56 --- /dev/null +++ b/plugins/modules/integration_settings_itsm_instances_info.py @@ -0,0 +1,78 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: integration_settings_itsm_instances_info +short_description: Information module for Integration Settings Itsm Instances +description: +- Get all Integration Settings Itsm Instances. +- Fetches all ITSM Integration settings. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for ITSM Integration GetAllITSMIntegrationSettings + description: Complete reference of the GetAllITSMIntegrationSettings API. + link: https://developer.cisco.com/docs/dna-center/#!get-all-itsm-integration-settings +notes: + - SDK Method used are + itsm_integration.ItsmIntegration.get_all_itsm_integration_settings, + + - Paths used are + get /dna/intent/api/v1/integration-settings/itsm/instances, + +""" + +EXAMPLES = r""" +- name: Get all Integration Settings Itsm Instances + cisco.dnac.integration_settings_itsm_instances_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: list + elements: dict + sample: > + [ + { + "id": "string", + "dypId": "string", + "dypName": "string", + "name": "string", + "uniqueKey": "string", + "dypMajorVersion": 0, + "description": "string", + "createdDate": 0, + "createdBy": "string", + "updatedBy": "string", + "softwareVersionLog": [ + {} + ], + "schemaVersion": 0, + "tenantId": "string" + } + ] +""" diff --git a/plugins/modules/integration_settings_status_info.py b/plugins/modules/integration_settings_status_info.py new file mode 100644 index 0000000000..141e9f3091 --- /dev/null +++ b/plugins/modules/integration_settings_status_info.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: integration_settings_status_info +short_description: Information module for Integration Settings Status +description: +- Get all Integration Settings Status. +- Fetches ITSM Integration status. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for ITSM Integration GetITSMIntegrationStatus + description: Complete reference of the GetITSMIntegrationStatus API. + link: https://developer.cisco.com/docs/dna-center/#!get-itsm-integration-status +notes: + - SDK Method used are + itsm_integration.ItsmIntegration.get_itsm_integration_status, + + - Paths used are + get /dna/intent/api/v1/integration-settings/status, + +""" + +EXAMPLES = r""" +- name: Get all Integration Settings Status + cisco.dnac.integration_settings_status_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "name": "string", + "status": "string", + "configurations": [ + { + "dypSchemaName": "string", + "dypInstanceId": "string" + } + ] + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/interface_info.py b/plugins/modules/interface_info.py index a6f0706ade..7c57b98123 100644 --- a/plugins/modules/interface_info.py +++ b/plugins/modules/interface_info.py @@ -24,8 +24,8 @@ - InterfaceUuid path parameter. Interface ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices LegitOperationsForInterface description: Complete reference of the LegitOperationsForInterface API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -63,62 +62,22 @@ sample: > { "response": { - "type": "string", - "properties": { - "interfaceUuid": { - "type": "string" - }, - "properties": { - "type": "string", - "items": [ - { - "type": "string", - "properties": { - "name": { - "type": "string" - }, - "applicable": { - "type": "string" - }, - "failureReason": { - "type": "string" - } - }, - "required": [ - "string" - ] - } - ] - }, - "operations": { - "type": "string", - "items": [ - { - "type": "string", - "properties": { - "name": { - "type": "string" - }, - "applicable": { - "type": "string" - }, - "failureReason": { - "type": "string" - } - }, - "required": [ - "string" - ] - } - ] + "interfaceUuid": "string", + "properties": [ + { + "name": "string", + "applicable": "string", + "failureReason": "string" + } + ], + "operations": [ + { + "name": "string", + "applicable": "string", + "failureReason": "string" } - }, - "required": [ - "string" ] }, - "version": { - "type": "string" - } + "version": "string" } """ diff --git a/plugins/modules/interface_network_device_detail_info.py b/plugins/modules/interface_network_device_detail_info.py index 81a3203d65..259b68ed31 100644 --- a/plugins/modules/interface_network_device_detail_info.py +++ b/plugins/modules/interface_network_device_detail_info.py @@ -28,8 +28,8 @@ - Name query parameter. Interface name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetInterfaceDetailsByDeviceIdAndInterfaceName description: Complete reference of the GetInterfaceDetailsByDeviceIdAndInterfaceName API. @@ -59,7 +59,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -68,9 +67,24 @@ sample: > { "response": { + "addresses": [ + { + "address": { + "ipAddress": { + "address": "string" + }, + "ipMask": { + "address": "string" + }, + "isInverseMask": true + }, + "type": "string" + } + ], "adminStatus": "string", "className": "string", "description": "string", + "name": "string", "deviceId": "string", "duplex": "string", "id": "string", @@ -81,11 +95,14 @@ "ipv4Address": "string", "ipv4Mask": "string", "isisSupport": "string", + "lastOutgoingPacketTime": 0, + "lastIncomingPacketTime": 0, "lastUpdated": "string", "macAddress": "string", "mappedPhysicalInterfaceId": "string", "mappedPhysicalInterfaceName": "string", "mediaType": "string", + "mtu": "string", "nativeVlanId": "string", "ospfSupport": "string", "pid": "string", @@ -97,7 +114,13 @@ "speed": "string", "status": "string", "vlanId": "string", - "voiceVlan": "string" + "voiceVlan": "string", + "poweroverethernet": "string", + "networkdevice_id": "string", + "managedComputeElement": "string", + "managedNetworkElement": "string", + "managedNetworkElementUrl": "string", + "managedComputeElementUrl": "string" }, "version": "string" } diff --git a/plugins/modules/interface_network_device_info.py b/plugins/modules/interface_network_device_info.py index 62bb64e03c..6437313265 100644 --- a/plugins/modules/interface_network_device_info.py +++ b/plugins/modules/interface_network_device_info.py @@ -24,8 +24,8 @@ - DeviceId path parameter. Device ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetInterfaceInfoById description: Complete reference of the GetInterfaceInfoById API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -64,9 +63,24 @@ { "response": [ { + "addresses": [ + { + "address": { + "ipAddress": { + "address": "string" + }, + "ipMask": { + "address": "string" + }, + "isInverseMask": true + }, + "type": "string" + } + ], "adminStatus": "string", "className": "string", "description": "string", + "name": "string", "deviceId": "string", "duplex": "string", "id": "string", @@ -77,11 +91,14 @@ "ipv4Address": "string", "ipv4Mask": "string", "isisSupport": "string", + "lastOutgoingPacketTime": 0, + "lastIncomingPacketTime": 0, "lastUpdated": "string", "macAddress": "string", "mappedPhysicalInterfaceId": "string", "mappedPhysicalInterfaceName": "string", "mediaType": "string", + "mtu": "string", "nativeVlanId": "string", "ospfSupport": "string", "pid": "string", diff --git a/plugins/modules/interface_network_device_range_info.py b/plugins/modules/interface_network_device_range_info.py index 2f2e3a6ea6..ce832dcbe9 100644 --- a/plugins/modules/interface_network_device_range_info.py +++ b/plugins/modules/interface_network_device_range_info.py @@ -32,8 +32,8 @@ - RecordsToReturn path parameter. Number of records to return. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDeviceInterfacesBySpecifiedRange description: Complete reference of the GetDeviceInterfacesBySpecifiedRange API. @@ -64,7 +64,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -74,9 +73,24 @@ { "response": [ { + "addresses": [ + { + "address": { + "ipAddress": { + "address": "string" + }, + "ipMask": { + "address": "string" + }, + "isInverseMask": true + }, + "type": "string" + } + ], "adminStatus": "string", "className": "string", "description": "string", + "name": "string", "deviceId": "string", "duplex": "string", "id": "string", @@ -87,11 +101,14 @@ "ipv4Address": "string", "ipv4Mask": "string", "isisSupport": "string", + "lastOutgoingPacketTime": 0, + "lastIncomingPacketTime": 0, "lastUpdated": "string", "macAddress": "string", "mappedPhysicalInterfaceId": "string", "mappedPhysicalInterfaceName": "string", "mediaType": "string", + "mtu": "string", "nativeVlanId": "string", "ospfSupport": "string", "pid": "string", diff --git a/plugins/modules/interface_operation_create.py b/plugins/modules/interface_operation_create.py index 1bc065c317..6272bcd8c6 100644 --- a/plugins/modules/interface_operation_create.py +++ b/plugins/modules/interface_operation_create.py @@ -27,14 +27,14 @@ description: InterfaceUuid path parameter. Interface Id. type: str operation: - description: Operation. + description: Operation needs to be specified as 'ClearMacAddress'. type: str payload: - description: Payload. + description: Payload is not applicable. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices ClearMacAddressTable description: Complete reference of the ClearMacAddressTable API. @@ -64,7 +64,6 @@ payload: {} """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/interface_update.py b/plugins/modules/interface_update.py index 261703d48c..5c6c198291 100644 --- a/plugins/modules/interface_update.py +++ b/plugins/modules/interface_update.py @@ -19,7 +19,7 @@ author: Rafael Campos (@racampos) options: adminStatus: - description: Admin Status. + description: Admin status as ('UP'/'DOWN'). type: str deploymentMode: description: DeploymentMode query parameter. Preview/Deploy 'Preview' means the @@ -27,20 +27,20 @@ to the device. type: str description: - description: Description. + description: Description for the Interface. type: str interfaceUuid: description: InterfaceUuid path parameter. Interface ID. type: str vlanId: - description: Vlan Id. + description: VLAN Id to be Updated. type: int voiceVlanId: - description: Voice Vlan Id. + description: Voice Vlan Id to be Updated. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices UpdateInterfaceDetails description: Complete reference of the UpdateInterfaceDetails API. @@ -72,7 +72,6 @@ voiceVlanId: 0 """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/ise_integration_status_info.py b/plugins/modules/ise_integration_status_info.py new file mode 100644 index 0000000000..d76eb0e012 --- /dev/null +++ b/plugins/modules/ise_integration_status_info.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: ise_integration_status_info +short_description: Information module for Ise Integration Status +description: +- Get all Ise Integration Status. +- API to check Cisco ISE server integration status. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for System Settings CiscoISEServerIntegrationStatus + description: Complete reference of the CiscoISEServerIntegrationStatus API. + link: https://developer.cisco.com/docs/dna-center/#!cisco-ise-server-integration-status +notes: + - SDK Method used are + system_settings.SystemSettings.cisco_ise_server_integration_status, + + - Paths used are + get /dna/intent/api/v1/ise-integration-status, + +""" + +EXAMPLES = r""" +- name: Get all Ise Integration Status + cisco.dnac.ise_integration_status_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "aaaServerSettingId": "string", + "overallStatus": "string", + "overallErrorMessage": "string", + "steps": [ + { + "stepId": "string", + "stepOrder": 0, + "stepName": "string", + "stepDescription": "string", + "stepStatus": "string", + "certAcceptedByUser": true, + "stepTime": 0 + } + ] + } +""" diff --git a/plugins/modules/issues_enrichment_details_info.py b/plugins/modules/issues_enrichment_details_info.py index 58d5c787cc..44359fb858 100644 --- a/plugins/modules/issues_enrichment_details_info.py +++ b/plugins/modules/issues_enrichment_details_info.py @@ -22,8 +22,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Issues GetIssueEnrichmentDetails description: Complete reference of the GetIssueEnrichmentDetails API. @@ -51,7 +51,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/issues_info.py b/plugins/modules/issues_info.py index f6131d2b88..61882040a2 100644 --- a/plugins/modules/issues_info.py +++ b/plugins/modules/issues_info.py @@ -24,11 +24,11 @@ startTime: description: - StartTime query parameter. Starting epoch time in milliseconds of query time window. - type: int + type: float endTime: description: - EndTime query parameter. Ending epoch time in milliseconds of query time window. - type: int + type: float siteId: description: - SiteId query parameter. Assurance UUID value of the site in the issue content. @@ -44,22 +44,22 @@ priority: description: - > - Priority query parameter. The issue's priority value (One of P1, P2, P3, or P4)(Use only when macAddress and - deviceId are not provided). + Priority query parameter. The issue's priority value P1, P2, P3, or P4 (case insensitive) (Use only when + macAddress and deviceId are not provided). type: str - aiDriven: + issueStatus: description: - - > - AiDriven query parameter. The issue's AI driven value (Yes or No)(Use only when macAddress and deviceId are - not provided). + - IssueStatus query parameter. The issue's status value ACTIVE, IGNORED, RESOLVED (case insensitive). type: str - issueStatus: + aiDriven: description: - - IssueStatus query parameter. The issue's status value (One of ACTIVE, IGNORED, RESOLVED). + - > + AiDriven query parameter. The issue's AI driven value YES or NO (case insensitive) (Use only when macAddress + and deviceId are not provided). type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Issues Issues description: Complete reference of the Issues API. @@ -90,12 +90,11 @@ deviceId: string macAddress: string priority: string - aiDriven: string issueStatus: string + aiDriven: string register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -104,7 +103,7 @@ sample: > { "version": "string", - "totalCount": 0, + "totalCount": "string", "response": [ { "issueId": "string", @@ -112,7 +111,7 @@ "siteId": "string", "deviceId": "string", "deviceRole": "string", - "aiDriven": true, + "aiDriven": "string", "clientMac": "string", "issue_occurence_count": 0, "status": "string", diff --git a/plugins/modules/itsm_cmdb_sync_status_info.py b/plugins/modules/itsm_cmdb_sync_status_info.py index 2b3a47ea2b..ce064e7e37 100644 --- a/plugins/modules/itsm_cmdb_sync_status_info.py +++ b/plugins/modules/itsm_cmdb_sync_status_info.py @@ -34,8 +34,8 @@ - Date query parameter. Provide date in "YYYY-MM-DD" format. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for ITSM GetCMDBSyncStatus description: Complete reference of the GetCMDBSyncStatus API. @@ -65,7 +65,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/itsm_integration_events_failed_info.py b/plugins/modules/itsm_integration_events_failed_info.py index c2a6dca63b..8fe853b890 100644 --- a/plugins/modules/itsm_integration_events_failed_info.py +++ b/plugins/modules/itsm_integration_events_failed_info.py @@ -24,8 +24,8 @@ - InstanceId query parameter. Instance Id of the failed event as in the Runtime Dashboard. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for ITSM GetFailedITSMEvents description: Complete reference of the GetFailedITSMEvents API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/itsm_integration_events_retry.py b/plugins/modules/itsm_integration_events_retry.py index 64c97fe80e..2e45a0e399 100644 --- a/plugins/modules/itsm_integration_events_retry.py +++ b/plugins/modules/itsm_integration_events_retry.py @@ -24,8 +24,8 @@ elements: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for ITSM RetryIntegrationEvents description: Complete reference of the RetryIntegrationEvents API. @@ -53,7 +53,6 @@ - string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/lan_automation_count_info.py b/plugins/modules/lan_automation_count_info.py index e275eaf2c8..3fff392e80 100644 --- a/plugins/modules/lan_automation_count_info.py +++ b/plugins/modules/lan_automation_count_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for LAN Automation LANAutomationSessionCount description: Complete reference of the LANAutomationSessionCount API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/lan_automation_create.py b/plugins/modules/lan_automation_create.py index b9c04f38d6..385a37e8c2 100644 --- a/plugins/modules/lan_automation_create.py +++ b/plugins/modules/lan_automation_create.py @@ -63,8 +63,8 @@ type: bool type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for LAN Automation LANAutomationStart description: Complete reference of the LANAutomationStart API. @@ -104,7 +104,6 @@ redistributeIsisToBgp: true """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/lan_automation_delete.py b/plugins/modules/lan_automation_delete.py index d31484c673..92b1eab287 100644 --- a/plugins/modules/lan_automation_delete.py +++ b/plugins/modules/lan_automation_delete.py @@ -20,8 +20,8 @@ description: Id path parameter. LAN Automation id can be obtained from /dna/intent/api/v1/lan-automation/status. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for LAN Automation LANAutomationStop description: Complete reference of the LANAutomationStop API. @@ -48,7 +48,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/lan_automation_log_by_serial_number_info.py b/plugins/modules/lan_automation_log_by_serial_number_info.py index fa75bec891..2af368cb43 100644 --- a/plugins/modules/lan_automation_log_by_serial_number_info.py +++ b/plugins/modules/lan_automation_log_by_serial_number_info.py @@ -13,7 +13,7 @@ - > Invoke this API to get the LAN Automation session logs for individual devices based on the given LAN Automation session id and device serial number. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -37,8 +37,8 @@ the remaining logs, please leave the query parameter blank. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for LAN Automation LANAutomationLogsForIndividualDevices description: Complete reference of the LANAutomationLogsForIndividualDevices API. @@ -69,7 +69,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/lan_automation_log_info.py b/plugins/modules/lan_automation_log_info.py index 6a8aa12919..d1fcde896b 100644 --- a/plugins/modules/lan_automation_log_info.py +++ b/plugins/modules/lan_automation_log_info.py @@ -24,18 +24,18 @@ offset: description: - Offset query parameter. Starting index of the LAN Automation session. Minimum value is 1. - type: int + type: float limit: description: - Limit query parameter. Number of LAN Automation sessions to be retrieved. Limit value can range between 1 to 10. - type: int + type: float id: description: - Id path parameter. LAN Automation session identifier. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for LAN Automation LANAutomationLog description: Complete reference of the LANAutomationLog API. @@ -83,7 +83,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/lan_automation_sessions_info.py b/plugins/modules/lan_automation_sessions_info.py new file mode 100644 index 0000000000..2b30d87322 --- /dev/null +++ b/plugins/modules/lan_automation_sessions_info.py @@ -0,0 +1,68 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: lan_automation_sessions_info +short_description: Information module for Lan Automation Sessions +description: +- Get all Lan Automation Sessions. +- Invoke this API to get the LAN Automation active session information. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for LAN Automation LANAutomationActiveSessions + description: Complete reference of the LANAutomationActiveSessions API. + link: https://developer.cisco.com/docs/dna-center/#!l-an-automation-active-sessions +notes: + - SDK Method used are + lan_automation.LanAutomation.lan_automation_active_sessions, + + - Paths used are + get /dna/intent/api/v1/lan-automation/sessions, + +""" + +EXAMPLES = r""" +- name: Get all Lan Automation Sessions + cisco.dnac.lan_automation_sessions_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "maxSupportedCount": "string", + "activeSessions": "string", + "activeSessionIds": [ + "string" + ] + }, + "version": "string" + } +""" diff --git a/plugins/modules/lan_automation_status_info.py b/plugins/modules/lan_automation_status_info.py index 3680a97ebb..3468d6bc20 100644 --- a/plugins/modules/lan_automation_status_info.py +++ b/plugins/modules/lan_automation_status_info.py @@ -24,18 +24,18 @@ offset: description: - Offset query parameter. Starting index of the LAN Automation session. Minimum value is 1. - type: int + type: float limit: description: - Limit query parameter. Number of LAN Automation sessions to be retrieved. Limit value can range between 1 to 10. - type: int + type: float id: description: - Id path parameter. LAN Automation session identifier. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for LAN Automation LANAutomationStatus description: Complete reference of the LANAutomationStatus API. @@ -83,7 +83,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -96,7 +95,7 @@ "id": "string", "discoveredDeviceSiteNameHierarchy": "string", "primaryDeviceManagmentIPAddress": "string", - "ipPoolList": [ + "ipPools": [ { "ipPoolName": "string", "ipPoolRole": "string" @@ -120,7 +119,12 @@ ] } ], - "redistributeIsisToBgp": true + "redistributeIsisToBgp": true, + "discoveryLevel": 0, + "discoveryTimeout": 0, + "discoveryDevices": [ + {} + ] } ], "version": "string" diff --git a/plugins/modules/lan_automation_update.py b/plugins/modules/lan_automation_update.py new file mode 100644 index 0000000000..fe63bf454e --- /dev/null +++ b/plugins/modules/lan_automation_update.py @@ -0,0 +1,78 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: lan_automation_update +short_description: Resource module for Lan Automation Update +description: +- Manage operation update of the resource Lan Automation Update. +- Invoke this API to stop LAN Automation and Update Loopback0 IP Address of Devices, discovered in the current session. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + id: + description: Id path parameter. LAN Automation id can be obtained from /dna/intent/api/v1/lan-automation/status. + type: str + payload: + description: Lan Automation Update's payload. + elements: dict + suboptions: + deviceManagementIPAddress: + description: Device Management IP Address. + type: str + newLoopback0IPAddress: + description: New Loopback0 IP Address from LAN pool of Device Discovery Site. + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for LAN Automation LANAutomationStopAndUpdateDevices + description: Complete reference of the LANAutomationStopAndUpdateDevices API. + link: https://developer.cisco.com/docs/dna-center/#!l-an-automation-stop-and-update-devices +notes: + - SDK Method used are + lan_automation.LanAutomation.lan_automation_stop_and_update_devices, + + - Paths used are + put /dna/intent/api/v1/lan-automation/{id}, + +""" + +EXAMPLES = r""" +- name: Update by id + cisco.dnac.lan_automation_update: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + id: string + payload: + - deviceManagementIPAddress: string + newLoopback0IPAddress: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/lan_automation_update_device.py b/plugins/modules/lan_automation_update_device.py new file mode 100644 index 0000000000..688e45b133 --- /dev/null +++ b/plugins/modules/lan_automation_update_device.py @@ -0,0 +1,122 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: lan_automation_updateDevice +short_description: Resource module for Lan Automation Updatedevice +description: +- Manage operation update of the resource Lan Automation Updatedevice. +- > + Invoke this API to perform a DAY-N update on LAN Automation-related devices. Supported features include Loopback0 + IP update, hostname update, link addition, and link deletion. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + feature: + description: Feature query parameter. Feature ID for the update. Supported feature + IDs include LOOPBACK0_IPADDRESS_UPDATE, HOSTNAME_UPDATE, LINK_ADD, and LINK_DELETE. + type: str + hostnameUpdateDevices: + description: Lan Automation Update Device's hostnameUpdateDevices. + elements: dict + suboptions: + deviceManagementIPAddress: + description: Device Management IP Address. + type: str + newHostName: + description: New hostname for the device. + type: str + type: list + linkUpdate: + description: Lan Automation Update Device's linkUpdate. + suboptions: + destinationDeviceInterfaceName: + description: Destination Device Interface Name. + type: str + destinationDeviceManagementIPAddress: + description: Destination Device Management IP Address. + type: str + ipPoolName: + description: Name of the IP LAN Pool, required for Link Add should be from discovery + site of source and destination device. + type: str + sourceDeviceInterfaceName: + description: Source Device Interface Name. + type: str + sourceDeviceManagementIPAddress: + description: Source Device Management IP Address. + type: str + type: dict + loopbackUpdateDeviceList: + description: Lan Automation Update Device's loopbackUpdateDeviceList. + elements: dict + suboptions: + deviceManagementIPAddress: + description: Device Management IP Address. + type: str + newLoopback0IPAddress: + description: New Loopback0 IP Address from LAN Pool of Device Discovery Site(Shared + pool should not be used). + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for LAN Automation LANAutomationDeviceUpdate + description: Complete reference of the LANAutomationDeviceUpdate API. + link: https://developer.cisco.com/docs/dna-center/#!l-an-automation-device-update +notes: + - SDK Method used are + lan_automation.LanAutomation.lan_automation_device_update, + + - Paths used are + put /dna/intent/api/v1/lan-automation/updateDevice, + +""" + +EXAMPLES = r""" +- name: Update all + cisco.dnac.lan_automation_updateDevice: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + feature: string + hostnameUpdateDevices: + - deviceManagementIPAddress: string + newHostName: string + linkUpdate: + destinationDeviceInterfaceName: string + destinationDeviceManagementIPAddress: string + ipPoolName: string + sourceDeviceInterfaceName: string + sourceDeviceManagementIPAddress: string + loopbackUpdateDeviceList: + - deviceManagementIPAddress: string + newLoopback0IPAddress: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/lan_automation_update_v2.py b/plugins/modules/lan_automation_update_v2.py new file mode 100644 index 0000000000..1c56e63c49 --- /dev/null +++ b/plugins/modules/lan_automation_update_v2.py @@ -0,0 +1,84 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: lan_automation_update_v2 +short_description: Resource module for Lan Automation Update V2 +description: +- Manage operation update of the resource Lan Automation Update V2. +- > + Invoke this API to stop LAN Automation and update device parameters such as Loopback0 IP address and/or hostname + discovered in the current session. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + id: + description: Id path parameter. LAN Automation id can be obtained from /dna/intent/api/v1/lan-automation/status. + type: str + payload: + description: Lan Automation Update V2's payload. + elements: dict + suboptions: + deviceManagementIPAddress: + description: Device Management IP Address. + type: str + newHostName: + description: New hostname to be assigned to the device. + type: str + newLoopback0IPAddress: + description: New Loopback0 IP Address from LAN pool of Device Discovery Site. + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for LAN Automation LANAutomationStopAndUpdateDevicesV2 + description: Complete reference of the LANAutomationStopAndUpdateDevicesV2 API. + link: https://developer.cisco.com/docs/dna-center/#!l-an-automation-stop-and-update-devices-v-2 +notes: + - SDK Method used are + lan_automation.LanAutomation.lan_automation_stop_and_update_devices_v2, + + - Paths used are + put /dna/intent/api/v2/lan-automation/{id}, + +""" + +EXAMPLES = r""" +- name: Update by id + cisco.dnac.lan_automation_update_v2: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + id: string + payload: + - deviceManagementIPAddress: string + newHostName: string + newLoopback0IPAddress: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/lan_automation_v2.py b/plugins/modules/lan_automation_v2.py new file mode 100644 index 0000000000..65477319ec --- /dev/null +++ b/plugins/modules/lan_automation_v2.py @@ -0,0 +1,166 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: lan_automation_v2 +short_description: Resource module for Lan Automation V2 +description: +- Manage operation create of the resource Lan Automation V2. +- > + Invoke V2 LAN Automation Start API, which supports optional auto-stop processing feature based on the provided + timeout or a specific device list, or both. The stop processing will be executed automatically when either of the + cases is satisfied, without specifically calling the stop API. The V2 API behaves similarly to V1 if no timeout or + device list is provided, and the user needs to call the stop API for LAN Automation stop processing. With the V2 + API, the user can also specify the level up to which the devices can be LAN automated. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + payload: + description: Lan Automation V2's payload. + elements: dict + suboptions: + discoveredDeviceSiteNameHierarchy: + description: Discovered device site name. + type: str + discoveryDevices: + description: Lan Automation V2's discoveryDevices. + elements: dict + suboptions: + deviceHostName: + description: Hostname of the device. + type: str + deviceManagementIPAddress: + description: Management IP Address of the device. + type: str + deviceSerialNumber: + description: Serial number of the device. + type: str + deviceSiteNameHierarchy: + description: "Site name hierarchy for the device, must be a child site of\ + \ the discoveredDeviceSiteNameHierarchy or same if it\u2019s not area\ + \ type." + type: str + type: list + discoveryLevel: + description: Level below primary seed device upto which the new devices will + be LAN Automated by this session, level + seed = tier. Supported range for + level is 1-5, default level is 2. + type: int + discoveryTimeout: + description: Discovery timeout in minutes. Until this time, the stop processing + will not be triggered. Any device contacting after the provided discovery + timeout will not be processed, and a device reset and reload will be attempted + to bring it back to the PnP agent state before process completion. The supported + timeout range is in minutes 20-10080. If both timeout and discovery devices + list are provided, the stop processing will be attempted whichever happens + earlier. Users can always use the LAN Automation delete API to force stop + processing. + type: int + hostNameFileId: + description: Use /dna/intent/api/v1/file/namespace/nw_orch API to get the file + ID for the already uploaded file in the nw_orch namespace. + type: str + hostNamePrefix: + description: Host name prefix assigned to the discovered device. + type: str + ipPools: + description: Lan Automation V2's ipPools. + elements: dict + suboptions: + ipPoolName: + description: Name of the IP pool. + type: str + ipPoolRole: + description: Role of the IP pool. Supported roles are MAIN_POOL and PHYSICAL_LINK_POOL. + type: str + type: list + isisDomainPwd: + description: IS-IS domain password in plain text. + type: str + multicastEnabled: + description: Enable underlay native multicast. + type: bool + peerDeviceManagmentIPAddress: + description: Peer seed management IP address. + type: str + primaryDeviceInterfaceNames: + description: The list of interfaces on primary seed via which the discovered + devices are connected. + elements: str + type: list + primaryDeviceManagmentIPAddress: + description: Primary seed management IP address. + type: str + redistributeIsisToBgp: + description: Advertise LAN Automation summary route into BGP. + type: bool + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for LAN Automation LANAutomationStartV2 + description: Complete reference of the LANAutomationStartV2 API. + link: https://developer.cisco.com/docs/dna-center/#!l-an-automation-start-v-2 +notes: + - SDK Method used are + lan_automation.LanAutomation.lan_automation_start_v2, + + - Paths used are + post /dna/intent/api/v2/lan-automation, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.lan_automation_v2: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + payload: + - discoveredDeviceSiteNameHierarchy: string + discoveryDevices: + - deviceHostName: string + deviceManagementIPAddress: string + deviceSerialNumber: string + deviceSiteNameHierarchy: string + discoveryLevel: 0 + discoveryTimeout: 0 + hostNameFileId: string + hostNamePrefix: string + ipPools: + - ipPoolName: string + ipPoolRole: string + isisDomainPwd: string + multicastEnabled: true + peerDeviceManagmentIPAddress: string + primaryDeviceInterfaceNames: + - string + primaryDeviceManagmentIPAddress: string + redistributeIsisToBgp: true + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/license_device_count_info.py b/plugins/modules/license_device_count_info.py index 0ec3976ac0..56db9d1ad9 100644 --- a/plugins/modules/license_device_count_info.py +++ b/plugins/modules/license_device_count_info.py @@ -40,15 +40,15 @@ - Smart_account_id query parameter. Smart account id. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Licenses DeviceCountDetails2 - description: Complete reference of the DeviceCountDetails2 API. - link: https://developer.cisco.com/docs/dna-center/#!device-count-details-2 +- name: Cisco DNA Center documentation for Licenses DeviceCountDetails + description: Complete reference of the DeviceCountDetails API. + link: https://developer.cisco.com/docs/dna-center/#!device-count-details notes: - SDK Method used are - licenses.Licenses.device_count_details2, + licenses.Licenses.device_count_details, - Paths used are get /dna/intent/api/v1/licenses/device/count, @@ -74,7 +74,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/license_device_deregistration.py b/plugins/modules/license_device_deregistration.py index ddf70df119..3d99685f1a 100644 --- a/plugins/modules/license_device_deregistration.py +++ b/plugins/modules/license_device_deregistration.py @@ -21,15 +21,15 @@ elements: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Licenses DeviceDeregistration2 - description: Complete reference of the DeviceDeregistration2 API. - link: https://developer.cisco.com/docs/dna-center/#!device-deregistration-2 +- name: Cisco DNA Center documentation for Licenses DeviceDeregistration + description: Complete reference of the DeviceDeregistration API. + link: https://developer.cisco.com/docs/dna-center/#!device-deregistration notes: - SDK Method used are - licenses.Licenses.device_deregistration2, + licenses.Licenses.device_deregistration, - Paths used are put /dna/intent/api/v1/licenses/smartAccount/virtualAccount/deregister, @@ -50,7 +50,6 @@ - string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/license_device_license_details_info.py b/plugins/modules/license_device_license_details_info.py index 965c577e36..0b5dc7050a 100644 --- a/plugins/modules/license_device_license_details_info.py +++ b/plugins/modules/license_device_license_details_info.py @@ -24,15 +24,15 @@ - Device_uuid path parameter. Id of device. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Licenses DeviceLicenseDetails2 - description: Complete reference of the DeviceLicenseDetails2 API. - link: https://developer.cisco.com/docs/dna-center/#!device-license-details-2 +- name: Cisco DNA Center documentation for Licenses DeviceLicenseDetails + description: Complete reference of the DeviceLicenseDetails API. + link: https://developer.cisco.com/docs/dna-center/#!device-license-details notes: - SDK Method used are - licenses.Licenses.device_license_details2, + licenses.Licenses.device_license_details, - Paths used are get /dna/intent/api/v1/licenses/device/{device_uuid}/details, @@ -54,70 +54,66 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK returned: always - type: list - elements: dict + type: dict sample: > - [ - { - "device_uuid": "string", - "site": "string", - "model": "string", - "license_mode": "string", - "is_license_expired": true, - "software_version": "string", - "network_license": "string", - "evaluation_license_expiry": "string", - "device_name": "string", - "device_type": "string", - "dna_level": "string", - "virtual_account_name": "string", - "ip_address": "string", - "mac_address": "string", - "sntc_status": "string", - "feature_license": [ - "string" - ], - "has_sup_cards": true, - "udi": "string", - "stacked_devices": [ + { + "device_uuid": "string", + "site": "string", + "model": "string", + "license_mode": "string", + "is_license_expired": true, + "software_version": "string", + "network_license": "string", + "evaluation_license_expiry": "string", + "device_name": "string", + "device_type": "string", + "dna_level": "string", + "virtual_account_name": "string", + "ip_address": "string", + "mac_address": "string", + "sntc_status": "string", + "feature_license": [ + "string" + ], + "has_sup_cards": true, + "udi": "string", + "stacked_devices": [ + { + "mac_address": "string", + "id": 0, + "role": "string", + "serial_number": "string" + } + ], + "is_stacked_device": true, + "access_points": [ + { + "ap_type": "string", + "count": "string" + } + ], + "chassis_details": { + "board_serial_number": "string", + "modules": [ { - "mac_address": "string", - "id": "string", - "role": "string", - "serial_number": "string" + "module_type": "string", + "module_name": "string", + "serial_number": "string", + "id": 0 } ], - "is_stacked_device": true, - "access_points": [ + "supervisor_cards": [ { - "ap_type": "string", - "count": "string" + "serial_number": "string", + "supervisor_card_type": "string", + "status": "string" } ], - "chassis_details": { - "board_serial_number": "string", - "modules": [ - { - "module_type": "string", - "module_name": "string", - "serial_number": "string", - "id": "string" - } - ], - "supervisor_cards": [ - { - "serial_number": "string", - "supervisor_card_type": "string", - "status": "string" - } - ], - "port": 0 - } + "port": 0 } - ] + } """ diff --git a/plugins/modules/license_device_license_summary_info.py b/plugins/modules/license_device_license_summary_info.py index c2806d39a1..6c6f29f64f 100644 --- a/plugins/modules/license_device_license_summary_info.py +++ b/plugins/modules/license_device_license_summary_info.py @@ -22,7 +22,7 @@ page_number: description: - Page_number query parameter. Page number of response. - type: int + type: float order: description: - Order query parameter. Sorting order. @@ -33,19 +33,22 @@ type: str dna_level: description: - - Dna_level query parameter. Device Cisco DNA license level. + - Dna_level query parameter. Device Cisco DNA license level. The valid values are Advantage, Essentials. type: str device_type: description: - - Device_type query parameter. Type of device. + - Device_type query parameter. Type of device. The valid values are Routers, Switches and Hubs, Wireless Controller. type: str limit: description: - Limit query parameter. - type: int + type: float registration_status: description: - - Registration_status query parameter. Smart license registration status of device. + - > + Registration_status query parameter. Smart license registration status of device. The valid values are + Unknown, NA, Unregistered, Registered, Registration_expired, Reservation_in_progress, Registered_slr, + Registered_plr, Registered_satellite. type: str virtual_account_name: description: @@ -54,21 +57,21 @@ smart_account_id: description: - Smart_account_id query parameter. Id of smart account. - type: int + type: str device_uuid: description: - Device_uuid query parameter. Id of device. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Licenses DeviceLicenseSummary2 - description: Complete reference of the DeviceLicenseSummary2 API. - link: https://developer.cisco.com/docs/dna-center/#!device-license-summary-2 +- name: Cisco DNA Center documentation for Licenses DeviceLicenseSummary + description: Complete reference of the DeviceLicenseSummary API. + link: https://developer.cisco.com/docs/dna-center/#!device-license-summary notes: - SDK Method used are - licenses.Licenses.device_license_summary2, + licenses.Licenses.device_license_summary, - Paths used are get /dna/intent/api/v1/licenses/device/summary, @@ -94,56 +97,57 @@ limit: 0 registration_status: string virtual_account_name: string - smart_account_id: 0 + smart_account_id: string device_uuid: string register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK returned: always - type: list - elements: dict + type: dict sample: > - [ - { - "authorization_status": "string", - "last_updated_time": "string", - "is_performance_allowed": true, - "sle_auth_code": "string", - "throughput_level": "string", - "hsec_status": "string", - "device_uuid": "string", - "site": "string", - "total_access_point_count": 0, - "model": "string", - "is_wireless_capable": true, - "registration_status": "string", - "sle_state": "string", - "performance_license": "string", - "license_mode": "string", - "is_license_expired": true, - "software_version": "string", - "reservation_status": "string", - "is_wireless": true, - "network_license": "string", - "evaluation_license_expiry": "string", - "wireless_capable_network_license": "string", - "device_name": "string", - "device_type": "string", - "dna_level": "string", - "virtual_account_name": "string", - "last_successful_rum_usage_upload_time": "string", - "ip_address": "string", - "wireless_capable_dna_license": "string", - "mac_address": "string", - "customer_tag1": "string", - "customer_tag2": "string", - "customer_tag3": "string", - "customer_tag4": "string", - "smart_account_name": "string" - } - ] + { + "response": [ + { + "authorization_status": "string", + "last_updated_time": "string", + "is_performance_allowed": true, + "sle_auth_code": "string", + "throughput_level": "string", + "hsec_status": "string", + "device_uuid": "string", + "site": "string", + "total_access_point_count": 0, + "model": "string", + "is_wireless_capable": true, + "registration_status": "string", + "sle_state": "string", + "performance_license": "string", + "license_mode": "string", + "is_license_expired": true, + "software_version": "string", + "reservation_status": "string", + "is_wireless": true, + "network_license": "string", + "evaluation_license_expiry": "string", + "wireless_capable_network_license": "string", + "device_name": "string", + "device_type": "string", + "dna_level": "string", + "virtual_account_name": "string", + "last_successful_rum_usage_upload_time": "string", + "ip_address": "string", + "wireless_capable_dna_license": "string", + "mac_address": "string", + "customer_tag1": "string", + "customer_tag2": "string", + "customer_tag3": "string", + "customer_tag4": "string", + "smart_account_name": "string" + } + ], + "version": "string" + } """ diff --git a/plugins/modules/license_device_registration.py b/plugins/modules/license_device_registration.py index de878f7908..19d485aec2 100644 --- a/plugins/modules/license_device_registration.py +++ b/plugins/modules/license_device_registration.py @@ -24,15 +24,15 @@ description: Virtual_account_name path parameter. Name of virtual account. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Licenses DeviceRegistration2 - description: Complete reference of the DeviceRegistration2 API. - link: https://developer.cisco.com/docs/dna-center/#!device-registration-2 +- name: Cisco DNA Center documentation for Licenses DeviceRegistration + description: Complete reference of the DeviceRegistration API. + link: https://developer.cisco.com/docs/dna-center/#!device-registration notes: - SDK Method used are - licenses.Licenses.device_registration2, + licenses.Licenses.device_registration, - Paths used are put /dna/intent/api/v1/licenses/smartAccount/virtualAccount/{virtual_account_name}/register, @@ -54,7 +54,6 @@ virtual_account_name: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/license_smart_account_details_info.py b/plugins/modules/license_smart_account_details_info.py index 70685c2ed3..c0b031bce2 100644 --- a/plugins/modules/license_smart_account_details_info.py +++ b/plugins/modules/license_smart_account_details_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Licenses SmartAccountDetails description: Complete reference of the SmartAccountDetails API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/license_term_details_info.py b/plugins/modules/license_term_details_info.py index d0bf73d4de..04d53b5d2c 100644 --- a/plugins/modules/license_term_details_info.py +++ b/plugins/modules/license_term_details_info.py @@ -34,15 +34,15 @@ - Device_type query parameter. Type of device like router, switch, wireless or ise. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Licenses LicenseTermDetails2 - description: Complete reference of the LicenseTermDetails2 API. - link: https://developer.cisco.com/docs/dna-center/#!license-term-details-2 +- name: Cisco DNA Center documentation for Licenses LicenseTermDetails + description: Complete reference of the LicenseTermDetails API. + link: https://developer.cisco.com/docs/dna-center/#!license-term-details notes: - SDK Method used are - licenses.Licenses.license_term_details2, + licenses.Licenses.license_term_details, - Paths used are get /dna/intent/api/v1/licenses/term/smartAccount/{smart_account_id}/virtualAccount/{virtual_account_name}, @@ -66,7 +66,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/license_usage_details_info.py b/plugins/modules/license_usage_details_info.py index 3fd4d54665..160d4decb2 100644 --- a/plugins/modules/license_usage_details_info.py +++ b/plugins/modules/license_usage_details_info.py @@ -34,15 +34,15 @@ - Device_type query parameter. Type of device like router, switch, wireless or ise. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Licenses LicenseUsageDetails2 - description: Complete reference of the LicenseUsageDetails2 API. - link: https://developer.cisco.com/docs/dna-center/#!license-usage-details-2 +- name: Cisco DNA Center documentation for Licenses LicenseUsageDetails + description: Complete reference of the LicenseUsageDetails API. + link: https://developer.cisco.com/docs/dna-center/#!license-usage-details notes: - SDK Method used are - licenses.Licenses.license_usage_details2, + licenses.Licenses.license_usage_details, - Paths used are get /dna/intent/api/v1/licenses/usage/smartAccount/{smart_account_id}/virtualAccount/{virtual_account_name}, @@ -66,7 +66,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -109,6 +108,24 @@ "license_count": 0 } ] + }, + "purchased_ise_license": { + "total_license_count": 0, + "license_count_by_type": [ + { + "license_type": "string", + "license_count": 0 + } + ] + }, + "used_ise_license": { + "total_license_count": 0, + "license_count_by_type": [ + { + "license_type": "string", + "license_count": 0 + } + ] } } """ diff --git a/plugins/modules/license_virtual_account_change.py b/plugins/modules/license_virtual_account_change.py index 762e015401..fd3a32793a 100644 --- a/plugins/modules/license_virtual_account_change.py +++ b/plugins/modules/license_virtual_account_change.py @@ -27,15 +27,15 @@ description: Virtual_account_name path parameter. Name of target virtual account. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Licenses ChangeVirtualAccount2 - description: Complete reference of the ChangeVirtualAccount2 API. - link: https://developer.cisco.com/docs/dna-center/#!change-virtual-account-2 +- name: Cisco DNA Center documentation for Licenses ChangeVirtualAccount + description: Complete reference of the ChangeVirtualAccount API. + link: https://developer.cisco.com/docs/dna-center/#!change-virtual-account notes: - SDK Method used are - licenses.Licenses.change_virtual_account2, + licenses.Licenses.change_virtual_account, - Paths used are post /dna/intent/api/v1/licenses/smartAccount/{smart_account_id}/virtualAccount/{virtual_account_name}/device/transfer, @@ -58,7 +58,6 @@ virtual_account_name: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/license_virtual_account_details_info.py b/plugins/modules/license_virtual_account_details_info.py index 72a2f1041a..73e9e9b26d 100644 --- a/plugins/modules/license_virtual_account_details_info.py +++ b/plugins/modules/license_virtual_account_details_info.py @@ -24,15 +24,15 @@ - Smart_account_id path parameter. Id of smart account. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Licenses VirtualAccountDetails2 - description: Complete reference of the VirtualAccountDetails2 API. - link: https://developer.cisco.com/docs/dna-center/#!virtual-account-details-2 +- name: Cisco DNA Center documentation for Licenses VirtualAccountDetails + description: Complete reference of the VirtualAccountDetails API. + link: https://developer.cisco.com/docs/dna-center/#!virtual-account-details notes: - SDK Method used are - licenses.Licenses.virtual_account_details2, + licenses.Licenses.virtual_account_details, - Paths used are get /dna/intent/api/v1/licenses/smartAccount/{smart_account_id}/virtualAccounts, @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/maps_export.py b/plugins/modules/maps_export.py new file mode 100644 index 0000000000..59301d0706 --- /dev/null +++ b/plugins/modules/maps_export.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: maps_export +short_description: Resource module for Maps Export +description: +- Manage operation create of the resource Maps Export. +- Allows exporting a Map archive in an XML interchange format along with the associated images. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + siteHierarchyUuid: + description: SiteHierarchyUuid path parameter. The site hierarchy element UUID to + export, all child elements starting at this hierarchy element will be included. + Limited to a hierarchy that contains 500 or fewer maps. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Sites ExportMapArchive + description: Complete reference of the ExportMapArchive API. + link: https://developer.cisco.com/docs/dna-center/#!export-map-archive +notes: + - SDK Method used are + sites.Sites.export_map_archive, + + - Paths used are + post /dna/intent/api/v1/maps/export/{siteHierarchyUuid}, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.maps_export: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + siteHierarchyUuid: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/maps_import.py b/plugins/modules/maps_import.py new file mode 100644 index 0000000000..4da87d4617 --- /dev/null +++ b/plugins/modules/maps_import.py @@ -0,0 +1,61 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: maps_import +short_description: Resource module for Maps Import +description: +- Manage operation delete of the resource Maps Import. +- > + Cancels a previously initatied import, allowing the system to cleanup cached resources about that import data, and + ensures the import cannot accidentally be performed / approved at a later time. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + importContextUuid: + description: ImportContextUuid path parameter. The unique import context UUID given + by a previous call to Start Import API. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Sites ImportMapArchiveCancelAnImport + description: Complete reference of the ImportMapArchiveCancelAnImport API. + link: https://developer.cisco.com/docs/dna-center/#!import-map-archive-cancel-an-import +notes: + - SDK Method used are + sites.Sites.import_map_archive_cancel_an_import, + + - Paths used are + delete /dna/intent/api/v1/maps/import/{importContextUuid}, + +""" + +EXAMPLES = r""" +- name: Delete by id + cisco.dnac.maps_import: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + importContextUuid: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + {} +""" diff --git a/plugins/modules/maps_import_perform.py b/plugins/modules/maps_import_perform.py new file mode 100644 index 0000000000..e3a0c13362 --- /dev/null +++ b/plugins/modules/maps_import_perform.py @@ -0,0 +1,63 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: maps_import_perform +short_description: Resource module for Maps Import Perform +description: +- Manage operation create of the resource Maps Import Perform. +- > + For a previously initatied import, approves the import to be performed, accepting that data loss may occur. A Map + import will fully replace existing Maps data for the sites defined in the archive. The Map Archive Import Status + API /maps/import/${contextUuid}/status should always be checked to validate the pre-import validation output prior + to performing the import. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + importContextUuid: + description: ImportContextUuid path parameter. The unique import context UUID given + by a previous call of Start Import API. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Sites ImportMapArchivePerformImport + description: Complete reference of the ImportMapArchivePerformImport API. + link: https://developer.cisco.com/docs/dna-center/#!import-map-archive-perform-import +notes: + - SDK Method used are + sites.Sites.import_map_archive_perform_import, + + - Paths used are + post /dna/intent/api/v1/maps/import/{importContextUuid}/perform, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.maps_import_perform: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + importContextUuid: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + {} +""" diff --git a/plugins/modules/maps_import_start.py b/plugins/modules/maps_import_start.py new file mode 100644 index 0000000000..3cca05d170 --- /dev/null +++ b/plugins/modules/maps_import_start.py @@ -0,0 +1,56 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: maps_import_start +short_description: Resource module for Maps Import Start +description: +- Manage operation create of the resource Maps Import Start. +- > + Initiates a map archive import of a tar.gz file. The archive must consist of one xmlDir/MapsImportExport.xml map + descriptor file, and 1 or more images for the map areas nested under /images folder. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: {} +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Sites ImportMapArchiveStartImport + description: Complete reference of the ImportMapArchiveStartImport API. + link: https://developer.cisco.com/docs/dna-center/#!import-map-archive-start-import +notes: + - SDK Method used are + sites.Sites.import_map_archive_start_import, + + - Paths used are + post /dna/intent/api/v1/maps/import/start, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.maps_import_start: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: str + sample: > + "'string'" +""" diff --git a/plugins/modules/maps_import_status_info.py b/plugins/modules/maps_import_status_info.py new file mode 100644 index 0000000000..c8004add60 --- /dev/null +++ b/plugins/modules/maps_import_status_info.py @@ -0,0 +1,117 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: maps_import_status_info +short_description: Information module for Maps Import Status +description: +- Get all Maps Import Status. +- > + Gets the status of a map archive import operation. For a map archive import that has just been initiated, will + provide the result of validation of the archive and a pre-import preview of what will be performed if the import + is performed. Once an import is requested to be performed, this API will give the status of the import and upon + completion a post-import summary of what was performed by the operation. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + importContextUuid: + description: + - > + ImportContextUuid path parameter. The unique import context UUID given by a previous and recent call to + maps/import/start API. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Sites ImportMapArchiveImportStatus + description: Complete reference of the ImportMapArchiveImportStatus API. + link: https://developer.cisco.com/docs/dna-center/#!import-map-archive-import-status +notes: + - SDK Method used are + sites.Sites.import_map_archive_import_status, + + - Paths used are + get /dna/intent/api/v1/maps/import/{importContextUuid}/status, + +""" + +EXAMPLES = r""" +- name: Get all Maps Import Status + cisco.dnac.maps_import_status_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + importContextUuid: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "auditLog": { + "children": [ + {} + ], + "entitiesCount": [ + { + "key": 0 + } + ], + "entityName": "string", + "entityType": "string", + "errorEntitiesCount": [ + { + "key": 0 + } + ], + "errors": [ + { + "message": "string" + } + ], + "infos": [ + { + "message": "string" + } + ], + "matchingEntitiesCount": [ + { + "key": 0 + } + ], + "subTasksRootTaskId": "string", + "successfullyImportedFloors": [ + "string" + ], + "warnings": [ + { + "message": "string" + } + ] + }, + "status": "string", + "uuid": { + "leastSignificantBits": 0, + "mostSignificantBits": 0 + } + } +""" diff --git a/plugins/modules/maps_supported_access_points_info.py b/plugins/modules/maps_supported_access_points_info.py new file mode 100644 index 0000000000..0e535f65a9 --- /dev/null +++ b/plugins/modules/maps_supported_access_points_info.py @@ -0,0 +1,72 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: maps_supported_access_points_info +short_description: Information module for Maps Supported Access Points +description: +- Get all Maps Supported Access Points. +- Gets the list of supported access point types as well as valid antenna pattern names that can be used for each. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Sites MapsSupportedAccessPoints + description: Complete reference of the MapsSupportedAccessPoints API. + link: https://developer.cisco.com/docs/dna-center/#!maps-supported-access-points +notes: + - SDK Method used are + sites.Sites.maps_supported_access_points, + + - Paths used are + get /dna/intent/api/v1/maps/supported-access-points, + +""" + +EXAMPLES = r""" +- name: Get all Maps Supported Access Points + cisco.dnac.maps_supported_access_points_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: list + elements: dict + sample: > + [ + { + "antennaPatterns": [ + { + "band": "string", + "names": [ + "string" + ] + } + ], + "apType": "string" + } + ] +""" diff --git a/plugins/modules/netconf_credential.py b/plugins/modules/netconf_credential.py index d75908aa6f..8551a1cb61 100644 --- a/plugins/modules/netconf_credential.py +++ b/plugins/modules/netconf_credential.py @@ -18,29 +18,30 @@ author: Rafael Campos (@racampos) options: comments: - description: Netconf Credential's comments. + description: Comments to identify the netconf credential. type: str credentialType: - description: Netconf Credential's credentialType. + description: Credential type to identify the application that uses the netconf credential. type: str description: - description: Netconf Credential's description. + description: Description for Netconf Credentials. type: str id: - description: Netconf Credential's id. + description: Id of the Netconf Credential in UUID format. type: str instanceTenantId: - description: Netconf Credential's instanceTenantId. + description: Deprecated. type: str instanceUuid: - description: Netconf Credential's instanceUuid. + description: Deprecated. type: str netconfPort: - description: Netconf Credential's netconfPort. + description: Netconf port on the device. Valid port should be in the range of 1 + to 65535. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery CreateNetconfCredentials description: Complete reference of the CreateNetconfCredentials API. @@ -98,7 +99,6 @@ netconfPort: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_create.py b/plugins/modules/network_create.py index 8bf553aba0..e747dc2340 100644 --- a/plugins/modules/network_create.py +++ b/plugins/modules/network_create.py @@ -78,7 +78,7 @@ type: str port: description: Port for NetFlow Collector (eg; 443). - type: int + type: float type: dict network_aaa: description: Network Create's network_aaa. @@ -134,8 +134,8 @@ the network settings. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings CreateNetwork description: Complete reference of the CreateNetwork API. @@ -199,7 +199,6 @@ siteId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device.py b/plugins/modules/network_device.py index 2fca16035c..f9693da44e 100644 --- a/plugins/modules/network_device.py +++ b/plugins/modules/network_device.py @@ -12,7 +12,9 @@ - Manage operations create, update and delete of the resource Network Device. - Adds the device with given credential. - Deletes the network device for the given Id. -- Sync the devices provided as input. +- > + Update the credentials, management IP address of a given device or a set of devices in Catalyst Center and trigger + an inventory sync. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module @@ -23,102 +25,106 @@ type: bool version_added: 4.0.0 cliTransport: - description: Network Device's cliTransport. + description: CLI transport. Supported values telnet, ssh2. type: str computeDevice: - description: ComputeDevice flag. + description: Compute Device or not. Options are TRUE / FALSE. type: bool enablePassword: - description: Network Device's enablePassword. + description: CLI enable password of the device. type: str extendedDiscoveryInfo: - description: Network Device's extendedDiscoveryInfo. + description: This field holds that info as whether to add device with canned data + or not. Supported values DISCOVER_WITH_CANNED_DATA. type: str httpPassword: - description: Network Device's httpPassword. + description: HTTP password of the device. type: str httpPort: - description: Network Device's httpPort. + description: HTTP port of the device. type: str httpSecure: - description: HttpSecure flag. + description: Flag to select HTTP / HTTPS protocol. Options are TRUE / FALSE. TRUE + for HTTPS and FALSE for HTTP. type: bool httpUserName: - description: Network Device's httpUserName. + description: HTTP Username of the device. type: str id: description: Id path parameter. Device ID. type: str ipAddress: - description: Network Device's ipAddress. + description: IP Address of the device. elements: str type: list merakiOrgId: - description: Network Device's merakiOrgId. + description: Selected meraki organization for which the devices needs to be imported. elements: str type: list netconfPort: - description: Network Device's netconfPort. + description: Netconf Port of the device. type: str password: - description: Network Device's password. + description: CLI Password of the device. type: str serialNumber: - description: Network Device's serialNumber. + description: Serial Number of the Device. type: str snmpAuthPassphrase: - description: Network Device's snmpAuthPassphrase. + description: SNMPV3 auth passphrase of the device. type: str snmpAuthProtocol: - description: Network Device's snmpAuthProtocol. + description: SNMPV3 auth protocol. Supported values sha, md5. type: str snmpMode: - description: Network Device's snmpMode. + description: SNMPV3 mode. Supported values noAuthnoPriv, authNoPriv, authPriv. type: str snmpPrivPassphrase: - description: Network Device's snmpPrivPassphrase. + description: SNMPV3 priv passphrase. type: str snmpPrivProtocol: - description: Network Device's snmpPrivProtocol. + description: SNMPV3 priv protocol. Supported values AES128. type: str snmpROCommunity: - description: Network Device's snmpROCommunity. + description: SNMP Read Community of the device. type: str snmpRWCommunity: - description: Network Device's snmpRWCommunity. + description: SNMP Write Community of the device. type: str snmpRetry: - description: Network Device's snmpRetry. + description: SNMP retry count. Max value supported is 3. Default is Global SNMP + retry (if exists) or 3. type: int snmpTimeout: - description: Network Device's snmpTimeout. + description: SNMP timeout in seconds. Max value supported is 300. Default is Global + SNMP timeout (if exists) or 5. type: int snmpUserName: - description: Network Device's snmpUserName. + description: SNMPV3 user name of the device. type: str snmpVersion: - description: Network Device's snmpVersion. + description: SNMP version. Values supported v2, v3. Default is v2. type: str type: - description: Network Device's type. + description: Type of device being added. type: str updateMgmtIPaddressList: description: Network Device's updateMgmtIPaddressList. elements: dict suboptions: existMgmtIpAddress: - description: Network Device's existMgmtIpAddress. + description: ExistMgmtIpAddress IP Address of the device. type: str newMgmtIpAddress: - description: Network Device's newMgmtIpAddress. + description: New IP Address to be Updated. type: str type: list userName: - description: Network Device's userName. + description: CLI user name of the device. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices AddDevice2 description: Complete reference of the AddDevice2 API. @@ -126,9 +132,9 @@ - name: Cisco DNA Center documentation for Devices DeleteDeviceById description: Complete reference of the DeleteDeviceById API. link: https://developer.cisco.com/docs/dna-center/#!delete-device-by-id -- name: Cisco DNA Center documentation for Devices SyncDevices2 - description: Complete reference of the SyncDevices2 API. - link: https://developer.cisco.com/docs/dna-center/#!sync-devices +- name: Cisco DNA Center documentation for Devices UpdateDeviceDetails + description: Complete reference of the UpdateDeviceDetails API. + link: https://developer.cisco.com/docs/dna-center/#!update-device-details notes: - SDK Method used are devices.Devices.add_device, @@ -181,9 +187,6 @@ snmpUserName: string snmpVersion: string type: string - updateMgmtIPaddressList: - - existMgmtIpAddress: string - newMgmtIpAddress: string userName: string - name: Update all @@ -242,7 +245,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_by_ip_info.py b/plugins/modules/network_device_by_ip_info.py index 502db8ba4d..c9206c301c 100644 --- a/plugins/modules/network_device_by_ip_info.py +++ b/plugins/modules/network_device_by_ip_info.py @@ -24,8 +24,8 @@ - IpAddress path parameter. Device IP address. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetNetworkDeviceByIP description: Complete reference of the GetNetworkDeviceByIP API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -101,7 +100,19 @@ "tunnelUdpPort": "string", "type": "string", "upTime": "string", - "waasDeviceMode": "string" + "waasDeviceMode": "string", + "dnsResolvedManagementAddress": "string", + "apEthernetMacAddress": "string", + "vendor": "string", + "reasonsForPendingSyncRequests": "string", + "pendingSyncRequestsCount": "string", + "reasonsForDeviceResync": "string", + "lastDeviceResyncStartTime": "string", + "uptimeSeconds": 0, + "managedAtleastOnce": true, + "deviceSupportLevel": "string", + "managementState": "string", + "description": "string" }, "version": "string" } diff --git a/plugins/modules/network_device_by_serial_number_info.py b/plugins/modules/network_device_by_serial_number_info.py index d40497b17c..69e4d249ac 100644 --- a/plugins/modules/network_device_by_serial_number_info.py +++ b/plugins/modules/network_device_by_serial_number_info.py @@ -10,7 +10,7 @@ short_description: Information module for Network Device By Serial Number description: - Get Network Device By Serial Number by id. -- Returns the network device if the given serial number matches with any of the serial numbers collected. +- Returns the network device with given serial number. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -24,8 +24,8 @@ - SerialNumber path parameter. Device serial number. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDeviceBySerialNumber description: Complete reference of the GetDeviceBySerialNumber API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -101,7 +100,19 @@ "tunnelUdpPort": "string", "type": "string", "upTime": "string", - "waasDeviceMode": "string" + "waasDeviceMode": "string", + "dnsResolvedManagementAddress": "string", + "apEthernetMacAddress": "string", + "vendor": "string", + "reasonsForPendingSyncRequests": "string", + "pendingSyncRequestsCount": "string", + "reasonsForDeviceResync": "string", + "lastDeviceResyncStartTime": "string", + "uptimeSeconds": 0, + "managedAtleastOnce": true, + "deviceSupportLevel": "string", + "managementState": "string", + "description": "string" }, "version": "string" } diff --git a/plugins/modules/network_device_chassis_details_info.py b/plugins/modules/network_device_chassis_details_info.py index c5b34a498b..d8fdb938fa 100644 --- a/plugins/modules/network_device_chassis_details_info.py +++ b/plugins/modules/network_device_chassis_details_info.py @@ -24,8 +24,8 @@ - DeviceId path parameter. Device ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetChassisDetailsForDevice description: Complete reference of the GetChassisDetailsForDevice API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_config__info.py b/plugins/modules/network_device_config__info.py new file mode 100644 index 0000000000..ab41a0acac --- /dev/null +++ b/plugins/modules/network_device_config__info.py @@ -0,0 +1,135 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: network_device_config__info +short_description: Information module for Network Device Config +description: +- Get all Network Device Config . +- > + Returns the historical device configurations running configuration , startup configuration , vlan if applicable by + specified criteria. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + deviceId: + description: + - > + DeviceId query parameter. Comma separated device id for example + cf35b0a1-407f-412f-b2f4-f0c3156695f9,aaa38191-0c22-4158-befd-779a09d7cec1. If device id is not provided it + will fetch for all devices. + type: str + fileType: + description: + - FileType query parameter. Config File Type can be RUNNINGCONFIG or STARTUPCONFIG. + type: str + createdTime: + description: + - CreatedTime query parameter. Supported with logical filters GT,GTE,LT,LTE & BT time in milliseconds (epoc format). + type: str + createdBy: + description: + - > + CreatedBy query parameter. Comma separated values for createdBy - SCHEDULED, USER, CONFIG_CHANGE_EVENT, + SCHEDULED_FIRST_TIME, DR_CALL_BACK, PRE_DEPLOY. + type: str + offset: + description: + - Offset query parameter. + type: float + limit: + description: + - Limit query parameter. + type: float +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Configuration Archive GetConfigurationArchiveDetails + description: Complete reference of the GetConfigurationArchiveDetails API. + link: https://developer.cisco.com/docs/dna-center/#!get-configuration-archive-details +notes: + - SDK Method used are + configuration_archive.ConfigurationArchive.get_configuration_archive_details, + + - Paths used are + get /dna/intent/api/v1/network-device-config, + +""" + +EXAMPLES = r""" +- name: Get all Network Device Config + cisco.dnac.network_device_config__info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + deviceId: string + fileType: string + createdTime: string + createdBy: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: list + elements: dict + sample: > + [ + { + "ipAddress": "string", + "deviceId": "string", + "versions": [ + { + "files": [ + { + "fileType": "string", + "fileId": "string", + "downloadPath": "string" + } + ], + "createdBy": "string", + "configChangeType": "string", + "syslogConfigEventDto": [ + { + "userName": "string", + "deviceUuid": "string", + "outOfBand": true, + "configMethod": "string", + "terminalName": "string", + "loginIpAddress": "string", + "processName": "string", + "syslogTime": 0 + } + ], + "createdTime": 0, + "startupRunningStatus": "string", + "id": "string", + "tags": [ + "string" + ], + "lastUpdatedTime": 0 + } + ], + "deviceName": "string" + } + ] +""" diff --git a/plugins/modules/network_device_config_count_info.py b/plugins/modules/network_device_config_count_info.py index 3d2c900b06..9e11e98671 100644 --- a/plugins/modules/network_device_config_count_info.py +++ b/plugins/modules/network_device_config_count_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDeviceConfigCount description: Complete reference of the GetDeviceConfigCount API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_config_info.py b/plugins/modules/network_device_config_info.py index 6810fd6db0..751e2e598a 100644 --- a/plugins/modules/network_device_config_info.py +++ b/plugins/modules/network_device_config_info.py @@ -11,7 +11,9 @@ description: - Get all Network Device Config. - Get Network Device Config by id. -- Returns the config for all devices. +- > + Returns the config for all devices. This API has been deprecated and will not be available in a Cisco Catalyst + Center release after Nov 1st 2024 23 59 59 GMT. - Returns the device config by specified device ID. version_added: '3.1.0' extends_documentation_fragment: @@ -26,8 +28,8 @@ - NetworkDeviceId path parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDeviceConfigById description: Complete reference of the GetDeviceConfigById API. @@ -73,7 +75,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_config_task_info.py b/plugins/modules/network_device_config_task_info.py new file mode 100644 index 0000000000..3a993da10c --- /dev/null +++ b/plugins/modules/network_device_config_task_info.py @@ -0,0 +1,82 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: network_device_config_task_info +short_description: Information module for Network Device Config Task +description: +- Get all Network Device Config Task. +- Returns a config task result details by specified id. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + parentTaskId: + description: + - ParentTaskId query parameter. Task Id. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Configuration Archive GetConfigTaskDetails + description: Complete reference of the GetConfigTaskDetails API. + link: https://developer.cisco.com/docs/dna-center/#!get-config-task-details +notes: + - SDK Method used are + configuration_archive.ConfigurationArchive.get_config_task_details, + + - Paths used are + get /dna/intent/api/v1/network-device-config/task, + +""" + +EXAMPLES = r""" +- name: Get all Network Device Config Task + cisco.dnac.network_device_config_task_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + parentTaskId: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "version": "string", + "response": [ + { + "startTime": 0, + "errorCode": "string", + "deviceId": "string", + "taskId": "string", + "taskStatus": "string", + "parentTaskId": "string", + "deviceIpAddress": "string", + "detailMessage": "string", + "failureMessage": "string", + "taskType": "string", + "completionTime": 0, + "hostName": "string" + } + ] + } +""" diff --git a/plugins/modules/network_device_config_write_memory.py b/plugins/modules/network_device_config_write_memory.py new file mode 100644 index 0000000000..966f0c41db --- /dev/null +++ b/plugins/modules/network_device_config_write_memory.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: network_device_config_write_memory +short_description: Resource module for Network Device Config Write Memory +description: +- Manage operation create of the resource Network Device Config Write Memory. +- This operation would commit device running configuration to startup by issuing "write memory" to device. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + deviceId: + description: UUID of the device. + elements: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Configuration Archive CommitDeviceConfiguration + description: Complete reference of the CommitDeviceConfiguration API. + link: https://developer.cisco.com/docs/dna-center/#!commit-device-configuration +notes: + - SDK Method used are + configuration_archive.ConfigurationArchive.commit_device_configuration, + + - Paths used are + post /dna/intent/api/v1/network-device-config/write-memory, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.network_device_config_write_memory: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + deviceId: + - string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "version": "string", + "response": { + "url": "string", + "taskId": "string" + } + } +""" diff --git a/plugins/modules/network_device_count_info.py b/plugins/modules/network_device_count_info.py index cdcf87b7cc..eca9dcaf8e 100644 --- a/plugins/modules/network_device_count_info.py +++ b/plugins/modules/network_device_count_info.py @@ -27,16 +27,36 @@ description: - DeviceId path parameter. Device ID. type: str + hostname: + description: + - Hostname query parameter. + elements: str + type: list + managementIpAddress: + description: + - ManagementIpAddress query parameter. + elements: str + type: list + macAddress: + description: + - MacAddress query parameter. + elements: str + type: list + locationName: + description: + - LocationName query parameter. + elements: str + type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDeviceCount2 description: Complete reference of the GetDeviceCount2 API. link: https://developer.cisco.com/docs/dna-center/#!get-device-count -- name: Cisco DNA Center documentation for Devices GetDeviceInterfaceCount2 - description: Complete reference of the GetDeviceInterfaceCount2 API. - link: https://developer.cisco.com/docs/dna-center/#!get-device-interface-count-2 +- name: Cisco DNA Center documentation for Devices GetDeviceInterfaceCount + description: Complete reference of the GetDeviceInterfaceCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-device-interface-count notes: - SDK Method used are devices.Devices.get_device_count, @@ -59,6 +79,10 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" headers: "{{my_headers | from_json}}" + hostname: [] + managementIpAddress: [] + macAddress: [] + locationName: [] register: result - name: Get Network Device Count by id @@ -75,7 +99,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_custom_prompt.py b/plugins/modules/network_device_custom_prompt.py index 38fbc4eaa5..5a69ba5b07 100644 --- a/plugins/modules/network_device_custom_prompt.py +++ b/plugins/modules/network_device_custom_prompt.py @@ -11,7 +11,7 @@ description: - Manage operation create of the resource Network Device Custom Prompt. - > - Save custom prompt added by user in Cisco DNA Center. API will always override the existing prompts. User should + Save custom prompt added by user in Catalyst Center. API will always override the existing prompts. User should provide all the custom prompt in case of any update. version_added: '6.0.0' extends_documentation_fragment: @@ -19,21 +19,21 @@ author: Rafael Campos (@racampos) options: passwordPrompt: - description: Password Prompt. + description: Password for Custom Prompt. type: str usernamePrompt: - description: Username Prompt. + description: Username for Custom Prompt. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for System Settings CustomPromptPOSTAPI description: Complete reference of the CustomPromptPOSTAPI API. link: https://developer.cisco.com/docs/dna-center/#!custom-prompt-postapi notes: - SDK Method used are - system_settings.SystemSettings.custom_prompt_post_api, + system_settings.SystemSettings.custom_prompt_p_o_s_t_api, - Paths used are post /dna/intent/api/v1/network-device/custom-prompt, @@ -54,7 +54,6 @@ usernamePrompt: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_custom_prompt_info.py b/plugins/modules/network_device_custom_prompt_info.py index cd3d02bdd0..06f247d00b 100644 --- a/plugins/modules/network_device_custom_prompt_info.py +++ b/plugins/modules/network_device_custom_prompt_info.py @@ -6,11 +6,11 @@ DOCUMENTATION = r""" --- -module: network_device_custom_prompt_info +module: network_device_custom_prompt_info_info short_description: Information module for Network Device Custom Prompt Info description: - Get all Network Device Custom Prompt Info. -- Returns supported custom prompts by Cisco DNA Center. +- Returns supported custom prompts by Catalyst Center. version_added: '6.0.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -20,15 +20,15 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for System Settings CustomPromptSupportGETAPI description: Complete reference of the CustomPromptSupportGETAPI API. link: https://developer.cisco.com/docs/dna-center/#!custom-prompt-support-getapi notes: - SDK Method used are - system_settings.SystemSettings.custom_prompt_support_get_api, + system_settings.SystemSettings.custom_prompt_support_g_e_t_api, - Paths used are get /dna/intent/api/v1/network-device/custom-prompt, @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_equipment_info.py b/plugins/modules/network_device_equipment_info.py index 7bc3a67334..86e5c4f89c 100644 --- a/plugins/modules/network_device_equipment_info.py +++ b/plugins/modules/network_device_equipment_info.py @@ -10,7 +10,9 @@ short_description: Information module for Network Device Equipment description: - Get all Network Device Equipment. -- Return PowerSupply/ Fan details for the Given device. +- > + Return all types of equipment details like PowerSupply, Fan, Chassis, Backplane, Module, PROCESSOR, Other and SFP + for the Given device. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -30,15 +32,15 @@ If no type is mentioned, All equipments are fetched for the device. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Devices ReturnPowerSupplyFanDetailsForTheGivenDevice - description: Complete reference of the ReturnPowerSupplyFanDetailsForTheGivenDevice API. - link: https://developer.cisco.com/docs/dna-center/#!return-power-supply-fan-details-for-the-given-device +- name: Cisco DNA Center documentation for Devices GetTheDetailsOfPhysicalComponentsOfTheGivenDevice + description: Complete reference of the GetTheDetailsOfPhysicalComponentsOfTheGivenDevice API. + link: https://developer.cisco.com/docs/dna-center/#!get-the-details-of-physical-components-of-the-given-device notes: - SDK Method used are - devices.Devices.return_power_supply_fan_details_for_the_given_device, + devices.Devices.get_the_details_of_physical_components_of_the_given_device, - Paths used are get /dna/intent/api/v1/network-device/{deviceUuid}/equipment, @@ -61,7 +63,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -77,7 +78,8 @@ "vendorEquipmentType": "string", "description": "string", "instanceUuid": "string", - "name": "string" + "name": "string", + "manufacturer": "string" } ], "version": "string" diff --git a/plugins/modules/network_device_export.py b/plugins/modules/network_device_export.py index c1bf8d245d..15d9a981c6 100644 --- a/plugins/modules/network_device_export.py +++ b/plugins/modules/network_device_export.py @@ -17,25 +17,22 @@ author: Rafael Campos (@racampos) options: deviceUuids: - description: Network Device Export's deviceUuids. + description: List of device uuids. elements: str type: list - id: - description: Network Device Export's id. - type: str operationEnum: - description: Network Device Export's operationEnum. + description: 0 to export Device Credential Details Or 1 to export Device Details. type: str parameters: - description: Network Device Export's parameters. + description: List of device parameters that needs to be exported to file. elements: str type: list password: - description: Network Device Export's password. + description: Password is required when the operationEnum value is 0. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices ExportDeviceList description: Complete reference of the ExportDeviceList API. @@ -61,14 +58,12 @@ dnac_debug: "{{dnac_debug}}" deviceUuids: - string - id: string operationEnum: string parameters: - string password: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_functional_capability_info.py b/plugins/modules/network_device_functional_capability_info.py index 1d88047ab9..213f6a32e6 100644 --- a/plugins/modules/network_device_functional_capability_info.py +++ b/plugins/modules/network_device_functional_capability_info.py @@ -29,7 +29,7 @@ type: str functionName: description: - - FunctionName query parameter. + - FunctionName query parameter. elements: str type: list id: @@ -37,8 +37,8 @@ - Id path parameter. Functional Capability UUID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetFunctionalCapabilityById description: Complete reference of the GetFunctionalCapabilityById API. @@ -86,7 +86,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_global_polling_interval_info.py b/plugins/modules/network_device_global_polling_interval_info.py index 41bced4d18..8754fa5573 100644 --- a/plugins/modules/network_device_global_polling_interval_info.py +++ b/plugins/modules/network_device_global_polling_interval_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetPollingIntervalForAllDevices description: Complete reference of the GetPollingIntervalForAllDevices API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_info.py b/plugins/modules/network_device_info.py index 7dae65a3f0..3bbbb1f9ce 100644 --- a/plugins/modules/network_device_info.py +++ b/plugins/modules/network_device_info.py @@ -113,17 +113,17 @@ type: list reachabilityStatus: description: - - ReachabilityStatus query parameter. + - ReachabilityStatus query parameter. elements: str type: list upTime: description: - - UpTime query parameter. + - UpTime query parameter. elements: str type: list associatedWlcIp: description: - - AssociatedWlcIp query parameter. + - AssociatedWlcIp query parameter. elements: str type: list license_name: @@ -190,8 +190,8 @@ - Limit query parameter. 1 <= limit <= 500 max. No. Of devices to be returned in the result. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDeviceByID description: Complete reference of the GetDeviceByID API. @@ -271,7 +271,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -318,7 +317,19 @@ "tunnelUdpPort": "string", "type": "string", "upTime": "string", - "waasDeviceMode": "string" + "waasDeviceMode": "string", + "dnsResolvedManagementAddress": "string", + "apEthernetMacAddress": "string", + "vendor": "string", + "reasonsForPendingSyncRequests": "string", + "pendingSyncRequestsCount": "string", + "reasonsForDeviceResync": "string", + "lastDeviceResyncStartTime": "string", + "uptimeSeconds": 0, + "managedAtleastOnce": true, + "deviceSupportLevel": "string", + "managementState": "string", + "description": "string" }, "version": "string" } diff --git a/plugins/modules/network_device_insight_device_link_info.py b/plugins/modules/network_device_insight_device_link_info.py new file mode 100644 index 0000000000..967b6ef472 --- /dev/null +++ b/plugins/modules/network_device_insight_device_link_info.py @@ -0,0 +1,126 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: network_device_insight_device_link_info +short_description: Information module for Network Device Insight Device Link +description: +- Get all Network Device Insight Device Link. +- Find all devices with link mismatch speed / vlan . +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + siteId: + description: + - SiteId path parameter. + type: str + offset: + description: + - Offset query parameter. Row Number. Default value is 1. + type: int + limit: + description: + - Limit query parameter. Default value is 500. + type: int + category: + description: + - Category query parameter. Links mismatch category. Value can be speed-duplex or vlan. + type: str + sortBy: + description: + - SortBy query parameter. Sort By. + type: str + order: + description: + - Order query parameter. Order. Value can be asc or desc. Default value is asc. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Devices InventoryInsightDeviceLinkMismatch + description: Complete reference of the InventoryInsightDeviceLinkMismatch API. + link: https://developer.cisco.com/docs/dna-center/#!inventory-insight-device-link-mismatch +notes: + - SDK Method used are + devices.Devices.inventory_insight_device_link_mismatch, + + - Paths used are + get /dna/intent/api/v1/network-device/insight/{siteId}/device-link, + +""" + +EXAMPLES = r""" +- name: Get all Network Device Insight Device Link + cisco.dnac.network_device_insight_device_link_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + offset: 0 + limit: 0 + category: string + sortBy: string + order: string + siteId: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "endPortAllowedVlanIds": "string", + "endPortNativeVlanId": "string", + "startPortAllowedVlanIds": "string", + "startPortNativeVlanId": "string", + "linkStatus": "string", + "endDeviceHostName": "string", + "endDeviceId": "string", + "endDeviceIpAddress": "string", + "endPortAddress": "string", + "endPortDuplex": "string", + "endPortId": "string", + "endPortMask": "string", + "endPortName": "string", + "endPortPepId": "string", + "endPortSpeed": "string", + "startDeviceHostName": "string", + "startDeviceId": "string", + "startDeviceIpAddress": "string", + "startPortAddress": "string", + "startPortDuplex": "string", + "startPortId": "string", + "startPortMask": "string", + "startPortName": "string", + "startPortPepId": "string", + "startPortSpeed": "string", + "lastUpdated": "string", + "numUpdates": 0, + "avgUpdateFrequency": 0, + "type": "string", + "instanceUuid": "string", + "instanceTenantId": "string" + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/network_device_interface_neighbor_info.py b/plugins/modules/network_device_interface_neighbor_info.py index da4550a9e2..dd0103517a 100644 --- a/plugins/modules/network_device_interface_neighbor_info.py +++ b/plugins/modules/network_device_interface_neighbor_info.py @@ -28,8 +28,8 @@ - InterfaceUuid path parameter. Instanceuuid of interface. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetConnectedDeviceDetail description: Complete reference of the GetConnectedDeviceDetail API. @@ -59,7 +59,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_interface_poe_info.py b/plugins/modules/network_device_interface_poe_info.py index 2c525456f6..4035da3a8f 100644 --- a/plugins/modules/network_device_interface_poe_info.py +++ b/plugins/modules/network_device_interface_poe_info.py @@ -31,8 +31,8 @@ - InterfaceNameList query parameter. Comma seperated interface names. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices ReturnsPOEInterfaceDetailsForTheDevice description: Complete reference of the ReturnsPOEInterfaceDetailsForTheDevice API. @@ -62,7 +62,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_inventory_insight_link_mismatch_info.py b/plugins/modules/network_device_inventory_insight_link_mismatch_info.py index ee282e771a..82b97fc2d0 100644 --- a/plugins/modules/network_device_inventory_insight_link_mismatch_info.py +++ b/plugins/modules/network_device_inventory_insight_link_mismatch_info.py @@ -44,8 +44,8 @@ - Order query parameter. Order. Value can be asc or desc. Default value is asc. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices InventoryInsightDeviceLinkMismatchAPI description: Complete reference of the InventoryInsightDeviceLinkMismatchAPI API. @@ -79,7 +79,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_ip_address_info.py b/plugins/modules/network_device_ip_address_info.py new file mode 100644 index 0000000000..be09615276 --- /dev/null +++ b/plugins/modules/network_device_ip_address_info.py @@ -0,0 +1,119 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: network_device_ip_address_info +short_description: Information module for Network Device Ip Address +description: +- Get Network Device Ip Address by id. +- Returns the network device by specified IP address. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + ipAddress: + description: + - IpAddress path parameter. Device IP address. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Devices GetNetworkDeviceByIP + description: Complete reference of the GetNetworkDeviceByIP API. + link: https://developer.cisco.com/docs/dna-center/#!get-network-device-by-ip +notes: + - SDK Method used are + devices.Devices.get_network_device_by_ip, + + - Paths used are + get /dna/intent/api/v1/network-device/ip-address/{ipAddress}, + +""" + +EXAMPLES = r""" +- name: Get Network Device Ip Address by id + cisco.dnac.network_device_ip_address_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + ipAddress: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "apManagerInterfaceIp": "string", + "associatedWlcIp": "string", + "bootDateTime": "string", + "collectionInterval": "string", + "collectionStatus": "string", + "errorCode": "string", + "errorDescription": "string", + "family": "string", + "hostname": "string", + "id": "string", + "instanceTenantId": "string", + "instanceUuid": "string", + "interfaceCount": "string", + "inventoryStatusDetail": "string", + "lastUpdateTime": 0, + "lastUpdated": "string", + "lineCardCount": "string", + "lineCardId": "string", + "location": "string", + "locationName": "string", + "macAddress": "string", + "managementIpAddress": "string", + "memorySize": "string", + "platformId": "string", + "reachabilityFailureReason": "string", + "reachabilityStatus": "string", + "role": "string", + "roleSource": "string", + "serialNumber": "string", + "series": "string", + "snmpContact": "string", + "snmpLocation": "string", + "softwareType": "string", + "softwareVersion": "string", + "tagCount": "string", + "tunnelUdpPort": "string", + "type": "string", + "upTime": "string", + "waasDeviceMode": "string", + "dnsResolvedManagementAddress": "string", + "apEthernetMacAddress": "string", + "vendor": "string", + "reasonsForPendingSyncRequests": "string", + "pendingSyncRequestsCount": "string", + "reasonsForDeviceResync": "string", + "lastDeviceResyncStartTime": "string", + "uptimeSeconds": 0, + "managedAtleastOnce": true, + "deviceSupportLevel": "string", + "managementState": "string", + "description": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/network_device_lexicographically_sorted_info.py b/plugins/modules/network_device_lexicographically_sorted_info.py index cd7473692b..0eb0ccd4bd 100644 --- a/plugins/modules/network_device_lexicographically_sorted_info.py +++ b/plugins/modules/network_device_lexicographically_sorted_info.py @@ -108,8 +108,8 @@ - Limit query parameter. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDeviceValuesThatMatchFullyOrPartiallyAnAttribute description: Complete reference of the GetDeviceValuesThatMatchFullyOrPartiallyAnAttribute API. @@ -159,17 +159,11 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK returned: always - type: dict + type: str sample: > - { - "response": [ - "string" - ], - "version": "string" - } + "string" """ diff --git a/plugins/modules/network_device_linecard_details_info.py b/plugins/modules/network_device_linecard_details_info.py index 6ec120deda..b4b9682c2c 100644 --- a/plugins/modules/network_device_linecard_details_info.py +++ b/plugins/modules/network_device_linecard_details_info.py @@ -24,8 +24,8 @@ - DeviceUuid path parameter. Instanceuuid of device. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetLinecardDetails description: Complete reference of the GetLinecardDetails API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_management_address_update.py b/plugins/modules/network_device_management_address_update.py new file mode 100644 index 0000000000..328e4e457a --- /dev/null +++ b/plugins/modules/network_device_management_address_update.py @@ -0,0 +1,69 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: network_device_management_address_update +short_description: Resource module for Network Device Management Address Update +description: +- Manage operation update of the resource Network Device Management Address Update. +- This is a simple PUT API to edit the management IP Address of the device. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + deviceid: + description: Deviceid path parameter. The UUID of the device whose management IP + address is to be updated. + type: str + newIP: + description: New IP Address of the device to be Updated. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Devices UpdateDeviceManagementAddress + description: Complete reference of the UpdateDeviceManagementAddress API. + link: https://developer.cisco.com/docs/dna-center/#!update-device-management-address +notes: + - SDK Method used are + devices.Devices.update_device_management_address, + + - Paths used are + put /dna/intent/api/v1/network-device/{deviceid}/management-address, + +""" + +EXAMPLES = r""" +- name: Update all + cisco.dnac.network_device_management_address_update: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + deviceid: string + newIP: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/network_device_meraki_organization_info.py b/plugins/modules/network_device_meraki_organization_info.py index a8bc1ddeb6..0315c080f1 100644 --- a/plugins/modules/network_device_meraki_organization_info.py +++ b/plugins/modules/network_device_meraki_organization_info.py @@ -21,11 +21,11 @@ type: dict id: description: - - Id path parameter. + - Id path parameter. Device Id. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetOrganizationListForMeraki description: Complete reference of the GetOrganizationListForMeraki API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_module_count_info.py b/plugins/modules/network_device_module_count_info.py index 5969b346ee..a02c59f21d 100644 --- a/plugins/modules/network_device_module_count_info.py +++ b/plugins/modules/network_device_module_count_info.py @@ -25,7 +25,7 @@ type: str nameList: description: - - NameList query parameter. + - NameList query parameter. elements: str type: list vendorEquipmentTypeList: @@ -40,12 +40,12 @@ type: list operationalStateCodeList: description: - - OperationalStateCodeList query parameter. + - OperationalStateCodeList query parameter. elements: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetModuleCount description: Complete reference of the GetModuleCount API. @@ -78,7 +78,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_module_info.py b/plugins/modules/network_device_module_info.py index be3bd1a556..33e6f4e0f6 100644 --- a/plugins/modules/network_device_module_info.py +++ b/plugins/modules/network_device_module_info.py @@ -35,7 +35,7 @@ type: int nameList: description: - - NameList query parameter. + - NameList query parameter. elements: str type: list vendorEquipmentTypeList: @@ -50,7 +50,7 @@ type: list operationalStateCodeList: description: - - OperationalStateCodeList query parameter. + - OperationalStateCodeList query parameter. elements: str type: list id: @@ -58,8 +58,8 @@ - Id path parameter. Module id. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetModuleInfoById description: Complete reference of the GetModuleInfoById API. @@ -112,7 +112,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_poe_info.py b/plugins/modules/network_device_poe_info.py index 4f78d1e703..7323d9d1ad 100644 --- a/plugins/modules/network_device_poe_info.py +++ b/plugins/modules/network_device_poe_info.py @@ -21,11 +21,11 @@ type: dict deviceUuid: description: - - DeviceUuid path parameter. Uuid of the device. + - DeviceUuid path parameter. UUID of the device. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices POEDetails description: Complete reference of the POEDetails API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_polling_interval_info.py b/plugins/modules/network_device_polling_interval_info.py index fc4707d26e..5a890d5474 100644 --- a/plugins/modules/network_device_polling_interval_info.py +++ b/plugins/modules/network_device_polling_interval_info.py @@ -24,8 +24,8 @@ - Id path parameter. Device ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetPollingIntervalById description: Complete reference of the GetPollingIntervalById API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_range_info.py b/plugins/modules/network_device_range_info.py index 5ea4572f49..01825cdf61 100644 --- a/plugins/modules/network_device_range_info.py +++ b/plugins/modules/network_device_range_info.py @@ -30,8 +30,8 @@ - RecordsToReturn path parameter. Number of records to return 1<= recordsToReturn <= 500. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetNetworkDeviceByPaginationRange description: Complete reference of the GetNetworkDeviceByPaginationRange API. @@ -61,7 +61,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -109,7 +108,19 @@ "tunnelUdpPort": "string", "type": "string", "upTime": "string", - "waasDeviceMode": "string" + "waasDeviceMode": "string", + "dnsResolvedManagementAddress": "string", + "apEthernetMacAddress": "string", + "vendor": "string", + "reasonsForPendingSyncRequests": "string", + "pendingSyncRequestsCount": "string", + "reasonsForDeviceResync": "string", + "lastDeviceResyncStartTime": "string", + "uptimeSeconds": 0, + "managedAtleastOnce": true, + "deviceSupportLevel": "string", + "managementState": "string", + "description": "string" } ], "version": "string" diff --git a/plugins/modules/network_device_register_for_wsa_info.py b/plugins/modules/network_device_register_for_wsa_info.py index 29c483aa29..7785cd9360 100644 --- a/plugins/modules/network_device_register_for_wsa_info.py +++ b/plugins/modules/network_device_register_for_wsa_info.py @@ -30,8 +30,8 @@ - Macaddress query parameter. Mac addres of the device. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDevicesRegisteredForWSANotification description: Complete reference of the GetDevicesRegisteredForWSANotification API. @@ -61,7 +61,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_stack_details_info.py b/plugins/modules/network_device_stack_details_info.py index 5cdaf55ad6..ebf1a6c1e9 100644 --- a/plugins/modules/network_device_stack_details_info.py +++ b/plugins/modules/network_device_stack_details_info.py @@ -24,8 +24,8 @@ - DeviceId path parameter. Device ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetStackDetailsForDevice description: Complete reference of the GetStackDetailsForDevice API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_summary_info.py b/plugins/modules/network_device_summary_info.py index 3096ba1cf2..9ef9c5dec9 100644 --- a/plugins/modules/network_device_summary_info.py +++ b/plugins/modules/network_device_summary_info.py @@ -24,8 +24,8 @@ - Id path parameter. Device ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDeviceSummary description: Complete reference of the GetDeviceSummary API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_supervisor_card_details_info.py b/plugins/modules/network_device_supervisor_card_details_info.py index f9db5bdd7a..f4bf0fc546 100644 --- a/plugins/modules/network_device_supervisor_card_details_info.py +++ b/plugins/modules/network_device_supervisor_card_details_info.py @@ -24,8 +24,8 @@ - DeviceUuid path parameter. Instanceuuid of device. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetSupervisorCardDetail description: Complete reference of the GetSupervisorCardDetail API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_sync.py b/plugins/modules/network_device_sync.py index 526b8d239b..049800bc3b 100644 --- a/plugins/modules/network_device_sync.py +++ b/plugins/modules/network_device_sync.py @@ -24,11 +24,11 @@ type: bool payload: description: Network Device Sync's payload. - elements: dict + elements: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices SyncDevices description: Complete reference of the SyncDevices API. @@ -54,10 +54,9 @@ dnac_debug: "{{dnac_debug}}" forceSync: true payload: - - {} + - string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_update_role.py b/plugins/modules/network_device_update_role.py index 14ded7ec10..319ef58e1c 100644 --- a/plugins/modules/network_device_update_role.py +++ b/plugins/modules/network_device_update_role.py @@ -17,17 +17,17 @@ author: Rafael Campos (@racampos) options: id: - description: Network Device Update Role's id. + description: DeviceId of the Device. type: str role: - description: Network Device Update Role's role. + description: Role of device as ACCESS, CORE, DISTRIBUTION, BORDER ROUTER. type: str roleSource: - description: Network Device Update Role's roleSource. + description: Role source as MANUAL / AUTO. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices UpdateDeviceRole description: Complete reference of the UpdateDeviceRole API. @@ -56,7 +56,6 @@ roleSource: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_user_defined_field.py b/plugins/modules/network_device_user_defined_field.py index 8d0ddc17ef..cb25f8eef3 100644 --- a/plugins/modules/network_device_user_defined_field.py +++ b/plugins/modules/network_device_user_defined_field.py @@ -13,7 +13,7 @@ - Creates a new global User Defined Field, which can be assigned to devices. - Deletes an existing Global User-Defined-Field using it's id. - Updates an existing global User Defined Field, using it's id. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -28,8 +28,8 @@ description: Name of UDF. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices CreateUserDefinedField description: Complete reference of the CreateUserDefinedField API. @@ -94,7 +94,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_user_defined_field_delete.py b/plugins/modules/network_device_user_defined_field_delete.py new file mode 100644 index 0000000000..ccc04acbcc --- /dev/null +++ b/plugins/modules/network_device_user_defined_field_delete.py @@ -0,0 +1,70 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: network_device_user_defined_field_delete +short_description: Resource module for Network Device User Defined Field Delete +description: +- Manage operation delete of the resource Network Device User Defined Field Delete. +- > + Remove a User-Defined-Field from device. Name of UDF has to be passed as the query parameter. Please note that + Global UDF will not be deleted by this operation. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + deviceId: + description: DeviceId path parameter. UUID of device from which UDF has to be removed. + type: str + name: + description: Name query parameter. Name of UDF to be removed. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Devices RemoveUserDefinedFieldFromDevice + description: Complete reference of the RemoveUserDefinedFieldFromDevice API. + link: https://developer.cisco.com/docs/dna-center/#!remove-user-defined-field-from-device +notes: + - SDK Method used are + devices.Devices.remove_user_defined_field_from_device, + + - Paths used are + delete /dna/intent/api/v1/network-device/{deviceId}/user-defined-field, + +""" + +EXAMPLES = r""" +- name: Delete all + cisco.dnac.network_device_user_defined_field_delete: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + deviceId: string + name: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/network_device_user_defined_field_info.py b/plugins/modules/network_device_user_defined_field_info.py index 9671142727..fb3a1b7f44 100644 --- a/plugins/modules/network_device_user_defined_field_info.py +++ b/plugins/modules/network_device_user_defined_field_info.py @@ -12,8 +12,8 @@ - Get all Network Device User Defined Field. - > Gets existing global User Defined Fields. If no input is given, it fetches ALL the Global UDFs. Filter/search is - supported either by UDF Ids or by UDF names, but not both. -version_added: '6.7.0' + supported by UDF Ids or UDF names or both. +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -30,8 +30,8 @@ - Name query parameter. Comma-seperated name(s) used for search/filtering. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetAllUserDefinedFields description: Complete reference of the GetAllUserDefinedFields API. @@ -61,7 +61,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_user_defined_field_update.py b/plugins/modules/network_device_user_defined_field_update.py new file mode 100644 index 0000000000..f0a9c4face --- /dev/null +++ b/plugins/modules/network_device_user_defined_field_update.py @@ -0,0 +1,81 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: network_device_user_defined_field_update +short_description: Resource module for Network Device User Defined Field Update +description: +- Manage operation update of the resource Network Device User Defined Field Update. +- > + Assigns an existing Global User-Defined-Field to a device. If the UDF is already assigned to the specific device, + then it updates the device UDF value accordingly. Please note that the assigning UDF 'name' must be an existing + global UDF. Otherwise error shall be shown. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + deviceId: + description: DeviceId path parameter. UUID of device to which UDF has to be added. + type: str + payload: + description: Network Device User Defined Field Update's payload. + elements: dict + suboptions: + name: + description: Name of the User Defined Field. + type: str + value: + description: Value of the User Defined Field that will be assigned to the device. + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Devices AddUserDefinedFieldToDevice + description: Complete reference of the AddUserDefinedFieldToDevice API. + link: https://developer.cisco.com/docs/dna-center/#!add-user-defined-field-to-device +notes: + - SDK Method used are + devices.Devices.add_user_defined_field_to_device, + + - Paths used are + put /dna/intent/api/v1/network-device/{deviceId}/user-defined-field, + +""" + +EXAMPLES = r""" +- name: Update all + cisco.dnac.network_device_user_defined_field_update: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + deviceId: string + payload: + - name: string + value: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/network_device_vlan_info.py b/plugins/modules/network_device_vlan_info.py index 132c102c7e..76ad0369ef 100644 --- a/plugins/modules/network_device_vlan_info.py +++ b/plugins/modules/network_device_vlan_info.py @@ -10,7 +10,7 @@ short_description: Information module for Network Device Vlan description: - Get all Network Device Vlan. -- Returns Device Interface VLANs. +- Returns Device Interface VLANs. If parameter value is null or empty, it won't return any value in response. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -25,11 +25,14 @@ type: str interfaceType: description: - - InterfaceType query parameter. Vlan assocaited with sub-interface. + - > + InterfaceType query parameter. Vlan associated with sub-interface. If no interfaceType mentioned it will + return all types of Vlan interfaces. If interfaceType is selected but not specified then it will take + default value. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetDeviceInterfaceVLANs description: Complete reference of the GetDeviceInterfaceVLANs API. @@ -59,7 +62,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/network_device_wireless_lan_info.py b/plugins/modules/network_device_wireless_lan_info.py index f08b1bcca0..f89bbead3d 100644 --- a/plugins/modules/network_device_wireless_lan_info.py +++ b/plugins/modules/network_device_wireless_lan_info.py @@ -24,8 +24,8 @@ - Id path parameter. Device ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetWirelessLanControllerDetailsById description: Complete reference of the GetWirelessLanControllerDetailsById API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -62,22 +61,19 @@ type: dict sample: > { - "response": { - "adminEnabledPorts": [ - 0 - ], - "apGroupName": "string", - "deviceId": "string", - "ethMacAddress": "string", - "flexGroupName": "string", - "id": "string", - "instanceTenantId": "string", - "instanceUuid": "string", - "lagModeEnabled": true, - "netconfEnabled": true, - "wirelessLicenseInfo": "string", - "wirelessPackageInstalled": true - }, - "version": "string" + "adminEnabledPorts": [ + 0 + ], + "apGroupName": "string", + "deviceId": "string", + "ethMacAddress": "string", + "flexGroupName": "string", + "id": "string", + "instanceTenantId": "string", + "instanceUuid": "string", + "lagModeEnabled": true, + "netconfEnabled": true, + "wirelessLicenseInfo": "string", + "wirelessPackageInstalled": true } """ diff --git a/plugins/modules/network_devices_interfaces_query.py b/plugins/modules/network_devices_interfaces_query.py new file mode 100644 index 0000000000..be92d6315f --- /dev/null +++ b/plugins/modules/network_devices_interfaces_query.py @@ -0,0 +1,35 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: networkDevices_interfaces_query +short_description: Resource module for Networkdevices Interfaces Query +description: +- Manage operation create of the resource Networkdevices Interfaces Query. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: {} +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +notes: + - Paths used are + +""" + +EXAMPLES = r""" +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + {} +""" diff --git a/plugins/modules/network_info.py b/plugins/modules/network_info.py index 0aa99bde53..36a7a62868 100644 --- a/plugins/modules/network_info.py +++ b/plugins/modules/network_info.py @@ -24,8 +24,8 @@ - SiteId query parameter. Site id to get the network settings associated with the site. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings GetNetwork description: Complete reference of the GetNetwork API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/path_trace.py b/plugins/modules/path_trace.py index 055db2d564..34c0d135fb 100644 --- a/plugins/modules/path_trace.py +++ b/plugins/modules/path_trace.py @@ -26,7 +26,7 @@ description: Destination IP address. type: str destPort: - description: Destination Port. + description: Destination Port, range 1-65535. type: str flowAnalysisId: description: FlowAnalysisId path parameter. Flow analysis request id. @@ -40,17 +40,17 @@ description: Periodic refresh of path for every 30 sec. type: bool protocol: - description: Protocol. + description: Protocol - one of TCP, UDP - checks both when left blank. type: str sourceIP: description: Source IP address. type: str sourcePort: - description: Source Port. + description: Source Port, range 1-65535. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Path Trace InitiateANewPathtrace description: Complete reference of the InitiateANewPathtrace API. @@ -103,7 +103,6 @@ flowAnalysisId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/path_trace_info.py b/plugins/modules/path_trace_info.py index d305183c19..03c9e6a04a 100644 --- a/plugins/modules/path_trace_info.py +++ b/plugins/modules/path_trace_info.py @@ -31,24 +31,24 @@ type: str destIP: description: - - DestIP query parameter. Destination IP adress. + - DestIP query parameter. Destination IP address. type: str sourcePort: description: - SourcePort query parameter. Source port. - type: str + type: float destPort: description: - DestPort query parameter. Destination port. - type: str + type: float gtCreateTime: description: - GtCreateTime query parameter. Analyses requested after this time. - type: str + type: float ltCreateTime: description: - LtCreateTime query parameter. Analyses requested before this time. - type: str + type: float protocol: description: - Protocol query parameter. @@ -64,15 +64,15 @@ lastUpdateTime: description: - LastUpdateTime query parameter. Last update time. - type: str + type: float limit: description: - Limit query parameter. Number of resources returned. - type: int + type: float offset: description: - Offset query parameter. Start index of resources returned (1-based). - type: int + type: float order: description: - Order query parameter. Order by this field. @@ -86,19 +86,19 @@ - FlowAnalysisId path parameter. Flow analysis request id. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: +- name: Cisco DNA Center documentation for Path Trace RetrievesAllPreviousPathtracesSummary + description: Complete reference of the RetrievesAllPreviousPathtracesSummary API. + link: https://developer.cisco.com/docs/dna-center/#!retrieves-all-previous-pathtraces-summary - name: Cisco DNA Center documentation for Path Trace RetrievesPreviousPathtrace description: Complete reference of the RetrievesPreviousPathtrace API. link: https://developer.cisco.com/docs/dna-center/#!retrieves-previous-pathtrace -- name: Cisco DNA Center documentation for Path Trace RetrivesAllPreviousPathtracesSummary - description: Complete reference of the RetrivesAllPreviousPathtracesSummary API. - link: https://developer.cisco.com/docs/dna-center/#!retrives-all-previous-pathtraces-summary notes: - SDK Method used are + path_trace.PathTrace.retrieves_all_previous_pathtraces_summary, path_trace.PathTrace.retrieves_previous_pathtrace, - path_trace.PathTrace.retrives_all_previous_pathtraces_summary, - Paths used are get /dna/intent/api/v1/flow-analysis, @@ -120,14 +120,14 @@ periodicRefresh: True sourceIP: string destIP: string - sourcePort: string - destPort: string - gtCreateTime: string - ltCreateTime: string + sourcePort: 0 + destPort: 0 + gtCreateTime: 0 + ltCreateTime: 0 protocol: string status: string taskId: string - lastUpdateTime: string + lastUpdateTime: 0 limit: 0 offset: 0 order: string @@ -148,7 +148,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -1068,7 +1067,8 @@ "protocol": "string", "sourceIP": "string", "sourcePort": "string", - "status": "string" + "status": "string", + "previousFlowAnalysisId": "string" } }, "version": "string" diff --git a/plugins/modules/planned_access_points.py b/plugins/modules/planned_access_points.py new file mode 100644 index 0000000000..b6c99f519f --- /dev/null +++ b/plugins/modules/planned_access_points.py @@ -0,0 +1,313 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: planned_access_points +short_description: Resource module for Planned Access Points +description: +- Manage operations create, update and delete of the resource Planned Access Points. +- > + Allows creation of a new planned access point on an existing floor map including its planned radio and antenna + details. Use the Get variant of this API to fetch any existing planned access points for the floor. The payload to + create a planned access point is in the same format, albeit a single object instead of a list, of that API. +- > + Allow to delete a planned access point from an existing floor map including its planned radio and antenna details. + Use the Get variant of this API to fetch the existing planned access points for the floor. The instanceUUID listed + in each of the planned access point attributes acts as the path param input to this API to delete that specific + instance. +- > + Allows updating a planned access point on an existing floor map including its planned radio and antenna details. + Use the Get variant of this API to fetch the existing planned access points for the floor. The payload to update a + planned access point is in the same format, albeit a single object instead of a list, of that API. +version_added: '6.0.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + attributes: + description: Planned Access Points's attributes. + suboptions: + createDate: + description: Planned Access Points's createDate. + type: int + domain: + description: Planned Access Points's domain. + type: str + heirarchyName: + description: Planned Access Points's heirarchyName. + type: str + id: + description: Planned Access Points's id. + type: float + instanceUuid: + description: Planned Access Points's instanceUuid. + type: str + macaddress: + description: Planned Access Points's macaddress. + type: str + name: + description: Planned Access Points's name. + type: str + source: + description: Planned Access Points's source. + type: str + typeString: + description: Planned Access Points's typeString. + type: str + type: dict + floorId: + description: FloorId path parameter. The instance UUID of the floor hierarchy element. + type: str + isSensor: + description: IsSensor flag. + type: bool + location: + description: Planned Access Points's location. + suboptions: + altitude: + description: Planned Access Points's altitude. + type: float + lattitude: + description: Planned Access Points's lattitude. + type: float + longtitude: + description: Planned Access Points's longtitude. + type: float + type: dict + plannedAccessPointUuid: + description: PlannedAccessPointUuid path parameter. The instance UUID of the planned + access point to delete. + type: str + position: + description: Planned Access Points's position. + suboptions: + x: + description: Planned Access Points's x. + type: float + y: + description: Planned Access Points's y. + type: float + z: + description: Planned Access Points's z. + type: float + type: dict + radioCount: + description: Planned Access Points's radioCount. + type: int + radios: + description: Planned Access Points's radios. + elements: dict + suboptions: + antenna: + description: Planned Access Points's antenna. + suboptions: + azimuthAngle: + description: Planned Access Points's azimuthAngle. + type: float + elevationAngle: + description: Planned Access Points's elevationAngle. + type: float + gain: + description: Planned Access Points's gain. + type: float + mode: + description: Planned Access Points's mode. + type: str + name: + description: Planned Access Points's name. + type: str + type: + description: Planned Access Points's type. + type: str + type: dict + attributes: + description: Planned Access Points's attributes. + suboptions: + channel: + description: Planned Access Points's channel. + type: float + channelString: + description: Planned Access Points's channelString. + type: str + id: + description: Planned Access Points's id. + type: float + ifMode: + description: Planned Access Points's ifMode. + type: str + ifTypeString: + description: Planned Access Points's ifTypeString. + type: str + ifTypeSubband: + description: Planned Access Points's ifTypeSubband. + type: str + instanceUuid: + description: Planned Access Points's instanceUuid. + type: str + slotId: + description: Planned Access Points's slotId. + type: float + type: dict + isSensor: + description: IsSensor flag. + type: bool + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Devices CreatePlannedAccessPointForFloor + description: Complete reference of the CreatePlannedAccessPointForFloor API. + link: https://developer.cisco.com/docs/dna-center/#!create-planned-access-point-for-floor +- name: Cisco DNA Center documentation for Devices DeletePlannedAccessPointForFloor + description: Complete reference of the DeletePlannedAccessPointForFloor API. + link: https://developer.cisco.com/docs/dna-center/#!delete-planned-access-point-for-floor +- name: Cisco DNA Center documentation for Devices UpdatePlannedAccessPointForFloor + description: Complete reference of the UpdatePlannedAccessPointForFloor API. + link: https://developer.cisco.com/docs/dna-center/#!update-planned-access-point-for-floor +notes: + - SDK Method used are + devices.Devices.create_planned_access_point_for_floor, + devices.Devices.delete_planned_access_point_for_floor, + devices.Devices.update_planned_access_point_for_floor, + + - Paths used are + post /dna/intent/api/v1/floors/{floorId}/planned-access-points, + delete /dna/intent/api/v1/floors/{floorId}/planned-access-points/{plannedAccessPointUuid}, + put /dna/intent/api/v1/floors/{floorId}/planned-access-points, + +""" + +EXAMPLES = r""" +- name: Update all + cisco.dnac.planned_access_points: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + attributes: + createDate: 0 + domain: string + heirarchyName: string + id: 0 + instanceUuid: string + macaddress: string + name: string + source: string + typeString: string + floorId: string + isSensor: true + location: + altitude: 0 + lattitude: 0 + longtitude: 0 + position: + x: 0 + y: 0 + z: 0 + radioCount: 0 + radios: + - antenna: + azimuthAngle: 0 + elevationAngle: 0 + gain: 0 + mode: string + name: string + type: string + attributes: + channel: 0 + channelString: string + id: 0 + ifMode: string + ifTypeString: string + ifTypeSubband: string + instanceUuid: string + slotId: 0 + isSensor: true + +- name: Create + cisco.dnac.planned_access_points: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + attributes: + createDate: 0 + domain: string + heirarchyName: string + id: 0 + instanceUuid: string + macaddress: string + name: string + source: string + typeString: string + floorId: string + isSensor: true + location: + altitude: 0 + lattitude: 0 + longtitude: 0 + position: + x: 0 + y: 0 + z: 0 + radioCount: 0 + radios: + - antenna: + azimuthAngle: 0 + elevationAngle: 0 + gain: 0 + mode: string + name: string + type: string + attributes: + channel: 0 + channelString: string + id: 0 + ifMode: string + ifTypeString: string + ifTypeSubband: string + instanceUuid: string + slotId: 0 + isSensor: true + +- name: Delete by id + cisco.dnac.planned_access_points: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + floorId: string + plannedAccessPointUuid: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/planned_access_points_info.py b/plugins/modules/planned_access_points_info.py index bed5d8656f..24203b1a3e 100644 --- a/plugins/modules/planned_access_points_info.py +++ b/plugins/modules/planned_access_points_info.py @@ -26,18 +26,18 @@ limit: description: - Limit query parameter. - type: int + type: float offset: description: - Offset query parameter. - type: int + type: float radios: description: - Radios query parameter. Inlcude planned radio details. type: bool requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Devices GetPlannedAccessPointsForFloor description: Complete reference of the GetPlannedAccessPointsForFloor API. @@ -69,7 +69,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/platform_nodes_configuration_summary_info.py b/plugins/modules/platform_nodes_configuration_summary_info.py index d06ecb029a..88e1b57499 100644 --- a/plugins/modules/platform_nodes_configuration_summary_info.py +++ b/plugins/modules/platform_nodes_configuration_summary_info.py @@ -23,8 +23,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Platform Configuration CiscoDNACenterNodesConfigurationSummary description: Complete reference of the CiscoDNACenterNodesConfigurationSummary API. @@ -52,7 +52,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/platform_release_summary_info.py b/plugins/modules/platform_release_summary_info.py index b37caefc01..bf8a458503 100644 --- a/plugins/modules/platform_release_summary_info.py +++ b/plugins/modules/platform_release_summary_info.py @@ -22,8 +22,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Platform Configuration CiscoDNACenterReleaseSummary description: Complete reference of the CiscoDNACenterReleaseSummary API. @@ -51,7 +51,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_device.py b/plugins/modules/pnp_device.py index a3451edeb4..60ab34e1f3 100644 --- a/plugins/modules/pnp_device.py +++ b/plugins/modules/pnp_device.py @@ -18,813 +18,119 @@ - cisco.dnac.module author: Rafael Campos (@racampos) options: - _id: - description: Pnp Device's _id. - type: str deviceInfo: description: Pnp Device's deviceInfo. suboptions: - aaaCredentials: - description: Pnp Device's aaaCredentials. - suboptions: - password: - description: Pnp Device's password. - type: str - username: - description: Pnp Device's username. - type: str - type: dict - addedOn: - description: Pnp Device's addedOn. - type: int - addnMacAddrs: - description: Pnp Device's addnMacAddrs. - elements: str - type: list - agentType: - description: Pnp Device's agentType. - type: str - authStatus: - description: Pnp Device's authStatus. - type: str - authenticatedSudiSerialNo: - description: Pnp Device's authenticatedSudiSerialNo. - type: str - capabilitiesSupported: - description: Pnp Device's capabilitiesSupported. - elements: str - type: list - cmState: - description: Pnp Device's cmState. - type: str description: - description: Pnp Device's description. + description: Description. type: str deviceSudiSerialNos: - description: Pnp Device's deviceSudiSerialNos. - elements: str - type: list - deviceType: - description: Pnp Device's deviceType. - type: str - featuresSupported: - description: Pnp Device's featuresSupported. + description: Device Sudi Serial Nos. elements: str type: list - fileSystemList: - description: Pnp Device's fileSystemList. - elements: dict - suboptions: - freespace: - description: Pnp Device's freespace. - type: int - name: - description: Pnp Device's name. - type: str - readable: - description: Readable flag. - type: bool - size: - description: Pnp Device's size. - type: int - type: - description: Pnp Device's type. - type: str - writeable: - description: Writeable flag. - type: bool - type: list - firstContact: - description: Pnp Device's firstContact. - type: int hostname: - description: Pnp Device's hostname. + description: Hostname. type: str - httpHeaders: - description: Pnp Device's httpHeaders. - elements: dict - suboptions: - key: - description: Pnp Device's key. - type: str - value: - description: Pnp Device's value. - type: str - type: list - imageFile: - description: Pnp Device's imageFile. - type: str - imageVersion: - description: Pnp Device's imageVersion. - type: str - ipInterfaces: - description: Pnp Device's ipInterfaces. - elements: dict - suboptions: - ipv4Address: - description: Pnp Device's ipv4Address. - type: dict - ipv6AddressList: - description: Pnp Device's ipv6AddressList. - elements: dict - type: list - macAddress: - description: Pnp Device's macAddress. - type: str - name: - description: Pnp Device's name. - type: str - status: - description: Pnp Device's status. - type: str - type: list - lastContact: - description: Pnp Device's lastContact. - type: int - lastSyncTime: - description: Pnp Device's lastSyncTime. - type: int - lastUpdateOn: - description: Pnp Device's lastUpdateOn. - type: int - location: - description: Pnp Device's location. - suboptions: - address: - description: Pnp Device's address. - type: str - altitude: - description: Pnp Device's altitude. - type: str - latitude: - description: Pnp Device's latitude. - type: str - longitude: - description: Pnp Device's longitude. - type: str - siteId: - description: Pnp Device's siteId. - type: str - type: dict + isSudiRequired: + description: Is Sudi Required. + type: bool macAddress: - description: Pnp Device's macAddress. - type: str - mode: - description: Pnp Device's mode. - type: str - name: - description: Pnp Device's name. - type: str - neighborLinks: - description: Pnp Device's neighborLinks. - elements: dict - suboptions: - localInterfaceName: - description: Pnp Device's localInterfaceName. - type: str - localMacAddress: - description: Pnp Device's localMacAddress. - type: str - localShortInterfaceName: - description: Pnp Device's localShortInterfaceName. - type: str - remoteDeviceName: - description: Pnp Device's remoteDeviceName. - type: str - remoteInterfaceName: - description: Pnp Device's remoteInterfaceName. - type: str - remoteMacAddress: - description: Pnp Device's remoteMacAddress. - type: str - remotePlatform: - description: Pnp Device's remotePlatform. - type: str - remoteShortInterfaceName: - description: Pnp Device's remoteShortInterfaceName. - type: str - remoteVersion: - description: Pnp Device's remoteVersion. - type: str - type: list - onbState: - description: Pnp Device's onbState. + description: Mac Address. type: str pid: - description: Pnp Device's pid. - type: str - pnpProfileList: - description: Pnp Device's pnpProfileList. - elements: dict - suboptions: - createdBy: - description: Pnp Device's createdBy. - type: str - discoveryCreated: - description: DiscoveryCreated flag. - type: bool - primaryEndpoint: - description: Pnp Device's primaryEndpoint. - suboptions: - certificate: - description: Pnp Device's certificate. - type: str - fqdn: - description: Pnp Device's fqdn. - type: str - ipv4Address: - description: Pnp Device's ipv4Address. - type: dict - ipv6Address: - description: Pnp Device's ipv6Address. - type: dict - port: - description: Pnp Device's port. - type: int - protocol: - description: Pnp Device's protocol. - type: str - type: dict - profileName: - description: Pnp Device's profileName. - type: str - secondaryEndpoint: - description: Pnp Device's secondaryEndpoint. - suboptions: - certificate: - description: Pnp Device's certificate. - type: str - fqdn: - description: Pnp Device's fqdn. - type: str - ipv4Address: - description: Pnp Device's ipv4Address. - type: dict - ipv6Address: - description: Pnp Device's ipv6Address. - type: dict - port: - description: Pnp Device's port. - type: int - protocol: - description: Pnp Device's protocol. - type: str - type: dict - type: list - populateInventory: - description: PopulateInventory flag. - type: bool - preWorkflowCliOuputs: - description: Pnp Device's preWorkflowCliOuputs. - elements: dict - suboptions: - cli: - description: Pnp Device's cli. - type: str - cliOutput: - description: Pnp Device's cliOutput. - type: str - type: list - projectId: - description: Pnp Device's projectId. + description: Pid. type: str - projectName: - description: Pnp Device's projectName. - type: str - reloadRequested: - description: ReloadRequested flag. - type: bool serialNumber: - description: Pnp Device's serialNumber. + description: Serial Number. type: str - smartAccountId: - description: Pnp Device's smartAccountId. - type: str - source: - description: Pnp Device's source. + siteId: + description: Site Id. type: str stack: - description: Stack flag. + description: Stack. type: bool stackInfo: description: Pnp Device's stackInfo. suboptions: isFullRing: - description: IsFullRing flag. + description: Is Full Ring. type: bool stackMemberList: description: Pnp Device's stackMemberList. elements: dict suboptions: hardwareVersion: - description: Pnp Device's hardwareVersion. + description: Hardware Version. type: str licenseLevel: - description: Pnp Device's licenseLevel. + description: License Level. type: str licenseType: - description: Pnp Device's licenseType. + description: License Type. type: str macAddress: - description: Pnp Device's macAddress. + description: Mac Address. type: str pid: - description: Pnp Device's pid. + description: Pid. type: str priority: - description: Pnp Device's priority. - type: int + description: Priority. + type: float role: - description: Pnp Device's role. + description: Role. type: str serialNumber: - description: Pnp Device's serialNumber. + description: Serial Number. type: str softwareVersion: - description: Pnp Device's softwareVersion. + description: Software Version. type: str stackNumber: - description: Pnp Device's stackNumber. - type: int + description: Stack Number. + type: float state: - description: Pnp Device's state. + description: State. type: str sudiSerialNumber: - description: Pnp Device's sudiSerialNumber. + description: Sudi Serial Number. type: str type: list stackRingProtocol: - description: Pnp Device's stackRingProtocol. + description: Stack Ring Protocol. type: str supportsStackWorkflows: - description: SupportsStackWorkflows flag. + description: Supports Stack Workflows. type: bool totalMemberCount: - description: Pnp Device's totalMemberCount. - type: int + description: Total Member Count. + type: float validLicenseLevels: - description: Pnp Device's validLicenseLevels. + description: Valid License Levels. elements: str type: list type: dict - state: - description: Pnp Device's state. - type: str - sudiRequired: - description: SudiRequired flag. - type: bool - tags: - description: Pnp Device's tags. - type: dict + userMicNumbers: + description: User Mic Numbers. + elements: str + type: list userSudiSerialNos: - description: Pnp Device's userSudiSerialNos. + description: User Sudi Serial Nos. elements: str type: list - virtualAccountId: - description: Pnp Device's virtualAccountId. - type: str workflowId: - description: Pnp Device's workflowId. + description: Workflow Id. type: str workflowName: - description: Pnp Device's workflowName. + description: Workflow Name. type: str type: dict id: - description: Id path parameter. + description: Id. type: str - runSummaryList: - description: Pnp Device's runSummaryList. - elements: dict - suboptions: - details: - description: Pnp Device's details. - type: str - errorFlag: - description: ErrorFlag flag. - type: bool - historyTaskInfo: - description: Pnp Device's historyTaskInfo. - suboptions: - addnDetails: - description: Pnp Device's addnDetails. - elements: dict - suboptions: - key: - description: Pnp Device's key. - type: str - value: - description: Pnp Device's value. - type: str - type: list - name: - description: Pnp Device's name. - type: str - timeTaken: - description: Pnp Device's timeTaken. - type: int - type: - description: Pnp Device's type. - type: str - workItemList: - description: Pnp Device's workItemList. - elements: dict - suboptions: - command: - description: Pnp Device's command. - type: str - endTime: - description: Pnp Device's endTime. - type: int - outputStr: - description: Pnp Device's outputStr. - type: str - startTime: - description: Pnp Device's startTime. - type: int - state: - description: Pnp Device's state. - type: str - timeTaken: - description: Pnp Device's timeTaken. - type: int - type: list - type: dict - timestamp: - description: Pnp Device's timestamp. - type: int - type: list - systemResetWorkflow: - description: Pnp Device's systemResetWorkflow. - suboptions: - _id: - description: Pnp Device's _id. - type: str - addToInventory: - description: AddToInventory flag. - type: bool - addedOn: - description: Pnp Device's addedOn. - type: int - configId: - description: Pnp Device's configId. - type: str - currTaskIdx: - description: Pnp Device's currTaskIdx. - type: int - description: - description: Pnp Device's description. - type: str - endTime: - description: Pnp Device's endTime. - type: int - execTime: - description: Pnp Device's execTime. - type: int - imageId: - description: Pnp Device's imageId. - type: str - instanceType: - description: Pnp Device's instanceType. - type: str - lastupdateOn: - description: Pnp Device's lastupdateOn. - type: int - name: - description: Pnp Device's name. - type: str - startTime: - description: Pnp Device's startTime. - type: int - state: - description: Pnp Device's state. - type: str - tasks: - description: Pnp Device's tasks. - elements: dict - suboptions: - currWorkItemIdx: - description: Pnp Device's currWorkItemIdx. - type: int - endTime: - description: Pnp Device's endTime. - type: int - name: - description: Pnp Device's name. - type: str - startTime: - description: Pnp Device's startTime. - type: int - state: - description: Pnp Device's state. - type: str - taskSeqNo: - description: Pnp Device's taskSeqNo. - type: int - timeTaken: - description: Pnp Device's timeTaken. - type: int - type: - description: Pnp Device's type. - type: str - workItemList: - description: Pnp Device's workItemList. - elements: dict - suboptions: - command: - description: Pnp Device's command. - type: str - endTime: - description: Pnp Device's endTime. - type: int - outputStr: - description: Pnp Device's outputStr. - type: str - startTime: - description: Pnp Device's startTime. - type: int - state: - description: Pnp Device's state. - type: str - timeTaken: - description: Pnp Device's timeTaken. - type: int - type: list - type: list - tenantId: - description: Pnp Device's tenantId. - type: str - type: - description: Pnp Device's type. - type: str - useState: - description: Pnp Device's useState. - type: str - version: - description: Pnp Device's version. - type: int - type: dict - systemWorkflow: - description: Pnp Device's systemWorkflow. - suboptions: - _id: - description: Pnp Device's _id. - type: str - addToInventory: - description: AddToInventory flag. - type: bool - addedOn: - description: Pnp Device's addedOn. - type: int - configId: - description: Pnp Device's configId. - type: str - currTaskIdx: - description: Pnp Device's currTaskIdx. - type: int - description: - description: Pnp Device's description. - type: str - endTime: - description: Pnp Device's endTime. - type: int - execTime: - description: Pnp Device's execTime. - type: int - imageId: - description: Pnp Device's imageId. - type: str - instanceType: - description: Pnp Device's instanceType. - type: str - lastupdateOn: - description: Pnp Device's lastupdateOn. - type: int - name: - description: Pnp Device's name. - type: str - startTime: - description: Pnp Device's startTime. - type: int - state: - description: Pnp Device's state. - type: str - tasks: - description: Pnp Device's tasks. - elements: dict - suboptions: - currWorkItemIdx: - description: Pnp Device's currWorkItemIdx. - type: int - endTime: - description: Pnp Device's endTime. - type: int - name: - description: Pnp Device's name. - type: str - startTime: - description: Pnp Device's startTime. - type: int - state: - description: Pnp Device's state. - type: str - taskSeqNo: - description: Pnp Device's taskSeqNo. - type: int - timeTaken: - description: Pnp Device's timeTaken. - type: int - type: - description: Pnp Device's type. - type: str - workItemList: - description: Pnp Device's workItemList. - elements: dict - suboptions: - command: - description: Pnp Device's command. - type: str - endTime: - description: Pnp Device's endTime. - type: int - outputStr: - description: Pnp Device's outputStr. - type: str - startTime: - description: Pnp Device's startTime. - type: int - state: - description: Pnp Device's state. - type: str - timeTaken: - description: Pnp Device's timeTaken. - type: int - type: list - type: list - tenantId: - description: Pnp Device's tenantId. - type: str - type: - description: Pnp Device's type. - type: str - useState: - description: Pnp Device's useState. - type: str - version: - description: Pnp Device's version. - type: int - type: dict - tenantId: - description: Pnp Device's tenantId. - type: str - version: - description: Pnp Device's version. - type: int - workflow: - description: Pnp Device's workflow. - suboptions: - _id: - description: Pnp Device's _id. - type: str - addToInventory: - description: AddToInventory flag. - type: bool - addedOn: - description: Pnp Device's addedOn. - type: int - configId: - description: Pnp Device's configId. - type: str - currTaskIdx: - description: Pnp Device's currTaskIdx. - type: int - description: - description: Pnp Device's description. - type: str - endTime: - description: Pnp Device's endTime. - type: int - execTime: - description: Pnp Device's execTime. - type: int - imageId: - description: Pnp Device's imageId. - type: str - instanceType: - description: Pnp Device's instanceType. - type: str - lastupdateOn: - description: Pnp Device's lastupdateOn. - type: int - name: - description: Pnp Device's name. - type: str - startTime: - description: Pnp Device's startTime. - type: int - state: - description: Pnp Device's state. - type: str - tasks: - description: Pnp Device's tasks. - elements: dict - suboptions: - currWorkItemIdx: - description: Pnp Device's currWorkItemIdx. - type: int - endTime: - description: Pnp Device's endTime. - type: int - name: - description: Pnp Device's name. - type: str - startTime: - description: Pnp Device's startTime. - type: int - state: - description: Pnp Device's state. - type: str - taskSeqNo: - description: Pnp Device's taskSeqNo. - type: int - timeTaken: - description: Pnp Device's timeTaken. - type: int - type: - description: Pnp Device's type. - type: str - workItemList: - description: Pnp Device's workItemList. - elements: dict - suboptions: - command: - description: Pnp Device's command. - type: str - endTime: - description: Pnp Device's endTime. - type: int - outputStr: - description: Pnp Device's outputStr. - type: str - startTime: - description: Pnp Device's startTime. - type: int - state: - description: Pnp Device's state. - type: str - timeTaken: - description: Pnp Device's timeTaken. - type: int - type: list - type: list - tenantId: - description: Pnp Device's tenantId. - type: str - type: - description: Pnp Device's type. - type: str - useState: - description: Pnp Device's useState. - type: str - version: - description: Pnp Device's version. - type: int - type: dict - workflowParameters: - description: Pnp Device's workflowParameters. - suboptions: - configList: - description: Pnp Device's configList. - elements: dict - suboptions: - configId: - description: Pnp Device's configId. - type: str - configParameters: - description: Pnp Device's configParameters. - elements: dict - suboptions: - key: - description: Pnp Device's key. - type: str - value: - description: Pnp Device's value. - type: str - type: list - type: list - licenseLevel: - description: Pnp Device's licenseLevel. - type: str - licenseType: - description: Pnp Device's licenseType. - type: str - topOfStackSerialNumber: - description: Pnp Device's topOfStackSerialNumber. - type: str - type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) AddDevice description: Complete reference of the AddDevice API. @@ -859,99 +165,16 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" state: present - _id: string deviceInfo: - aaaCredentials: - password: string - username: string - addedOn: 0 - addnMacAddrs: - - string - agentType: string - authStatus: string - authenticatedSudiSerialNo: string - capabilitiesSupported: - - string - cmState: string description: string deviceSudiSerialNos: - string - deviceType: string - featuresSupported: - - string - fileSystemList: - - freespace: 0 - name: string - readable: true - size: 0 - type: string - writeable: true - firstContact: 0 hostname: string - httpHeaders: - - key: string - value: string - imageFile: string - imageVersion: string - ipInterfaces: - - ipv4Address: {} - ipv6AddressList: - - {} - macAddress: string - name: string - status: string - lastContact: 0 - lastSyncTime: 0 - lastUpdateOn: 0 - location: - address: string - altitude: string - latitude: string - longitude: string - siteId: string + isSudiRequired: true macAddress: string - mode: string - name: string - neighborLinks: - - localInterfaceName: string - localMacAddress: string - localShortInterfaceName: string - remoteDeviceName: string - remoteInterfaceName: string - remoteMacAddress: string - remotePlatform: string - remoteShortInterfaceName: string - remoteVersion: string - onbState: string pid: string - pnpProfileList: - - createdBy: string - discoveryCreated: true - primaryEndpoint: - certificate: string - fqdn: string - ipv4Address: {} - ipv6Address: {} - port: 0 - protocol: string - profileName: string - secondaryEndpoint: - certificate: string - fqdn: string - ipv4Address: {} - ipv6Address: {} - port: 0 - protocol: string - populateInventory: true - preWorkflowCliOuputs: - - cli: string - cliOutput: string - projectId: string - projectName: string - reloadRequested: true serialNumber: string - smartAccountId: string - source: string + siteId: string stack: true stackInfo: isFullRing: true @@ -973,148 +196,12 @@ totalMemberCount: 0 validLicenseLevels: - string - state: string - sudiRequired: true - tags: {} + userMicNumbers: + - string userSudiSerialNos: - string - virtualAccountId: string workflowId: string workflowName: string - runSummaryList: - - details: string - errorFlag: true - historyTaskInfo: - addnDetails: - - key: string - value: string - name: string - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - timestamp: 0 - systemResetWorkflow: - _id: string - addToInventory: true - addedOn: 0 - configId: string - currTaskIdx: 0 - description: string - endTime: 0 - execTime: 0 - imageId: string - instanceType: string - lastupdateOn: 0 - name: string - startTime: 0 - state: string - tasks: - - currWorkItemIdx: 0 - endTime: 0 - name: string - startTime: 0 - state: string - taskSeqNo: 0 - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - tenantId: string - type: string - useState: string - version: 0 - systemWorkflow: - _id: string - addToInventory: true - addedOn: 0 - configId: string - currTaskIdx: 0 - description: string - endTime: 0 - execTime: 0 - imageId: string - instanceType: string - lastupdateOn: 0 - name: string - startTime: 0 - state: string - tasks: - - currWorkItemIdx: 0 - endTime: 0 - name: string - startTime: 0 - state: string - taskSeqNo: 0 - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - tenantId: string - type: string - useState: string - version: 0 - tenantId: string - version: 0 - workflow: - _id: string - addToInventory: true - addedOn: 0 - configId: string - currTaskIdx: 0 - description: string - endTime: 0 - execTime: 0 - imageId: string - instanceType: string - lastupdateOn: 0 - name: string - startTime: 0 - state: string - tasks: - - currWorkItemIdx: 0 - endTime: 0 - name: string - startTime: 0 - state: string - taskSeqNo: 0 - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - tenantId: string - type: string - useState: string - version: 0 - workflowParameters: - configList: - - configId: string - configParameters: - - key: string - value: string - licenseLevel: string - licenseType: string - topOfStackSerialNumber: string - name: Update by id cisco.dnac.pnp_device: @@ -1126,263 +213,15 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" state: present - _id: string deviceInfo: - aaaCredentials: - password: string - username: string - addedOn: 0 - addnMacAddrs: - - string - agentType: string - authStatus: string - authenticatedSudiSerialNo: string - capabilitiesSupported: - - string - cmState: string - description: string - deviceSudiSerialNos: - - string - deviceType: string - featuresSupported: - - string - fileSystemList: - - freespace: 0 - name: string - readable: true - size: 0 - type: string - writeable: true - firstContact: 0 hostname: string - httpHeaders: - - key: string - value: string - imageFile: string - imageVersion: string - ipInterfaces: - - ipv4Address: {} - ipv6AddressList: - - {} - macAddress: string - name: string - status: string - lastContact: 0 - lastSyncTime: 0 - lastUpdateOn: 0 - location: - address: string - altitude: string - latitude: string - longitude: string - siteId: string - macAddress: string - mode: string - name: string - neighborLinks: - - localInterfaceName: string - localMacAddress: string - localShortInterfaceName: string - remoteDeviceName: string - remoteInterfaceName: string - remoteMacAddress: string - remotePlatform: string - remoteShortInterfaceName: string - remoteVersion: string - onbState: string pid: string - pnpProfileList: - - createdBy: string - discoveryCreated: true - primaryEndpoint: - certificate: string - fqdn: string - ipv4Address: {} - ipv6Address: {} - port: 0 - protocol: string - profileName: string - secondaryEndpoint: - certificate: string - fqdn: string - ipv4Address: {} - ipv6Address: {} - port: 0 - protocol: string - populateInventory: true - preWorkflowCliOuputs: - - cli: string - cliOutput: string - projectId: string - projectName: string - reloadRequested: true serialNumber: string - smartAccountId: string - source: string stack: true - stackInfo: - isFullRing: true - stackMemberList: - - hardwareVersion: string - licenseLevel: string - licenseType: string - macAddress: string - pid: string - priority: 0 - role: string - serialNumber: string - softwareVersion: string - stackNumber: 0 - state: string - sudiSerialNumber: string - stackRingProtocol: string - supportsStackWorkflows: true - totalMemberCount: 0 - validLicenseLevels: - - string - state: string sudiRequired: true - tags: {} - userSudiSerialNos: - - string - virtualAccountId: string - workflowId: string - workflowName: string + sudiSerialNos: + - {} id: string - runSummaryList: - - details: string - errorFlag: true - historyTaskInfo: - addnDetails: - - key: string - value: string - name: string - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - timestamp: 0 - systemResetWorkflow: - _id: string - addToInventory: true - addedOn: 0 - configId: string - currTaskIdx: 0 - description: string - endTime: 0 - execTime: 0 - imageId: string - instanceType: string - lastupdateOn: 0 - name: string - startTime: 0 - state: string - tasks: - - currWorkItemIdx: 0 - endTime: 0 - name: string - startTime: 0 - state: string - taskSeqNo: 0 - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - tenantId: string - type: string - useState: string - version: 0 - systemWorkflow: - _id: string - addToInventory: true - addedOn: 0 - configId: string - currTaskIdx: 0 - description: string - endTime: 0 - execTime: 0 - imageId: string - instanceType: string - lastupdateOn: 0 - name: string - startTime: 0 - state: string - tasks: - - currWorkItemIdx: 0 - endTime: 0 - name: string - startTime: 0 - state: string - taskSeqNo: 0 - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - tenantId: string - type: string - useState: string - version: 0 - tenantId: string - version: 0 - workflow: - _id: string - addToInventory: true - addedOn: 0 - configId: string - currTaskIdx: 0 - description: string - endTime: 0 - execTime: 0 - imageId: string - instanceType: string - lastupdateOn: 0 - name: string - startTime: 0 - state: string - tasks: - - currWorkItemIdx: 0 - endTime: 0 - name: string - startTime: 0 - state: string - taskSeqNo: 0 - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - tenantId: string - type: string - useState: string - version: 0 - workflowParameters: - configList: - - configId: string - configParameters: - - key: string - value: string - licenseLevel: string - licenseType: string - topOfStackSerialNumber: string - name: Delete by id cisco.dnac.pnp_device: @@ -1397,7 +236,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_device_authorize.py b/plugins/modules/pnp_device_authorize.py index 2a033f504b..da2ad652b4 100644 --- a/plugins/modules/pnp_device_authorize.py +++ b/plugins/modules/pnp_device_authorize.py @@ -11,7 +11,7 @@ description: - Manage operation create of the resource Pnp Device Authorize. - Authorizes one of more devices. A device can only be authorized if Authorization is set in Device Settings. -version_added: '6.5.0' +version_added: '6.0.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -21,15 +21,15 @@ elements: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for AuthorizeDevice +- name: Cisco DNA Center documentation for Device Onboarding (PnP) AuthorizeDevice description: Complete reference of the AuthorizeDevice API. link: https://developer.cisco.com/docs/dna-center/#!authorize-device notes: - SDK Method used are - ..authorize_device, + device_onboarding_pnp.DeviceOnboardingPnp.authorize_device, - Paths used are post /api/v1/onboarding/pnp-device/authorize, @@ -50,7 +50,6 @@ - string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_device_claim.py b/plugins/modules/pnp_device_claim.py index 4ce1b33892..81a7f42c85 100644 --- a/plugins/modules/pnp_device_claim.py +++ b/plugins/modules/pnp_device_claim.py @@ -77,8 +77,8 @@ description: Pnp Device Claim's workflowId. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) ClaimDevice description: Complete reference of the ClaimDevice API. @@ -122,7 +122,6 @@ workflowId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_device_claim_to_site.py b/plugins/modules/pnp_device_claim_to_site.py index 2e3bdd0a5b..1baeaa2f75 100644 --- a/plugins/modules/pnp_device_claim_to_site.py +++ b/plugins/modules/pnp_device_claim_to_site.py @@ -10,7 +10,9 @@ short_description: Resource module for Pnp Device Claim To Site description: - Manage operation create of the resource Pnp Device Claim To Site. -- Claim a device based on DNA-C Site-based design process. Some required parameters differ based on device platform. +- > + Claim a device based on Catalyst Center Site-based design process. Some required parameters differ based on device + platform. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module @@ -18,13 +20,13 @@ options: configInfo: description: Pnp Device Claim To Site's configInfo. - elements: dict suboptions: configId: description: Config Id. type: str configParameters: description: Pnp Device Claim To Site's configParameters. + elements: dict suboptions: key: description: Key. @@ -32,8 +34,8 @@ value: description: Value. type: str - type: dict - type: list + type: list + type: dict version_added: 4.2.0 deviceId: description: Device Id. @@ -53,9 +55,10 @@ type: bool type: dict version_added: 4.2.0 - interfaceName: + ipInterfaceName: description: For Catalyst 9800 WLC. type: str + version_added: 6.4.0 rfProfile: description: For Access Points. type: str @@ -76,12 +79,13 @@ type: description: Type. type: str - vlanID: + vlanId: description: For Catalyst 9800 WLC. type: str + version_added: 6.4.0 requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) ClaimADeviceToASite description: Complete reference of the ClaimADeviceToASite API. @@ -106,26 +110,25 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" configInfo: - - configId: string + configId: string configParameters: - key: string + - key: string value: string deviceId: string gateway: string imageInfo: imageId: string skip: true - interfaceName: string + ipInterfaceName: string rfProfile: string sensorProfile: string siteId: string staticIP: string subnetMask: string type: string - vlanID: string + vlanId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_device_config_preview.py b/plugins/modules/pnp_device_config_preview.py index 24d1ae219c..35cce9d30e 100644 --- a/plugins/modules/pnp_device_config_preview.py +++ b/plugins/modules/pnp_device_config_preview.py @@ -26,8 +26,8 @@ description: Pnp Device Config Preview's type. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) PreviewConfig description: Complete reference of the PreviewConfig API. @@ -56,7 +56,6 @@ type: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_device_count_info.py b/plugins/modules/pnp_device_count_info.py index 94dc35fa23..562196fe08 100644 --- a/plugins/modules/pnp_device_count_info.py +++ b/plugins/modules/pnp_device_count_info.py @@ -21,67 +21,52 @@ type: dict serialNumber: description: - - SerialNumber query parameter. Device Serial Number. + - SerialNumber query parameter. Device Serial Number. elements: str type: list state_: description: - - State query parameter. Device State. + - State query parameter. Device State. elements: str type: list onbState: description: - - OnbState query parameter. Device Onboarding State. - elements: str - type: list - cmState: - description: - - CmState query parameter. Device Connection Manager State. + - OnbState query parameter. Device Onboarding State. elements: str type: list name: description: - - Name query parameter. Device Name. + - Name query parameter. Device Name. elements: str type: list pid: description: - - Pid query parameter. Device ProductId. + - Pid query parameter. Device ProductId. elements: str type: list source: description: - - Source query parameter. Device Source. - elements: str - type: list - projectId: - description: - - ProjectId query parameter. Device Project Id. + - Source query parameter. Device Source. elements: str type: list workflowId: description: - - WorkflowId query parameter. Device Workflow Id. - elements: str - type: list - projectName: - description: - - ProjectName query parameter. Device Project Name. + - WorkflowId query parameter. Device Workflow Id. elements: str type: list workflowName: description: - - WorkflowName query parameter. Device Workflow Name. + - WorkflowName query parameter. Device Workflow Name. elements: str type: list smartAccountId: description: - - SmartAccountId query parameter. Device Smart Account. + - SmartAccountId query parameter. Device Smart Account. elements: str type: list virtualAccountId: description: - - VirtualAccountId query parameter. Device Virtual Account. + - VirtualAccountId query parameter. Device Virtual Account. elements: str type: list lastContact: @@ -89,8 +74,8 @@ - LastContact query parameter. Device Has Contacted lastContact > 0. type: bool requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) GetDeviceCount description: Complete reference of the GetDeviceCount API. @@ -118,13 +103,10 @@ serialNumber: [] state_: [] onbState: [] - cmState: [] name: [] pid: [] source: [] - projectId: [] workflowId: [] - projectName: [] workflowName: [] smartAccountId: [] virtualAccountId: [] @@ -132,7 +114,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_device_history_info.py b/plugins/modules/pnp_device_history_info.py index 781a2f035c..44bad616ce 100644 --- a/plugins/modules/pnp_device_history_info.py +++ b/plugins/modules/pnp_device_history_info.py @@ -25,7 +25,7 @@ type: str sort: description: - - Sort query parameter. Comma seperated list of fields to sort on. + - Sort query parameter. Comma seperated list of fields to sort on. elements: str type: list sortOrder: @@ -33,8 +33,8 @@ - SortOrder query parameter. Sort Order Ascending (asc) or Descending (des). type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) GetDeviceHistory description: Complete reference of the GetDeviceHistory API. @@ -65,7 +65,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_device_import.py b/plugins/modules/pnp_device_import.py index ed0802a80b..a99660f570 100644 --- a/plugins/modules/pnp_device_import.py +++ b/plugins/modules/pnp_device_import.py @@ -21,810 +21,119 @@ elements: dict suboptions: _id: - description: Pnp Device Import's _id. + description: Id. type: str deviceInfo: description: Pnp Device Import's deviceInfo. suboptions: - aaaCredentials: - description: Pnp Device Import's aaaCredentials. - suboptions: - password: - description: Pnp Device Import's password. - type: str - username: - description: Pnp Device Import's username. - type: str - type: dict - addedOn: - description: Pnp Device Import's addedOn. - type: int - addnMacAddrs: - description: Pnp Device Import's addnMacAddrs. - elements: str - type: list - agentType: - description: Pnp Device Import's agentType. - type: str - authStatus: - description: Pnp Device Import's authStatus. - type: str - authenticatedSudiSerialNo: - description: Pnp Device Import's authenticatedSudiSerialNo. - type: str - capabilitiesSupported: - description: Pnp Device Import's capabilitiesSupported. - elements: str - type: list - cmState: - description: Pnp Device Import's cmState. - type: str description: - description: Pnp Device Import's description. + description: Description. type: str deviceSudiSerialNos: - description: Pnp Device Import's deviceSudiSerialNos. - elements: str - type: list - deviceType: - description: Pnp Device Import's deviceType. - type: str - featuresSupported: - description: Pnp Device Import's featuresSupported. + description: Device Sudi Serial Nos. elements: str type: list - fileSystemList: - description: Pnp Device Import's fileSystemList. - elements: dict - suboptions: - freespace: - description: Pnp Device Import's freespace. - type: int - name: - description: Pnp Device Import's name. - type: str - readable: - description: Readable flag. - type: bool - size: - description: Pnp Device Import's size. - type: int - type: - description: Pnp Device Import's type. - type: str - writeable: - description: Writeable flag. - type: bool - type: list - firstContact: - description: Pnp Device Import's firstContact. - type: int hostname: - description: Pnp Device Import's hostname. - type: str - httpHeaders: - description: Pnp Device Import's httpHeaders. - elements: dict - suboptions: - key: - description: Pnp Device Import's key. - type: str - value: - description: Pnp Device Import's value. - type: str - type: list - imageFile: - description: Pnp Device Import's imageFile. + description: Hostname. type: str - imageVersion: - description: Pnp Device Import's imageVersion. - type: str - ipInterfaces: - description: Pnp Device Import's ipInterfaces. - elements: dict - suboptions: - ipv4Address: - description: Pnp Device Import's ipv4Address. - type: dict - ipv6AddressList: - description: Pnp Device Import's ipv6AddressList. - elements: dict - type: list - macAddress: - description: Pnp Device Import's macAddress. - type: str - name: - description: Pnp Device Import's name. - type: str - status: - description: Pnp Device Import's status. - type: str - type: list - lastContact: - description: Pnp Device Import's lastContact. - type: int - lastSyncTime: - description: Pnp Device Import's lastSyncTime. - type: int - lastUpdateOn: - description: Pnp Device Import's lastUpdateOn. - type: int - location: - description: Pnp Device Import's location. - suboptions: - address: - description: Pnp Device Import's address. - type: str - altitude: - description: Pnp Device Import's altitude. - type: str - latitude: - description: Pnp Device Import's latitude. - type: str - longitude: - description: Pnp Device Import's longitude. - type: str - siteId: - description: Pnp Device Import's siteId. - type: str - type: dict + isSudiRequired: + description: Is Sudi Required. + type: bool macAddress: - description: Pnp Device Import's macAddress. - type: str - mode: - description: Pnp Device Import's mode. - type: str - name: - description: Pnp Device Import's name. - type: str - neighborLinks: - description: Pnp Device Import's neighborLinks. - elements: dict - suboptions: - localInterfaceName: - description: Pnp Device Import's localInterfaceName. - type: str - localMacAddress: - description: Pnp Device Import's localMacAddress. - type: str - localShortInterfaceName: - description: Pnp Device Import's localShortInterfaceName. - type: str - remoteDeviceName: - description: Pnp Device Import's remoteDeviceName. - type: str - remoteInterfaceName: - description: Pnp Device Import's remoteInterfaceName. - type: str - remoteMacAddress: - description: Pnp Device Import's remoteMacAddress. - type: str - remotePlatform: - description: Pnp Device Import's remotePlatform. - type: str - remoteShortInterfaceName: - description: Pnp Device Import's remoteShortInterfaceName. - type: str - remoteVersion: - description: Pnp Device Import's remoteVersion. - type: str - type: list - onbState: - description: Pnp Device Import's onbState. + description: Mac Address. type: str pid: - description: Pnp Device Import's pid. - type: str - pnpProfileList: - description: Pnp Device Import's pnpProfileList. - elements: dict - suboptions: - createdBy: - description: Pnp Device Import's createdBy. - type: str - discoveryCreated: - description: DiscoveryCreated flag. - type: bool - primaryEndpoint: - description: Pnp Device Import's primaryEndpoint. - suboptions: - certificate: - description: Pnp Device Import's certificate. - type: str - fqdn: - description: Pnp Device Import's fqdn. - type: str - ipv4Address: - description: Pnp Device Import's ipv4Address. - type: dict - ipv6Address: - description: Pnp Device Import's ipv6Address. - type: dict - port: - description: Pnp Device Import's port. - type: int - protocol: - description: Pnp Device Import's protocol. - type: str - type: dict - profileName: - description: Pnp Device Import's profileName. - type: str - secondaryEndpoint: - description: Pnp Device Import's secondaryEndpoint. - suboptions: - certificate: - description: Pnp Device Import's certificate. - type: str - fqdn: - description: Pnp Device Import's fqdn. - type: str - ipv4Address: - description: Pnp Device Import's ipv4Address. - type: dict - ipv6Address: - description: Pnp Device Import's ipv6Address. - type: dict - port: - description: Pnp Device Import's port. - type: int - protocol: - description: Pnp Device Import's protocol. - type: str - type: dict - type: list - populateInventory: - description: PopulateInventory flag. - type: bool - preWorkflowCliOuputs: - description: Pnp Device Import's preWorkflowCliOuputs. - elements: dict - suboptions: - cli: - description: Pnp Device Import's cli. - type: str - cliOutput: - description: Pnp Device Import's cliOutput. - type: str - type: list - projectId: - description: Pnp Device Import's projectId. + description: Pid. type: str - projectName: - description: Pnp Device Import's projectName. - type: str - reloadRequested: - description: ReloadRequested flag. - type: bool serialNumber: - description: Pnp Device Import's serialNumber. - type: str - smartAccountId: - description: Pnp Device Import's smartAccountId. + description: Serial Number. type: str - source: - description: Pnp Device Import's source. + siteId: + description: Site Id. type: str stack: - description: Stack flag. + description: Stack. type: bool stackInfo: description: Pnp Device Import's stackInfo. suboptions: isFullRing: - description: IsFullRing flag. + description: Is Full Ring. type: bool stackMemberList: description: Pnp Device Import's stackMemberList. elements: dict suboptions: hardwareVersion: - description: Pnp Device Import's hardwareVersion. + description: Hardware Version. type: str licenseLevel: - description: Pnp Device Import's licenseLevel. + description: License Level. type: str licenseType: - description: Pnp Device Import's licenseType. + description: License Type. type: str macAddress: - description: Pnp Device Import's macAddress. + description: Mac Address. type: str pid: - description: Pnp Device Import's pid. + description: Pid. type: str priority: - description: Pnp Device Import's priority. - type: int + description: Priority. + type: float role: - description: Pnp Device Import's role. + description: Role. type: str serialNumber: - description: Pnp Device Import's serialNumber. + description: Serial Number. type: str softwareVersion: - description: Pnp Device Import's softwareVersion. + description: Software Version. type: str stackNumber: - description: Pnp Device Import's stackNumber. - type: int + description: Stack Number. + type: float state: - description: Pnp Device Import's state. + description: State. type: str sudiSerialNumber: - description: Pnp Device Import's sudiSerialNumber. + description: Sudi Serial Number. type: str type: list stackRingProtocol: - description: Pnp Device Import's stackRingProtocol. + description: Stack Ring Protocol. type: str supportsStackWorkflows: - description: SupportsStackWorkflows flag. + description: Supports Stack Workflows. type: bool totalMemberCount: - description: Pnp Device Import's totalMemberCount. - type: int + description: Total Member Count. + type: float validLicenseLevels: - description: Pnp Device Import's validLicenseLevels. + description: Valid License Levels. elements: str type: list type: dict - state: - description: Pnp Device Import's state. - type: str - sudiRequired: - description: SudiRequired flag. - type: bool - tags: - description: Pnp Device Import's tags. - type: dict + userMicNumbers: + description: User Mic Numbers. + elements: str + type: list userSudiSerialNos: - description: Pnp Device Import's userSudiSerialNos. + description: User Sudi Serial Nos. elements: str type: list - virtualAccountId: - description: Pnp Device Import's virtualAccountId. - type: str workflowId: - description: Pnp Device Import's workflowId. + description: Workflow Id. type: str workflowName: - description: Pnp Device Import's workflowName. - type: str - type: dict - runSummaryList: - description: Pnp Device Import's runSummaryList. - elements: dict - suboptions: - details: - description: Pnp Device Import's details. - type: str - errorFlag: - description: ErrorFlag flag. - type: bool - historyTaskInfo: - description: Pnp Device Import's historyTaskInfo. - suboptions: - addnDetails: - description: Pnp Device Import's addnDetails. - elements: dict - suboptions: - key: - description: Pnp Device Import's key. - type: str - value: - description: Pnp Device Import's value. - type: str - type: list - name: - description: Pnp Device Import's name. - type: str - timeTaken: - description: Pnp Device Import's timeTaken. - type: int - type: - description: Pnp Device Import's type. - type: str - workItemList: - description: Pnp Device Import's workItemList. - elements: dict - suboptions: - command: - description: Pnp Device Import's command. - type: str - endTime: - description: Pnp Device Import's endTime. - type: int - outputStr: - description: Pnp Device Import's outputStr. - type: str - startTime: - description: Pnp Device Import's startTime. - type: int - state: - description: Pnp Device Import's state. - type: str - timeTaken: - description: Pnp Device Import's timeTaken. - type: int - type: list - type: dict - timestamp: - description: Pnp Device Import's timestamp. - type: int - type: list - systemResetWorkflow: - description: Pnp Device Import's systemResetWorkflow. - suboptions: - _id: - description: Pnp Device Import's _id. - type: str - addToInventory: - description: AddToInventory flag. - type: bool - addedOn: - description: Pnp Device Import's addedOn. - type: int - configId: - description: Pnp Device Import's configId. - type: str - currTaskIdx: - description: Pnp Device Import's currTaskIdx. - type: int - description: - description: Pnp Device Import's description. - type: str - endTime: - description: Pnp Device Import's endTime. - type: int - execTime: - description: Pnp Device Import's execTime. - type: int - imageId: - description: Pnp Device Import's imageId. - type: str - instanceType: - description: Pnp Device Import's instanceType. - type: str - lastupdateOn: - description: Pnp Device Import's lastupdateOn. - type: int - name: - description: Pnp Device Import's name. - type: str - startTime: - description: Pnp Device Import's startTime. - type: int - state: - description: Pnp Device Import's state. - type: str - tasks: - description: Pnp Device Import's tasks. - elements: dict - suboptions: - currWorkItemIdx: - description: Pnp Device Import's currWorkItemIdx. - type: int - endTime: - description: Pnp Device Import's endTime. - type: int - name: - description: Pnp Device Import's name. - type: str - startTime: - description: Pnp Device Import's startTime. - type: int - state: - description: Pnp Device Import's state. - type: str - taskSeqNo: - description: Pnp Device Import's taskSeqNo. - type: int - timeTaken: - description: Pnp Device Import's timeTaken. - type: int - type: - description: Pnp Device Import's type. - type: str - workItemList: - description: Pnp Device Import's workItemList. - elements: dict - suboptions: - command: - description: Pnp Device Import's command. - type: str - endTime: - description: Pnp Device Import's endTime. - type: int - outputStr: - description: Pnp Device Import's outputStr. - type: str - startTime: - description: Pnp Device Import's startTime. - type: int - state: - description: Pnp Device Import's state. - type: str - timeTaken: - description: Pnp Device Import's timeTaken. - type: int - type: list - type: list - tenantId: - description: Pnp Device Import's tenantId. - type: str - type: - description: Pnp Device Import's type. - type: str - useState: - description: Pnp Device Import's useState. - type: str - version: - description: Pnp Device Import's version. - type: int - type: dict - systemWorkflow: - description: Pnp Device Import's systemWorkflow. - suboptions: - _id: - description: Pnp Device Import's _id. - type: str - addToInventory: - description: AddToInventory flag. - type: bool - addedOn: - description: Pnp Device Import's addedOn. - type: int - configId: - description: Pnp Device Import's configId. - type: str - currTaskIdx: - description: Pnp Device Import's currTaskIdx. - type: int - description: - description: Pnp Device Import's description. - type: str - endTime: - description: Pnp Device Import's endTime. - type: int - execTime: - description: Pnp Device Import's execTime. - type: int - imageId: - description: Pnp Device Import's imageId. - type: str - instanceType: - description: Pnp Device Import's instanceType. - type: str - lastupdateOn: - description: Pnp Device Import's lastupdateOn. - type: int - name: - description: Pnp Device Import's name. - type: str - startTime: - description: Pnp Device Import's startTime. - type: int - state: - description: Pnp Device Import's state. - type: str - tasks: - description: Pnp Device Import's tasks. - elements: dict - suboptions: - currWorkItemIdx: - description: Pnp Device Import's currWorkItemIdx. - type: int - endTime: - description: Pnp Device Import's endTime. - type: int - name: - description: Pnp Device Import's name. - type: str - startTime: - description: Pnp Device Import's startTime. - type: int - state: - description: Pnp Device Import's state. - type: str - taskSeqNo: - description: Pnp Device Import's taskSeqNo. - type: int - timeTaken: - description: Pnp Device Import's timeTaken. - type: int - type: - description: Pnp Device Import's type. - type: str - workItemList: - description: Pnp Device Import's workItemList. - elements: dict - suboptions: - command: - description: Pnp Device Import's command. - type: str - endTime: - description: Pnp Device Import's endTime. - type: int - outputStr: - description: Pnp Device Import's outputStr. - type: str - startTime: - description: Pnp Device Import's startTime. - type: int - state: - description: Pnp Device Import's state. - type: str - timeTaken: - description: Pnp Device Import's timeTaken. - type: int - type: list - type: list - tenantId: - description: Pnp Device Import's tenantId. - type: str - type: - description: Pnp Device Import's type. - type: str - useState: - description: Pnp Device Import's useState. - type: str - version: - description: Pnp Device Import's version. - type: int - type: dict - tenantId: - description: Pnp Device Import's tenantId. - type: str - version: - description: Pnp Device Import's version. - type: int - workflow: - description: Pnp Device Import's workflow. - suboptions: - _id: - description: Pnp Device Import's _id. - type: str - addToInventory: - description: AddToInventory flag. - type: bool - addedOn: - description: Pnp Device Import's addedOn. - type: int - configId: - description: Pnp Device Import's configId. - type: str - currTaskIdx: - description: Pnp Device Import's currTaskIdx. - type: int - description: - description: Pnp Device Import's description. - type: str - endTime: - description: Pnp Device Import's endTime. - type: int - execTime: - description: Pnp Device Import's execTime. - type: int - imageId: - description: Pnp Device Import's imageId. - type: str - instanceType: - description: Pnp Device Import's instanceType. - type: str - lastupdateOn: - description: Pnp Device Import's lastupdateOn. - type: int - name: - description: Pnp Device Import's name. - type: str - startTime: - description: Pnp Device Import's startTime. - type: int - state: - description: Pnp Device Import's state. - type: str - tasks: - description: Pnp Device Import's tasks. - elements: dict - suboptions: - currWorkItemIdx: - description: Pnp Device Import's currWorkItemIdx. - type: int - endTime: - description: Pnp Device Import's endTime. - type: int - name: - description: Pnp Device Import's name. - type: str - startTime: - description: Pnp Device Import's startTime. - type: int - state: - description: Pnp Device Import's state. - type: str - taskSeqNo: - description: Pnp Device Import's taskSeqNo. - type: int - timeTaken: - description: Pnp Device Import's timeTaken. - type: int - type: - description: Pnp Device Import's type. - type: str - workItemList: - description: Pnp Device Import's workItemList. - elements: dict - suboptions: - command: - description: Pnp Device Import's command. - type: str - endTime: - description: Pnp Device Import's endTime. - type: int - outputStr: - description: Pnp Device Import's outputStr. - type: str - startTime: - description: Pnp Device Import's startTime. - type: int - state: - description: Pnp Device Import's state. - type: str - timeTaken: - description: Pnp Device Import's timeTaken. - type: int - type: list - type: list - tenantId: - description: Pnp Device Import's tenantId. - type: str - type: - description: Pnp Device Import's type. - type: str - useState: - description: Pnp Device Import's useState. - type: str - version: - description: Pnp Device Import's version. - type: int - type: dict - workflowParameters: - description: Pnp Device Import's workflowParameters. - suboptions: - configList: - description: Pnp Device Import's configList. - elements: dict - suboptions: - configId: - description: Pnp Device Import's configId. - type: str - configParameters: - description: Pnp Device Import's configParameters. - elements: dict - suboptions: - key: - description: Pnp Device Import's key. - type: str - value: - description: Pnp Device Import's value. - type: str - type: list - type: list - licenseLevel: - description: Pnp Device Import's licenseLevel. - type: str - licenseType: - description: Pnp Device Import's licenseType. - type: str - topOfStackSerialNumber: - description: Pnp Device Import's topOfStackSerialNumber. + description: Workflow Name. type: str type: dict type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) ImportDevicesInBulk description: Complete reference of the ImportDevicesInBulk API. @@ -851,97 +160,15 @@ payload: - _id: string deviceInfo: - aaaCredentials: - password: string - username: string - addedOn: 0 - addnMacAddrs: - - string - agentType: string - authStatus: string - authenticatedSudiSerialNo: string - capabilitiesSupported: - - string - cmState: string description: string deviceSudiSerialNos: - string - deviceType: string - featuresSupported: - - string - fileSystemList: - - freespace: 0 - name: string - readable: true - size: 0 - type: string - writeable: true - firstContact: 0 hostname: string - httpHeaders: - - key: string - value: string - imageFile: string - imageVersion: string - ipInterfaces: - - ipv4Address: {} - ipv6AddressList: - - {} - macAddress: string - name: string - status: string - lastContact: 0 - lastSyncTime: 0 - lastUpdateOn: 0 - location: - address: string - altitude: string - latitude: string - longitude: string - siteId: string + isSudiRequired: true macAddress: string - mode: string - name: string - neighborLinks: - - localInterfaceName: string - localMacAddress: string - localShortInterfaceName: string - remoteDeviceName: string - remoteInterfaceName: string - remoteMacAddress: string - remotePlatform: string - remoteShortInterfaceName: string - remoteVersion: string - onbState: string pid: string - pnpProfileList: - - createdBy: string - discoveryCreated: true - primaryEndpoint: - certificate: string - fqdn: string - ipv4Address: {} - ipv6Address: {} - port: 0 - protocol: string - profileName: string - secondaryEndpoint: - certificate: string - fqdn: string - ipv4Address: {} - ipv6Address: {} - port: 0 - protocol: string - populateInventory: true - preWorkflowCliOuputs: - - cli: string - cliOutput: string - projectId: string - projectName: string - reloadRequested: true serialNumber: string - smartAccountId: string - source: string + siteId: string stack: true stackInfo: isFullRing: true @@ -963,151 +190,14 @@ totalMemberCount: 0 validLicenseLevels: - string - state: string - sudiRequired: true - tags: {} + userMicNumbers: + - string userSudiSerialNos: - string - virtualAccountId: string workflowId: string workflowName: string - runSummaryList: - - details: string - errorFlag: true - historyTaskInfo: - addnDetails: - - key: string - value: string - name: string - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - timestamp: 0 - systemResetWorkflow: - _id: string - addToInventory: true - addedOn: 0 - configId: string - currTaskIdx: 0 - description: string - endTime: 0 - execTime: 0 - imageId: string - instanceType: string - lastupdateOn: 0 - name: string - startTime: 0 - state: string - tasks: - - currWorkItemIdx: 0 - endTime: 0 - name: string - startTime: 0 - state: string - taskSeqNo: 0 - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - tenantId: string - type: string - useState: string - version: 0 - systemWorkflow: - _id: string - addToInventory: true - addedOn: 0 - configId: string - currTaskIdx: 0 - description: string - endTime: 0 - execTime: 0 - imageId: string - instanceType: string - lastupdateOn: 0 - name: string - startTime: 0 - state: string - tasks: - - currWorkItemIdx: 0 - endTime: 0 - name: string - startTime: 0 - state: string - taskSeqNo: 0 - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - tenantId: string - type: string - useState: string - version: 0 - tenantId: string - version: 0 - workflow: - _id: string - addToInventory: true - addedOn: 0 - configId: string - currTaskIdx: 0 - description: string - endTime: 0 - execTime: 0 - imageId: string - instanceType: string - lastupdateOn: 0 - name: string - startTime: 0 - state: string - tasks: - - currWorkItemIdx: 0 - endTime: 0 - name: string - startTime: 0 - state: string - taskSeqNo: 0 - timeTaken: 0 - type: string - workItemList: - - command: string - endTime: 0 - outputStr: string - startTime: 0 - state: string - timeTaken: 0 - tenantId: string - type: string - useState: string - version: 0 - workflowParameters: - configList: - - configId: string - configParameters: - - key: string - value: string - licenseLevel: string - licenseType: string - topOfStackSerialNumber: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -1117,7 +207,6 @@ { "successList": [ { - "_id": "string", "id": "string", "deviceInfo": { "source": "string", diff --git a/plugins/modules/pnp_device_info.py b/plugins/modules/pnp_device_info.py index 06500ec52b..6811c1c857 100644 --- a/plugins/modules/pnp_device_info.py +++ b/plugins/modules/pnp_device_info.py @@ -13,8 +13,8 @@ - Get Pnp Device by id. - Returns device details specified by device id. - > - Returns list of devices based on filter crieteria. If a limit is not specified, it will default to return 50 - devices. Pagination and sorting are also supported by this endpoint. + Returns list of devices from Plug & Play based on filter criteria. Returns 50 devices by default. This endpoint + supports Pagination and Sorting. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -33,7 +33,7 @@ type: int sort: description: - - Sort query parameter. Comma seperated list of fields to sort on. + - Sort query parameter. Comma seperated list of fields to sort on. elements: str type: list sortOrder: @@ -42,67 +42,52 @@ type: str serialNumber: description: - - SerialNumber query parameter. Device Serial Number. + - SerialNumber query parameter. Device Serial Number. elements: str type: list state_: description: - - State query parameter. Device State. + - State query parameter. Device State. elements: str type: list onbState: description: - - OnbState query parameter. Device Onboarding State. - elements: str - type: list - cmState: - description: - - CmState query parameter. Device Connection Manager State. + - OnbState query parameter. Device Onboarding State. elements: str type: list name: description: - - Name query parameter. Device Name. + - Name query parameter. Device Name. elements: str type: list pid: description: - - Pid query parameter. Device ProductId. + - Pid query parameter. Device ProductId. elements: str type: list source: description: - - Source query parameter. Device Source. - elements: str - type: list - projectId: - description: - - ProjectId query parameter. Device Project Id. + - Source query parameter. Device Source. elements: str type: list workflowId: description: - - WorkflowId query parameter. Device Workflow Id. - elements: str - type: list - projectName: - description: - - ProjectName query parameter. Device Project Name. + - WorkflowId query parameter. Device Workflow Id. elements: str type: list workflowName: description: - - WorkflowName query parameter. Device Workflow Name. + - WorkflowName query parameter. Device Workflow Name. elements: str type: list smartAccountId: description: - - SmartAccountId query parameter. Device Smart Account. + - SmartAccountId query parameter. Device Smart Account. elements: str type: list virtualAccountId: description: - - VirtualAccountId query parameter. Device Virtual Account. + - VirtualAccountId query parameter. Device Virtual Account. elements: str type: list lastContact: @@ -126,8 +111,8 @@ - Id path parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) GetDeviceById description: Complete reference of the GetDeviceById API. @@ -164,13 +149,10 @@ serialNumber: [] state_: [] onbState: [] - cmState: [] name: [] pid: [] source: [] - projectId: [] workflowId: [] - projectName: [] workflowName: [] smartAccountId: [] virtualAccountId: [] @@ -194,7 +176,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_device_reset.py b/plugins/modules/pnp_device_reset.py index df5a7fe154..3470560f88 100644 --- a/plugins/modules/pnp_device_reset.py +++ b/plugins/modules/pnp_device_reset.py @@ -59,8 +59,8 @@ description: Pnp Device Reset's workflowId. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) ResetDevice description: Complete reference of the ResetDevice API. @@ -98,7 +98,6 @@ workflowId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_device_unclaim.py b/plugins/modules/pnp_device_unclaim.py index 81ac6a27be..47e4c00ef8 100644 --- a/plugins/modules/pnp_device_unclaim.py +++ b/plugins/modules/pnp_device_unclaim.py @@ -10,7 +10,7 @@ short_description: Resource module for Pnp Device Unclaim description: - Manage operation create of the resource Pnp Device Unclaim. -- Un-Claims one of more devices with specified workflow. +- Un-Claims one of more devices with specified workflow Deprecated . version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module @@ -21,8 +21,8 @@ elements: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) UnClaimDevice description: Complete reference of the UnClaimDevice API. @@ -50,7 +50,6 @@ - string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_global_settings.py b/plugins/modules/pnp_global_settings.py index b7bd4f09ea..5c08d610d4 100644 --- a/plugins/modules/pnp_global_settings.py +++ b/plugins/modules/pnp_global_settings.py @@ -16,150 +16,81 @@ - cisco.dnac.module author: Rafael Campos (@racampos) options: - _id: - description: Pnp Global Settings's _id. - type: str - aaaCredentials: - description: Pnp Global Settings's aaaCredentials. - suboptions: - password: - description: Pnp Global Settings's password. - type: str - username: - description: Pnp Global Settings's username. - type: str - type: dict acceptEula: - description: AcceptEula flag. - type: bool + description: Accept Eula. + type: str defaultProfile: description: Pnp Global Settings's defaultProfile. suboptions: cert: - description: Pnp Global Settings's cert. + description: Cert. type: str fqdnAddresses: - description: Pnp Global Settings's fqdnAddresses. + description: Fqdn Addresses. elements: str type: list ipAddresses: - description: Pnp Global Settings's ipAddresses. + description: Ip Addresses. elements: str type: list port: - description: Pnp Global Settings's port. - type: int + description: Port. + type: str proxy: - description: Proxy flag. - type: bool + description: Proxy. + type: str type: dict + id: + description: Id. + type: str savaMappingList: description: Pnp Global Settings's savaMappingList. elements: dict suboptions: - autoSyncPeriod: - description: Pnp Global Settings's autoSyncPeriod. - type: int ccoUser: - description: Pnp Global Settings's ccoUser. + description: Cco User. type: str expiry: - description: Pnp Global Settings's expiry. - type: int - lastSync: - description: Pnp Global Settings's lastSync. - type: int + description: Expiry. + type: str profile: description: Pnp Global Settings's profile. suboptions: addressFqdn: - description: Pnp Global Settings's addressFqdn. + description: Address Fqdn. type: str addressIpV4: - description: Pnp Global Settings's addressIpV4. + description: Address Ip V4. type: str cert: - description: Pnp Global Settings's cert. + description: Cert. type: str makeDefault: - description: MakeDefault flag. - type: bool + description: Make Default. + type: str name: - description: Pnp Global Settings's name. + description: Name. type: str port: - description: Pnp Global Settings's port. - type: int + description: Port. + type: str profileId: - description: Pnp Global Settings's profileId. + description: Profile Id. type: str proxy: - description: Proxy flag. - type: bool - type: dict - smartAccountId: - description: Pnp Global Settings's smartAccountId. - type: str - syncResult: - description: Pnp Global Settings's syncResult. - suboptions: - syncList: - description: Pnp Global Settings's syncList. - elements: dict - suboptions: - deviceSnList: - description: Pnp Global Settings's deviceSnList. - elements: str - type: list - syncType: - description: Pnp Global Settings's syncType. - type: str - type: list - syncMsg: - description: Pnp Global Settings's syncMsg. + description: Proxy. type: str type: dict - syncResultStr: - description: Pnp Global Settings's syncResultStr. - type: str - syncStartTime: - description: Pnp Global Settings's syncStartTime. - type: int - syncStatus: - description: Pnp Global Settings's syncStatus. - type: str - tenantId: - description: Pnp Global Settings's tenantId. - type: str - token: - description: Pnp Global Settings's token. + smartAccountId: + description: Smart Account Id. type: str virtualAccountId: - description: Pnp Global Settings's virtualAccountId. + description: Virtual Account Id. type: str type: list - taskTimeOuts: - description: Pnp Global Settings's taskTimeOuts. - suboptions: - configTimeOut: - description: Pnp Global Settings's configTimeOut. - type: int - generalTimeOut: - description: Pnp Global Settings's generalTimeOut. - type: int - imageDownloadTimeOut: - description: Pnp Global Settings's imageDownloadTimeOut. - type: int - type: dict - tenantId: - description: Pnp Global Settings's tenantId. - type: str - version: - description: Pnp Global Settings's version. - type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) UpdatePnPGlobalSettings description: Complete reference of the UpdatePnPGlobalSettings API. @@ -184,55 +115,32 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" state: present - _id: string - aaaCredentials: - password: string - username: string - acceptEula: true + acceptEula: string defaultProfile: cert: string fqdnAddresses: - string ipAddresses: - string - port: 0 - proxy: true + port: string + proxy: string + id: string savaMappingList: - - autoSyncPeriod: 0 - ccoUser: string - expiry: 0 - lastSync: 0 + - ccoUser: string + expiry: string profile: addressFqdn: string addressIpV4: string cert: string - makeDefault: true + makeDefault: string name: string - port: 0 + port: string profileId: string - proxy: true + proxy: string smartAccountId: string - syncResult: - syncList: - - deviceSnList: - - string - syncType: string - syncMsg: string - syncResultStr: string - syncStartTime: 0 - syncStatus: string - tenantId: string - token: string virtualAccountId: string - taskTimeOuts: - configTimeOut: 0 - generalTimeOut: 0 - imageDownloadTimeOut: 0 - tenantId: string - version: 0 """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -299,7 +207,6 @@ }, "acceptEula": true, "id": "string", - "_id": "string", "version": 0 } """ diff --git a/plugins/modules/pnp_global_settings_info.py b/plugins/modules/pnp_global_settings_info.py index e9c124ec51..4ced097c3f 100644 --- a/plugins/modules/pnp_global_settings_info.py +++ b/plugins/modules/pnp_global_settings_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) GetPnPGlobalSettings description: Complete reference of the GetPnPGlobalSettings API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -116,7 +115,6 @@ }, "acceptEula": true, "id": "string", - "_id": "string", "version": 0 } """ diff --git a/plugins/modules/pnp_server_profile_update.py b/plugins/modules/pnp_server_profile_update.py index ee90a6978f..e51c2f5866 100644 --- a/plugins/modules/pnp_server_profile_update.py +++ b/plugins/modules/pnp_server_profile_update.py @@ -18,89 +18,46 @@ - cisco.dnac.module author: Rafael Campos (@racampos) options: - autoSyncPeriod: - description: Pnp Server Profile Update's autoSyncPeriod. - type: int ccoUser: - description: Pnp Server Profile Update's ccoUser. + description: Cco User. type: str - expiry: - description: Pnp Server Profile Update's expiry. - type: int - lastSync: - description: Pnp Server Profile Update's lastSync. - type: int profile: description: Pnp Server Profile Update's profile. suboptions: addressFqdn: - description: Pnp Server Profile Update's addressFqdn. + description: Address Fqdn. type: str addressIpV4: - description: Pnp Server Profile Update's addressIpV4. + description: Address Ip V4. type: str cert: - description: Pnp Server Profile Update's cert. + description: Cert. type: str makeDefault: - description: MakeDefault flag. + description: Make Default. type: bool name: - description: Pnp Server Profile Update's name. + description: Name. type: str port: - description: Pnp Server Profile Update's port. - type: int + description: Port. + type: float profileId: - description: Pnp Server Profile Update's profileId. + description: Profile Id. type: str proxy: - description: Proxy flag. + description: Proxy. type: bool type: dict smartAccountId: - description: Pnp Server Profile Update's smartAccountId. - type: str - syncResult: - description: Pnp Server Profile Update's syncResult. - suboptions: - syncList: - description: Pnp Server Profile Update's syncList. - elements: dict - suboptions: - deviceSnList: - description: Pnp Server Profile Update's deviceSnList. - elements: str - type: list - syncType: - description: Pnp Server Profile Update's syncType. - type: str - type: list - syncMsg: - description: Pnp Server Profile Update's syncMsg. - type: str - type: dict - syncResultStr: - description: Pnp Server Profile Update's syncResultStr. - type: str - syncStartTime: - description: Pnp Server Profile Update's syncStartTime. - type: int - syncStatus: - description: Pnp Server Profile Update's syncStatus. - type: str - tenantId: - description: Pnp Server Profile Update's tenantId. - type: str - token: - description: Pnp Server Profile Update's token. + description: Smart Account Id. type: str virtualAccountId: - description: Pnp Server Profile Update's virtualAccountId. + description: Virtual Account Id. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) UpdatePnPServerProfile description: Complete reference of the UpdatePnPServerProfile API. @@ -124,10 +81,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" - autoSyncPeriod: 0 ccoUser: string - expiry: 0 - lastSync: 0 profile: addressFqdn: string addressIpV4: string @@ -138,21 +92,9 @@ profileId: string proxy: true smartAccountId: string - syncResult: - syncList: - - deviceSnList: - - string - syncType: string - syncMsg: string - syncResultStr: string - syncStartTime: 0 - syncStatus: string - tenantId: string - token: string virtualAccountId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_smart_account_domains_info.py b/plugins/modules/pnp_smart_account_domains_info.py index bc612723a2..9472829730 100644 --- a/plugins/modules/pnp_smart_account_domains_info.py +++ b/plugins/modules/pnp_smart_account_domains_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) GetSmartAccountList description: Complete reference of the GetSmartAccountList API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_virtual_account_add.py b/plugins/modules/pnp_virtual_account_add.py index 7a3ceef874..6164411f2c 100644 --- a/plugins/modules/pnp_virtual_account_add.py +++ b/plugins/modules/pnp_virtual_account_add.py @@ -100,8 +100,8 @@ description: Pnp Virtual Account Add's virtualAccountId. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) AddVirtualAccount description: Complete reference of the AddVirtualAccount API. @@ -153,7 +153,6 @@ virtualAccountId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_virtual_account_deregister.py b/plugins/modules/pnp_virtual_account_deregister.py index 06af57d3b9..1aa0a0be84 100644 --- a/plugins/modules/pnp_virtual_account_deregister.py +++ b/plugins/modules/pnp_virtual_account_deregister.py @@ -26,8 +26,8 @@ description: Name query parameter. Virtual Account Name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) DeregisterVirtualAccount description: Complete reference of the DeregisterVirtualAccount API. @@ -55,7 +55,6 @@ name: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_virtual_account_devices_sync.py b/plugins/modules/pnp_virtual_account_devices_sync.py index 208bd3352c..b0da9899ab 100644 --- a/plugins/modules/pnp_virtual_account_devices_sync.py +++ b/plugins/modules/pnp_virtual_account_devices_sync.py @@ -12,7 +12,7 @@ - Manage operation create of the resource Pnp Virtual Account Devices Sync. - > Synchronizes the device info from the given smart account & virtual account with the PnP database. The response - payload returns a list of synced devices. + payload returns a list of synced devices Deprecated . version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module @@ -99,8 +99,8 @@ description: Pnp Virtual Account Devices Sync's virtualAccountId. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) SyncVirtualAccountDevices description: Complete reference of the SyncVirtualAccountDevices API. @@ -152,7 +152,6 @@ virtualAccountId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_virtual_account_sync_result_info.py b/plugins/modules/pnp_virtual_account_sync_result_info.py index 61a07cb79f..64f16b99fd 100644 --- a/plugins/modules/pnp_virtual_account_sync_result_info.py +++ b/plugins/modules/pnp_virtual_account_sync_result_info.py @@ -10,7 +10,7 @@ short_description: Information module for Pnp Virtual Account Sync Result description: - Get all Pnp Virtual Account Sync Result. -- Returns the summary of devices synced from the given smart account & virtual account with PnP. +- Returns the summary of devices synced from the given smart account & virtual account with PnP Deprecated . version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -28,8 +28,8 @@ - Name path parameter. Virtual Account Name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) GetSyncResultForVirtualAccount description: Complete reference of the GetSyncResultForVirtualAccount API. @@ -59,7 +59,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_virtual_accounts_info.py b/plugins/modules/pnp_virtual_accounts_info.py index 635a189d5d..548d52030d 100644 --- a/plugins/modules/pnp_virtual_accounts_info.py +++ b/plugins/modules/pnp_virtual_accounts_info.py @@ -24,8 +24,8 @@ - Domain path parameter. Smart Account Domain. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) GetVirtualAccountList description: Complete reference of the GetVirtualAccountList API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_workflow.py b/plugins/modules/pnp_workflow.py index d8658e0ea3..d1a9fa473f 100644 --- a/plugins/modules/pnp_workflow.py +++ b/plugins/modules/pnp_workflow.py @@ -128,8 +128,8 @@ description: Pnp Workflow's version. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) AddAWorkflow description: Complete reference of the AddAWorkflow API. @@ -258,7 +258,6 @@ version: 0 """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_workflow_count_info.py b/plugins/modules/pnp_workflow_count_info.py index 3c835c119b..ae4630b978 100644 --- a/plugins/modules/pnp_workflow_count_info.py +++ b/plugins/modules/pnp_workflow_count_info.py @@ -21,12 +21,12 @@ type: dict name: description: - - Name query parameter. Workflow Name. + - Name query parameter. Workflow Name. elements: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) GetWorkflowCount description: Complete reference of the GetWorkflowCount API. @@ -55,7 +55,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/pnp_workflow_info.py b/plugins/modules/pnp_workflow_info.py index d91ea342b7..0de9b85ab2 100644 --- a/plugins/modules/pnp_workflow_info.py +++ b/plugins/modules/pnp_workflow_info.py @@ -33,7 +33,7 @@ type: int sort: description: - - Sort query parameter. Comma seperated lost of fields to sort on. + - Sort query parameter. Comma seperated lost of fields to sort on. elements: str type: list sortOrder: @@ -42,12 +42,12 @@ type: str type: description: - - Type query parameter. Workflow Type. + - Type query parameter. Workflow Type. elements: str type: list name: description: - - Name query parameter. Workflow Name. + - Name query parameter. Workflow Name. elements: str type: list id: @@ -55,8 +55,8 @@ - Id path parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Device Onboarding (PnP) GetWorkflowById description: Complete reference of the GetWorkflowById API. @@ -108,7 +108,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/projects_details_info.py b/plugins/modules/projects_details_info.py index 2185060fde..4cd5705c00 100644 --- a/plugins/modules/projects_details_info.py +++ b/plugins/modules/projects_details_info.py @@ -40,8 +40,8 @@ - SortOrder query parameter. Sort Order Ascending (asc) or Descending (dsc). type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates GetProjectsDetails description: Complete reference of the GetProjectsDetails API. @@ -74,7 +74,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/qos_device_interface.py b/plugins/modules/qos_device_interface.py index e9b67c7601..147e4f2396 100644 --- a/plugins/modules/qos_device_interface.py +++ b/plugins/modules/qos_device_interface.py @@ -70,8 +70,8 @@ type: list type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy CreateQosDeviceInterfaceInfo description: Complete reference of the CreateQosDeviceInterfaceInfo API. @@ -159,7 +159,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/qos_device_interface_info.py b/plugins/modules/qos_device_interface_info.py index ad7bb2bbef..3e68409dc5 100644 --- a/plugins/modules/qos_device_interface_info.py +++ b/plugins/modules/qos_device_interface_info.py @@ -24,8 +24,8 @@ - NetworkDeviceId query parameter. Network device id. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy GetQosDeviceInterfaceInfo description: Complete reference of the GetQosDeviceInterfaceInfo API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/qos_device_interface_info_count_info.py b/plugins/modules/qos_device_interface_info_count_info.py index f77c2ce31f..7060c66699 100644 --- a/plugins/modules/qos_device_interface_info_count_info.py +++ b/plugins/modules/qos_device_interface_info_count_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Application Policy GetQosDeviceInterfaceInfoCount description: Complete reference of the GetQosDeviceInterfaceInfoCount API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/reports.py b/plugins/modules/reports.py index 3e7eab25c4..2227dd501e 100644 --- a/plugins/modules/reports.py +++ b/plugins/modules/reports.py @@ -19,6 +19,9 @@ - cisco.dnac.module author: Rafael Campos (@racampos) options: + dataCategory: + description: Category of viewgroup for the report. + type: str deliveries: description: Array of available delivery channels. elements: dict @@ -103,8 +106,8 @@ description: Version of viewgroup for the report. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Reports CreateOrScheduleAReport description: Complete reference of the CreateOrScheduleAReport API. @@ -134,6 +137,7 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" state: present + dataCategory: string deliveries: - {} name: string @@ -173,7 +177,6 @@ reportId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/reports_executions_info.py b/plugins/modules/reports_executions_info.py index f12cd7caa1..afb64b7ddc 100644 --- a/plugins/modules/reports_executions_info.py +++ b/plugins/modules/reports_executions_info.py @@ -44,8 +44,8 @@ - The filename used to save the download file. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Reports DownloadReportContent description: Complete reference of the DownloadReportContent API. @@ -93,7 +93,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/reports_info.py b/plugins/modules/reports_info.py index aed7e10df6..f0e58b723e 100644 --- a/plugins/modules/reports_info.py +++ b/plugins/modules/reports_info.py @@ -34,8 +34,8 @@ - ReportId path parameter. ReportId of report. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Reports GetAScheduledReport description: Complete reference of the GetAScheduledReport API. @@ -83,7 +83,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/reports_view_group_info.py b/plugins/modules/reports_view_group_info.py index 76b1317181..81219c69e4 100644 --- a/plugins/modules/reports_view_group_info.py +++ b/plugins/modules/reports_view_group_info.py @@ -28,8 +28,8 @@ - ViewGroupId path parameter. ViewGroupId of viewgroup. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Reports GetAllViewGroups description: Complete reference of the GetAllViewGroups API. @@ -75,7 +75,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/reports_view_group_view_info.py b/plugins/modules/reports_view_group_view_info.py index 11889bac94..2eb44befa3 100644 --- a/plugins/modules/reports_view_group_view_info.py +++ b/plugins/modules/reports_view_group_view_info.py @@ -30,8 +30,8 @@ - ViewId path parameter. View id of view. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Reports GetViewDetailsForAGivenViewGroup_View description: Complete reference of the GetViewDetailsForAGivenViewGroup_View API. @@ -61,7 +61,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/reserve_ip_subpool.py b/plugins/modules/reserve_ip_subpool.py index 507b0e0783..779dbc0910 100644 --- a/plugins/modules/reserve_ip_subpool.py +++ b/plugins/modules/reserve_ip_subpool.py @@ -22,11 +22,11 @@ description: Id path parameter. Id of reserve ip subpool to be deleted. type: str ipv4DhcpServers: - description: IPv4 input for dhcp server ip example 1.1.1.1. + description: IPv4 input for dhcp server ip example "1.1.1.1". elements: str type: list ipv4DnsServers: - description: IPv4 input for dns server ip example 4.4.4.4. + description: IPv4 input for dns server ip example "4.4.4.4". elements: str type: list ipv4GateWay: @@ -44,21 +44,22 @@ description: The ipv4 prefix length is required when ipv4prefix value is true. type: int ipv4Subnet: - description: IPv4 Subnet address, example 175.175.0.0. + description: IPv4 Subnet address, example 175.175.0.0. Either ipv4Subnet or ipv4TotalHost + needs to be passed if creating IPv4 subpool. type: str ipv4TotalHost: description: IPv4 total host is required when ipv4prefix value is false. type: int ipv6AddressSpace: - description: If the value is false only ipv4 input are required, otherwise both - ipv6 and ipv4 are required. + description: If the value is omitted or false only ipv4 input are required, otherwise + both ipv6 and ipv4 are required. type: bool ipv6DhcpServers: - description: IPv6 format dhcp server as input example 2001 db8 1234. + description: IPv6 format dhcp server as input example "2001 db8 1234". elements: str type: list ipv6DnsServers: - description: IPv6 format dns server input example 2001 db8 1234. + description: IPv6 format dns server input example "2001 db8 1234". elements: str type: list ipv6GateWay: @@ -76,7 +77,8 @@ description: IPv6 prefix length is required when the ipv6prefix value is true. type: int ipv6Subnet: - description: IPv6 Subnet address, example 2001 db8 85a3 0 100. + description: IPv6 Subnet address, example 2001 db8 85a3 0 100. Either ipv6Subnet + or ipv6TotalHost needs to be passed if creating IPv6 subpool. type: str ipv6TotalHost: description: IPv6 total host is required when ipv6prefix value is false. @@ -94,8 +96,8 @@ description: Type of the reserve ip sub pool. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings ReserveIPSubpool description: Complete reference of the ReserveIPSubpool API. @@ -200,7 +202,6 @@ slaacSupport: true """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/reserve_ip_subpool_create.py b/plugins/modules/reserve_ip_subpool_create.py index 699e7c96cb..55f70ba8bd 100644 --- a/plugins/modules/reserve_ip_subpool_create.py +++ b/plugins/modules/reserve_ip_subpool_create.py @@ -17,11 +17,11 @@ author: Rafael Campos (@racampos) options: ipv4DhcpServers: - description: IPv4 input for dhcp server ip example 1.1.1.1. + description: IPv4 input for dhcp server ip example "1.1.1.1". elements: str type: list ipv4DnsServers: - description: IPv4 input for dns server ip example 4.4.4.4. + description: IPv4 input for dns server ip example "4.4.4.4". elements: str type: list ipv4GateWay: @@ -38,21 +38,22 @@ description: The ipv4 prefix length is required when ipv4prefix value is true. type: int ipv4Subnet: - description: IPv4 Subnet address, example 175.175.0.0. + description: IPv4 Subnet address, example 175.175.0.0. Either ipv4Subnet or ipv4TotalHost + needs to be passed if creating IPv4 subpool. type: str ipv4TotalHost: description: IPv4 total host is required when ipv4prefix value is false. type: int ipv6AddressSpace: - description: If the value is false only ipv4 input are required, otherwise both - ipv6 and ipv4 are required. + description: If the value is omitted or false only ipv4 input are required, otherwise + both ipv6 and ipv4 are required. type: bool ipv6DhcpServers: - description: IPv6 format dhcp server as input example 2001 db8 1234. + description: IPv6 format dhcp server as input example "2001 db8 1234". elements: str type: list ipv6DnsServers: - description: IPv6 format dns server input example 2001 db8 1234. + description: IPv6 format dns server input example "2001 db8 1234". elements: str type: list ipv6GateWay: @@ -70,7 +71,8 @@ description: IPv6 prefix length is required when the ipv6prefix value is true. type: int ipv6Subnet: - description: IPv6 Subnet address, example 2001 db8 85a3 0 100. + description: IPv6 Subnet address, example 2001 db8 85a3 0 100. Either ipv6Subnet + or ipv6TotalHost needs to be passed if creating IPv6 subpool. type: str ipv6TotalHost: description: IPv6 total host is required when ipv6prefix value is false. @@ -88,8 +90,8 @@ description: Type of the reserve ip sub pool. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings ReserveIPSubpool description: Complete reference of the ReserveIPSubpool API. @@ -140,7 +142,6 @@ type: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/reserve_ip_subpool_delete.py b/plugins/modules/reserve_ip_subpool_delete.py index 65ecd4733c..18bd1decb8 100644 --- a/plugins/modules/reserve_ip_subpool_delete.py +++ b/plugins/modules/reserve_ip_subpool_delete.py @@ -20,8 +20,8 @@ description: Id path parameter. Id of reserve ip subpool to be deleted. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings ReleaseReserveIPSubpool description: Complete reference of the ReleaseReserveIPSubpool API. @@ -48,7 +48,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/reserve_ip_subpool_info.py b/plugins/modules/reserve_ip_subpool_info.py index ec3c76d16c..5a787a7d3e 100644 --- a/plugins/modules/reserve_ip_subpool_info.py +++ b/plugins/modules/reserve_ip_subpool_info.py @@ -21,19 +21,37 @@ type: dict siteId: description: - - SiteId query parameter. Site id to get the reserve ip associated with the site. + - > + SiteId query parameter. Site id of site from which to retrieve associated reserve pools. Either siteId (per + site queries) or ignoreInheritedGroups must be used. They can also be used together. type: str offset: description: - - Offset query parameter. Offset/starting row. - type: int + - Offset query parameter. Offset/starting row. Indexed from 1. + type: float limit: description: - - Limit query parameter. No of Global Pools to be retrieved. - type: int + - > + Limit query parameter. Number of reserve pools to be retrieved. Default is 25 if not specified. Maximum + allowed limit is 500. + type: float + ignoreInheritedGroups: + description: + - > + IgnoreInheritedGroups query parameter. Ignores pools inherited from parent site. Either siteId or + ignoreInheritedGroups must be passed. They can also be used together. + type: str + poolUsage: + description: + - PoolUsage query parameter. Can take values empty, partially-full or empty-partially-full. + type: str + groupName: + description: + - GroupName query parameter. Name of the group. + type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings GetReserveIPSubpool description: Complete reference of the GetReserveIPSubpool API. @@ -61,10 +79,12 @@ siteId: string offset: 0 limit: 0 + ignoreInheritedGroups: string + poolUsage: string + groupName: string register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/reserve_ip_subpool_update.py b/plugins/modules/reserve_ip_subpool_update.py index 4bf71c42ce..93dc11c0c8 100644 --- a/plugins/modules/reserve_ip_subpool_update.py +++ b/plugins/modules/reserve_ip_subpool_update.py @@ -17,50 +17,51 @@ author: Rafael Campos (@racampos) options: id: - description: Id query parameter. Id of subpool to be associated with the site. + description: Id query parameter. Id of subpool group. type: str ipv4DhcpServers: - description: IPv4 input for dhcp server ip example 1.1.1.1. + description: IPv4 input for dhcp server ip example "1.1.1.1". elements: str type: list ipv4DnsServers: - description: IPv4 input for dns server ip example 4.4.4.4. + description: IPv4 input for dns server ip example "4.4.4.4". elements: str type: list ipv4GateWay: - description: Ipv4 Gate Way. + description: Gateway ip address details, example 175.175.0.1. type: str ipv6AddressSpace: - description: If the value is false only ipv4 input are required, otherwise both - ipv6 and ipv4 are required. + description: If the value is false only ipv4 input are required. NOTE if value is + false then any existing ipv6 subpool in the group will be removed. type: bool ipv6DhcpServers: - description: IPv6 format dhcp server as input example 2001 db8 1234. + description: IPv6 format dhcp server as input example "2001 db8 1234". elements: str type: list ipv6DnsServers: - description: IPv6 format dns server input example 2001 db8 1234. + description: IPv6 format dns server input example "2001 db8 1234". elements: str type: list ipv6GateWay: description: Gateway ip address details, example 2001 db8 85a3 0 100 1. type: str ipv6GlobalPool: - description: IP v6 Global pool address with cidr this is required when Ipv6AddressSpace + description: IPv6 Global pool address with cidr this is required when Ipv6AddressSpace value is true, example 2001 db8 85a3 /64. type: str ipv6Prefix: - description: IPv6 prefix value is true, the ip6 prefix length input field is enabled - , if it is false ipv6 total Host input is enable. + description: Ipv6 prefix value is true, the ip6 prefix length input field is enabled, + if it is false ipv6 total Host input is enable. type: bool ipv6PrefixLength: description: IPv6 prefix length is required when the ipv6prefix value is true. type: int ipv6Subnet: - description: IPv6 Subnet address, example 2001 db8 85a3 0 100. + description: IPv6 Subnet address, example 2001 db8 85a3 0 100 . type: str ipv6TotalHost: - description: IPv6 total host is required when ipv6prefix value is false. + description: Size of pool in terms of number of IPs. IPv6 total host is required + when ipv6prefix value is false. type: int name: description: Name of the reserve ip sub pool. @@ -72,8 +73,8 @@ description: Slaac Support. type: bool requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings UpdateReserveIPSubpool description: Complete reference of the UpdateReserveIPSubpool API. @@ -122,7 +123,6 @@ slaacSupport: true """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/role_permissions_info.py b/plugins/modules/role_permissions_info.py index 51957ed067..6354356651 100644 --- a/plugins/modules/role_permissions_info.py +++ b/plugins/modules/role_permissions_info.py @@ -11,7 +11,7 @@ description: - Get all Role Permissions. - Get permissions for a role from Cisco DNA Center System. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -20,15 +20,15 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for User and Roles GetPermissionsAPI description: Complete reference of the GetPermissionsAPI API. link: https://developer.cisco.com/docs/dna-center/#!get-permissions-api notes: - SDK Method used are - user_and_roles.UserandRoles.get_permissions_ap_i, + userand_roles.UserandRoles.get_permissions_api, - Paths used are get /dna/system/api/v1/role/permissions, @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/roles.py b/plugins/modules/roles.py new file mode 100644 index 0000000000..c5d1aca2dc --- /dev/null +++ b/plugins/modules/roles.py @@ -0,0 +1,127 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: roles +short_description: Resource module for Roles +description: +- Manage operations create, update and delete of the resource Roles. +- Add a new role in Cisco DNA Center System. +- Delete a role in Cisco DNA Center System. +- Update a role in Cisco DNA Center System. +version_added: '3.1.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + description: + description: Description of role. + type: str + resourceTypes: + description: Roles's resourceTypes. + elements: dict + suboptions: + operations: + description: List of operations allowed for the application. Possible values + are "gRead", "gWrite", "gUpdate", "gDelete", or some combination of these. + elements: str + type: list + type: + description: Name of the application in Cisco DNA Center System. + type: str + type: list + role: + description: Name of the role. + type: str + roleId: + description: Id of the role. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for User and Roles AddRoleAPI + description: Complete reference of the AddRoleAPI API. + link: https://developer.cisco.com/docs/dna-center/#!add-role-api +- name: Cisco DNA Center documentation for User and Roles DeleteRoleAPI + description: Complete reference of the DeleteRoleAPI API. + link: https://developer.cisco.com/docs/dna-center/#!delete-role-api +- name: Cisco DNA Center documentation for User and Roles UpdateRoleAPI + description: Complete reference of the UpdateRoleAPI API. + link: https://developer.cisco.com/docs/dna-center/#!update-role-api +notes: + - SDK Method used are + userand_roles.UserandRoles.add_role_api, + userand_roles.UserandRoles.delete_role_api, + userand_roles.UserandRoles.update_role_api, + + - Paths used are + post /dna/system/api/v1/role, + delete /dna/system/api/v1/role/{roleId}, + put /dna/system/api/v1/role, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.roles: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + description: string + resourceTypes: + - operations: + - string + type: string + role: string + +- name: Update all + cisco.dnac.roles: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + description: string + resourceTypes: + - operations: + - string + type: string + roleId: string + +- name: Delete by id + cisco.dnac.roles: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + roleId: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "roleId": "string", + "message": "string" + } +""" diff --git a/plugins/modules/roles_info.py b/plugins/modules/roles_info.py index a8ce30ddfc..deb930512a 100644 --- a/plugins/modules/roles_info.py +++ b/plugins/modules/roles_info.py @@ -10,8 +10,8 @@ short_description: Information module for Roles description: - Get all Roles. -- Get all roles for the Cisco DNA Center system. -version_added: '6.7.0' +- Get all roles for the Cisco DNA Center System. +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -20,15 +20,15 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for User and Roles GetRolesAPI description: Complete reference of the GetRolesAPI API. link: https://developer.cisco.com/docs/dna-center/#!get-roles-api notes: - SDK Method used are - user_and_roles.UserandRoles.get_roles_ap_i, + userand_roles.UserandRoles.get_roles_api, - Paths used are get /dna/system/api/v1/roles, @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_anycast_gateways.py b/plugins/modules/sda_anycast_gateways.py new file mode 100644 index 0000000000..a53b86d0be --- /dev/null +++ b/plugins/modules/sda_anycast_gateways.py @@ -0,0 +1,203 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_anycastGateways +short_description: Resource module for Sda Anycastgateways +description: +- Manage operations create, update and delete of the resource Sda Anycastgateways. +- Adds anycast gateways based on user input. +- Deletes an anycast gateway based on id. +- Updates anycast gateways based on user input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + id: + description: Id path parameter. ID of the anycast gateway to be deleted. + type: str + payload: + description: Sda Anycast Gateways's payload. + elements: dict + suboptions: + fabricId: + description: ID of the fabric containing this anycast gateway. Updating anycast + gateways on fabric zones is not allowed--instead, update the corresponding + anycast gateway on the fabric site and the updates will be applied on all + applicable fabric zones (updating this field is not allowed). + type: str + id: + description: ID of the anycast gateway (updating this field is not allowed). + type: str + ipPoolName: + description: Name of the IP pool associated with the anycast gateway (updating + this field is not allowed). + type: str + isCriticalPool: + description: Enable/disable critical VLAN (not applicable to INFRA_VN; updating + this field is not allowed). + type: bool + isIntraSubnetRoutingEnabled: + description: Enable/disable Intra-Subnet Routing (not applicable to INFRA_VN; + updating this field is not allowed). + type: bool + isIpDirectedBroadcast: + description: Enable/disable IP-directed broadcast (not applicable to INFRA_VN). + type: bool + isLayer2FloodingEnabled: + description: Enable/disable layer 2 flooding (not applicable to INFRA_VN). + type: bool + isMultipleIpToMacAddresses: + description: Enable/disable multiple IP-to-MAC Addresses (Wireless Bridged-Network + Virtual Machine; not applicable to INFRA_VN). + type: bool + isSupplicantBasedExtendedNodeOnboarding: + description: Enable/disable Supplicant-Based Extended Node Onboarding (applicable + only to INFRA_VN; required when poolType is EXTENDED_NODE). + type: bool + isWirelessPool: + description: Enable/disable fabric-enabled wireless (not applicable to INFRA_VN). + type: bool + poolType: + description: The pool type of the anycast gateway (applicable only to INFRA_VN; + updating this field is not allowed). + type: str + securityGroupName: + description: Name of the associated Security Group (not applicable to INFRA_VN). + type: str + tcpMssAdjustment: + description: TCP maximum segment size adjustment. + type: int + trafficType: + description: The type of traffic the anycast gateway serves. + type: str + virtualNetworkName: + description: Name of the layer 3 virtual network associated with the anycast + gateway (updating this field is not allowed). + type: str + vlanId: + description: ID of the VLAN of the anycast gateway (updating this field is not + allowed). + type: int + vlanName: + description: Name of the VLAN of the anycast gateway (updating this field is + not allowed). + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA AddAnycastGateways + description: Complete reference of the AddAnycastGateways API. + link: https://developer.cisco.com/docs/dna-center/#!add-anycast-gateways +- name: Cisco DNA Center documentation for SDA DeleteAnycastGatewayById + description: Complete reference of the DeleteAnycastGatewayById API. + link: https://developer.cisco.com/docs/dna-center/#!delete-anycast-gateway-by-id +- name: Cisco DNA Center documentation for SDA UpdateAnycastGateways + description: Complete reference of the UpdateAnycastGateways API. + link: https://developer.cisco.com/docs/dna-center/#!update-anycast-gateways +notes: + - SDK Method used are + sda.Sda.add_anycast_gateways, + sda.Sda.delete_anycast_gateway_by_id, + sda.Sda.update_anycast_gateways, + + - Paths used are + post /dna/intent/api/v1/sda/anycastGateways, + delete /dna/intent/api/v1/sda/anycastGateways/{id}, + put /dna/intent/api/v1/sda/anycastGateways, + +""" + +EXAMPLES = r""" +- name: Update all + cisco.dnac.sda_anycastGateways: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - fabricId: string + id: string + ipPoolName: string + isCriticalPool: true + isIntraSubnetRoutingEnabled: true + isIpDirectedBroadcast: true + isLayer2FloodingEnabled: true + isMultipleIpToMacAddresses: true + isSupplicantBasedExtendedNodeOnboarding: true + isWirelessPool: true + poolType: string + securityGroupName: string + tcpMssAdjustment: 0 + trafficType: string + virtualNetworkName: string + vlanId: 0 + vlanName: string + +- name: Create + cisco.dnac.sda_anycastGateways: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - autoGenerateVlanName: true + fabricId: string + ipPoolName: string + isCriticalPool: true + isIntraSubnetRoutingEnabled: true + isIpDirectedBroadcast: true + isLayer2FloodingEnabled: true + isMultipleIpToMacAddresses: true + isSupplicantBasedExtendedNodeOnboarding: true + isWirelessPool: true + poolType: string + securityGroupName: string + tcpMssAdjustment: 0 + trafficType: string + virtualNetworkName: string + vlanId: 0 + vlanName: string + +- name: Delete by id + cisco.dnac.sda_anycastGateways: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_anycast_gateways_count_info.py b/plugins/modules/sda_anycast_gateways_count_info.py new file mode 100644 index 0000000000..76b979741f --- /dev/null +++ b/plugins/modules/sda_anycast_gateways_count_info.py @@ -0,0 +1,89 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_anycastGateways_count_info +short_description: Information module for Sda Anycastgateways Count +description: +- Get all Sda Anycastgateways Count. +- Returns the count of anycast gateways that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. Only count anycast gateways within this fabric. + type: str + virtualNetworkName: + description: + - VirtualNetworkName query parameter. Only count anycast gateways associated with this virtual network. + type: str + ipPoolName: + description: + - IpPoolName query parameter. Only count anycast gateways associated with this IP pool. + type: str + vlanName: + description: + - VlanName query parameter. Only count anycast gateways associated with this VLAN name. + type: str + vlanId: + description: + - VlanId query parameter. Only count anycast gateways associated with this VLAN ID. + type: int +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetAnycastGatewayCount + description: Complete reference of the GetAnycastGatewayCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-anycast-gateway-count +notes: + - SDK Method used are + sda.Sda.get_anycast_gateway_count, + + - Paths used are + get /dna/intent/api/v1/sda/anycastGateways/count, + +""" + +EXAMPLES = r""" +- name: Get all Sda Anycastgateways Count + cisco.dnac.sda_anycastGateways_count_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + virtualNetworkName: string + ipPoolName: string + vlanName: string + vlanId: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "count": 0 + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_anycast_gateways_info.py b/plugins/modules/sda_anycast_gateways_info.py new file mode 100644 index 0000000000..b37753e354 --- /dev/null +++ b/plugins/modules/sda_anycast_gateways_info.py @@ -0,0 +1,122 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_anycastGateways_info +short_description: Information module for Sda Anycastgateways +description: +- Get all Sda Anycastgateways. +- Returns a list of anycast gateways that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + id: + description: + - Id query parameter. ID of the anycast gateway to search for in the database. + type: str + fabricId: + description: + - FabricId query parameter. Get anycast gateways within this fabric. + type: str + virtualNetworkName: + description: + - VirtualNetworkName query parameter. Get anycast gateways associated with this virtual network. + type: str + ipPoolName: + description: + - IpPoolName query parameter. Get anycast gateways associated with this IP pool. + type: str + vlanName: + description: + - VlanName query parameter. Get anycast gateways associated with this VLAN name. + type: str + vlanId: + description: + - VlanId query parameter. Get anycast gateways associated with this VLAN ID. + type: int + offset: + description: + - Offset query parameter. Starting record for pagination. + type: int + limit: + description: + - Limit query parameter. Maximum number of records to return. + type: int +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetAnycastGateways + description: Complete reference of the GetAnycastGateways API. + link: https://developer.cisco.com/docs/dna-center/#!get-anycast-gateways +notes: + - SDK Method used are + sda.Sda.get_anycast_gateways, + + - Paths used are + get /dna/intent/api/v1/sda/anycastGateways, + +""" + +EXAMPLES = r""" +- name: Get all Sda Anycastgateways + cisco.dnac.sda_anycastGateways_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + id: string + fabricId: string + virtualNetworkName: string + ipPoolName: string + vlanName: string + vlanId: 0 + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "fabricId": "string", + "virtualNetworkName": "string", + "ipPoolName": "string", + "tcpMssAdjustment": 0, + "vlanName": "string", + "vlanId": 0, + "trafficType": "string", + "poolType": "string", + "securityGroupName": "string", + "isCriticalPool": true, + "isLayer2FloodingEnabled": true, + "isWirelessPool": true, + "isIpDirectedBroadcast": true, + "isIntraSubnetRoutingEnabled": true, + "isMultipleIpToMacAddresses": true, + "isSupplicantBasedExtendedNodeOnboarding": true + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/sda_authentication_profiles.py b/plugins/modules/sda_authentication_profiles.py new file mode 100644 index 0000000000..c79e14ddee --- /dev/null +++ b/plugins/modules/sda_authentication_profiles.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_authenticationProfiles +short_description: Resource module for Sda Authenticationprofiles +description: +- Manage operation update of the resource Sda Authenticationprofiles. +- Updates an authentication profile based on user input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + payload: + description: Sda Authentication Profiles's payload. + elements: dict + suboptions: + authenticationOrder: + description: First authentication method. + type: str + authenticationProfileName: + description: The default host authentication template (updating this field is + not allowed). + type: str + dot1xToMabFallbackTimeout: + description: 802.1x Timeout. + type: int + fabricId: + description: ID of the fabric site/zone (updating this field is not allowed). + type: str + id: + description: ID of the authentication profile (updating this field is not allowed). + type: str + numberOfHosts: + description: Number of Hosts. + type: str + wakeOnLan: + description: Wake on LAN. + type: bool + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA UpdateAuthenticationProfile + description: Complete reference of the UpdateAuthenticationProfile API. + link: https://developer.cisco.com/docs/dna-center/#!update-authentication-profile +notes: + - SDK Method used are + sda.Sda.update_authentication_profile, + + - Paths used are + put /dna/intent/api/v1/sda/authenticationProfiles, + +""" + +EXAMPLES = r""" +- name: Update all + cisco.dnac.sda_authenticationProfiles: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - authenticationOrder: string + authenticationProfileName: string + dot1xToMabFallbackTimeout: 0 + fabricId: string + id: string + numberOfHosts: string + wakeOnLan: true + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_authentication_profiles_info.py b/plugins/modules/sda_authentication_profiles_info.py new file mode 100644 index 0000000000..bdacc510ae --- /dev/null +++ b/plugins/modules/sda_authentication_profiles_info.py @@ -0,0 +1,84 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_authenticationProfiles_info +short_description: Information module for Sda Authenticationprofiles +description: +- Get all Sda Authenticationprofiles. +- Returns a list of authentication profiles that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. ID of the fabric whose authentication profiles are to be returned. + type: str + authenticationProfileName: + description: + - > + AuthenticationProfileName query parameter. Return only the authentication profiles with this specified name. + Note that 'No Authentication' is not a valid option for this parameter. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetAuthenticationProfiles + description: Complete reference of the GetAuthenticationProfiles API. + link: https://developer.cisco.com/docs/dna-center/#!get-authentication-profiles +notes: + - SDK Method used are + sda.Sda.get_authentication_profiles, + + - Paths used are + get /dna/intent/api/v1/sda/authenticationProfiles, + +""" + +EXAMPLES = r""" +- name: Get all Sda Authenticationprofiles + cisco.dnac.sda_authenticationProfiles_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + authenticationProfileName: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "fabricId": "string", + "authenticationProfileName": "string", + "authenticationOrder": "string", + "dot1xToMabFallbackTimeout": 0, + "wakeOnLan": true, + "numberOfHosts": "string" + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/sda_device_info.py b/plugins/modules/sda_device_info.py index 22029fe55b..2ccc129f92 100644 --- a/plugins/modules/sda_device_info.py +++ b/plugins/modules/sda_device_info.py @@ -24,8 +24,8 @@ - DeviceManagementIpAddress query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetDeviceInfoFromSDAFabric description: Complete reference of the GetDeviceInfoFromSDAFabric API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_device_role_info.py b/plugins/modules/sda_device_role_info.py index b06a698a18..09efaf717d 100644 --- a/plugins/modules/sda_device_role_info.py +++ b/plugins/modules/sda_device_role_info.py @@ -24,8 +24,8 @@ - DeviceManagementIpAddress query parameter. Device Management IP Address. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetDeviceRoleInSDAFabric description: Complete reference of the GetDeviceRoleInSDAFabric API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -62,13 +61,10 @@ type: dict sample: > { - "response": { - "status": "string", - "description": "string", - "roles": [ - "string" - ] - }, - "version": "string" + "roles": [ + "string" + ], + "status": "string", + "description": "string" } """ diff --git a/plugins/modules/sda_extranet_policies.py b/plugins/modules/sda_extranet_policies.py new file mode 100644 index 0000000000..2f7eb409ad --- /dev/null +++ b/plugins/modules/sda_extranet_policies.py @@ -0,0 +1,140 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_extranetPolicies +short_description: Resource module for Sda Extranetpolicies +description: +- Manage operations create, update and delete of the resource Sda Extranetpolicies. +- Adds an extranet policy based on user input. +- Deletes an extranet policy based on id. +- Updates an extranet policy based on user input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + id: + description: Id path parameter. ID of the extranet policy. + type: str + payload: + description: Sda Extranet Policies's payload. + elements: dict + suboptions: + extranetPolicyName: + description: Name of the existing extranet policy (updating this field is not + allowed). + type: str + fabricIds: + description: ID of the fabric sites/zones that associated with this extranet + policy. + elements: str + type: list + id: + description: ID of the existing extranet policy (updating this field is not + allowed). + type: str + providerVirtualNetworkName: + description: Name of the existing provider virtual network (updating this field + is not allowed). + type: str + subscriberVirtualNetworkNames: + description: Name of the subscriber virtual networks. + elements: str + type: list + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA AddExtranetPolicy + description: Complete reference of the AddExtranetPolicy API. + link: https://developer.cisco.com/docs/dna-center/#!add-extranet-policy +- name: Cisco DNA Center documentation for SDA DeleteExtranetPolicyById + description: Complete reference of the DeleteExtranetPolicyById API. + link: https://developer.cisco.com/docs/dna-center/#!delete-extranet-policy-by-id +- name: Cisco DNA Center documentation for SDA UpdateExtranetPolicy + description: Complete reference of the UpdateExtranetPolicy API. + link: https://developer.cisco.com/docs/dna-center/#!update-extranet-policy +notes: + - SDK Method used are + sda.Sda.add_extranet_policy, + sda.Sda.delete_extranet_policy_by_id, + sda.Sda.update_extranet_policy, + + - Paths used are + post /dna/intent/api/v1/sda/extranetPolicies, + delete /dna/intent/api/v1/sda/extranetPolicies/{id}, + put /dna/intent/api/v1/sda/extranetPolicies, + +""" + +EXAMPLES = r""" +- name: Update all + cisco.dnac.sda_extranetPolicies: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - extranetPolicyName: string + fabricIds: + - string + id: string + providerVirtualNetworkName: string + subscriberVirtualNetworkNames: + - string + +- name: Create + cisco.dnac.sda_extranetPolicies: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - extranetPolicyName: string + fabricIds: + - string + providerVirtualNetworkName: string + subscriberVirtualNetworkNames: + - string + +- name: Delete by id + cisco.dnac.sda_extranetPolicies: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_extranet_policies_count_info.py b/plugins/modules/sda_extranet_policies_count_info.py new file mode 100644 index 0000000000..c36637675f --- /dev/null +++ b/plugins/modules/sda_extranet_policies_count_info.py @@ -0,0 +1,64 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_extranetPolicies_count_info +short_description: Information module for Sda Extranetpolicies Count +description: +- Get all Sda Extranetpolicies Count. +- Returns the count of extranet policies that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetExtranetPolicyCount + description: Complete reference of the GetExtranetPolicyCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-extranet-policy-count +notes: + - SDK Method used are + sda.Sda.get_extranet_policy_count, + + - Paths used are + get /dna/intent/api/v1/sda/extranetPolicies/count, + +""" + +EXAMPLES = r""" +- name: Get all Sda Extranetpolicies Count + cisco.dnac.sda_extranetPolicies_count_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "count": 0 + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_extranet_policies_info.py b/plugins/modules/sda_extranet_policies_info.py new file mode 100644 index 0000000000..af10423206 --- /dev/null +++ b/plugins/modules/sda_extranet_policies_info.py @@ -0,0 +1,89 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_extranetPolicies_info +short_description: Information module for Sda Extranetpolicies +description: +- Get all Sda Extranetpolicies. +- Returns a list of extranet policies that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + extranetPolicyName: + description: + - ExtranetPolicyName query parameter. Name of the extranet policy. + type: str + offset: + description: + - Offset query parameter. Starting record for pagination. + type: float + limit: + description: + - Limit query parameter. Maximum number of records to return. + type: float +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetExtranetPolicies + description: Complete reference of the GetExtranetPolicies API. + link: https://developer.cisco.com/docs/dna-center/#!get-extranet-policies +notes: + - SDK Method used are + sda.Sda.get_extranet_policies, + + - Paths used are + get /dna/intent/api/v1/sda/extranetPolicies, + +""" + +EXAMPLES = r""" +- name: Get all Sda Extranetpolicies + cisco.dnac.sda_extranetPolicies_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + extranetPolicyName: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "extranetPolicyName": "string", + "fabricIds": [ + "string" + ], + "providerVirtualNetworkName": "string", + "subscriberVirtualNetworkNames": [ + "string" + ] + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_authentication_profile.py b/plugins/modules/sda_fabric_authentication_profile.py index 925e28fa1a..924114ff3e 100644 --- a/plugins/modules/sda_fabric_authentication_profile.py +++ b/plugins/modules/sda_fabric_authentication_profile.py @@ -34,8 +34,8 @@ description: SiteNameHierarchy query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA AddDefaultAuthenticationTemplateInSDAFabric description: Complete reference of the AddDefaultAuthenticationTemplateInSDAFabric API. @@ -105,7 +105,6 @@ siteNameHierarchy: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_fabric_authentication_profile_info.py b/plugins/modules/sda_fabric_authentication_profile_info.py index 619af5f016..b5fa4849ac 100644 --- a/plugins/modules/sda_fabric_authentication_profile_info.py +++ b/plugins/modules/sda_fabric_authentication_profile_info.py @@ -29,8 +29,8 @@ - AuthenticateTemplateName query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetDefaultAuthenticationProfileFromSDAFabric description: Complete reference of the GetDefaultAuthenticationProfileFromSDAFabric API. @@ -60,24 +60,21 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK returned: always - type: list - elements: dict + type: dict sample: > - [ - { - "siteNameHierarchy": "string", - "authenticateTemplateName": "string", - "authenticationOrder": "string", - "dot1xToMabFallbackTimeout": "string", - "wakeOnLan": true, - "numberOfHosts": "string", - "status": "string", - "description": "string" - } - ] + { + "siteNameHierarchy": "string", + "authenticateTemplateName": "string", + "authenticationOrder": "string", + "dot1xToMabFallbackTimeout": "string", + "wakeOnLan": true, + "numberOfHosts": "string", + "status": "string", + "description": "string", + "executionId": "string" + } """ diff --git a/plugins/modules/sda_fabric_border_device.py b/plugins/modules/sda_fabric_border_device.py index e2441daf86..1b4778f067 100644 --- a/plugins/modules/sda_fabric_border_device.py +++ b/plugins/modules/sda_fabric_border_device.py @@ -110,7 +110,7 @@ description: External Domain Routing Protocol Name. type: str internalAutonomouSystemNumber: - description: Internal Autonomouns System Number (e.g.,1-65535). + description: Internal Autonomous System Number. type: str routeDistributionProtocol: description: Route Distribution Protocol for Control Plane Device. Allowed values @@ -125,8 +125,8 @@ type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA AddBorderDeviceInSDAFabric description: Complete reference of the AddBorderDeviceInSDAFabric API. @@ -195,7 +195,6 @@ deviceManagementIpAddress: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_fabric_border_device_info.py b/plugins/modules/sda_fabric_border_device_info.py index c4318cd732..ee09938074 100644 --- a/plugins/modules/sda_fabric_border_device_info.py +++ b/plugins/modules/sda_fabric_border_device_info.py @@ -25,8 +25,8 @@ - DeviceManagementIpAddress query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetBorderDeviceDetailFromSDAFabric description: Complete reference of the GetBorderDeviceDetailFromSDAFabric API. @@ -55,7 +55,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_fabric_control_plane_device.py b/plugins/modules/sda_fabric_control_plane_device.py index ff3ecf449d..8e99ed6f0d 100644 --- a/plugins/modules/sda_fabric_control_plane_device.py +++ b/plugins/modules/sda_fabric_control_plane_device.py @@ -31,8 +31,8 @@ type: str version_added: 4.0.0 requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA AddControlPlaneDeviceInSDAFabric description: Complete reference of the AddControlPlaneDeviceInSDAFabric API. @@ -79,7 +79,6 @@ siteNameHierarchy: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_fabric_control_plane_device_info.py b/plugins/modules/sda_fabric_control_plane_device_info.py index 9267a70140..9250e75818 100644 --- a/plugins/modules/sda_fabric_control_plane_device_info.py +++ b/plugins/modules/sda_fabric_control_plane_device_info.py @@ -25,8 +25,8 @@ - DeviceManagementIpAddress query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetControlPlaneDeviceFromSDAFabric description: Complete reference of the GetControlPlaneDeviceFromSDAFabric API. @@ -55,7 +55,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_fabric_devices.py b/plugins/modules/sda_fabric_devices.py new file mode 100644 index 0000000000..de78e18e40 --- /dev/null +++ b/plugins/modules/sda_fabric_devices.py @@ -0,0 +1,215 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices +short_description: Resource module for Sda Fabricdevices +description: +- Manage operations create, update and delete of the resource Sda Fabricdevices. +- Adds fabric devices based on user input. +- Deletes a fabric device based on id. +- Deletes fabric devices based on user input. +- Updates fabric devices based on user input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + deviceRoles: + description: DeviceRoles query parameter. Device roles of the fabric device. + type: str + fabricId: + description: FabricId query parameter. ID of the fabric this device belongs to. + type: str + id: + description: Id path parameter. ID of the fabric device. + type: str + networkDeviceId: + description: NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str + payload: + description: Sda Fabric Devices's payload. + elements: dict + suboptions: + borderDeviceSettings: + description: Sda Fabric Devices's borderDeviceSettings. + suboptions: + borderTypes: + description: List of the border types of the fabric device. Allowed values + are LAYER_2, LAYER_3. + elements: str + type: list + layer3Settings: + description: Sda Fabric Devices's layer3Settings. + suboptions: + borderPriority: + description: Border priority of the fabric border device. Allowed range + is 1-9. A lower value indicates higher priority. E.g., a priority + of 1 takes precedence over 5. Default priority would be set to 10. + type: int + importExternalRoutes: + description: Set this to import external routes from other routing protocols + (such as BGP) to the fabric control plane. (updating this field is + not allowed). + type: bool + isDefaultExit: + description: Set this to make the fabric border device the gateway of + last resort for this site. Any unknown traffic will be sent to this + fabric border device from edge nodes. (updating this field is not + allowed). + type: bool + localAutonomousSystemNumber: + description: BGP Local autonomous system number of the fabric border + device. Allowed range is 1 to 4294967295. (updating this field is + not allowed). + type: str + prependAutonomousSystemCount: + description: Prepend autonomous system count of the fabric border device. + Allowed range is 1 to 10. + type: int + type: dict + type: dict + deviceRoles: + description: List of the roles of the fabric device. Allowed values are CONTROL_PLANE_NODE, + EDGE_NODE, BORDER_NODE. (updating this field is not allowed). + elements: str + type: list + fabricId: + description: ID of the fabric site/zone of this fabric device. (updating this + field is not allowed). + type: str + id: + description: ID of the fabric device. (updating this field is not allowed). + type: str + networkDeviceId: + description: Network device ID of the fabric device. (updating this field is + not allowed). + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA AddFabricDevices + description: Complete reference of the AddFabricDevices API. + link: https://developer.cisco.com/docs/dna-center/#!add-fabric-devices +- name: Cisco DNA Center documentation for SDA DeleteAFabricDeviceById + description: Complete reference of the DeleteAFabricDeviceById API. + link: https://developer.cisco.com/docs/dna-center/#!delete-a-fabric-device-by-id +- name: Cisco DNA Center documentation for SDA DeleteFabricDevices + description: Complete reference of the DeleteFabricDevices API. + link: https://developer.cisco.com/docs/dna-center/#!delete-fabric-devices +- name: Cisco DNA Center documentation for SDA UpdateFabricDevices + description: Complete reference of the UpdateFabricDevices API. + link: https://developer.cisco.com/docs/dna-center/#!update-fabric-devices +notes: + - SDK Method used are + sda.Sda.add_fabric_devices, + sda.Sda.delete_a_fabric_device_by_id, + sda.Sda.update_fabric_devices, + + - Paths used are + post /dna/intent/api/v1/sda/fabricDevices, + delete /dna/intent/api/v1/sda/fabricDevices, + delete /dna/intent/api/v1/sda/fabricDevices/{id}, + put /dna/intent/api/v1/sda/fabricDevices, + +""" + +EXAMPLES = r""" +- name: Update all + cisco.dnac.sda_fabricDevices: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - borderDeviceSettings: + borderTypes: + - string + layer3Settings: + borderPriority: 0 + importExternalRoutes: true + isDefaultExit: true + localAutonomousSystemNumber: string + prependAutonomousSystemCount: 0 + deviceRoles: + - string + fabricId: string + id: string + networkDeviceId: string + +- name: Delete all + cisco.dnac.sda_fabricDevices: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + deviceRoles: string + fabricId: string + networkDeviceId: string + +- name: Create + cisco.dnac.sda_fabricDevices: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - borderDeviceSettings: + borderTypes: + - string + layer3Settings: + borderPriority: 0 + importExternalRoutes: true + isDefaultExit: true + localAutonomousSystemNumber: string + prependAutonomousSystemCount: 0 + deviceRoles: + - string + fabricId: string + networkDeviceId: string + +- name: Delete by id + cisco.dnac.sda_fabricDevices: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_devices_count_info.py b/plugins/modules/sda_fabric_devices_count_info.py new file mode 100644 index 0000000000..90cd980bb2 --- /dev/null +++ b/plugins/modules/sda_fabric_devices_count_info.py @@ -0,0 +1,79 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices_count_info +short_description: Information module for Sda Fabricdevices Count +description: +- Get all Sda Fabricdevices Count. +- Returns the count of fabric devices that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. ID of the fabric this device belongs to. + type: str + networkDeviceId: + description: + - NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str + deviceRoles: + description: + - DeviceRoles query parameter. Device roles of the fabric device. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricDevicesCount + description: Complete reference of the GetFabricDevicesCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-devices-count +notes: + - SDK Method used are + sda.Sda.get_fabric_devices_count, + + - Paths used are + get /dna/intent/api/v1/sda/fabricDevices/count, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabricdevices Count + cisco.dnac.sda_fabricDevices_count_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + networkDeviceId: string + deviceRoles: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "count": 0 + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_devices_info.py b/plugins/modules/sda_fabric_devices_info.py new file mode 100644 index 0000000000..dfa246004f --- /dev/null +++ b/plugins/modules/sda_fabric_devices_info.py @@ -0,0 +1,108 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices_info +short_description: Information module for Sda Fabricdevices +description: +- Get all Sda Fabricdevices. +- Returns a list of fabric devices that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. ID of the fabric this device belongs to. + type: str + networkDeviceId: + description: + - NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str + deviceRoles: + description: + - DeviceRoles query parameter. Device roles of the fabric device. + type: str + offset: + description: + - Offset query parameter. Starting record for pagination. + type: float + limit: + description: + - Limit query parameter. Maximum number of records to return. + type: float +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricDevices + description: Complete reference of the GetFabricDevices API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-devices +notes: + - SDK Method used are + sda.Sda.get_fabric_devices, + + - Paths used are + get /dna/intent/api/v1/sda/fabricDevices, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabricdevices + cisco.dnac.sda_fabricDevices_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + networkDeviceId: string + deviceRoles: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "networkDeviceId": "string", + "fabricId": "string", + "deviceRoles": [ + "string" + ], + "borderDeviceSettings": { + "borderTypes": [ + "string" + ], + "layer3Settings": { + "localAutonomousSystemNumber": "string", + "isDefaultExit": true, + "importExternalRoutes": true, + "borderPriority": 0, + "prependAutonomousSystemCount": 0 + } + } + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs.py b/plugins/modules/sda_fabric_devices_layer2_handoffs.py new file mode 100644 index 0000000000..3499dd43e1 --- /dev/null +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs.py @@ -0,0 +1,134 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices_layer2Handoffs +short_description: Resource module for Sda Fabricdevices Layer2handoffs +description: +- Manage operations create, update and delete of the resource Sda Fabricdevices Layer2handoffs. +- Adds layer 2 handoffs in fabric devices based on user input. +- Deletes a layer 2 handoff of a fabric device based on id. +- Deletes layer 2 handoffs of a fabric device based on user input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + fabricId: + description: FabricId query parameter. ID of the fabric this device belongs to. + type: str + id: + description: Id path parameter. ID of the layer 2 handoff of a fabric device. + type: str + networkDeviceId: + description: NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str + payload: + description: Sda Fabric Devices Layer2 Handoffs's payload. + elements: dict + suboptions: + externalVlanId: + description: External VLAN number into which the fabric must be extended. Allowed + VLAN range is 2-4094 except for reserved vlans (1, 1002-1005, 2046, 4094). + type: int + fabricId: + description: ID of the fabric this device belongs to. + type: str + interfaceName: + description: Interface name of the layer 2 handoff. E.g., GigabitEthernet1/0/4. + type: str + internalVlanId: + description: VLAN number associated with this fabric. Allowed VLAN range is + 2-4094 except for reserved vlans (1, 1002-1005, 2046, 4094). + type: int + networkDeviceId: + description: Network device ID of the fabric device. + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA AddFabricDevicesLayer2Handoffs + description: Complete reference of the AddFabricDevicesLayer2Handoffs API. + link: https://developer.cisco.com/docs/dna-center/#!add-fabric-devices-layer-2-handoffs +- name: Cisco DNA Center documentation for SDA DeleteFabricDeviceLayer2HandoffById + description: Complete reference of the DeleteFabricDeviceLayer2HandoffById API. + link: https://developer.cisco.com/docs/dna-center/#!delete-fabric-device-layer-2-handoff-by-id +- name: Cisco DNA Center documentation for SDA DeleteFabricDeviceLayer2Handoffs + description: Complete reference of the DeleteFabricDeviceLayer2Handoffs API. + link: https://developer.cisco.com/docs/dna-center/#!delete-fabric-device-layer-2-handoffs +notes: + - SDK Method used are + sda.Sda.add_fabric_devices_layer2_handoffs, + sda.Sda.delete_fabric_device_layer2_handoff_by_id, + + - Paths used are + post /dna/intent/api/v1/sda/fabricDevices/layer2Handoffs, + delete /dna/intent/api/v1/sda/fabricDevices/layer2Handoffs, + delete /dna/intent/api/v1/sda/fabricDevices/layer2Handoffs/{id}, + +""" + +EXAMPLES = r""" +- name: Delete all + cisco.dnac.sda_fabricDevices_layer2Handoffs: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + fabricId: string + networkDeviceId: string + +- name: Create + cisco.dnac.sda_fabricDevices_layer2Handoffs: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - externalVlanId: 0 + fabricId: string + interfaceName: string + internalVlanId: 0 + networkDeviceId: string + +- name: Delete by id + cisco.dnac.sda_fabricDevices_layer2Handoffs: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_count_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_count_info.py new file mode 100644 index 0000000000..de3e733ecb --- /dev/null +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_count_info.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices_layer2Handoffs_count_info +short_description: Information module for Sda Fabricdevices Layer2handoffs Count +description: +- Get all Sda Fabricdevices Layer2handoffs Count. +- Returns the count of layer 2 handoffs of fabric devices that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. ID of the fabric this device belongs to. + type: str + networkDeviceId: + description: + - NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricDevicesLayer2HandoffsCount + description: Complete reference of the GetFabricDevicesLayer2HandoffsCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-devices-layer-2-handoffs-count +notes: + - SDK Method used are + sda.Sda.get_fabric_devices_layer2_handoffs_count, + + - Paths used are + get /dna/intent/api/v1/sda/fabricDevices/layer2Handoffs/count, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabricdevices Layer2handoffs Count + cisco.dnac.sda_fabricDevices_layer2Handoffs_count_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + networkDeviceId: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "count": 0 + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_info.py new file mode 100644 index 0000000000..1f05bc2ebd --- /dev/null +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_info.py @@ -0,0 +1,91 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices_layer2Handoffs_info +short_description: Information module for Sda Fabricdevices Layer2handoffs +description: +- Get all Sda Fabricdevices Layer2handoffs. +- Returns a list of layer 2 handoffs of fabric devices that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. ID of the fabric this device belongs to. + type: str + networkDeviceId: + description: + - NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str + offset: + description: + - Offset query parameter. Starting record for pagination. + type: float + limit: + description: + - Limit query parameter. Maximum number of records to return. + type: float +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricDevicesLayer2Handoffs + description: Complete reference of the GetFabricDevicesLayer2Handoffs API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-devices-layer-2-handoffs +notes: + - SDK Method used are + sda.Sda.get_fabric_devices_layer2_handoffs, + + - Paths used are + get /dna/intent/api/v1/sda/fabricDevices/layer2Handoffs, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabricdevices Layer2handoffs + cisco.dnac.sda_fabricDevices_layer2Handoffs_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + networkDeviceId: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "networkDeviceId": "string", + "fabricId": "string", + "interfaceName": "string", + "internalVlanId": 0, + "externalVlanId": 0 + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits.py new file mode 100644 index 0000000000..1a2dd38e7a --- /dev/null +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits.py @@ -0,0 +1,209 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices_layer2Handoffs_ipTransits +short_description: Resource module for Sda Fabricdevices Layer2handoffs Iptransits +description: +- Manage operations create, update and delete of the resource Sda Fabricdevices Layer2handoffs Iptransits. +- Adds layer 3 handoffs with ip transit in fabric devices based on user input. +- Deletes a layer 3 handoff with ip transit of a fabric device by id. +- Deletes layer 3 handoffs with ip transit of a fabric device based on user input. +- Updates layer 3 handoffs with ip transit of fabric devices based on user input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + fabricId: + description: FabricId query parameter. ID of the fabric this device belongs to. + type: str + id: + description: Id path parameter. ID of the layer 3 handoff with ip transit of a fabric + device to be deleted. + type: str + networkDeviceId: + description: NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str + payload: + description: Sda Fabric Devices Layer2 Handoffs Ip Transits's payload. + elements: dict + suboptions: + externalConnectivityIpPoolName: + description: External connectivity ip pool will be used by Catalyst Center to + allocate IP address for the connection between the border node and peer. + type: str + fabricId: + description: ID of the fabric this device belongs to. + type: str + interfaceName: + description: Interface name of the layer 3 handoff ip transit. + type: str + localIpAddress: + description: Local ipv4 address for the selected virtual network. Enter the + IP addresses and subnet mask in the CIDR notation (IP address/prefix-length). + Not applicable if you have already provided an external connectivity ip pool + name. + type: str + localIpv6Address: + description: Local ipv6 address for the selected virtual network. Enter the + IP addresses and subnet mask in the CIDR notation (IP address/prefix-length). + Not applicable if you have already provided an external connectivity ip pool + name. + type: str + networkDeviceId: + description: Network device ID of the fabric device. + type: str + remoteIpAddress: + description: Remote ipv4 address for the selected virtual network. Enter the + IP addresses and subnet mask in the CIDR notation (IP address/prefix-length). + Not applicable if you have already provided an external connectivity ip pool + name. + type: str + remoteIpv6Address: + description: Remote ipv6 address for the selected virtual network. Enter the + IP addresses and subnet mask in the CIDR notation (IP address/prefix-length). + Not applicable if you have already provided an external connectivity ip pool + name. + type: str + tcpMssAdjustment: + description: TCP maximum segment size (mss) value for the layer 3 handoff. Allowed + range is 500-1440. TCP MSS Adjustment value is applicable for the TCP sessions + over both IPv4 and IPv6. + type: int + transitNetworkId: + description: ID of the transit network of the layer 3 handoff ip transit. + type: str + virtualNetworkName: + description: Name of the virtual network associated with this fabric site. + type: str + vlanId: + description: VLAN number for the Switch Virtual Interface (SVI) used to establish + BGP peering with the external domain for the virtual network. Allowed VLAN + range is 2-4094 except for reserved vlans (1, 1002-1005, 2046, 4094). + type: int + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA AddFabricDevicesLayer3HandoffsWithIpTransit + description: Complete reference of the AddFabricDevicesLayer3HandoffsWithIpTransit API. + link: https://developer.cisco.com/docs/dna-center/#!add-fabric-devices-layer-3-handoffs-with-ip-transit +- name: Cisco DNA Center documentation for SDA DeleteFabricDeviceLayer3HandoffWithIpTransitById + description: Complete reference of the DeleteFabricDeviceLayer3HandoffWithIpTransitById API. + link: https://developer.cisco.com/docs/dna-center/#!delete-fabric-device-layer-3-handoff-with-ip-transit-by-id +- name: Cisco DNA Center documentation for SDA DeleteFabricDeviceLayer3HandoffsWithIpTransit + description: Complete reference of the DeleteFabricDeviceLayer3HandoffsWithIpTransit API. + link: https://developer.cisco.com/docs/dna-center/#!delete-fabric-device-layer-3-handoffs-with-ip-transit +- name: Cisco DNA Center documentation for SDA UpdateFabricDevicesLayer3HandoffsWithIpTransit + description: Complete reference of the UpdateFabricDevicesLayer3HandoffsWithIpTransit API. + link: https://developer.cisco.com/docs/dna-center/#!update-fabric-devices-layer-3-handoffs-with-ip-transit +notes: + - SDK Method used are + sda.Sda.add_fabric_devices_layer3_handoffs_with_ip_transit, + sda.Sda.delete_fabric_device_layer3_handoff_with_ip_transit_by_id, + sda.Sda.update_fabric_devices_layer3_handoffs_with_ip_transit, + + - Paths used are + post /dna/intent/api/v1/sda/fabricDevices/layer3Handoffs/ipTransits, + delete /dna/intent/api/v1/sda/fabricDevices/layer3Handoffs/ipTransits, + delete /dna/intent/api/v1/sda/fabricDevices/layer3Handoffs/ipTransits/{id}, + put /dna/intent/api/v1/sda/fabricDevices/layer3Handoffs/ipTransits, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - externalConnectivityIpPoolName: string + fabricId: string + interfaceName: string + localIpAddress: string + localIpv6Address: string + networkDeviceId: string + remoteIpAddress: string + remoteIpv6Address: string + tcpMssAdjustment: 0 + transitNetworkId: string + virtualNetworkName: string + vlanId: 0 + +- name: Update all + cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - externalConnectivityIpPoolName: string + fabricId: string + id: string + interfaceName: string + localIpAddress: string + localIpv6Address: string + networkDeviceId: string + remoteIpAddress: string + remoteIpv6Address: string + tcpMssAdjustment: 0 + transitNetworkId: string + virtualNetworkName: string + vlanId: 0 + +- name: Delete all + cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + fabricId: string + networkDeviceId: string + +- name: Delete by id + cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py new file mode 100644 index 0000000000..2b2d4d2c27 --- /dev/null +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices_layer2Handoffs_ipTransits_count_info +short_description: Information module for Sda Fabricdevices Layer2handoffs Iptransits Count +description: +- Get all Sda Fabricdevices Layer2handoffs Iptransits Count. +- Returns the count of layer 3 handoffs with ip transit of fabric devices that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. ID of the fabric this device belongs to. + type: str + networkDeviceId: + description: + - NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricDevicesLayer3HandoffsWithIpTransitCount + description: Complete reference of the GetFabricDevicesLayer3HandoffsWithIpTransitCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-devices-layer-3-handoffs-with-ip-transit-count +notes: + - SDK Method used are + sda.Sda.get_fabric_devices_layer3_handoffs_with_ip_transit_count, + + - Paths used are + get /dna/intent/api/v1/sda/fabricDevices/layer3Handoffs/ipTransits/count, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabricdevices Layer2handoffs Iptransits Count + cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits_count_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + networkDeviceId: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "count": 0 + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_info.py new file mode 100644 index 0000000000..495836cb7b --- /dev/null +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_info.py @@ -0,0 +1,98 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices_layer2Handoffs_ipTransits_info +short_description: Information module for Sda Fabricdevices Layer2handoffs Iptransits +description: +- Get all Sda Fabricdevices Layer2handoffs Iptransits. +- Returns a list of layer 3 handoffs with ip transit of fabric devices that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. ID of the fabric this device belongs to. + type: str + networkDeviceId: + description: + - NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str + offset: + description: + - Offset query parameter. Starting record for pagination. + type: float + limit: + description: + - Limit query parameter. Maximum number of records to return. + type: float +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricDevicesLayer3HandoffsWithIpTransit + description: Complete reference of the GetFabricDevicesLayer3HandoffsWithIpTransit API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-devices-layer-3-handoffs-with-ip-transit +notes: + - SDK Method used are + sda.Sda.get_fabric_devices_layer3_handoffs_with_ip_transit, + + - Paths used are + get /dna/intent/api/v1/sda/fabricDevices/layer3Handoffs/ipTransits, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabricdevices Layer2handoffs Iptransits + cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + networkDeviceId: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "networkDeviceId": "string", + "fabricId": "string", + "transitNetworkId": "string", + "interfaceName": "string", + "externalConnectivityIpPoolName": "string", + "virtualNetworkName": "string", + "vlanId": 0, + "tcpMssAdjustment": 0, + "localIpAddress": "string", + "remoteIpAddress": "string", + "localIpv6Address": "string", + "remoteIpv6Address": "string" + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py new file mode 100644 index 0000000000..fa7a8e5bb5 --- /dev/null +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py @@ -0,0 +1,157 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices_layer2Handoffs_sdaTransits +short_description: Resource module for Sda Fabricdevices Layer2handoffs Sdatransits +description: +- Manage operations create, update and delete of the resource Sda Fabricdevices Layer2handoffs Sdatransits. +- Adds layer 3 handoffs with sda transit in fabric devices based on user input. +- Deletes layer 3 handoffs with sda transit of a fabric device based on user input. +- Updates layer 3 handoffs with sda transit of fabric devices based on user input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + fabricId: + description: FabricId query parameter. ID of the fabric this device belongs to. + type: str + networkDeviceId: + description: NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str + payload: + description: Sda Fabric Devices Layer2 Handoffs Sda Transits's payload. + elements: dict + suboptions: + affinityIdDecider: + description: Affinity id decider value of the border node. When the affinity + id prime value is the same on multiple devices, the affinity id decider value + is used as a tiebreaker. Allowed range is 0-2147483647. The lower the relative + value of affinity id decider, the higher the preference for a destination + border node. + type: int + affinityIdPrime: + description: Affinity id prime value of the border node. It supersedes the border + priority to determine border node preference. Allowed range is 0-2147483647. + The lower the relative value of affinity id prime, the higher the preference + for a destination border node. + type: int + connectedToInternet: + description: Set this true to allow associated site to provide internet access + to other sites through sd-access. + type: bool + fabricId: + description: ID of the fabric this device belongs to. (updating this field is + not allowed). + type: str + isMulticastOverTransitEnabled: + description: Set this true to configure native multicast over multiple sites + that are connected to an sd-access transit. + type: bool + networkDeviceId: + description: Network device ID of the fabric device. (updating this field is + not allowed). + type: str + transitNetworkId: + description: ID of the transit network of the layer 3 handoff sda transit. (updating + this field is not allowed). + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA AddFabricDevicesLayer3HandoffsWithSdaTransit + description: Complete reference of the AddFabricDevicesLayer3HandoffsWithSdaTransit API. + link: https://developer.cisco.com/docs/dna-center/#!add-fabric-devices-layer-3-handoffs-with-sda-transit +- name: Cisco DNA Center documentation for SDA DeleteFabricDeviceLayer3HandoffsWithSdaTransit + description: Complete reference of the DeleteFabricDeviceLayer3HandoffsWithSdaTransit API. + link: https://developer.cisco.com/docs/dna-center/#!delete-fabric-device-layer-3-handoffs-with-sda-transit +- name: Cisco DNA Center documentation for SDA UpdateFabricDevicesLayer3HandoffsWithSdaTransit + description: Complete reference of the UpdateFabricDevicesLayer3HandoffsWithSdaTransit API. + link: https://developer.cisco.com/docs/dna-center/#!update-fabric-devices-layer-3-handoffs-with-sda-transit +notes: + - SDK Method used are + sda.Sda.add_fabric_devices_layer3_handoffs_with_sda_transit, + sda.Sda.delete_fabric_device_layer3_handoffs_with_sda_transit, + sda.Sda.update_fabric_devices_layer3_handoffs_with_sda_transit, + + - Paths used are + post /dna/intent/api/v1/sda/fabricDevices/layer3Handoffs/sdaTransits, + delete /dna/intent/api/v1/sda/fabricDevices/layer3Handoffs/sdaTransits, + put /dna/intent/api/v1/sda/fabricDevices/layer3Handoffs/sdaTransits, + +""" + +EXAMPLES = r""" +- name: Update all + cisco.dnac.sda_fabricDevices_layer2Handoffs_sdaTransits: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - affinityIdDecider: 0 + affinityIdPrime: 0 + connectedToInternet: true + fabricId: string + isMulticastOverTransitEnabled: true + networkDeviceId: string + transitNetworkId: string + +- name: Delete all + cisco.dnac.sda_fabricDevices_layer2Handoffs_sdaTransits: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + fabricId: string + networkDeviceId: string + +- name: Create + cisco.dnac.sda_fabricDevices_layer2Handoffs_sdaTransits: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - affinityIdDecider: 0 + affinityIdPrime: 0 + connectedToInternet: true + fabricId: string + isMulticastOverTransitEnabled: true + networkDeviceId: string + transitNetworkId: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py new file mode 100644 index 0000000000..224f078932 --- /dev/null +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices_layer2Handoffs_sdaTransits_count_info +short_description: Information module for Sda Fabricdevices Layer2handoffs Sdatransits Count +description: +- Get all Sda Fabricdevices Layer2handoffs Sdatransits Count. +- Returns the count of layer 3 handoffs with sda transit of fabric devices that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. ID of the fabric this device belongs to. + type: str + networkDeviceId: + description: + - NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricDevicesLayer3HandoffsWithSdaTransitCount + description: Complete reference of the GetFabricDevicesLayer3HandoffsWithSdaTransitCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-devices-layer-3-handoffs-with-sda-transit-count +notes: + - SDK Method used are + sda.Sda.get_fabric_devices_layer3_handoffs_with_sda_transit_count, + + - Paths used are + get /dna/intent/api/v1/sda/fabricDevices/layer3Handoffs/sdaTransits/count, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabricdevices Layer2handoffs Sdatransits Count + cisco.dnac.sda_fabricDevices_layer2Handoffs_sdaTransits_count_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + networkDeviceId: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "count": 0 + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py new file mode 100644 index 0000000000..1affe2f9c0 --- /dev/null +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py @@ -0,0 +1,92 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricDevices_layer2Handoffs_sdaTransits_info +short_description: Information module for Sda Fabricdevices Layer2handoffs Sdatransits +description: +- Get all Sda Fabricdevices Layer2handoffs Sdatransits. +- Returns a list of layer 3 handoffs with sda transit of fabric devices that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. ID of the fabric this device belongs to. + type: str + networkDeviceId: + description: + - NetworkDeviceId query parameter. Network device ID of the fabric device. + type: str + offset: + description: + - Offset query parameter. Starting record for pagination. + type: float + limit: + description: + - Limit query parameter. Maximum number of records to return. + type: float +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricDevicesLayer3HandoffsWithSdaTransit + description: Complete reference of the GetFabricDevicesLayer3HandoffsWithSdaTransit API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-devices-layer-3-handoffs-with-sda-transit +notes: + - SDK Method used are + sda.Sda.get_fabric_devices_layer3_handoffs_with_sda_transit, + + - Paths used are + get /dna/intent/api/v1/sda/fabricDevices/layer3Handoffs/sdaTransits, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabricdevices Layer2handoffs Sdatransits + cisco.dnac.sda_fabricDevices_layer2Handoffs_sdaTransits_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + networkDeviceId: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "networkDeviceId": "string", + "fabricId": "string", + "transitNetworkId": "string", + "affinityIdPrime": 0, + "affinityIdDecider": 0, + "connectedToInternet": true, + "isMulticastOverTransitEnabled": true + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_edge_device.py b/plugins/modules/sda_fabric_edge_device.py index 9bcde0422f..375232dc39 100644 --- a/plugins/modules/sda_fabric_edge_device.py +++ b/plugins/modules/sda_fabric_edge_device.py @@ -26,8 +26,8 @@ type: str version_added: 4.0.0 requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA AddEdgeDeviceInSDAFabric description: Complete reference of the AddEdgeDeviceInSDAFabric API. @@ -73,7 +73,6 @@ deviceManagementIpAddress: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_fabric_edge_device_info.py b/plugins/modules/sda_fabric_edge_device_info.py index a4f6eecc28..e91cca762f 100644 --- a/plugins/modules/sda_fabric_edge_device_info.py +++ b/plugins/modules/sda_fabric_edge_device_info.py @@ -24,8 +24,8 @@ - DeviceManagementIpAddress query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetEdgeDeviceFromSDAFabric description: Complete reference of the GetEdgeDeviceFromSDAFabric API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_fabric_site.py b/plugins/modules/sda_fabric_site.py index eed71ad48e..6c8dc5823b 100644 --- a/plugins/modules/sda_fabric_site.py +++ b/plugins/modules/sda_fabric_site.py @@ -31,8 +31,8 @@ description: SiteNameHierarchy query parameter. Site Name Hierarchy. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA AddSiteInSDAFabric description: Complete reference of the AddSiteInSDAFabric API. @@ -79,7 +79,6 @@ siteNameHierarchy: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_fabric_site_info.py b/plugins/modules/sda_fabric_site_info.py index bd2e8c1772..be6e890e33 100644 --- a/plugins/modules/sda_fabric_site_info.py +++ b/plugins/modules/sda_fabric_site_info.py @@ -24,8 +24,8 @@ - SiteNameHierarchy query parameter. Site Name Hierarchy. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetSiteFromSDAFabric description: Complete reference of the GetSiteFromSDAFabric API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_fabric_sites.py b/plugins/modules/sda_fabric_sites.py new file mode 100644 index 0000000000..75676b0eff --- /dev/null +++ b/plugins/modules/sda_fabric_sites.py @@ -0,0 +1,123 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricSites +short_description: Resource module for Sda Fabricsites +description: +- Manage operations create, update and delete of the resource Sda Fabricsites. +- Adds a fabric site based on user input. +- Deletes a fabric site based on id. +- Updates a fabric site based on user input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + id: + description: Id path parameter. ID of the fabric site to be deleted. + type: str + payload: + description: Sda Fabric Sites's payload. + elements: dict + suboptions: + authenticationProfileName: + description: Authentication profile used for this fabric. + type: str + isPubSubEnabled: + description: Specifies whether this fabric site will use pub/sub for control + nodes. + type: bool + siteId: + description: ID of the network hierarchy. + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA AddFabricSite + description: Complete reference of the AddFabricSite API. + link: https://developer.cisco.com/docs/dna-center/#!add-fabric-site +- name: Cisco DNA Center documentation for SDA DeleteFabricSiteById + description: Complete reference of the DeleteFabricSiteById API. + link: https://developer.cisco.com/docs/dna-center/#!delete-fabric-site-by-id +- name: Cisco DNA Center documentation for SDA UpdateFabricSite + description: Complete reference of the UpdateFabricSite API. + link: https://developer.cisco.com/docs/dna-center/#!update-fabric-site +notes: + - SDK Method used are + sda.Sda.add_fabric_site, + sda.Sda.delete_fabric_site_by_id, + sda.Sda.update_fabric_site, + + - Paths used are + post /dna/intent/api/v1/sda/fabricSites, + delete /dna/intent/api/v1/sda/fabricSites/{id}, + put /dna/intent/api/v1/sda/fabricSites, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.sda_fabricSites: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - authenticationProfileName: string + isPubSubEnabled: true + siteId: string + +- name: Update all + cisco.dnac.sda_fabricSites: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - authenticationProfileName: string + id: string + isPubSubEnabled: true + siteId: string + +- name: Delete by id + cisco.dnac.sda_fabricSites: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_sites_count_info.py b/plugins/modules/sda_fabric_sites_count_info.py new file mode 100644 index 0000000000..17037a3fce --- /dev/null +++ b/plugins/modules/sda_fabric_sites_count_info.py @@ -0,0 +1,64 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricSites_count_info +short_description: Information module for Sda Fabricsites Count +description: +- Get all Sda Fabricsites Count. +- Returns the count of fabric sites that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricSiteCount + description: Complete reference of the GetFabricSiteCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-site-count +notes: + - SDK Method used are + sda.Sda.get_fabric_site_count, + + - Paths used are + get /dna/intent/api/v1/sda/fabricSites/count, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabricsites Count + cisco.dnac.sda_fabricSites_count_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "count": 0 + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_sites_info.py b/plugins/modules/sda_fabric_sites_info.py new file mode 100644 index 0000000000..cfc520572f --- /dev/null +++ b/plugins/modules/sda_fabric_sites_info.py @@ -0,0 +1,89 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricSites_info +short_description: Information module for Sda Fabricsites +description: +- Get all Sda Fabricsites. +- Returns a list of fabric sites that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + id: + description: + - Id query parameter. ID of the fabric site to search for in the database. + type: str + siteId: + description: + - SiteId query parameter. Get the fabric site associated with this network hierarchy. + type: str + offset: + description: + - Offset query parameter. Starting record for pagination. + type: int + limit: + description: + - Limit query parameter. Maximum number of records to return. + type: int +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricSites + description: Complete reference of the GetFabricSites API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-sites +notes: + - SDK Method used are + sda.Sda.get_fabric_sites, + + - Paths used are + get /dna/intent/api/v1/sda/fabricSites, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabricsites + cisco.dnac.sda_fabricSites_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + id: string + siteId: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "siteId": "string", + "authenticationProfileName": "string", + "isPubSubEnabled": true + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_zones.py b/plugins/modules/sda_fabric_zones.py new file mode 100644 index 0000000000..b347e50a4d --- /dev/null +++ b/plugins/modules/sda_fabric_zones.py @@ -0,0 +1,120 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricZones +short_description: Resource module for Sda Fabriczones +description: +- Manage operations create, update and delete of the resource Sda Fabriczones. +- Adds a fabric zone based on user input. +- Deletes a fabric zone based on id. +- Updates a fabric zone based on user input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + id: + description: Id path parameter. ID of the fabric zone to be deleted. + type: str + payload: + description: Sda Fabric Zones's payload. + elements: dict + suboptions: + authenticationProfileName: + description: Authentication profile used for this fabric. + type: str + id: + description: ID of the fabric zone (updating this field is not allowed). + type: str + siteId: + description: ID of the network hierarchy (updating this field is not allowed). + type: str + type: list +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA AddFabricZone + description: Complete reference of the AddFabricZone API. + link: https://developer.cisco.com/docs/dna-center/#!add-fabric-zone +- name: Cisco DNA Center documentation for SDA DeleteFabricZoneById + description: Complete reference of the DeleteFabricZoneById API. + link: https://developer.cisco.com/docs/dna-center/#!delete-fabric-zone-by-id +- name: Cisco DNA Center documentation for SDA UpdateFabricZone + description: Complete reference of the UpdateFabricZone API. + link: https://developer.cisco.com/docs/dna-center/#!update-fabric-zone +notes: + - SDK Method used are + sda.Sda.add_fabric_zone, + sda.Sda.delete_fabric_zone_by_id, + sda.Sda.update_fabric_zone, + + - Paths used are + post /dna/intent/api/v1/sda/fabricZones, + delete /dna/intent/api/v1/sda/fabricZones/{id}, + put /dna/intent/api/v1/sda/fabricZones, + +""" + +EXAMPLES = r""" +- name: Update all + cisco.dnac.sda_fabricZones: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - authenticationProfileName: string + id: string + siteId: string + +- name: Create + cisco.dnac.sda_fabricZones: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - authenticationProfileName: string + siteId: string + +- name: Delete by id + cisco.dnac.sda_fabricZones: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_zones_count_info.py b/plugins/modules/sda_fabric_zones_count_info.py new file mode 100644 index 0000000000..153f931bc5 --- /dev/null +++ b/plugins/modules/sda_fabric_zones_count_info.py @@ -0,0 +1,64 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricZones_count_info +short_description: Information module for Sda Fabriczones Count +description: +- Get all Sda Fabriczones Count. +- Returns the count of fabric zones that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricZoneCount + description: Complete reference of the GetFabricZoneCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-zone-count +notes: + - SDK Method used are + sda.Sda.get_fabric_zone_count, + + - Paths used are + get /dna/intent/api/v1/sda/fabricZones/count, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabriczones Count + cisco.dnac.sda_fabricZones_count_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "count": 0 + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_fabric_zones_info.py b/plugins/modules/sda_fabric_zones_info.py new file mode 100644 index 0000000000..8825b8ef83 --- /dev/null +++ b/plugins/modules/sda_fabric_zones_info.py @@ -0,0 +1,88 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_fabricZones_info +short_description: Information module for Sda Fabriczones +description: +- Get all Sda Fabriczones. +- Returns a list of fabric zones that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + id: + description: + - Id query parameter. ID of the fabric zone to search for in the database. + type: str + siteId: + description: + - SiteId query parameter. Get the fabric zone associated with this network hierarchy. + type: str + offset: + description: + - Offset query parameter. Starting record for pagination. + type: int + limit: + description: + - Limit query parameter. Maximum number of records to return. + type: int +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetFabricZones + description: Complete reference of the GetFabricZones API. + link: https://developer.cisco.com/docs/dna-center/#!get-fabric-zones +notes: + - SDK Method used are + sda.Sda.get_fabric_zones, + + - Paths used are + get /dna/intent/api/v1/sda/fabricZones, + +""" + +EXAMPLES = r""" +- name: Get all Sda Fabriczones + cisco.dnac.sda_fabricZones_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + id: string + siteId: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "siteId": "string", + "authenticationProfileName": "string" + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/sda_multicast.py b/plugins/modules/sda_multicast.py index 6e1045c5d0..10d99b81d1 100644 --- a/plugins/modules/sda_multicast.py +++ b/plugins/modules/sda_multicast.py @@ -56,8 +56,8 @@ description: Full path of sda Fabric Site. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA AddMulticastInSDAFabric description: Complete reference of the AddMulticastInSDAFabric API. @@ -113,7 +113,6 @@ siteNameHierarchy: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_multicast_info.py b/plugins/modules/sda_multicast_info.py index 2f4ae1218b..ac7fefcaa6 100644 --- a/plugins/modules/sda_multicast_info.py +++ b/plugins/modules/sda_multicast_info.py @@ -24,8 +24,8 @@ - SiteNameHierarchy query parameter. Fabric site name hierarchy. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetMulticastDetailsFromSDAFabric description: Complete reference of the GetMulticastDetailsFromSDAFabric API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_port_assignment_for_access_point.py b/plugins/modules/sda_port_assignment_for_access_point.py index c8280407db..88ad55d724 100644 --- a/plugins/modules/sda_port_assignment_for_access_point.py +++ b/plugins/modules/sda_port_assignment_for_access_point.py @@ -41,8 +41,8 @@ type: str version_added: 4.0.0 requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA AddPortAssignmentForAccessPointInSDAFabric description: Complete reference of the AddPortAssignmentForAccessPointInSDAFabric API. @@ -93,7 +93,6 @@ interfaceName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_port_assignment_for_access_point_info.py b/plugins/modules/sda_port_assignment_for_access_point_info.py index 3cdb7cd3af..8cc99924d0 100644 --- a/plugins/modules/sda_port_assignment_for_access_point_info.py +++ b/plugins/modules/sda_port_assignment_for_access_point_info.py @@ -29,8 +29,8 @@ - InterfaceName query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetPortAssignmentForAccessPointInSDAFabric description: Complete reference of the GetPortAssignmentForAccessPointInSDAFabric API. @@ -60,7 +60,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_port_assignment_for_user_device.py b/plugins/modules/sda_port_assignment_for_user_device.py index 58664b8e2e..207dc6130e 100644 --- a/plugins/modules/sda_port_assignment_for_user_device.py +++ b/plugins/modules/sda_port_assignment_for_user_device.py @@ -54,8 +54,8 @@ type: str version_added: 4.0.0 requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA AddPortAssignmentForUserDeviceInSDAFabric description: Complete reference of the AddPortAssignmentForUserDeviceInSDAFabric API. @@ -110,7 +110,6 @@ voiceIpAddressPoolName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_port_assignment_for_user_device_info.py b/plugins/modules/sda_port_assignment_for_user_device_info.py index 2fdbee0464..ad5b7cd6d1 100644 --- a/plugins/modules/sda_port_assignment_for_user_device_info.py +++ b/plugins/modules/sda_port_assignment_for_user_device_info.py @@ -28,8 +28,8 @@ - InterfaceName query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetPortAssignmentForUserDeviceInSDAFabric description: Complete reference of the GetPortAssignmentForUserDeviceInSDAFabric API. @@ -59,7 +59,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_port_assignments.py b/plugins/modules/sda_port_assignments.py new file mode 100644 index 0000000000..0670e803ef --- /dev/null +++ b/plugins/modules/sda_port_assignments.py @@ -0,0 +1,188 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_portAssignments +short_description: Resource module for Sda Portassignments +description: +- Manage operations create, update and delete of the resource Sda Portassignments. +- Adds port assignments based on user input. +- Deletes a port assignment based on id. +- Deletes port assignments based on user input. +- Updates port assignments based on user input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + dataVlanName: + description: DataVlanName query parameter. Data VLAN name of the port assignment. + type: str + fabricId: + description: FabricId query parameter. ID of the fabric this device belongs to. + type: str + id: + description: Id path parameter. ID of the port assignment. + type: str + interfaceName: + description: InterfaceName query parameter. Interface name of the port assignment. + type: str + networkDeviceId: + description: NetworkDeviceId query parameter. Network device ID of the port assignment. + type: str + payload: + description: Sda Port Assignments's payload. + elements: dict + suboptions: + authenticateTemplateName: + description: Authenticate template name of the port assignment. + type: str + connectedDeviceType: + description: Connected device type of the port assignment. + type: str + dataVlanName: + description: Data VLAN name of the port assignment. + type: str + fabricId: + description: ID of the fabric this device belongs to. + type: str + interfaceDescription: + description: Interface description of the port assignment. + type: str + interfaceName: + description: Interface name of the port assignment. + type: str + networkDeviceId: + description: Network device ID of the port assignment. + type: str + scalableGroupName: + description: Scalable group name of the port assignment. + type: str + voiceVlanName: + description: Voice VLAN name of the port assignment. + type: str + type: list + voiceVlanName: + description: VoiceVlanName query parameter. Voice VLAN name of the port assignment. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA AddPortAssignments + description: Complete reference of the AddPortAssignments API. + link: https://developer.cisco.com/docs/dna-center/#!add-port-assignments +- name: Cisco DNA Center documentation for SDA DeletePortAssignmentById + description: Complete reference of the DeletePortAssignmentById API. + link: https://developer.cisco.com/docs/dna-center/#!delete-port-assignment-by-id +- name: Cisco DNA Center documentation for SDA DeletePortAssignments + description: Complete reference of the DeletePortAssignments API. + link: https://developer.cisco.com/docs/dna-center/#!delete-port-assignments +- name: Cisco DNA Center documentation for SDA UpdatePortAssignments + description: Complete reference of the UpdatePortAssignments API. + link: https://developer.cisco.com/docs/dna-center/#!update-port-assignments +notes: + - SDK Method used are + sda.Sda.add_port_assignments, + sda.Sda.delete_port_assignment_by_id, + sda.Sda.update_port_assignments, + + - Paths used are + post /dna/intent/api/v1/sda/portAssignments, + delete /dna/intent/api/v1/sda/portAssignments, + delete /dna/intent/api/v1/sda/portAssignments/{id}, + put /dna/intent/api/v1/sda/portAssignments, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.sda_portAssignments: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - authenticateTemplateName: string + connectedDeviceType: string + dataVlanName: string + fabricId: string + interfaceDescription: string + interfaceName: string + networkDeviceId: string + scalableGroupName: string + voiceVlanName: string + +- name: Update all + cisco.dnac.sda_portAssignments: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - authenticateTemplateName: string + connectedDeviceType: string + dataVlanName: string + fabricId: string + id: string + interfaceDescription: string + interfaceName: string + networkDeviceId: string + scalableGroupName: string + voiceVlanName: string + +- name: Delete all + cisco.dnac.sda_portAssignments: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + dataVlanName: string + fabricId: string + interfaceName: string + networkDeviceId: string + voiceVlanName: string + +- name: Delete by id + cisco.dnac.sda_portAssignments: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_port_assignments_count_info.py b/plugins/modules/sda_port_assignments_count_info.py new file mode 100644 index 0000000000..82e3b42c4f --- /dev/null +++ b/plugins/modules/sda_port_assignments_count_info.py @@ -0,0 +1,89 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_portAssignments_count_info +short_description: Information module for Sda Portassignments Count +description: +- Get all Sda Portassignments Count. +- Returns the count of port assignments that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. ID of the fabric this device belongs to. + type: str + networkDeviceId: + description: + - NetworkDeviceId query parameter. Network device ID of the port assignment. + type: str + interfaceName: + description: + - InterfaceName query parameter. Interface name of the port assignment. + type: str + dataVlanName: + description: + - DataVlanName query parameter. Data VLAN name of the port assignment. + type: str + voiceVlanName: + description: + - VoiceVlanName query parameter. Voice VLAN name of the port assignment. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetPortAssignmentCount + description: Complete reference of the GetPortAssignmentCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-port-assignment-count +notes: + - SDK Method used are + sda.Sda.get_port_assignment_count, + + - Paths used are + get /dna/intent/api/v1/sda/portAssignments/count, + +""" + +EXAMPLES = r""" +- name: Get all Sda Portassignments Count + cisco.dnac.sda_portAssignments_count_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + networkDeviceId: string + interfaceName: string + dataVlanName: string + voiceVlanName: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "count": 0 + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_port_assignments_info.py b/plugins/modules/sda_port_assignments_info.py new file mode 100644 index 0000000000..e6596a3e93 --- /dev/null +++ b/plugins/modules/sda_port_assignments_info.py @@ -0,0 +1,110 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_portAssignments_info +short_description: Information module for Sda Portassignments +description: +- Get all Sda Portassignments. +- Returns a list of port assignments that match the provided query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + fabricId: + description: + - FabricId query parameter. ID of the fabric this device belongs to. + type: str + networkDeviceId: + description: + - NetworkDeviceId query parameter. Network device ID of the port assignment. + type: str + interfaceName: + description: + - InterfaceName query parameter. Interface Name of the port assignment. + type: str + dataVlanName: + description: + - DataVlanName query parameter. Data VLAN name of the port assignment. + type: str + voiceVlanName: + description: + - VoiceVlanName query parameter. Voice VLAN name of the port assignment. + type: str + offset: + description: + - Offset query parameter. Starting record for pagination. + type: float + limit: + description: + - Limit query parameter. Maximum number of records to return. + type: float +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetPortAssignments + description: Complete reference of the GetPortAssignments API. + link: https://developer.cisco.com/docs/dna-center/#!get-port-assignments +notes: + - SDK Method used are + sda.Sda.get_port_assignments, + + - Paths used are + get /dna/intent/api/v1/sda/portAssignments, + +""" + +EXAMPLES = r""" +- name: Get all Sda Portassignments + cisco.dnac.sda_portAssignments_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + fabricId: string + networkDeviceId: string + interfaceName: string + dataVlanName: string + voiceVlanName: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "fabricId": "string", + "networkDeviceId": "string", + "interfaceName": "string", + "connectedDeviceType": "string", + "dataVlanName": "string", + "voiceVlanName": "string", + "authenticateTemplateName": "string", + "scalableGroupName": "string", + "interfaceDescription": "string" + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/sda_provision_device.py b/plugins/modules/sda_provision_device.py index 5940634b8f..ac7b8ffe70 100644 --- a/plugins/modules/sda_provision_device.py +++ b/plugins/modules/sda_provision_device.py @@ -26,8 +26,8 @@ description: SiteNameHierarchy of the provisioned device. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA ProvisionWiredDevice description: Complete reference of the ProvisionWiredDevice API. @@ -91,7 +91,6 @@ siteNameHierarchy: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_provision_device_info.py b/plugins/modules/sda_provision_device_info.py index ae78549ec7..09a219a39f 100644 --- a/plugins/modules/sda_provision_device_info.py +++ b/plugins/modules/sda_provision_device_info.py @@ -24,8 +24,8 @@ - DeviceManagementIpAddress query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetProvisionedWiredDevice description: Complete reference of the GetProvisionedWiredDevice API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_provision_devices.py b/plugins/modules/sda_provision_devices.py new file mode 100644 index 0000000000..493a7a04e5 --- /dev/null +++ b/plugins/modules/sda_provision_devices.py @@ -0,0 +1,141 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_provisionDevices +short_description: Resource module for Sda Provisiondevices +description: +- Manage operations create, update and delete of the resource Sda Provisiondevices. +- Provisions network devices to respective Sites based on user input. +- Delete provisioned devices based on query parameters. +- Deletes provisioned device based on Id. +- Re-provisions network devices to the site based on the user input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + id: + description: Id path parameter. ID of provisioned device. + type: str + networkDeviceId: + description: NetworkDeviceId query parameter. ID of the network device. + type: str + payload: + description: Sda Provision Devices's payload. + elements: dict + suboptions: + networkDeviceId: + description: ID of network device to be provisioned. + type: str + siteId: + description: ID of the site this network device needs to be provisioned. + type: str + type: list + siteId: + description: SiteId query parameter. ID of the site hierarchy. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA ProvisionDevices + description: Complete reference of the ProvisionDevices API. + link: https://developer.cisco.com/docs/dna-center/#!provision-devices +- name: Cisco DNA Center documentation for SDA DeleteProvisionedDeviceById + description: Complete reference of the DeleteProvisionedDeviceById API. + link: https://developer.cisco.com/docs/dna-center/#!delete-provisioned-device-by-id +- name: Cisco DNA Center documentation for SDA DeleteProvisionedDevices + description: Complete reference of the DeleteProvisionedDevices API. + link: https://developer.cisco.com/docs/dna-center/#!delete-provisioned-devices +- name: Cisco DNA Center documentation for SDA ReProvisionDevices + description: Complete reference of the ReProvisionDevices API. + link: https://developer.cisco.com/docs/dna-center/#!re-provision-devices +notes: + - SDK Method used are + sda.Sda.delete_provisioned_device_by_id, + sda.Sda.provision_devices, + sda.Sda.re_provision_devices, + + - Paths used are + post /dna/intent/api/v1/sda/provisionDevices, + delete /dna/intent/api/v1/sda/provisionDevices, + delete /dna/intent/api/v1/sda/provisionDevices/{id}, + put /dna/intent/api/v1/sda/provisionDevices, + +""" + +EXAMPLES = r""" +- name: Delete all + cisco.dnac.sda_provisionDevices: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + networkDeviceId: string + siteId: string + +- name: Create + cisco.dnac.sda_provisionDevices: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - networkDeviceId: string + siteId: string + +- name: Update all + cisco.dnac.sda_provisionDevices: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + payload: + - id: string + networkDeviceId: string + siteId: string + +- name: Delete by id + cisco.dnac.sda_provisionDevices: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + id: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_provision_devices_count_info.py b/plugins/modules/sda_provision_devices_count_info.py new file mode 100644 index 0000000000..50ef2b8afe --- /dev/null +++ b/plugins/modules/sda_provision_devices_count_info.py @@ -0,0 +1,69 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_provisionDevices_count_info +short_description: Information module for Sda Provisiondevices Count +description: +- Get all Sda Provisiondevices Count. +- Returns the count of provisioned devices based on query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + siteId: + description: + - SiteId query parameter. ID of the site hierarchy. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetProvisionedDevicesCount + description: Complete reference of the GetProvisionedDevicesCount API. + link: https://developer.cisco.com/docs/dna-center/#!get-provisioned-devices-count +notes: + - SDK Method used are + sda.Sda.get_provisioned_devices_count, + + - Paths used are + get /dna/intent/api/v1/sda/provisionDevices/count, + +""" + +EXAMPLES = r""" +- name: Get all Sda Provisiondevices Count + cisco.dnac.sda_provisionDevices_count_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + siteId: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "count": 0 + }, + "version": "string" + } +""" diff --git a/plugins/modules/sda_provision_devices_info.py b/plugins/modules/sda_provision_devices_info.py new file mode 100644 index 0000000000..253ce600f8 --- /dev/null +++ b/plugins/modules/sda_provision_devices_info.py @@ -0,0 +1,93 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_provisionDevices_info +short_description: Information module for Sda Provisiondevices +description: +- Get all Sda Provisiondevices. +- Returns the list of provisioned devices based on query parameters. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + id: + description: + - Id query parameter. ID of the provisioned device. + type: str + networkDeviceId: + description: + - NetworkDeviceId query parameter. ID of the network device. + type: str + siteId: + description: + - SiteId query parameter. ID of the site hierarchy. + type: str + offset: + description: + - Offset query parameter. Starting record for pagination. + type: float + limit: + description: + - Limit query parameter. Maximum number of devices to return. + type: float +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for SDA GetProvisionedDevices + description: Complete reference of the GetProvisionedDevices API. + link: https://developer.cisco.com/docs/dna-center/#!get-provisioned-devices +notes: + - SDK Method used are + sda.Sda.get_provisioned_devices, + + - Paths used are + get /dna/intent/api/v1/sda/provisionDevices, + +""" + +EXAMPLES = r""" +- name: Get all Sda Provisiondevices + cisco.dnac.sda_provisionDevices_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + id: string + networkDeviceId: string + siteId: string + offset: 0 + limit: 0 + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": [ + { + "id": "string", + "siteId": "string", + "networkDeviceId": "string" + } + ], + "version": "string" + } +""" diff --git a/plugins/modules/sda_site_member_member_info.py b/plugins/modules/sda_site_member_member_info.py new file mode 100644 index 0000000000..f79e95e028 --- /dev/null +++ b/plugins/modules/sda_site_member_member_info.py @@ -0,0 +1,141 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: sda_site_member_member_info +short_description: Information module for Sda Site Member Member +description: +- Get all Sda Site Member Member. +- API to get devices that are assigned to a site. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + id: + description: + - Id path parameter. Site Id. + type: str + offset: + description: + - Offset query parameter. Offset/starting index for pagination. + type: str + limit: + description: + - Limit query parameter. Number of devices to be listed. Default and max supported value is 500. + type: str + memberType: + description: + - MemberType query parameter. Member type (This API only supports the 'networkdevice' type). + type: str + level: + description: + - > + Level query parameter. Depth of site hierarchy to be considered to list the devices. If the provided value + is -1, devices for all child sites will be listed. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Sites GetDevicesThatAreAssignedToASite + description: Complete reference of the GetDevicesThatAreAssignedToASite API. + link: https://developer.cisco.com/docs/dna-center/#!get-devices-that-are-assigned-to-a-site +notes: + - SDK Method used are + sites.Sites.get_devices_that_are_assigned_to_a_site, + + - Paths used are + get /dna/intent/api/v1/site-member/{id}/member, + +""" + +EXAMPLES = r""" +- name: Get all Sda Site Member Member + cisco.dnac.sda_site_member_member_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + offset: string + limit: string + memberType: string + level: string + id: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: list + elements: dict + sample: > + [ + { + "instanceUuid": "string", + "instanceId": 0, + "authEntityId": 0, + "authEntityClass": 0, + "instanceTenantId": "string", + "deployPending": "string", + "instanceVersion": 0, + "apManagerInterfaceIp": "string", + "associatedWlcIp": "string", + "bootDateTime": "string", + "collectionInterval": "string", + "collectionIntervalValue": "string", + "collectionStatus": "string", + "description": "string", + "deviceSupportLevel": "string", + "dnsResolvedManagementAddress": "string", + "family": "string", + "hostname": "string", + "interfaceCount": "string", + "inventoryStatusDetail": "string", + "lastUpdateTime": 0, + "lastUpdated": "string", + "lineCardCount": "string", + "lineCardId": "string", + "lastDeviceResyncStartTime": "string", + "macAddress": "string", + "managedAtleastOnce": true, + "managementIpAddress": "string", + "managementState": "string", + "memorySize": "string", + "paddedMgmtIpAddress": "string", + "pendingSyncRequestsCount": "string", + "platformId": "string", + "reachabilityFailureReason": "string", + "reachabilityStatus": "string", + "reasonsForDeviceResync": "string", + "reasonsForPendingSyncRequests": "string", + "role": "string", + "roleSource": "string", + "serialNumber": "string", + "series": "string", + "snmpContact": "string", + "snmpLocation": "string", + "softwareType": "string", + "softwareVersion": "string", + "tagCount": "string", + "type": "string", + "upTime": "string", + "uptimeSeconds": 0, + "vendor": "string", + "displayName": "string" + } + ] +""" diff --git a/plugins/modules/sda_virtual_network.py b/plugins/modules/sda_virtual_network.py index 09d01e5ed2..f2030d954b 100644 --- a/plugins/modules/sda_virtual_network.py +++ b/plugins/modules/sda_virtual_network.py @@ -24,8 +24,8 @@ description: VirtualNetworkName query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA AddVNInFabric description: Complete reference of the AddVNInFabric API. @@ -72,7 +72,6 @@ virtualNetworkName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_virtual_network_info.py b/plugins/modules/sda_virtual_network_info.py index 560c9179ff..c0e11c7e13 100644 --- a/plugins/modules/sda_virtual_network_info.py +++ b/plugins/modules/sda_virtual_network_info.py @@ -28,8 +28,8 @@ - SiteNameHierarchy query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetVNFromSDAFabric description: Complete reference of the GetVNFromSDAFabric API. @@ -59,7 +59,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -70,9 +69,12 @@ "siteNameHierarchy": "string", "virtualNetworkName": "string", "fabricName": "string", - "isInfraVN": "string", - "isDefaultVN": "string", + "isInfraVN": true, + "isDefaultVN": true, + "virtualNetworkContextId": "string", + "virtualNetworkId": "string", "status": "string", - "description": "string" + "description": "string", + "executionId": "string" } """ diff --git a/plugins/modules/sda_virtual_network_ip_pool.py b/plugins/modules/sda_virtual_network_ip_pool.py index 71bdf744f1..f13be8baf8 100644 --- a/plugins/modules/sda_virtual_network_ip_pool.py +++ b/plugins/modules/sda_virtual_network_ip_pool.py @@ -83,8 +83,8 @@ type: str version_added: 4.0.0 requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA AddIPPoolInSDAVirtualNetwork description: Complete reference of the AddIPPoolInSDAVirtualNetwork API. @@ -146,7 +146,6 @@ vlanName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_virtual_network_ip_pool_info.py b/plugins/modules/sda_virtual_network_ip_pool_info.py index 35de542c63..cffc2e9a34 100644 --- a/plugins/modules/sda_virtual_network_ip_pool_info.py +++ b/plugins/modules/sda_virtual_network_ip_pool_info.py @@ -31,11 +31,13 @@ ipPoolName: version_added: "4.0.0" description: - - IpPoolName query parameter. + - > + IpPoolName query parameter. IpPoolName. Note Use vlanName as a value for this parameter if same ip pool is + assigned to multiple virtual networks (e.g.. IpPoolName=vlan1021). type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetIPPoolFromSDAVirtualNetwork description: Complete reference of the GetIPPoolFromSDAVirtualNetwork API. @@ -66,7 +68,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_virtual_network_v2.py b/plugins/modules/sda_virtual_network_v2.py index 27bffd8d97..ecb7822d71 100644 --- a/plugins/modules/sda_virtual_network_v2.py +++ b/plugins/modules/sda_virtual_network_v2.py @@ -32,8 +32,8 @@ description: Virtual Network Name to be assigned at global level. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA AddVirtualNetworkWithScalableGroups description: Complete reference of the AddVirtualNetworkWithScalableGroups API. @@ -103,7 +103,6 @@ virtualNetworkName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sda_virtual_network_v2_info.py b/plugins/modules/sda_virtual_network_v2_info.py index fc73454d14..14e78cdc47 100644 --- a/plugins/modules/sda_virtual_network_v2_info.py +++ b/plugins/modules/sda_virtual_network_v2_info.py @@ -24,8 +24,8 @@ - VirtualNetworkName query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for SDA GetVirtualNetworkWithScalableGroups description: Complete reference of the GetVirtualNetworkWithScalableGroups API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -68,7 +67,9 @@ "string" ], "vManageVpnId": "string", + "virtualNetworkContextId": "string", "status": "string", - "description": "string" + "description": "string", + "executionId": "string" } """ diff --git a/plugins/modules/security_advisories_devices_info.py b/plugins/modules/security_advisories_devices_info.py index 977fe48cd8..9cd619db2d 100644 --- a/plugins/modules/security_advisories_devices_info.py +++ b/plugins/modules/security_advisories_devices_info.py @@ -24,8 +24,8 @@ - AdvisoryId path parameter. Advisory ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Security Advisories GetDevicesPerAdvisory description: Complete reference of the GetDevicesPerAdvisory API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/security_advisories_ids_per_device_info.py b/plugins/modules/security_advisories_ids_per_device_info.py index 47f2db3968..b94f4128ef 100644 --- a/plugins/modules/security_advisories_ids_per_device_info.py +++ b/plugins/modules/security_advisories_ids_per_device_info.py @@ -10,7 +10,7 @@ short_description: Information module for Security Advisories Ids Per Device description: - Get Security Advisories Ids Per Device by id. -- Retrieves list of advisory IDs for a device. +- Retrieves advisory device details for a device. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -24,15 +24,15 @@ - DeviceId path parameter. Device instance UUID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Security Advisories GetAdvisoryIDsPerDevice - description: Complete reference of the GetAdvisoryIDsPerDevice API. - link: https://developer.cisco.com/docs/dna-center/#!get-advisory-i-ds-per-device +- name: Cisco DNA Center documentation for Security Advisories GetAdvisoryDeviceDetail + description: Complete reference of the GetAdvisoryDeviceDetail API. + link: https://developer.cisco.com/docs/dna-center/#!get-advisory-device-detail notes: - SDK Method used are - security_advisories.SecurityAdvisories.get_advisory_ids_per_device, + security_advisories.SecurityAdvisories.get_advisory_device_detail, - Paths used are get /dna/intent/api/v1/security-advisory/device/{deviceId}, @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -62,14 +61,17 @@ type: dict sample: > { - "response": [ - { - "deviceId": "string", - "advisoryIds": [ - "string" - ] - } - ], + "response": { + "deviceId": "string", + "advisoryIds": [ + "string" + ], + "hiddenAdvisoryCount": 0, + "scanMode": "string", + "scanStatus": "string", + "comments": "string", + "lastScanTime": 0 + }, "version": "string" } """ diff --git a/plugins/modules/security_advisories_info.py b/plugins/modules/security_advisories_info.py index a2d8603167..755e0d2cab 100644 --- a/plugins/modules/security_advisories_info.py +++ b/plugins/modules/security_advisories_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Security Advisories GetAdvisoriesList description: Complete reference of the GetAdvisoriesList API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -57,21 +56,20 @@ type: dict sample: > { - "response": [ - { - "advisoryId": "string", - "deviceCount": 0, - "hiddenDeviceCount": 0, - "cves": [ - "string" - ], - "publicationUrl": "string", - "sir": "string", - "detectionType": "string", - "defaultDetectionType": "string", - "defaultConfigMatchPattern": "string" - } - ], + "response": { + "advisoryId": "string", + "deviceCount": 0, + "hiddenDeviceCount": 0, + "cves": [ + "string" + ], + "publicationUrl": "string", + "sir": "string", + "detectionType": "string", + "defaultDetectionType": "string", + "defaultConfigMatchPattern": "string", + "fixedVersions": {} + }, "version": "string" } """ diff --git a/plugins/modules/security_advisories_per_device_info.py b/plugins/modules/security_advisories_per_device_info.py index 486bb46541..0ba2e4a88f 100644 --- a/plugins/modules/security_advisories_per_device_info.py +++ b/plugins/modules/security_advisories_per_device_info.py @@ -24,8 +24,8 @@ - DeviceId path parameter. Device instance UUID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Security Advisories GetAdvisoriesPerDevice description: Complete reference of the GetAdvisoriesPerDevice API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -62,21 +61,20 @@ type: dict sample: > { - "response": [ - { - "advisoryId": "string", - "deviceCount": 0, - "hiddenDeviceCount": 0, - "cves": [ - "string" - ], - "publicationUrl": "string", - "sir": "string", - "detectionType": "string", - "defaultDetectionType": "string", - "defaultConfigMatchPattern": "string" - } - ], + "response": { + "advisoryId": "string", + "deviceCount": 0, + "hiddenDeviceCount": 0, + "cves": [ + "string" + ], + "publicationUrl": "string", + "sir": "string", + "detectionType": "string", + "defaultDetectionType": "string", + "defaultConfigMatchPattern": "string", + "fixedVersions": {} + }, "version": "string" } """ diff --git a/plugins/modules/security_advisories_summary_info.py b/plugins/modules/security_advisories_summary_info.py index 88440acebf..2485c288a9 100644 --- a/plugins/modules/security_advisories_summary_info.py +++ b/plugins/modules/security_advisories_summary_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Security Advisories GetAdvisoriesSummary description: Complete reference of the GetAdvisoriesSummary API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -58,33 +57,39 @@ sample: > { "response": { - "NA": { - "CONFIG": 0, - "VERSION": 0, - "TOTAL": 0 - }, "INFORMATIONAL": { "CONFIG": 0, + "CUSTOM_CONFIG": 0, "VERSION": 0, "TOTAL": 0 }, "LOW": { "CONFIG": 0, + "CUSTOM_CONFIG": 0, "VERSION": 0, "TOTAL": 0 }, "MEDIUM": { "CONFIG": 0, + "CUSTOM_CONFIG": 0, "VERSION": 0, "TOTAL": 0 }, "HIGH": { "CONFIG": 0, + "CUSTOM_CONFIG": 0, "VERSION": 0, "TOTAL": 0 }, "CRITICAL": { "CONFIG": 0, + "CUSTOM_CONFIG": 0, + "VERSION": 0, + "TOTAL": 0 + }, + "NA": { + "CONFIG": 0, + "CUSTOM_CONFIG": 0, "VERSION": 0, "TOTAL": 0 } diff --git a/plugins/modules/sensor.py b/plugins/modules/sensor.py index c98887c451..9b7964d3f0 100644 --- a/plugins/modules/sensor.py +++ b/plugins/modules/sensor.py @@ -22,73 +22,578 @@ elements: dict suboptions: bands: - description: Bands. + description: The WIFI bands. type: str numberOfApsToTest: - description: Number Of Aps To Test. - type: str + description: Number of APs to test. + type: int rssiThreshold: - description: Rssi Threshold. - type: str + description: RSSI threshold. + type: int type: list connection: - description: Connection. + description: Connection type of test WIRED, WIRELESS, BOTH. + type: str + encryptionMode: + description: Encryption mode. type: str + locationInfoList: + description: Sensor's locationInfoList. + elements: dict + suboptions: + allSensors: + description: Use all sensors in the site for test. + type: bool + customManagementVlan: + description: Custom Management VLAN. + type: bool + locationId: + description: Site UUID. + type: str + locationType: + description: Site type. + type: str + macAddressList: + description: MAC addresses. + elements: str + type: list + managementVlan: + description: Management VLAN. + type: str + siteHierarchy: + description: Site name hierarhy. + type: str + type: list modelVersion: - description: Model Version. + description: Test template object model version (must be 2). type: int name: - description: Name. + description: The sensor test template name. + type: str + profiles: + description: Sensor's profiles. + elements: dict + suboptions: + authProtocol: + description: Auth protocol. + type: str + authType: + description: Authentication type OPEN, WPA2_PSK, WPA2_EaP, WEB_AUTH, MAB, DOT1X, + OTHER. + type: str + certdownloadurl: + description: Certificate download URL. + type: str + certfilename: + description: Auth certificate file name. + type: str + certpassphrase: + description: Certificate password phrase. + type: str + certstatus: + description: Certificate status INACTIVE or ACTIVE. + type: str + certxferprotocol: + description: Certificate transfering protocol HTTP or HTTPS. + type: str + deviceType: + description: Device Type. + type: str + eapMethod: + description: WPA2_EAP methods EAP-FAST, PEAP-MSCHAPv2, EAP-TLS, PEAP-TLS, EAP-TTLS-MSCHAPv2, + EAP-TTLS-PAP, EAP-TTLS-CHAP, EAP-FAST-GTC, EAP-PEAP-GTC. + type: str + extWebAuth: + description: Indication of using external WEB Auth. + type: bool + extWebAuthAccessUrl: + description: External WEB Auth access URL. + type: str + extWebAuthHtmlTag: + description: Sensor's extWebAuthHtmlTag. + elements: dict + suboptions: + label: + description: Label. + type: str + tag: + description: Tag. + type: str + value: + description: Value. + type: str + type: list + extWebAuthPortal: + description: External authentication portal. + type: str + extWebAuthVirtualIp: + description: External WEB Auth virtual IP. + type: str + locationVlanList: + description: Sensor's locationVlanList. + elements: dict + suboptions: + locationId: + description: Site UUID. + type: str + vlans: + description: Array of VLANs. + elements: str + type: list + type: list + password: + description: Password string for onboarding SSID. + type: str + passwordType: + description: SSID password type ASCII or HEX. + type: str + profileName: + description: Profile name. + type: str + psk: + description: Password of SSID when passwordType is ASCII. + type: str + qosPolicy: + description: QoS policy PlATINUM, GOLD, SILVER, BRONZE. + type: str + scep: + description: Secure certificate enrollment protocol true or false or null for + not applicable. + type: bool + tests: + description: Sensor's tests. + elements: dict + suboptions: + config: + description: Sensor's config. + elements: dict + suboptions: + direction: + description: IPerf direction (UPLOAD, DOWNLOAD, BOTH). + type: str + domains: + description: DNS domain name. + elements: str + type: list + downlinkTest: + description: Downlink test. + type: bool + endPort: + description: IPerf end port. + type: int + exitCommand: + description: Exit command. + type: str + finalPrompt: + description: Final prompt. + type: str + ndtServer: + description: NDT server. + type: str + ndtServerPath: + description: NDT server path. + type: str + ndtServerPort: + description: NDT server port. + type: str + numPackets: + description: Number of packets. + type: int + password: + description: Password. + type: str + passwordPrompt: + description: Password prompt. + type: str + pathToDownload: + description: File path for file transfer. + type: str + port: + description: Radius or WEB server port. + type: int + probeType: + description: Probe type. + type: str + protocol: + description: Protocol used by file transfer, IPerf, mail server, and + radius (TCP, UDP, FTP, POP3, IMAP, CHAP, PAP). + type: str + proxyPassword: + description: Proxy password. + type: str + proxyPort: + description: Proxy port. + type: str + proxyServer: + description: Proxy server. + type: str + proxyUserName: + description: Proxy user name. + type: str + server: + description: Ping, file transfer, mail, radius, ssh, or telnet server. + type: str + servers: + description: IPerf server list. + elements: str + type: list + sharedSecret: + description: Shared secret. + type: str + startPort: + description: IPerf start port. + type: int + transferType: + description: File transfer type (UPLOAD, DOWNLOAD, BOTH). + type: str + udpBandwidth: + description: IPerf UDP bandwidth. + type: int + uplinkTest: + description: Uplink test. + type: bool + url: + description: URL. + type: str + userName: + description: User name. + type: str + userNamePrompt: + description: User name prompt. + type: str + type: list + name: + description: Name of the test. + type: str + type: list + username: + description: User name string for onboarding SSID. + type: str + vlan: + description: VLAN. + type: str + whiteList: + description: Indication of being on allowed list. + type: bool + type: list + runNow: + description: Run now (YES, NO). type: str + sensors: + description: Sensor's sensors. + elements: dict + suboptions: + allSensorAddition: + description: Is all sensor addition. + type: bool + assigned: + description: Is assigned. + type: bool + configUpdated: + description: Configuration updated YES, NO. + type: str + hostName: + description: Host name. + type: str + iPerfInfo: + description: A string-stringList iPerf information. + type: dict + id: + description: Sensor ID. + type: str + ipAddress: + description: IP address. + type: str + locationId: + description: Site UUID. + type: str + macAddress: + description: MAC address. + type: str + markedForUninstall: + description: Is marked for uninstall. + type: bool + name: + description: Sensor name. + type: str + runNow: + description: Run now YES, NO. + type: str + sensorType: + description: Sensor type. + type: str + servicePolicy: + description: Service policy. + type: str + status: + description: Sensor device status UP, DOWN, REBOOT. + type: str + switchMac: + description: Switch MAC address. + type: str + switchSerialNumber: + description: Switch serial number. + type: str + switchUuid: + description: Switch device UUID. + type: str + targetAPs: + description: Array of target APs. + elements: str + type: list + testMacAddresses: + description: A string-string test MAC address. + type: dict + wiredApplicationMessage: + description: Wired application message. + type: str + wiredApplicationStatus: + description: Wired application status. + type: str + xorSensor: + description: Is XOR sensor. + type: bool + type: list ssids: description: Sensor's ssids. elements: dict suboptions: + authProtocol: + description: Auth protocol. + type: str authType: - description: Auth Type. + description: Authentication type OPEN, WPA2_PSK, WPA2_EaP, WEB_AUTH, MAB, DOT1X, + OTHER. type: str - categories: - description: Categories. - elements: str + bands: + description: WIFI bands 2.4GHz or 5GHz. + type: str + certdownloadurl: + description: Certificate download URL. + type: str + certfilename: + description: Auth certificate file name. + type: str + certpassphrase: + description: Certificate password phrase. + type: str + certstatus: + description: Certificate status INACTIVE or ACTIVE. + type: str + certxferprotocol: + description: Certificate transfering protocol HTTP or HTTPS. + type: str + eapMethod: + description: WPA2_EAP methods EAP-FAST, PEAP-MSCHAPv2, EAP-TLS, PEAP-TLS, EAP-TTLS-MSCHAPv2, + EAP-TTLS-PAP, EAP-TTLS-CHAP, EAP-FAST-GTC, EAP-PEAP-GTC. + type: str + extWebAuth: + description: Indication of using external WEB Auth. + type: bool + extWebAuthAccessUrl: + description: External WEB Auth access URL. + type: str + extWebAuthHtmlTag: + description: Sensor's extWebAuthHtmlTag. + elements: dict + suboptions: + label: + description: Label. + type: str + tag: + description: Tag. + type: str + value: + description: Value. + type: str type: list + extWebAuthPortal: + description: External authentication portal. + type: str + extWebAuthVirtualIp: + description: External WEB Auth virtual IP. + type: str + layer3webAuthEmailAddress: + description: Layer 3 WEB Auth email address. + type: str + layer3webAuthpassword: + description: Layer 3 WEB Auth password. + type: str + layer3webAuthsecurity: + description: Layer 3 WEB Auth security. + type: str + layer3webAuthuserName: + description: Layer 3 WEB Auth user name. + type: str + password: + description: Password string for onboarding SSID. + type: str + passwordType: + description: SSID password type ASCII or HEX. + type: str profileName: - description: Profile Name. + description: The SSID profile name string. + type: str + proxyPassword: + description: Proxy server password. + type: str + proxyPort: + description: Proxy server port. + type: str + proxyServer: + description: Proxy server for onboarding SSID. + type: str + proxyUserName: + description: Proxy server user name. type: str psk: - description: Psk. + description: Password of SSID when passwordType is ASCII. type: str qosPolicy: - description: Qos Policy. + description: QoS policy PlATINUM, GOLD, SILVER, BRONZE. type: str + scep: + description: Secure certificate enrollment protocol true or false or null for + not applicable. + type: bool ssid: - description: Ssid. + description: The SSID string. type: str tests: description: Sensor's tests. elements: dict suboptions: config: - description: Config. + description: Sensor's config. elements: dict + suboptions: + direction: + description: IPerf direction (UPLOAD, DOWNLOAD, BOTH). + type: str + domains: + description: DNS domain name. + elements: str + type: list + downlinkTest: + description: Downlink test. + type: bool + endPort: + description: IPerf end port. + type: int + exitCommand: + description: Exit command. + type: str + finalPrompt: + description: Final prompt. + type: str + ndtServer: + description: NDT server. + type: str + ndtServerPath: + description: NDT server path. + type: str + ndtServerPort: + description: NDT server port. + type: str + numPackets: + description: Number of packets. + type: int + password: + description: Password. + type: str + passwordPrompt: + description: Password prompt. + type: str + pathToDownload: + description: File path for file transfer. + type: str + port: + description: Radius or WEB server port. + type: int + probeType: + description: Probe type. + type: str + protocol: + description: Protocol used by file transfer, IPerf, mail server, and + radius (TCP, UDP, FTP, POP3, IMAP, CHAP, PAP). + type: str + proxyPassword: + description: Proxy password. + type: str + proxyPort: + description: Proxy port. + type: str + proxyServer: + description: Proxy server. + type: str + proxyUserName: + description: Proxy user name. + type: str + server: + description: Ping, file transfer, mail, radius, ssh, or telnet server. + type: str + servers: + description: IPerf server list. + elements: str + type: list + sharedSecret: + description: Shared secret. + type: str + startPort: + description: IPerf start port. + type: int + transferType: + description: File transfer type (UPLOAD, DOWNLOAD, BOTH). + type: str + udpBandwidth: + description: IPerf UDP bandwidth. + type: int + uplinkTest: + description: Uplink test. + type: bool + url: + description: URL. + type: str + userName: + description: User name. + type: str + userNamePrompt: + description: User name prompt. + type: str type: list name: - description: Name. + description: Name of the test. type: str type: list thirdParty: description: Sensor's thirdParty. suboptions: selected: - description: Selected. + description: True the SSID is third party. type: bool type: dict + username: + description: User name string for onboarding SSID. + type: str + whiteList: + description: Indication of being on allowed list. + type: bool + wlanId: + description: WLAN ID. + type: int + wlc: + description: WLC IP addres. + type: str type: list templateName: description: TemplateName query parameter. type: str + version: + description: The sensor test template version (must be 2). + type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sensors CreateSensorTestTemplate description: Complete reference of the CreateSensorTestTemplate API. @@ -120,25 +625,188 @@ state: present apCoverage: - bands: string - numberOfApsToTest: string - rssiThreshold: string + numberOfApsToTest: 0 + rssiThreshold: 0 connection: string + encryptionMode: string + locationInfoList: + - allSensors: true + customManagementVlan: true + locationId: string + locationType: string + macAddressList: + - string + managementVlan: string + siteHierarchy: string modelVersion: 0 name: string - ssids: - - authType: string - categories: + profiles: + - authProtocol: string + authType: string + certdownloadurl: string + certfilename: string + certpassphrase: string + certstatus: string + certxferprotocol: string + deviceType: string + eapMethod: string + extWebAuth: true + extWebAuthAccessUrl: string + extWebAuthHtmlTag: + - label: string + tag: string + value: string + extWebAuthPortal: string + extWebAuthVirtualIp: string + locationVlanList: + - locationId: string + vlans: + - string + password: string + passwordType: string + profileName: string + psk: string + qosPolicy: string + scep: true + tests: + - config: + - direction: string + domains: + - string + downlinkTest: true + endPort: 0 + exitCommand: string + finalPrompt: string + ndtServer: string + ndtServerPath: string + ndtServerPort: string + numPackets: 0 + password: string + passwordPrompt: string + pathToDownload: string + port: 0 + probeType: string + protocol: string + proxyPassword: string + proxyPort: string + proxyServer: string + proxyUserName: string + server: string + servers: + - string + sharedSecret: string + startPort: 0 + transferType: string + udpBandwidth: 0 + uplinkTest: true + url: string + userName: string + userNamePrompt: string + name: string + username: string + vlan: string + whiteList: true + runNow: string + sensors: + - allSensorAddition: true + assigned: true + configUpdated: string + hostName: string + iPerfInfo: {} + id: string + ipAddress: string + locationId: string + macAddress: string + markedForUninstall: true + name: string + runNow: string + sensorType: string + servicePolicy: string + status: string + switchMac: string + switchSerialNumber: string + switchUuid: string + targetAPs: - string + testMacAddresses: {} + wiredApplicationMessage: string + wiredApplicationStatus: string + xorSensor: true + ssids: + - authProtocol: string + authType: string + bands: string + certdownloadurl: string + certfilename: string + certpassphrase: string + certstatus: string + certxferprotocol: string + eapMethod: string + extWebAuth: true + extWebAuthAccessUrl: string + extWebAuthHtmlTag: + - label: string + tag: string + value: string + extWebAuthPortal: string + extWebAuthVirtualIp: string + layer3webAuthEmailAddress: string + layer3webAuthpassword: string + layer3webAuthsecurity: string + layer3webAuthuserName: string + password: string + passwordType: string profileName: string + proxyPassword: string + proxyPort: string + proxyServer: string + proxyUserName: string psk: string qosPolicy: string + scep: true ssid: string tests: - config: - - {} + - direction: string + domains: + - string + downlinkTest: true + endPort: 0 + exitCommand: string + finalPrompt: string + ndtServer: string + ndtServerPath: string + ndtServerPort: string + numPackets: 0 + password: string + passwordPrompt: string + pathToDownload: string + port: 0 + probeType: string + protocol: string + proxyPassword: string + proxyPort: string + proxyServer: string + proxyUserName: string + server: string + servers: + - string + sharedSecret: string + startPort: 0 + transferType: string + udpBandwidth: 0 + uplinkTest: true + url: string + userName: string + userNamePrompt: string name: string thirdParty: selected: true + username: string + whiteList: true + wlanId: 0 + wlc: string + version: 0 - name: Delete all cisco.dnac.sensor: @@ -153,7 +821,6 @@ templateName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -163,71 +830,202 @@ { "version": "string", "response": { - "_id": "string", "name": "string", + "_id": "string", "version": 0, "modelVersion": 0, "startTime": 0, "lastModifiedTime": 0, "numAssociatedSensor": 0, - "location": {}, - "siteHierarchy": {}, + "location": "string", + "siteHierarchy": "string", "status": "string", "connection": "string", - "frequency": {}, + "actionInProgress": "string", + "frequency": { + "value": 0, + "unit": "string" + }, "rssiThreshold": 0, "numNeighborAPThreshold": 0, "scheduleInDays": 0, "wlans": [ - {} + "string" ], "ssids": [ { - "bands": {}, + "bands": "string", "ssid": "string", "profileName": "string", - "authType": "string", - "authTypeRcvd": {}, - "psk": "string", - "username": {}, - "password": {}, - "eapMethod": {}, - "scep": true, - "authProtocol": {}, - "certfilename": {}, - "certxferprotocol": "string", - "certstatus": "string", - "certpassphrase": {}, - "certdownloadurl": {}, "numAps": 0, "numSensors": 0, - "layer3webAuthsecurity": {}, - "layer3webAuthuserName": {}, - "layer3webAuthpassword": {}, - "extWebAuthVirtualIp": {}, - "layer3webAuthEmailAddress": {}, - "qosPolicy": "string", - "extWebAuth": true, - "whiteList": true, - "extWebAuthPortal": {}, - "extWebAuthAccessUrl": {}, - "extWebAuthHtmlTag": [ - {} - ], + "layer3webAuthsecurity": "string", + "layer3webAuthuserName": "string", + "layer3webAuthpassword": "string", + "layer3webAuthEmailAddress": "string", "thirdParty": { "selected": true }, "id": 0, "wlanId": 0, - "wlc": {}, + "wlc": "string", "validFrom": 0, "validTo": 0, "status": "string", + "proxyServer": "string", + "proxyPort": "string", + "proxyUserName": "string", + "proxyPassword": "string", + "authType": "string", + "psk": "string", + "username": "string", + "password": "string", + "passwordType": "string", + "eapMethod": "string", + "scep": true, + "authProtocol": "string", + "certfilename": "string", + "certxferprotocol": "string", + "certstatus": "string", + "certpassphrase": "string", + "certdownloadurl": "string", + "extWebAuthVirtualIp": "string", + "extWebAuth": true, + "whiteList": true, + "extWebAuthPortal": "string", + "extWebAuthAccessUrl": "string", + "extWebAuthHtmlTag": [ + { + "label": "string", + "tag": "string", + "value": "string" + } + ], + "qosPolicy": "string", + "tests": [ + { + "name": "string", + "config": [ + { + "domains": [ + "string" + ], + "server": "string", + "userName": "string", + "password": "string", + "url": "string", + "port": 0, + "protocol": "string", + "servers": [ + "string" + ], + "direction": "string", + "startPort": 0, + "endPort": 0, + "udpBandwidth": 0, + "probeType": "string", + "numPackets": 0, + "pathToDownload": "string", + "transferType": "string", + "sharedSecret": "string", + "ndtServer": "string", + "ndtServerPort": "string", + "ndtServerPath": "string", + "uplinkTest": true, + "downlinkTest": true, + "proxyServer": "string", + "proxyPort": "string", + "proxyUserName": "string", + "proxyPassword": "string", + "userNamePrompt": "string", + "passwordPrompt": "string", + "exitCommand": "string", + "finalPrompt": "string" + } + ] + } + ] + } + ], + "profiles": [ + { + "authType": "string", + "psk": "string", + "username": "string", + "password": "string", + "passwordType": "string", + "eapMethod": "string", + "scep": true, + "authProtocol": "string", + "certfilename": "string", + "certxferprotocol": "string", + "certstatus": "string", + "certpassphrase": "string", + "certdownloadurl": "string", + "extWebAuthVirtualIp": "string", + "extWebAuth": true, + "whiteList": true, + "extWebAuthPortal": "string", + "extWebAuthAccessUrl": "string", + "extWebAuthHtmlTag": [ + { + "label": "string", + "tag": "string", + "value": "string" + } + ], + "qosPolicy": "string", "tests": [ { "name": "string", "config": [ - {} + { + "domains": [ + "string" + ], + "server": "string", + "userName": "string", + "password": "string", + "url": "string", + "port": 0, + "protocol": "string", + "servers": [ + "string" + ], + "direction": "string", + "startPort": 0, + "endPort": 0, + "udpBandwidth": 0, + "probeType": "string", + "numPackets": 0, + "pathToDownload": "string", + "transferType": "string", + "sharedSecret": "string", + "ndtServer": "string", + "ndtServerPort": "string", + "ndtServerPath": "string", + "uplinkTest": true, + "downlinkTest": true, + "proxyServer": "string", + "proxyPort": "string", + "proxyUserName": "string", + "proxyPassword": "string", + "userNamePrompt": "string", + "passwordPrompt": "string", + "exitCommand": "string", + "finalPrompt": "string" + } + ] + } + ], + "profileName": "string", + "deviceType": "string", + "vlan": "string", + "locationVlanList": [ + { + "locationId": "string", + "vlans": [ + "string" ] } ] @@ -239,12 +1037,46 @@ "encryptionMode": "string", "runNow": "string", "locationInfoList": [ - {} + { + "locationId": "string", + "locationType": "string", + "allSensors": true, + "siteHierarchy": "string", + "macAddressList": [ + "string" + ], + "managementVlan": "string", + "customManagementVlan": true + } ], - "schedule": {}, - "tests": {}, "sensors": [ - {} + { + "name": "string", + "macAddress": "string", + "switchMac": "string", + "switchUuid": "string", + "switchSerialNumber": "string", + "markedForUninstall": true, + "ipAddress": "string", + "hostName": "string", + "wiredApplicationStatus": "string", + "wiredApplicationMessage": "string", + "assigned": true, + "status": "string", + "xorSensor": true, + "targetAPs": [ + "string" + ], + "runNow": "string", + "locationId": "string", + "allSensorAddition": true, + "configUpdated": "string", + "sensorType": "string", + "testMacAddresses": {}, + "id": "string", + "servicePolicy": "string", + "iPerfInfo": {} + } ], "apCoverage": [ { @@ -252,11 +1084,7 @@ "numberOfApsToTest": 0, "rssiThreshold": 0 } - ], - "testDurationEstimate": 0, - "testTemplate": true, - "legacyTestSuite": true, - "tenantId": {} + ] } } """ diff --git a/plugins/modules/sensor_info.py b/plugins/modules/sensor_info.py index 2955ceac13..479c1b4f9f 100644 --- a/plugins/modules/sensor_info.py +++ b/plugins/modules/sensor_info.py @@ -24,8 +24,8 @@ - SiteId query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sensors Sensors description: Complete reference of the Sensors API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -76,13 +75,13 @@ "version": "string", "lastSeen": 0, "type": "string", - "sshConfig": { + "ssh": { "sshState": "string", "sshUserName": "string", "sshPassword": "string", "enablePassword": "string" }, - "isLEDEnabled": true + "led": true } ] } diff --git a/plugins/modules/sensor_test_run.py b/plugins/modules/sensor_test_run.py index cb800c9687..c1aaac43dc 100644 --- a/plugins/modules/sensor_test_run.py +++ b/plugins/modules/sensor_test_run.py @@ -20,8 +20,8 @@ description: Template Name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sensors RunNowSensorTest description: Complete reference of the RunNowSensorTest API. @@ -48,7 +48,6 @@ templateName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sensor_test_template_duplicate.py b/plugins/modules/sensor_test_template_duplicate.py index 85cad96d2c..f0df5aab78 100644 --- a/plugins/modules/sensor_test_template_duplicate.py +++ b/plugins/modules/sensor_test_template_duplicate.py @@ -17,14 +17,14 @@ author: Rafael Campos (@racampos) options: newTemplateName: - description: New Template Name. + description: Destination test template name. type: str templateName: - description: Template Name. + description: Source test template name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sensors DuplicateSensorTestTemplate description: Complete reference of the DuplicateSensorTestTemplate API. @@ -52,7 +52,6 @@ templateName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -62,71 +61,202 @@ { "version": "string", "response": { - "_id": "string", "name": "string", + "_id": "string", "version": 0, "modelVersion": 0, "startTime": 0, "lastModifiedTime": 0, "numAssociatedSensor": 0, - "location": {}, - "siteHierarchy": {}, + "location": "string", + "siteHierarchy": "string", "status": "string", "connection": "string", - "frequency": {}, + "actionInProgress": "string", + "frequency": { + "value": 0, + "unit": "string" + }, "rssiThreshold": 0, "numNeighborAPThreshold": 0, "scheduleInDays": 0, "wlans": [ - {} + "string" ], "ssids": [ { - "bands": {}, + "bands": "string", "ssid": "string", "profileName": "string", - "authType": "string", - "authTypeRcvd": {}, - "psk": "string", - "username": {}, - "password": {}, - "eapMethod": {}, - "scep": true, - "authProtocol": {}, - "certfilename": {}, - "certxferprotocol": "string", - "certstatus": "string", - "certpassphrase": {}, - "certdownloadurl": {}, "numAps": 0, "numSensors": 0, - "layer3webAuthsecurity": {}, - "layer3webAuthuserName": {}, - "layer3webAuthpassword": {}, - "extWebAuthVirtualIp": {}, - "layer3webAuthEmailAddress": {}, - "qosPolicy": "string", - "extWebAuth": true, - "whiteList": true, - "extWebAuthPortal": {}, - "extWebAuthAccessUrl": {}, - "extWebAuthHtmlTag": [ - {} - ], + "layer3webAuthsecurity": "string", + "layer3webAuthuserName": "string", + "layer3webAuthpassword": "string", + "layer3webAuthEmailAddress": "string", "thirdParty": { "selected": true }, "id": 0, "wlanId": 0, - "wlc": {}, + "wlc": "string", "validFrom": 0, "validTo": 0, "status": "string", + "proxyServer": "string", + "proxyPort": "string", + "proxyUserName": "string", + "proxyPassword": "string", + "authType": "string", + "psk": "string", + "username": "string", + "password": "string", + "passwordType": "string", + "eapMethod": "string", + "scep": true, + "authProtocol": "string", + "certfilename": "string", + "certxferprotocol": "string", + "certstatus": "string", + "certpassphrase": "string", + "certdownloadurl": "string", + "extWebAuthVirtualIp": "string", + "extWebAuth": true, + "whiteList": true, + "extWebAuthPortal": "string", + "extWebAuthAccessUrl": "string", + "extWebAuthHtmlTag": [ + { + "label": "string", + "tag": "string", + "value": "string" + } + ], + "qosPolicy": "string", "tests": [ { "name": "string", "config": [ - {} + { + "domains": [ + "string" + ], + "server": "string", + "userName": "string", + "password": "string", + "url": "string", + "port": 0, + "protocol": "string", + "servers": [ + "string" + ], + "direction": "string", + "startPort": 0, + "endPort": 0, + "udpBandwidth": 0, + "probeType": "string", + "numPackets": 0, + "pathToDownload": "string", + "transferType": "string", + "sharedSecret": "string", + "ndtServer": "string", + "ndtServerPort": "string", + "ndtServerPath": "string", + "uplinkTest": true, + "downlinkTest": true, + "proxyServer": "string", + "proxyPort": "string", + "proxyUserName": "string", + "proxyPassword": "string", + "userNamePrompt": "string", + "passwordPrompt": "string", + "exitCommand": "string", + "finalPrompt": "string" + } + ] + } + ] + } + ], + "profiles": [ + { + "authType": "string", + "psk": "string", + "username": "string", + "password": "string", + "passwordType": "string", + "eapMethod": "string", + "scep": true, + "authProtocol": "string", + "certfilename": "string", + "certxferprotocol": "string", + "certstatus": "string", + "certpassphrase": "string", + "certdownloadurl": "string", + "extWebAuthVirtualIp": "string", + "extWebAuth": true, + "whiteList": true, + "extWebAuthPortal": "string", + "extWebAuthAccessUrl": "string", + "extWebAuthHtmlTag": [ + { + "label": "string", + "tag": "string", + "value": "string" + } + ], + "qosPolicy": "string", + "tests": [ + { + "name": "string", + "config": [ + { + "domains": [ + "string" + ], + "server": "string", + "userName": "string", + "password": "string", + "url": "string", + "port": 0, + "protocol": "string", + "servers": [ + "string" + ], + "direction": "string", + "startPort": 0, + "endPort": 0, + "udpBandwidth": 0, + "probeType": "string", + "numPackets": 0, + "pathToDownload": "string", + "transferType": "string", + "sharedSecret": "string", + "ndtServer": "string", + "ndtServerPort": "string", + "ndtServerPath": "string", + "uplinkTest": true, + "downlinkTest": true, + "proxyServer": "string", + "proxyPort": "string", + "proxyUserName": "string", + "proxyPassword": "string", + "userNamePrompt": "string", + "passwordPrompt": "string", + "exitCommand": "string", + "finalPrompt": "string" + } + ] + } + ], + "profileName": "string", + "deviceType": "string", + "vlan": "string", + "locationVlanList": [ + { + "locationId": "string", + "vlans": [ + "string" ] } ] @@ -144,36 +274,40 @@ "allSensors": true, "siteHierarchy": "string", "macAddressList": [ - {} - ] + "string" + ], + "managementVlan": "string", + "customManagementVlan": true } ], - "schedule": { - "testScheduleMode": "string", - "scheduleRange": [ - { - "timeRange": [ - { - "from": "string", - "to": "string", - "frequency": { - "value": 0, - "unit": "string" - } - } - ], - "day": "string" - } - ], - "startTime": 0, - "frequency": { - "value": 0, - "unit": "string" - } - }, - "tests": {}, "sensors": [ - {} + { + "name": "string", + "macAddress": "string", + "switchMac": "string", + "switchUuid": "string", + "switchSerialNumber": "string", + "markedForUninstall": true, + "ipAddress": "string", + "hostName": "string", + "wiredApplicationStatus": "string", + "wiredApplicationMessage": "string", + "assigned": true, + "status": "string", + "xorSensor": true, + "targetAPs": [ + "string" + ], + "runNow": "string", + "locationId": "string", + "allSensorAddition": true, + "configUpdated": "string", + "sensorType": "string", + "testMacAddresses": {}, + "id": "string", + "servicePolicy": "string", + "iPerfInfo": {} + } ], "apCoverage": [ { @@ -181,11 +315,7 @@ "numberOfApsToTest": 0, "rssiThreshold": 0 } - ], - "testDurationEstimate": 0, - "testTemplate": true, - "legacyTestSuite": true, - "tenantId": {} + ] } } """ diff --git a/plugins/modules/sensor_test_template_edit.py b/plugins/modules/sensor_test_template_edit.py index b8bf3f3b42..fd9ef70829 100644 --- a/plugins/modules/sensor_test_template_edit.py +++ b/plugins/modules/sensor_test_template_edit.py @@ -16,75 +16,659 @@ - cisco.dnac.module author: Rafael Campos (@racampos) options: + _id: + description: The sensor test template unique identifier, generated at test creation + time. + type: str + actionInProgress: + description: Indication of inprogress action. + type: str + apCoverage: + description: Sensor Test Template Edit's apCoverage. + elements: dict + suboptions: + bands: + description: The WIFI bands. + type: str + numberOfApsToTest: + description: Number of APs to test. + type: int + rssiThreshold: + description: RSSI threshold. + type: int + type: list + connection: + description: Connection type of test WIRED, WIRELESS, BOTH. + type: str + encryptionMode: + description: Encryption mode. + type: str + frequency: + description: Sensor Test Template Edit's frequency. + suboptions: + unit: + description: Unit of the time value (NANOSECONDS, MICROSECONDS, MILLISECONDS, + SECONDS, MINUTES, HOURS, DAYS). + type: str + value: + description: Value of the unit. + type: int + type: dict + lastModifiedTime: + description: Last modify time. + type: int + location: + description: Location string. + type: str locationInfoList: description: Sensor Test Template Edit's locationInfoList. elements: dict suboptions: allSensors: - description: All Sensors. + description: Use all sensors in the site for test. + type: bool + customManagementVlan: + description: Custom Management VLAN. type: bool locationId: - description: Location Id. + description: Site UUID. type: str locationType: - description: Location Type. + description: Site type. + type: str + macAddressList: + description: MAC addresses. + elements: str + type: list + managementVlan: + description: Management VLAN. type: str siteHierarchy: - description: Site Hierarchy. + description: Site name hierarhy. type: str type: list - schedule: - description: Sensor Test Template Edit's schedule. + modelVersion: + description: Test template object model version (must be 2). + type: int + name: + description: The sensor test template name, which is the same as in 'templateName'. + type: str + numAssociatedSensor: + description: Number of associated sensor. + type: int + numNeighborAPThreshold: + description: Number of neighboring AP threshold. + type: int + profiles: + description: Sensor Test Template Edit's profiles. + elements: dict suboptions: - frequency: - description: Sensor Test Template Edit's frequency. + authProtocol: + description: Auth protocol. + type: str + authType: + description: Authentication type OPEN, WPA2_PSK, WPA2_EAP, WEB_AUTH, MAB, DOT1X, + OTHER. + type: str + certdownloadurl: + description: Certificate download URL. + type: str + certfilename: + description: Auth certificate file name. + type: str + certpassphrase: + description: Certificate password phrase. + type: str + certstatus: + description: Certificate status INACTIVE or ACTIVE. + type: str + certxferprotocol: + description: Certificate transfering protocol HTTP or HTTPS. + type: str + deviceType: + description: Device Type. + type: str + eapMethod: + description: WPA2_EAP methods EAP-FAST, PEAP-MSCHAPv2, EAP-TLS, PEAP-TLS, EAP-TTLS-MSCHAPv2, + EAP-TTLS-PAP, EAP-TTLS-CHAP, EAP-FAST-GTC, EAP-PEAP-GTC. + type: str + extWebAuth: + description: Indication of using external WEB Auth. + type: bool + extWebAuthAccessUrl: + description: External WEB Auth access URL. + type: str + extWebAuthHtmlTag: + description: Sensor Test Template Edit's extWebAuthHtmlTag. + elements: dict suboptions: - unit: - description: Unit. + label: + description: Label. + type: str + tag: + description: Tag. type: str value: description: Value. - type: int + type: str + type: list + extWebAuthPortal: + description: External authentication portal. + type: str + extWebAuthVirtualIp: + description: External WEB Auth virtual IP. + type: str + locationVlanList: + description: Sensor Test Template Edit's locationVlanList. + elements: dict + suboptions: + locationId: + description: Site UUID. + type: str + vlans: + description: Array of VLANs. + elements: str + type: list + type: list + password: + description: Password string for onboarding SSID. + type: str + passwordType: + description: SSID password type ASCII or HEX. + type: str + profileName: + description: Profile name. + type: str + psk: + description: Password of SSID when passwordType is ASCII. + type: str + qosPolicy: + description: QoS policy PlATINUM, GOLD, SILVER, BRONZE. + type: str + scep: + description: Secure certificate enrollment protocol true or false or null for + not applicable. + type: bool + tests: + description: Sensor Test Template Edit's tests. + elements: dict + suboptions: + config: + description: Sensor Test Template Edit's config. + elements: dict + suboptions: + direction: + description: IPerf direction (UPLOAD, DOWNLOAD, BOTH). + type: str + domains: + description: DNS domain name. + elements: str + type: list + downlinkTest: + description: Downlink test. + type: bool + endPort: + description: IPerf end port. + type: int + exitCommand: + description: Exit command. + type: str + finalPrompt: + description: Final prompt. + type: str + ndtServer: + description: NDT server. + type: str + ndtServerPath: + description: NDT server path. + type: str + ndtServerPort: + description: NDT server port. + type: str + numPackets: + description: Number of packets. + type: int + password: + description: Password. + type: str + passwordPrompt: + description: Password prompt. + type: str + pathToDownload: + description: File path for file transfer. + type: str + port: + description: Radius or WEB server port. + type: int + probeType: + description: Probe type. + type: str + protocol: + description: Protocol used by file transfer, IPerf, mail server, and + radius (TCP, UDP, FTP, POP3, IMAP, CHAP, PAP). + type: str + proxyPassword: + description: Proxy password. + type: str + proxyPort: + description: Proxy port. + type: str + proxyServer: + description: Proxy server. + type: str + proxyUserName: + description: Proxy user name. + type: str + server: + description: Ping, file transfer, mail, radius, ssh, or telnet server. + type: str + servers: + description: IPerf server list. + elements: str + type: list + sharedSecret: + description: Shared secret. + type: str + startPort: + description: IPerf start port. + type: int + transferType: + description: File transfer type (UPLOAD, DOWNLOAD, BOTH). + type: str + udpBandwidth: + description: IPerf UDP bandwidth. + type: int + uplinkTest: + description: Uplink test. + type: bool + url: + description: URL. + type: str + userName: + description: User name. + type: str + userNamePrompt: + description: User name prompt. + type: str + type: list + name: + description: Name of the test. + type: str + type: list + username: + description: User name string for onboarding SSID. + type: str + vlan: + description: VLAN. + type: str + whiteList: + description: Indication of being on allowed list. + type: bool + type: list + radioAsSensorRemoved: + description: Radio as sensor removed. + type: bool + rssiThreshold: + description: RSSI threshold. + type: int + runNow: + description: Run now (YES, NO). + type: str + scheduleInDays: + description: Bit-wise value of scheduled test days. + type: int + sensors: + description: Sensor Test Template Edit's sensors. + elements: dict + suboptions: + allSensorAddition: + description: Is all sensor addition. + type: bool + assigned: + description: Is assigned. + type: bool + configUpdated: + description: Configuration updated YES, NO. + type: str + hostName: + description: Host name. + type: str + iPerfInfo: + description: A string-stringList iPerf information. + type: dict + id: + description: Sensor ID. + type: str + ipAddress: + description: IP address. + type: str + locationId: + description: Site UUID. + type: str + macAddress: + description: MAC address. + type: str + markedForUninstall: + description: Is marked for uninstall. + type: bool + name: + description: Sensor name. + type: str + runNow: + description: Run now YES, NO. + type: str + sensorType: + description: Sensor type. + type: str + servicePolicy: + description: Service policy. + type: str + status: + description: Sensor device status UP, DOWN, REBOOT. + type: str + switchMac: + description: Switch MAC address. + type: str + switchSerialNumber: + description: Switch serial number. + type: str + switchUuid: + description: Switch device UUID. + type: str + targetAPs: + description: Array of target APs. + elements: str + type: list + testMacAddresses: + description: A string-string test MAC address. type: dict - scheduleRange: - description: Sensor Test Template Edit's scheduleRange. + wiredApplicationMessage: + description: Wired application message. + type: str + wiredApplicationStatus: + description: Wired application status. + type: str + xorSensor: + description: Is XOR sensor. + type: bool + type: list + showWlcUpgradeBanner: + description: Show WLC upgrade banner. + type: bool + siteHierarchy: + description: Site hierarchy. + type: str + ssids: + description: Sensor Test Template Edit's ssids. + elements: dict + suboptions: + authProtocol: + description: Auth protocol. + type: str + authType: + description: Authentication type OPEN, WPA2_PSK, WPA2_EAP, WEB_AUTH, MAB, DOT1X, + OTHER. + type: str + bands: + description: WIFI bands 2.4GHz or 5GHz. + type: str + certdownloadurl: + description: Certificate download URL. + type: str + certfilename: + description: Auth certificate file name. + type: str + certpassphrase: + description: Certificate password phrase. + type: str + certstatus: + description: Certificate status INACTIVE or ACTIVE. + type: str + certxferprotocol: + description: Certificate transfering protocol HTTP or HTTPS. + type: str + eapMethod: + description: WPA2_EAP methods EAP-FAST, PEAP-MSCHAPv2, EAP-TLS, PEAP-TLS, EAP-TTLS-MSCHAPv2, + EAP-TTLS-PAP, EAP-TTLS-CHAP, EAP-FAST-GTC, EAP-PEAP-GTC. + type: str + extWebAuth: + description: Indication of using external WEB Auth. + type: bool + extWebAuthAccessUrl: + description: External WEB Auth access URL. + type: str + extWebAuthHtmlTag: + description: Sensor Test Template Edit's extWebAuthHtmlTag. elements: dict suboptions: - day: - description: Day. + label: + description: Label. type: str - timeRange: - description: Sensor Test Template Edit's timeRange. + tag: + description: Tag. + type: str + value: + description: Value. + type: str + type: list + extWebAuthPortal: + description: External authentication portal. + type: str + extWebAuthVirtualIp: + description: External WEB Auth virtual IP. + type: str + id: + description: Identification number. + type: int + layer3webAuthEmailAddress: + description: Layer 3 WEB Auth email address. + type: str + layer3webAuthpassword: + description: Layer 3 WEB Auth password. + type: str + layer3webAuthsecurity: + description: Layer 3 WEB Auth security. + type: str + layer3webAuthuserName: + description: Layer 3 WEB Auth user name. + type: str + numAps: + description: Number of APs in the test. + type: int + numSensors: + description: Number of Sensors in the test. + type: int + password: + description: Password string for onboarding SSID. + type: str + passwordType: + description: SSID password type ASCII or HEX. + type: str + profileName: + description: The SSID profile name string. + type: str + proxyPassword: + description: Proxy server password. + type: str + proxyPort: + description: Proxy server port. + type: str + proxyServer: + description: Proxy server for onboarding SSID. + type: str + proxyUserName: + description: Proxy server user name. + type: str + psk: + description: Password of SSID when passwordType is ASCII. + type: str + qosPolicy: + description: QoS policy PlATINUM, GOLD, SILVER, BRONZE. + type: str + scep: + description: Secure certificate enrollment protocol true or false or null for + not applicable. + type: bool + ssid: + description: The SSID string. + type: str + status: + description: WLAN status ENABLED or DISABLED. + type: str + tests: + description: Sensor Test Template Edit's tests. + elements: dict + suboptions: + config: + description: Sensor Test Template Edit's config. elements: dict suboptions: - frequency: - description: Sensor Test Template Edit's frequency. - suboptions: - unit: - description: Unit. - type: str - value: - description: Value. - type: int - type: dict - from: - description: From. - type: str - to: - description: To. + direction: + description: IPerf direction (UPLOAD, DOWNLOAD, BOTH). + type: str + domains: + description: DNS domain name. + elements: str + type: list + downlinkTest: + description: Downlink test. + type: bool + endPort: + description: IPerf end port. + type: int + exitCommand: + description: Exit command. + type: str + finalPrompt: + description: Final prompt. + type: str + ndtServer: + description: NDT server. + type: str + ndtServerPath: + description: NDT server path. + type: str + ndtServerPort: + description: NDT server port. + type: str + numPackets: + description: Number of packets. + type: int + password: + description: Password. + type: str + passwordPrompt: + description: Password prompt. + type: str + pathToDownload: + description: File path for file transfer. + type: str + port: + description: Radius or WEB server port. + type: int + probeType: + description: Probe type. + type: str + protocol: + description: Protocol used by file transfer, IPerf, mail server, and + radius (TCP, UDP, FTP, POP3, IMAP, CHAP, PAP). + type: str + proxyPassword: + description: Proxy password. + type: str + proxyPort: + description: Proxy port. + type: str + proxyServer: + description: Proxy server. + type: str + proxyUserName: + description: Proxy user name. + type: str + server: + description: Ping, file transfer, mail, radius, ssh, or telnet server. + type: str + servers: + description: IPerf server list. + elements: str + type: list + sharedSecret: + description: Shared secret. + type: str + startPort: + description: IPerf start port. + type: int + transferType: + description: File transfer type (UPLOAD, DOWNLOAD, BOTH). + type: str + udpBandwidth: + description: IPerf UDP bandwidth. + type: int + uplinkTest: + description: Uplink test. + type: bool + url: + description: URL. + type: str + userName: + description: User name. + type: str + userNamePrompt: + description: User name prompt. type: str type: list + name: + description: Name of the test. + type: str type: list - testScheduleMode: - description: Test Schedule Mode. + thirdParty: + description: Sensor Test Template Edit's thirdParty. + suboptions: + selected: + description: True the SSID is third party. + type: bool + type: dict + username: + description: User name string for onboarding SSID. type: str - type: dict + validFrom: + description: Valid From UTC timestamp. + type: int + validTo: + description: Valid To UTC timestamp. + type: int + whiteList: + description: Indication of being on allowed list. + type: bool + wlanId: + description: WLAN ID. + type: int + wlc: + description: WLC IP addres. + type: str + type: list + startTime: + description: Start time. + type: int + status: + description: Status of the test (RUNNING, NOTRUNNING). + type: str templateName: - description: Template Name. + description: The test template name that is to be edited. + type: str + testScheduleMode: + description: Test schedule mode (ONDEMAND, DEDICATED, SCHEDULED, CONTINUOUS, RUNNOW). type: str + version: + description: The sensor test template version (must be 2). + type: int + wlans: + description: WLANs list. + elements: str + type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sensors EditSensorTestTemplate description: Complete reference of the EditSensorTestTemplate API. @@ -108,28 +692,218 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + _id: string + actionInProgress: string + apCoverage: + - bands: string + numberOfApsToTest: 0 + rssiThreshold: 0 + connection: string + encryptionMode: string + frequency: + unit: string + value: 0 + lastModifiedTime: 0 + location: string locationInfoList: - allSensors: true + customManagementVlan: true locationId: string locationType: string + macAddressList: + - string + managementVlan: string siteHierarchy: string - schedule: - frequency: - unit: string - value: 0 - scheduleRange: - - day: string - timeRange: - - frequency: - unit: string - value: 0 - from: string - to: string - testScheduleMode: string + modelVersion: 0 + name: string + numAssociatedSensor: 0 + numNeighborAPThreshold: 0 + profiles: + - authProtocol: string + authType: string + certdownloadurl: string + certfilename: string + certpassphrase: string + certstatus: string + certxferprotocol: string + deviceType: string + eapMethod: string + extWebAuth: true + extWebAuthAccessUrl: string + extWebAuthHtmlTag: + - label: string + tag: string + value: string + extWebAuthPortal: string + extWebAuthVirtualIp: string + locationVlanList: + - locationId: string + vlans: + - string + password: string + passwordType: string + profileName: string + psk: string + qosPolicy: string + scep: true + tests: + - config: + - direction: string + domains: + - string + downlinkTest: true + endPort: 0 + exitCommand: string + finalPrompt: string + ndtServer: string + ndtServerPath: string + ndtServerPort: string + numPackets: 0 + password: string + passwordPrompt: string + pathToDownload: string + port: 0 + probeType: string + protocol: string + proxyPassword: string + proxyPort: string + proxyServer: string + proxyUserName: string + server: string + servers: + - string + sharedSecret: string + startPort: 0 + transferType: string + udpBandwidth: 0 + uplinkTest: true + url: string + userName: string + userNamePrompt: string + name: string + username: string + vlan: string + whiteList: true + radioAsSensorRemoved: true + rssiThreshold: 0 + runNow: string + scheduleInDays: 0 + sensors: + - allSensorAddition: true + assigned: true + configUpdated: string + hostName: string + iPerfInfo: {} + id: string + ipAddress: string + locationId: string + macAddress: string + markedForUninstall: true + name: string + runNow: string + sensorType: string + servicePolicy: string + status: string + switchMac: string + switchSerialNumber: string + switchUuid: string + targetAPs: + - string + testMacAddresses: {} + wiredApplicationMessage: string + wiredApplicationStatus: string + xorSensor: true + showWlcUpgradeBanner: true + siteHierarchy: string + ssids: + - authProtocol: string + authType: string + bands: string + certdownloadurl: string + certfilename: string + certpassphrase: string + certstatus: string + certxferprotocol: string + eapMethod: string + extWebAuth: true + extWebAuthAccessUrl: string + extWebAuthHtmlTag: + - label: string + tag: string + value: string + extWebAuthPortal: string + extWebAuthVirtualIp: string + id: 0 + layer3webAuthEmailAddress: string + layer3webAuthpassword: string + layer3webAuthsecurity: string + layer3webAuthuserName: string + numAps: 0 + numSensors: 0 + password: string + passwordType: string + profileName: string + proxyPassword: string + proxyPort: string + proxyServer: string + proxyUserName: string + psk: string + qosPolicy: string + scep: true + ssid: string + status: string + tests: + - config: + - direction: string + domains: + - string + downlinkTest: true + endPort: 0 + exitCommand: string + finalPrompt: string + ndtServer: string + ndtServerPath: string + ndtServerPort: string + numPackets: 0 + password: string + passwordPrompt: string + pathToDownload: string + port: 0 + probeType: string + protocol: string + proxyPassword: string + proxyPort: string + proxyServer: string + proxyUserName: string + server: string + servers: + - string + sharedSecret: string + startPort: 0 + transferType: string + udpBandwidth: 0 + uplinkTest: true + url: string + userName: string + userNamePrompt: string + name: string + thirdParty: + selected: true + username: string + validFrom: 0 + validTo: 0 + whiteList: true + wlanId: 0 + wlc: string + startTime: 0 + status: string templateName: string + testScheduleMode: string + version: 0 + wlans: + - string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -139,71 +913,202 @@ { "version": "string", "response": { - "_id": "string", "name": "string", + "_id": "string", "version": 0, "modelVersion": 0, "startTime": 0, "lastModifiedTime": 0, "numAssociatedSensor": 0, - "location": {}, - "siteHierarchy": {}, + "location": "string", + "siteHierarchy": "string", "status": "string", "connection": "string", - "frequency": {}, + "actionInProgress": "string", + "frequency": { + "value": 0, + "unit": "string" + }, "rssiThreshold": 0, "numNeighborAPThreshold": 0, "scheduleInDays": 0, "wlans": [ - {} + "string" ], "ssids": [ { - "bands": {}, + "bands": "string", "ssid": "string", "profileName": "string", - "authType": "string", - "authTypeRcvd": {}, - "psk": "string", - "username": {}, - "password": {}, - "eapMethod": {}, - "scep": true, - "authProtocol": {}, - "certfilename": {}, - "certxferprotocol": "string", - "certstatus": "string", - "certpassphrase": {}, - "certdownloadurl": {}, "numAps": 0, "numSensors": 0, - "layer3webAuthsecurity": {}, - "layer3webAuthuserName": {}, - "layer3webAuthpassword": {}, - "extWebAuthVirtualIp": {}, - "layer3webAuthEmailAddress": {}, - "qosPolicy": "string", - "extWebAuth": true, - "whiteList": true, - "extWebAuthPortal": {}, - "extWebAuthAccessUrl": {}, - "extWebAuthHtmlTag": [ - {} - ], + "layer3webAuthsecurity": "string", + "layer3webAuthuserName": "string", + "layer3webAuthpassword": "string", + "layer3webAuthEmailAddress": "string", "thirdParty": { "selected": true }, "id": 0, "wlanId": 0, - "wlc": {}, + "wlc": "string", "validFrom": 0, "validTo": 0, "status": "string", + "proxyServer": "string", + "proxyPort": "string", + "proxyUserName": "string", + "proxyPassword": "string", + "authType": "string", + "psk": "string", + "username": "string", + "password": "string", + "passwordType": "string", + "eapMethod": "string", + "scep": true, + "authProtocol": "string", + "certfilename": "string", + "certxferprotocol": "string", + "certstatus": "string", + "certpassphrase": "string", + "certdownloadurl": "string", + "extWebAuthVirtualIp": "string", + "extWebAuth": true, + "whiteList": true, + "extWebAuthPortal": "string", + "extWebAuthAccessUrl": "string", + "extWebAuthHtmlTag": [ + { + "label": "string", + "tag": "string", + "value": "string" + } + ], + "qosPolicy": "string", + "tests": [ + { + "name": "string", + "config": [ + { + "domains": [ + "string" + ], + "server": "string", + "userName": "string", + "password": "string", + "url": "string", + "port": 0, + "protocol": "string", + "servers": [ + "string" + ], + "direction": "string", + "startPort": 0, + "endPort": 0, + "udpBandwidth": 0, + "probeType": "string", + "numPackets": 0, + "pathToDownload": "string", + "transferType": "string", + "sharedSecret": "string", + "ndtServer": "string", + "ndtServerPort": "string", + "ndtServerPath": "string", + "uplinkTest": true, + "downlinkTest": true, + "proxyServer": "string", + "proxyPort": "string", + "proxyUserName": "string", + "proxyPassword": "string", + "userNamePrompt": "string", + "passwordPrompt": "string", + "exitCommand": "string", + "finalPrompt": "string" + } + ] + } + ] + } + ], + "profiles": [ + { + "authType": "string", + "psk": "string", + "username": "string", + "password": "string", + "passwordType": "string", + "eapMethod": "string", + "scep": true, + "authProtocol": "string", + "certfilename": "string", + "certxferprotocol": "string", + "certstatus": "string", + "certpassphrase": "string", + "certdownloadurl": "string", + "extWebAuthVirtualIp": "string", + "extWebAuth": true, + "whiteList": true, + "extWebAuthPortal": "string", + "extWebAuthAccessUrl": "string", + "extWebAuthHtmlTag": [ + { + "label": "string", + "tag": "string", + "value": "string" + } + ], + "qosPolicy": "string", "tests": [ { "name": "string", "config": [ - {} + { + "domains": [ + "string" + ], + "server": "string", + "userName": "string", + "password": "string", + "url": "string", + "port": 0, + "protocol": "string", + "servers": [ + "string" + ], + "direction": "string", + "startPort": 0, + "endPort": 0, + "udpBandwidth": 0, + "probeType": "string", + "numPackets": 0, + "pathToDownload": "string", + "transferType": "string", + "sharedSecret": "string", + "ndtServer": "string", + "ndtServerPort": "string", + "ndtServerPath": "string", + "uplinkTest": true, + "downlinkTest": true, + "proxyServer": "string", + "proxyPort": "string", + "proxyUserName": "string", + "proxyPassword": "string", + "userNamePrompt": "string", + "passwordPrompt": "string", + "exitCommand": "string", + "finalPrompt": "string" + } + ] + } + ], + "profileName": "string", + "deviceType": "string", + "vlan": "string", + "locationVlanList": [ + { + "locationId": "string", + "vlans": [ + "string" ] } ] @@ -221,36 +1126,40 @@ "allSensors": true, "siteHierarchy": "string", "macAddressList": [ - {} - ] + "string" + ], + "managementVlan": "string", + "customManagementVlan": true } ], - "schedule": { - "testScheduleMode": "string", - "scheduleRange": [ - { - "timeRange": [ - { - "from": "string", - "to": "string", - "frequency": { - "value": 0, - "unit": "string" - } - } - ], - "day": "string" - } - ], - "startTime": 0, - "frequency": { - "value": 0, - "unit": "string" - } - }, - "tests": {}, "sensors": [ - {} + { + "name": "string", + "macAddress": "string", + "switchMac": "string", + "switchUuid": "string", + "switchSerialNumber": "string", + "markedForUninstall": true, + "ipAddress": "string", + "hostName": "string", + "wiredApplicationStatus": "string", + "wiredApplicationMessage": "string", + "assigned": true, + "status": "string", + "xorSensor": true, + "targetAPs": [ + "string" + ], + "runNow": "string", + "locationId": "string", + "allSensorAddition": true, + "configUpdated": "string", + "sensorType": "string", + "testMacAddresses": {}, + "id": "string", + "servicePolicy": "string", + "iPerfInfo": {} + } ], "apCoverage": [ { @@ -258,11 +1167,7 @@ "numberOfApsToTest": 0, "rssiThreshold": 0 } - ], - "testDurationEstimate": 0, - "testTemplate": true, - "legacyTestSuite": true, - "tenantId": "string" + ] } } """ diff --git a/plugins/modules/service_provider_create.py b/plugins/modules/service_provider_create.py index 2ce62b6649..1947468f97 100644 --- a/plugins/modules/service_provider_create.py +++ b/plugins/modules/service_provider_create.py @@ -35,8 +35,8 @@ type: list type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings CreateSPProfile description: Complete reference of the CreateSPProfile API. @@ -67,7 +67,6 @@ wanProvider: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/service_provider_info.py b/plugins/modules/service_provider_info.py index d2bc282f39..2bd9156ed0 100644 --- a/plugins/modules/service_provider_info.py +++ b/plugins/modules/service_provider_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings GetServiceProviderDetails description: Complete reference of the GetServiceProviderDetails API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -64,7 +63,7 @@ "namespace": "string", "type": "string", "key": "string", - "version": "string", + "version": 0, "value": [ { "wanProvider": "string", @@ -77,6 +76,6 @@ "inheritedGroupName": "string" } ], - "version": 0 + "version": "string" } """ diff --git a/plugins/modules/service_provider_profile_delete.py b/plugins/modules/service_provider_profile_delete.py index 0d076885ea..9c37800af5 100644 --- a/plugins/modules/service_provider_profile_delete.py +++ b/plugins/modules/service_provider_profile_delete.py @@ -20,8 +20,8 @@ description: SpProfileName path parameter. Sp profile name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings DeleteSPProfile description: Complete reference of the DeleteSPProfile API. @@ -48,7 +48,6 @@ spProfileName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/service_provider_update.py b/plugins/modules/service_provider_update.py index 3ec3fcde9b..470f50d101 100644 --- a/plugins/modules/service_provider_update.py +++ b/plugins/modules/service_provider_update.py @@ -38,8 +38,8 @@ type: list type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings UpdateSPProfile description: Complete reference of the UpdateSPProfile API. @@ -71,7 +71,6 @@ wanProvider: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/service_provider_v2.py b/plugins/modules/service_provider_v2.py index 5dcf4f3676..d9286b506f 100644 --- a/plugins/modules/service_provider_v2.py +++ b/plugins/modules/service_provider_v2.py @@ -12,7 +12,7 @@ - Manage operations create and update of the resource Service Provider V2. - API to create Service Provider Profile QOS . - API to update Service Provider Profile QoS . -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -36,8 +36,8 @@ type: list type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings CreateSPProfileV2 description: Complete reference of the CreateSPProfileV2 API. @@ -91,7 +91,6 @@ wanProvider: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/service_provider_v2_info.py b/plugins/modules/service_provider_v2_info.py index 2641b9bdb1..ebeeac9999 100644 --- a/plugins/modules/service_provider_v2_info.py +++ b/plugins/modules/service_provider_v2_info.py @@ -11,7 +11,7 @@ description: - Get all Service Provider V2. - API to get Service Provider details QoS . -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings GetServiceProviderDetailsV2 description: Complete reference of the GetServiceProviderDetailsV2 API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/site_assign_credential.py b/plugins/modules/site_assign_credential.py index b21a5ca776..c5b68dc397 100644 --- a/plugins/modules/site_assign_credential.py +++ b/plugins/modules/site_assign_credential.py @@ -41,8 +41,8 @@ description: Snmp V3 Id. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings AssignDeviceCredentialToSite description: Complete reference of the AssignDeviceCredentialToSite API. @@ -76,7 +76,6 @@ snmpV3Id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/site_count_info.py b/plugins/modules/site_count_info.py index c4a5dbd961..44908d5752 100644 --- a/plugins/modules/site_count_info.py +++ b/plugins/modules/site_count_info.py @@ -10,7 +10,7 @@ short_description: Information module for Site Count description: - Get all Site Count. -- API to get site count. +- Get the site count of the specified site's sub-hierarchy inclusive of the provided site . version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -21,11 +21,11 @@ type: dict siteId: description: - - SiteId query parameter. Site id to retrieve site count. + - SiteId query parameter. Site instance UUID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sites GetSiteCount description: Complete reference of the GetSiteCount API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/site_count_v2_info.py b/plugins/modules/site_count_v2_info.py new file mode 100644 index 0000000000..0318cbbdc8 --- /dev/null +++ b/plugins/modules/site_count_v2_info.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: site_count_v2_info +short_description: Information module for Site Count V2 +description: +- Get all Site Count V2. +- Get the site count of the specified site's sub-hierarchy inclusive of the provided site . +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + id: + description: + - Id query parameter. Site instance UUID. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Sites GetSiteCountV2 + description: Complete reference of the GetSiteCountV2 API. + link: https://developer.cisco.com/docs/dna-center/#!get-site-count-v-2 +notes: + - SDK Method used are + sites.Sites.get_site_count_v2, + + - Paths used are + get /dna/intent/api/v2/site/count, + +""" + +EXAMPLES = r""" +- name: Get all Site Count V2 + cisco.dnac.site_count_v2_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + id: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": 0, + "version": "string" + } +""" diff --git a/plugins/modules/site_create.py b/plugins/modules/site_create.py index 6b690ac25d..730a0c2182 100644 --- a/plugins/modules/site_create.py +++ b/plugins/modules/site_create.py @@ -43,10 +43,10 @@ type: str latitude: description: Latitude coordinate of the building (eg 37.338). - type: int + type: float longitude: description: Longitude coordinate of the building (eg -121.832). - type: int + type: float name: description: Name of the building (eg building1). type: str @@ -59,13 +59,13 @@ suboptions: floorNumber: description: Floor number. (eg 5). - type: int + type: float height: description: Height of the floor. Unit of measure is ft. (eg 15). - type: int + type: float length: description: Length of the floor. Unit of measure is ft. (eg 100). - type: int + type: float name: description: Name of the floor (eg floor-1). type: str @@ -77,15 +77,15 @@ type: str width: description: Width of the floor. Unit of measure is ft. (eg 100). - type: int + type: float type: dict type: dict type: description: Type of site to create (eg area, building, floor). type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sites CreateSite description: Complete reference of the CreateSite API. @@ -132,7 +132,6 @@ type: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/site_delete.py b/plugins/modules/site_delete.py index 6c52cc343a..8d7a8173bc 100644 --- a/plugins/modules/site_delete.py +++ b/plugins/modules/site_delete.py @@ -20,8 +20,8 @@ description: SiteId path parameter. Site id to which site details to be deleted. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sites DeleteSite description: Complete reference of the DeleteSite API. @@ -48,7 +48,6 @@ siteId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -57,7 +56,7 @@ sample: > { "executionId": "string", - "executionStatusURL": "string", + "executionStatusUrl": "string", "message": "string" } """ diff --git a/plugins/modules/site_health_info.py b/plugins/modules/site_health_info.py index cbb91dcd64..0ea75e2720 100644 --- a/plugins/modules/site_health_info.py +++ b/plugins/modules/site_health_info.py @@ -19,25 +19,25 @@ headers: description: Additional headers. type: dict - timestamp: - description: - - Timestamp query parameter. Epoch time(in milliseconds) when the Site Hierarchy data is required. - type: str siteType: description: - - SiteType query parameter. Type of the site to return. AREA or BUILDING. Default to AREA. + - SiteType query parameter. Site type AREA or BUILDING (case insensitive). type: str offset: description: - - Offset query parameter. The offset value, starting from 1, of the first returned site entry. Default is 1. - type: int + - Offset query parameter. Offset of the first returned data set entry (Multiple of 'limit' + 1). + type: float limit: description: - - Limit query parameter. The max number of sites in the returned data set. Default is 25, and max at 50. - type: int + - Limit query parameter. Max number of data entries in the returned data set 1,50. Default is 25. + type: float + timestamp: + description: + - Timestamp query parameter. Epoch time(in milliseconds) when the Site Hierarchy data is required. + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sites GetSiteHealth description: Complete reference of the GetSiteHealth API. @@ -62,14 +62,13 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" headers: "{{my_headers | from_json}}" - timestamp: string siteType: string offset: 0 limit: 0 + timestamp: 0 register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -86,41 +85,62 @@ "siteType": "string", "latitude": 0, "longitude": 0, - "healthyNetworkDevicePercentage": {}, - "healthyClientsPercentage": {}, - "clientHealthWired": {}, - "clientHealthWireless": {}, - "numberOfClients": {}, - "numberOfNetworkDevice": {}, - "networkHealthAverage": {}, - "networkHealthAccess": {}, - "networkHealthCore": {}, - "networkHealthDistribution": {}, - "networkHealthRouter": {}, - "networkHealthWireless": {}, - "networkHealthOthers": {}, - "numberOfWiredClients": {}, - "numberOfWirelessClients": {}, - "totalNumberOfConnectedWiredClients": {}, - "totalNumberOfActiveWirelessClients": {}, - "wiredGoodClients": {}, - "wirelessGoodClients": {}, - "overallGoodDevices": {}, - "accessGoodCount": {}, - "accessTotalCount": {}, - "coreGoodCount": {}, - "coreTotalCount": {}, - "distributionGoodCount": {}, - "distributionTotalCount": {}, - "routerGoodCount": {}, - "routerTotalCount": {}, - "wirelessDeviceGoodCount": {}, - "wirelessDeviceTotalCount": {}, - "applicationHealth": {}, - "applicationGoodCount": {}, - "applicationTotalCount": {}, - "applicationBytesTotalCount": {}, - "dnacInfo": {}, + "healthyNetworkDevicePercentage": 0, + "healthyClientsPercentage": 0, + "clientHealthWired": 0, + "clientHealthWireless": 0, + "numberOfClients": 0, + "numberOfNetworkDevice": 0, + "networkHealthAverage": 0, + "networkHealthAccess": 0, + "networkHealthCore": 0, + "networkHealthDistribution": 0, + "networkHealthRouter": 0, + "networkHealthWireless": 0, + "networkHealthAP": 0, + "networkHealthWLC": 0, + "networkHealthSwitch": 0, + "networkHealthOthers": 0, + "numberOfWiredClients": 0, + "numberOfWirelessClients": 0, + "totalNumberOfConnectedWiredClients": 0, + "totalNumberOfActiveWirelessClients": 0, + "wiredGoodClients": 0, + "wirelessGoodClients": 0, + "overallGoodDevices": 0, + "accessGoodCount": 0, + "accessTotalCount": 0, + "coreGoodCount": 0, + "coreTotalCount": 0, + "distributionGoodCount": 0, + "distributionTotalCount": 0, + "routerGoodCount": 0, + "routerTotalCount": 0, + "wirelessDeviceGoodCount": 0, + "wirelessDeviceTotalCount": 0, + "apDeviceGoodCount": 0, + "apDeviceTotalCount": 0, + "wlcDeviceGoodCount": 0, + "wlcDeviceTotalCount": 0, + "switchDeviceGoodCount": 0, + "switchDeviceTotalCount": 0, + "applicationHealth": 0, + "applicationHealthInfo": [ + { + "trafficClass": "string", + "bytesCount": 0, + "healthScore": 0 + } + ], + "applicationGoodCount": 0, + "applicationTotalCount": 0, + "applicationBytesTotalCount": 0, + "dnacInfo": { + "uuid": "string", + "ip": "string", + "status": "string" + }, + "usage": 0, "applicationHealthStats": { "appTotalCount": 0, "businessRelevantAppCount": { diff --git a/plugins/modules/site_info.py b/plugins/modules/site_info.py index be914d2e2c..e728b8b123 100644 --- a/plugins/modules/site_info.py +++ b/plugins/modules/site_info.py @@ -10,7 +10,7 @@ short_description: Information module for Site description: - Get all Site. -- Get site using siteNameHierarchy/siteId/type ,return all sites if these parameters are not given as input. +- Get sites by site-name-hierarchy or siteId or type. List all sites if these parameters are not given as an input. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -21,27 +21,27 @@ type: dict name: description: - - Name query parameter. SiteNameHierarchy (ex global/groupName). + - Name query parameter. Site name hierarchy (E.g Global/USA/CA). type: str siteId: description: - - SiteId query parameter. Site id to which site details to retrieve. + - SiteId query parameter. Site Id. type: str type: description: - - Type query parameter. Type (ex area, building, floor). + - Type query parameter. Site type (Ex area, building, floor). type: str offset: description: - - Offset query parameter. Offset/starting row. The default value is 1. + - Offset query parameter. Offset/starting index for pagination. Indexed from 1. type: int limit: description: - - Limit query parameter. Number of sites to be retrieved. The default value is 500. + - Limit query parameter. Number of sites to be listed. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sites GetSite description: Complete reference of the GetSite API. @@ -74,7 +74,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/site_membership_info.py b/plugins/modules/site_membership_info.py index bc28ba3f3b..70452cfd93 100644 --- a/plugins/modules/site_membership_info.py +++ b/plugins/modules/site_membership_info.py @@ -26,11 +26,11 @@ offset: description: - Offset query parameter. Offset/starting row. - type: int + type: float limit: description: - Limit query parameter. Number of sites to be retrieved. - type: int + type: float deviceFamily: description: - DeviceFamily query parameter. Device family name. @@ -40,8 +40,8 @@ - SerialNumber query parameter. Device serial number. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sites GetMembership description: Complete reference of the GetMembership API. @@ -74,7 +74,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/site_update.py b/plugins/modules/site_update.py index 86c54a60b8..a94359ef60 100644 --- a/plugins/modules/site_update.py +++ b/plugins/modules/site_update.py @@ -26,60 +26,68 @@ description: Site Update's area. suboptions: name: - description: Name. + description: Area name. type: str parentName: - description: Parent Name. + description: Parent hierarchical name (Example Global/USA/CA). type: str type: dict building: description: Site Update's building. suboptions: address: - description: Address. + description: Building address (Example 4900 Marie P. Debartolo Way, Santa + Clara, California 95054, United States). + type: str + country: + description: Country name. This field is mandatory for air-gapped networks + (Example United States). type: str latitude: - description: Latitude. - type: int + description: Building latitude (Example 37.403712). + type: float longitude: - description: Longitude. - type: int + description: Building longitude (Example -121.971063). + type: float name: - description: Name. + description: Building name. type: str parentName: - description: Parent Name. + description: Parent hierarchical name (Example Global/USA/CA/SantaClara). type: str type: dict floor: description: Site Update's floor. suboptions: + floorNumber: + description: Floor Number (Example 3). + type: float height: - description: Height. - type: int + description: Floor height in feet (Example 10). + type: float length: - description: Length. - type: int + description: Floor length in feet (Example 100). + type: float name: - description: Name. + description: Floor name. type: str rfModel: - description: Rf Model. + description: RF model (Example Cubes And Walled Offices). type: str width: - description: Width. - type: int + description: Floor width in feet (Example 200). + type: float type: dict type: dict siteId: description: SiteId path parameter. Site id to which site details to be updated. type: str type: - description: Type. + description: Site type. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Sites UpdateSite description: Complete reference of the UpdateSite API. @@ -110,11 +118,13 @@ parentName: string building: address: string + country: string latitude: 0 longitude: 0 name: string parentName: string floor: + floorNumber: 0 height: 0 length: 0 name: string @@ -124,7 +134,6 @@ type: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/site_v2_info.py b/plugins/modules/site_v2_info.py new file mode 100644 index 0000000000..267234579a --- /dev/null +++ b/plugins/modules/site_v2_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: site_v2_info +short_description: Information module for Site V2 +description: +- Get all Site V2. +- > + API to get sites by site-name-hierarchy or siteId or type. List all sites if these parameters are not given as an + input. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict + groupNameHierarchy: + description: + - GroupNameHierarchy query parameter. Site name hierarchy (E.g. Global/USA/CA). + type: str + id: + description: + - Id query parameter. Site Id. + type: str + type: + description: + - Type query parameter. Site type (Acceptable values area, building, floor). + type: str + offset: + description: + - Offset query parameter. Offset/starting index for pagination. + type: str + limit: + description: + - Limit query parameter. Number of sites to be listed. Default and max supported value is 500. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Sites GetSiteV2 + description: Complete reference of the GetSiteV2 API. + link: https://developer.cisco.com/docs/dna-center/#!get-site-v-2 +notes: + - SDK Method used are + sites.Sites.get_site_v2, + + - Paths used are + get /dna/intent/api/v2/site, + +""" + +EXAMPLES = r""" +- name: Get all Site V2 + cisco.dnac.site_v2_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + groupNameHierarchy: string + id: string + type: string + offset: string + limit: string + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: list + elements: dict + sample: > + [ + { + "parentId": "string", + "groupTypeList": [ + "string" + ], + "groupHierarchy": "string", + "additionalInfo": [ + { + "nameSpace": "string", + "attributes": { + "addressInheritedFrom": "string", + "type": "string", + "country": "string", + "address": "string", + "latitude": "string", + "longitude": "string" + } + } + ], + "groupNameHierarchy": "string", + "name": "string", + "instanceTenantId": "string", + "id": "string" + } + ] +""" diff --git a/plugins/modules/snmp_properties.py b/plugins/modules/snmp_properties.py index 9cbcae16c1..0fce9c0aec 100644 --- a/plugins/modules/snmp_properties.py +++ b/plugins/modules/snmp_properties.py @@ -37,8 +37,8 @@ type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery CreateUpdateSNMPProperties description: Complete reference of the CreateUpdateSNMPProperties API. @@ -71,7 +71,6 @@ systemPropertyName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/snmp_properties_info.py b/plugins/modules/snmp_properties_info.py index 4f32fd28d6..933cbc9299 100644 --- a/plugins/modules/snmp_properties_info.py +++ b/plugins/modules/snmp_properties_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery GetSNMPProperties description: Complete reference of the GetSNMPProperties API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/snmpv2_read_community_credential.py b/plugins/modules/snmpv2_read_community_credential.py index 0fd5ce8cb1..b3067d9e83 100644 --- a/plugins/modules/snmpv2_read_community_credential.py +++ b/plugins/modules/snmpv2_read_community_credential.py @@ -27,14 +27,14 @@ description: Name/Description of the credential. type: str instanceUuid: - description: Snmpv2 Read Community Credential's instanceUuid. + description: Credential UUID. type: str readCommunity: description: SNMP read community. NO!$DATA!$ for no value change. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery CreateSNMPReadCommunity description: Complete reference of the CreateSNMPReadCommunity API. @@ -86,7 +86,6 @@ readCommunity: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/snmpv2_write_community_credential.py b/plugins/modules/snmpv2_write_community_credential.py index 00caf3e5bc..cef5534619 100644 --- a/plugins/modules/snmpv2_write_community_credential.py +++ b/plugins/modules/snmpv2_write_community_credential.py @@ -27,14 +27,14 @@ description: Name/Description of the credential. type: str instanceUuid: - description: Snmpv2 Write Community Credential's instanceUuid. + description: Credential UUID. type: str writeCommunity: description: SNMP write community. NO!$DATA!$ for no value change. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery CreateSNMPWriteCommunity description: Complete reference of the CreateSNMPWriteCommunity API. @@ -86,7 +86,6 @@ writeCommunity: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/snmpv3_credential.py b/plugins/modules/snmpv3_credential.py index 705d9e507d..dd43a29d00 100644 --- a/plugins/modules/snmpv3_credential.py +++ b/plugins/modules/snmpv3_credential.py @@ -18,44 +18,44 @@ author: Rafael Campos (@racampos) options: authPassword: - description: Snmpv3 Credential's authPassword. + description: Auth Password for SNMP. type: str authType: - description: Snmpv3 Credential's authType. + description: SNMP auth protocol. 'SHA' or 'MD5'. type: str comments: - description: Snmpv3 Credential's comments. + description: Comments to identify the SNMPv3 credential. type: str credentialType: - description: Snmpv3 Credential's credentialType. + description: Credential type to identify the application that uses the SNMPv3 credential. type: str description: - description: Snmpv3 Credential's description. + description: Description for Snmp V3 Credential. type: str id: - description: Snmpv3 Credential's id. + description: Id of the SNMP V3 Credential in UUID format. type: str instanceTenantId: - description: Snmpv3 Credential's instanceTenantId. + description: Deprecated. type: str instanceUuid: - description: Snmpv3 Credential's instanceUuid. + description: Deprecated. type: str privacyPassword: - description: Snmpv3 Credential's privacyPassword. + description: Privacy Password for SNMP privacy. type: str privacyType: - description: Snmpv3 Credential's privacyType. + description: SNMP privacy protocol. type: str snmpMode: - description: Snmpv3 Credential's snmpMode. + description: Mode of SNMP. 'AUTHPRIV' or 'AUTHNOPRIV' or 'NOAUTHNOPRIV'. type: str username: - description: Snmpv3 Credential's username. + description: SNMP V3 Username. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Discovery CreateSNMPv3Credentials description: Complete reference of the CreateSNMPv3Credentials API. @@ -122,7 +122,6 @@ username: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/sp_profile_delete_v2.py b/plugins/modules/sp_profile_delete_v2.py index 236a0ba49a..df31ed1f94 100644 --- a/plugins/modules/sp_profile_delete_v2.py +++ b/plugins/modules/sp_profile_delete_v2.py @@ -11,17 +11,17 @@ description: - Manage operation delete of the resource Sp Profile Delete V2. - API to delete Service Provider Profile QoS . -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) options: spProfileName: - description: SpProfileName path parameter. Sp profile name. + description: SpProfileName path parameter. SP profile name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Network Settings DeleteSPProfileV2 description: Complete reference of the DeleteSPProfileV2 API. @@ -48,7 +48,6 @@ spProfileName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/swim_image_details_info.py b/plugins/modules/swim_image_details_info.py index d41519382c..1138286705 100644 --- a/plugins/modules/swim_image_details_info.py +++ b/plugins/modules/swim_image_details_info.py @@ -92,8 +92,8 @@ - Offset query parameter. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Software Image Management (SWIM) GetSoftwareImageDetails description: Complete reference of the GetSoftwareImageDetails API. @@ -139,7 +139,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/swim_import_local.py b/plugins/modules/swim_import_local.py index 27966b4cdd..a8c0ba28aa 100644 --- a/plugins/modules/swim_import_local.py +++ b/plugins/modules/swim_import_local.py @@ -35,8 +35,8 @@ description: ThirdPartyVendor query parameter. Third Party Vendor. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Software Image Management (SWIM) ImportLocalSoftwareImage description: Complete reference of the ImportLocalSoftwareImage API. @@ -67,7 +67,6 @@ thirdPartyVendor: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/swim_import_via_url.py b/plugins/modules/swim_import_via_url.py index df217a30c1..fdeb49ddaf 100644 --- a/plugins/modules/swim_import_via_url.py +++ b/plugins/modules/swim_import_via_url.py @@ -49,8 +49,8 @@ description: ScheduleOrigin query parameter. Originator of this call (Optional). type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Software Image Management (SWIM) ImportSoftwareImageViaURL description: Complete reference of the ImportSoftwareImageViaURL API. @@ -85,7 +85,6 @@ scheduleOrigin: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/swim_trigger_activation.py b/plugins/modules/swim_trigger_activation.py index 5d7cae2b54..41694e5d45 100644 --- a/plugins/modules/swim_trigger_activation.py +++ b/plugins/modules/swim_trigger_activation.py @@ -49,8 +49,8 @@ before schedule (Optional). type: bool requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Software Image Management (SWIM) TriggerSoftwareImageActivation description: Complete reference of the TriggerSoftwareImageActivation API. @@ -87,7 +87,6 @@ scheduleValidate: true """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/swim_trigger_distribution.py b/plugins/modules/swim_trigger_distribution.py index ce1b5e1fc7..72ebad1622 100644 --- a/plugins/modules/swim_trigger_distribution.py +++ b/plugins/modules/swim_trigger_distribution.py @@ -30,8 +30,8 @@ type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Software Image Management (SWIM) TriggerSoftwareImageDistribution description: Complete reference of the TriggerSoftwareImageDistribution API. @@ -60,7 +60,6 @@ imageUuid: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/system_health_count_info.py b/plugins/modules/system_health_count_info.py index bf9b723611..75eb45fdaa 100644 --- a/plugins/modules/system_health_count_info.py +++ b/plugins/modules/system_health_count_info.py @@ -32,8 +32,8 @@ here /dna/platform/app/consumer-portal/developer-toolkit/events. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Health and Performance SystemHealthCountAPI description: Complete reference of the SystemHealthCountAPI API. @@ -63,7 +63,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/system_health_info.py b/plugins/modules/system_health_info.py index 01a23ee641..eeab1aa40c 100644 --- a/plugins/modules/system_health_info.py +++ b/plugins/modules/system_health_info.py @@ -38,14 +38,14 @@ limit: description: - Limit query parameter. - type: int + type: float offset: description: - Offset query parameter. - type: int + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Health and Performance SystemHealthAPI description: Complete reference of the SystemHealthAPI API. @@ -78,7 +78,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/system_performance_historical_info.py b/plugins/modules/system_performance_historical_info.py index 11476ed6f0..68c365ef88 100644 --- a/plugins/modules/system_performance_historical_info.py +++ b/plugins/modules/system_performance_historical_info.py @@ -10,7 +10,10 @@ short_description: Information module for System Performance Historical description: - Get all System Performance Historical. -- This API retrieves the historical performance indicators. The data can be retrieved for the last 3 months. +- > + Retrieves the average values of cluster key performance indicators KPIs , like CPU utilization, memory utilization + or network rates grouped by time intervals within a specified time range. The data will be available from the past + 24 hours. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -28,16 +31,16 @@ - > StartTime query parameter. This is the epoch start time in milliseconds from which performance indicator need to be fetched. - type: int + type: float endTime: description: - > EndTime query parameter. This is the epoch end time in milliseconds upto which performance indicator need to be fetched. - type: int + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Health and Performance SystemPerformanceHistoricalAPI description: Complete reference of the SystemPerformanceHistoricalAPI API. @@ -68,7 +71,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -97,7 +99,9 @@ "t1": [ "string" ] - } + }, + "cpuAvg": "string", + "memoryAvg": "string" } } """ diff --git a/plugins/modules/system_performance_info.py b/plugins/modules/system_performance_info.py index 41b14ccdde..0be1b89d80 100644 --- a/plugins/modules/system_performance_info.py +++ b/plugins/modules/system_performance_info.py @@ -10,7 +10,10 @@ short_description: Information module for System Performance description: - Get all System Performance. -- This API gives the aggregated performance indicators. The data can be retrieved for the last 3 months. +- > + Retrieves the aggregated metrics total, average or maximum of cluster key performance indicators KPIs , such as + CPU utilization, memory utilization or network rates recorded within a specified time period. The data will be + available from the past 24 hours. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -32,16 +35,16 @@ - > StartTime query parameter. This is the epoch start time in milliseconds from which performance indicator need to be fetched. - type: int + type: float endTime: description: - > EndTime query parameter. This is the epoch end time in milliseconds upto which performance indicator need to be fetched. - type: int + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Health and Performance SystemPerformanceAPI description: Complete reference of the SystemPerformanceAPI API. @@ -73,7 +76,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/tag.py b/plugins/modules/tag.py index 0b26448c03..71589a303a 100644 --- a/plugins/modules/tag.py +++ b/plugins/modules/tag.py @@ -19,52 +19,59 @@ author: Rafael Campos (@racampos) options: description: - description: Tag's description. + description: Description of the tag. type: str dynamicRules: description: Tag's dynamicRules. elements: dict suboptions: memberType: - description: Tag's memberType. + description: MemberType of the tag (e.g. Networkdevice, interface). type: str rules: description: Tag's rules. suboptions: items: - description: Tag's items. - elements: str + description: Items details,multiple rules can be defined by items(e.g. "items" + {"operation" "ILIKE", "name" "managementIpAddress", "value" "%10%"}, {"operation" + "ILIKE", "name" "hostname", "value" "%NA%"} ). + elements: dict type: list name: - description: Tag's name. + description: Name of the parameter (e.g. For interface portName,adminStatus,speed,status,description. + For networkdevice family,series,hostname,managementIpAddress,groupNameHierarchy,softwareVersion). type: str operation: - description: Tag's operation. + description: Opeartion used in the rules (e.g. OR,IN,EQ,LIKE,ILIKE,AND). type: str value: - description: Tag's value. + description: Value of the parameter (e.g. For portName 1/0/1,for adminStatus,status + up/down, for speed any integer value, for description any valid string, + for family switches, for series C3650, for managementIpAddress 10.197.124.90, + groupNameHierarchy Global, softwareVersion 16.9.1). type: str values: - description: Tag's values. + description: Values of the parameter,Only one of the value or values can + be used for the given parameter. (for managementIpAddress e.g. "10.197.124.90","10.197.124.91"). elements: str type: list type: dict type: list id: - description: Tag's id. + description: Mandatory instanceUuid of the tag that needs to be updated. type: str instanceTenantId: - description: Tag's instanceTenantId. + description: InstanceTenantId generated for the tag. type: str name: - description: Tag's name. + description: Name of the tag. type: str systemTag: - description: SystemTag flag. + description: True for system created tags, false for user defined tags. type: bool requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Tag CreateTag description: Complete reference of the CreateTag API. @@ -104,7 +111,7 @@ - memberType: string rules: items: - - string + - {} name: string operation: string value: string @@ -129,7 +136,8 @@ dynamicRules: - memberType: string rules: - items: string + items: + - {} name: string operation: string value: string @@ -153,7 +161,6 @@ id: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/tag_count_info.py b/plugins/modules/tag_count_info.py index 7562f71fc6..9d5bfee5ba 100644 --- a/plugins/modules/tag_count_info.py +++ b/plugins/modules/tag_count_info.py @@ -31,10 +31,6 @@ description: - AttributeName query parameter. type: str - level: - description: - - Level query parameter. - type: str size: description: - Size query parameter. Size in kilobytes(KB). @@ -44,8 +40,8 @@ - SystemTag query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Tag GetTagCount description: Complete reference of the GetTagCount API. @@ -73,13 +69,11 @@ name: string nameSpace: string attributeName: string - level: string size: string systemTag: string register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/tag_info.py b/plugins/modules/tag_info.py index c7c32e7d56..bbc0372142 100644 --- a/plugins/modules/tag_info.py +++ b/plugins/modules/tag_info.py @@ -40,11 +40,11 @@ offset: description: - Offset query parameter. - type: int + type: float limit: description: - Limit query parameter. - type: int + type: float size: description: - Size query parameter. Size in kilobytes(KB). @@ -72,8 +72,8 @@ - Id path parameter. Tag ID. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Tag GetTag description: Complete reference of the GetTag API. @@ -130,7 +130,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -149,7 +148,9 @@ "values": [ "string" ], - "items": "string", + "items": [ + {} + ], "operation": "string", "name": "string", "value": "string" diff --git a/plugins/modules/tag_member.py b/plugins/modules/tag_member.py index 2ffe6ce106..b102c1d96e 100644 --- a/plugins/modules/tag_member.py +++ b/plugins/modules/tag_member.py @@ -23,15 +23,16 @@ memberId: description: MemberId path parameter. TagMember id to be removed from tag. type: str - object: - description: Object. - type: str + memberType: + description: Tag Member's memberType. + elements: str + type: list payload: description: Map of member type and member ids. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Tag AddMembersToTheTag description: Complete reference of the AddMembersToTheTag API. @@ -62,7 +63,8 @@ dnac_debug: "{{dnac_debug}}" state: present id: string - object: string + memberType: + - string payload: networkinterface: - string @@ -79,10 +81,8 @@ state: absent id: string memberId: string - memberType: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/tag_member_count_info.py b/plugins/modules/tag_member_count_info.py index 82dbf33d0c..192c359ff5 100644 --- a/plugins/modules/tag_member_count_info.py +++ b/plugins/modules/tag_member_count_info.py @@ -31,13 +31,9 @@ description: - MemberAssociationType query parameter. type: str - level: - description: - - Level query parameter. - type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Tag GetTagMemberCount description: Complete reference of the GetTagMemberCount API. @@ -64,12 +60,10 @@ headers: "{{my_headers | from_json}}" memberType: string memberAssociationType: string - level: string id: string register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/tag_member_info.py b/plugins/modules/tag_member_info.py index 57401f1529..d700a5c774 100644 --- a/plugins/modules/tag_member_info.py +++ b/plugins/modules/tag_member_info.py @@ -32,11 +32,11 @@ offset: description: - Offset query parameter. Used for pagination. It indicates the starting row number out of available member records. - type: str + type: float limit: description: - Limit query parameter. Used to Number of maximum members to return in the result. - type: str + type: float memberAssociationType: description: - > @@ -50,8 +50,8 @@ - Level query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Tag GetTagMembersById description: Complete reference of the GetTagMembersById API. @@ -77,15 +77,14 @@ dnac_debug: "{{dnac_debug}}" headers: "{{my_headers | from_json}}" memberType: string - offset: string - limit: string + offset: 0 + limit: 0 memberAssociationType: string level: string id: string register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/tag_member_type_info.py b/plugins/modules/tag_member_type_info.py index a7e4cd1c93..c8a0f10652 100644 --- a/plugins/modules/tag_member_type_info.py +++ b/plugins/modules/tag_member_type_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Tag GetTagResourceTypes description: Complete reference of the GetTagResourceTypes API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/tag_membership.py b/plugins/modules/tag_membership.py index 9366e9ed2e..5c6e729c42 100644 --- a/plugins/modules/tag_membership.py +++ b/plugins/modules/tag_membership.py @@ -11,7 +11,7 @@ description: - Manage operation update of the resource Tag Membership. - > - Updates tag membership. As part of the request payload through this API, only the specified members are added / + Update tag membership. As part of the request payload through this API, only the specified members are added / retained to the given input tags. Possible values of memberType attribute in the request payload can be queried by using the /tag/member/type API. version_added: '3.1.0' @@ -21,26 +21,25 @@ options: memberToTags: description: Tag Membership's memberToTags. - elements: dict suboptions: key: description: Tag Membership's key. elements: str type: list - type: list + type: dict memberType: description: Tag Membership's memberType. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Tag UpdatesTagMembership - description: Complete reference of the UpdatesTagMembership API. - link: https://developer.cisco.com/docs/dna-center/#!updates-tag-membership +- name: Cisco DNA Center documentation for Tag UpdateTagMembership + description: Complete reference of the UpdateTagMembership API. + link: https://developer.cisco.com/docs/dna-center/#!update-tag-membership notes: - SDK Method used are - tag.Tag.updates_tag_membership, + tag.Tag.update_tag_membership, - Paths used are put /dna/intent/api/v1/tag/member, @@ -58,12 +57,11 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" memberToTags: - - key: + key: - string memberType: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/task_count_info.py b/plugins/modules/task_count_info.py index a1eedd4459..ca2aa0eb08 100644 --- a/plugins/modules/task_count_info.py +++ b/plugins/modules/task_count_info.py @@ -60,8 +60,8 @@ - ParentId query parameter. Fetch tasks that have this parent Id. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Task GetTaskCount description: Complete reference of the GetTaskCount API. @@ -99,7 +99,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/task_info.py b/plugins/modules/task_info.py index 9adaf195a4..3b76977687 100644 --- a/plugins/modules/task_info.py +++ b/plugins/modules/task_info.py @@ -82,8 +82,8 @@ - TaskId path parameter. UUID of the Task. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Task GetTaskById description: Complete reference of the GetTaskById API. @@ -143,7 +143,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/task_operation_info.py b/plugins/modules/task_operation_info.py index ea08f3306b..30c80cbc48 100644 --- a/plugins/modules/task_operation_info.py +++ b/plugins/modules/task_operation_info.py @@ -34,8 +34,8 @@ value is 1. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Task GetTaskByOperationId description: Complete reference of the GetTaskByOperationId API. @@ -66,7 +66,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -78,20 +77,20 @@ { "additionalStatusURL": "string", "data": "string", - "endTime": "string", + "endTime": 0, "errorCode": "string", "errorKey": "string", "failureReason": "string", "id": "string", "instanceTenantId": "string", "isError": true, - "lastUpdate": "string", + "lastUpdate": 0, "operationIdList": {}, "parentId": "string", "progress": "string", "rootId": "string", "serviceType": "string", - "startTime": "string", + "startTime": 0, "username": "string", "version": 0 } diff --git a/plugins/modules/task_tree_info.py b/plugins/modules/task_tree_info.py index 9e80665b34..334aa5b1eb 100644 --- a/plugins/modules/task_tree_info.py +++ b/plugins/modules/task_tree_info.py @@ -24,8 +24,8 @@ - TaskId path parameter. UUID of the Task. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Task GetTaskTree description: Complete reference of the GetTaskTree API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -66,20 +65,20 @@ { "additionalStatusURL": "string", "data": "string", - "endTime": "string", + "endTime": 0, "errorCode": "string", "errorKey": "string", "failureReason": "string", "id": "string", "instanceTenantId": "string", "isError": true, - "lastUpdate": "string", + "lastUpdate": 0, "operationIdList": {}, "parentId": "string", "progress": "string", "rootId": "string", "serviceType": "string", - "startTime": "string", + "startTime": 0, "username": "string", "version": 0 } diff --git a/plugins/modules/template_preview.py b/plugins/modules/template_preview.py index cb1657cccd..679f355842 100644 --- a/plugins/modules/template_preview.py +++ b/plugins/modules/template_preview.py @@ -29,8 +29,8 @@ description: UUID of template to get template preview. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates PreviewTemplate description: Complete reference of the PreviewTemplate API. @@ -60,7 +60,6 @@ templateId: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/templates_details_info.py b/plugins/modules/templates_details_info.py index f2f45271cb..9178b21e9d 100644 --- a/plugins/modules/templates_details_info.py +++ b/plugins/modules/templates_details_info.py @@ -61,7 +61,7 @@ type: bool tags: description: - - Tags query parameter. Filter template(s) based on tags. + - Tags query parameter. Filter template(s) based on tags. elements: str type: list unCommitted: @@ -89,8 +89,8 @@ - Limit query parameter. Limits number of results. type: int requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Configuration Templates GetTemplatesDetails description: Complete reference of the GetTemplatesDetails API. @@ -135,7 +135,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/topology_layer_2_info.py b/plugins/modules/topology_layer_2_info.py index 2ba3667e27..227062be57 100644 --- a/plugins/modules/topology_layer_2_info.py +++ b/plugins/modules/topology_layer_2_info.py @@ -24,8 +24,8 @@ - VlanID path parameter. Vlan Name for e.g Vlan1, Vlan23 etc. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Topology GetTopologyDetails description: Complete reference of the GetTopologyDetails API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/topology_layer_3_info.py b/plugins/modules/topology_layer_3_info.py index 008b5d1ac7..f7134cd678 100644 --- a/plugins/modules/topology_layer_3_info.py +++ b/plugins/modules/topology_layer_3_info.py @@ -24,8 +24,8 @@ - TopologyType path parameter. Type of topology(OSPF,ISIS,etc). type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Topology GetL3TopologyDetails description: Complete reference of the GetL3TopologyDetails API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/topology_network_health_info.py b/plugins/modules/topology_network_health_info.py index b9c856316e..7faecb1e84 100644 --- a/plugins/modules/topology_network_health_info.py +++ b/plugins/modules/topology_network_health_info.py @@ -23,11 +23,11 @@ type: dict timestamp: description: - - Timestamp query parameter. Epoch time(in milliseconds) when the Network health data is required. - type: str + - Timestamp query parameter. UTC timestamp of network health data in milliseconds. + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Topology GetOverallNetworkHealth description: Complete reference of the GetOverallNetworkHealth API. @@ -52,11 +52,10 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" headers: "{{my_headers | from_json}}" - timestamp: string + timestamp: 0 register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -71,20 +70,27 @@ "healthScore": 0, "totalCount": 0, "goodCount": 0, + "noHealthCount": 0, "unmonCount": 0, "fairCount": 0, "badCount": 0, - "entity": {}, + "maintenanceModeCount": 0, + "entity": "string", "timeinMillis": 0 } ], "measuredBy": "string", - "latestMeasuredByEntity": {}, + "latestMeasuredByEntity": "string", "latestHealthScore": 0, "monitoredDevices": 0, "monitoredHealthyDevices": 0, "monitoredUnHealthyDevices": 0, "unMonitoredDevices": 0, + "noHealthDevices": 0, + "totalDevices": 0, + "monitoredPoorHealthDevices": 0, + "monitoredFairHealthDevices": 0, + "healthContributingDevices": 0, "healthDistirubution": [ { "category": "string", @@ -93,13 +99,19 @@ "goodPercentage": 0, "badPercentage": 0, "fairPercentage": 0, + "noHealthPercentage": 0, "unmonPercentage": 0, "goodCount": 0, "badCount": 0, "fairCount": 0, + "noHealthCount": 0, "unmonCount": 0, + "thirdPartyDeviceCount": 0, "kpiMetrics": [ - {} + { + "key": "string", + "value": "string" + } ] } ] diff --git a/plugins/modules/topology_physical_info.py b/plugins/modules/topology_physical_info.py index 6a9573d577..4db9461e85 100644 --- a/plugins/modules/topology_physical_info.py +++ b/plugins/modules/topology_physical_info.py @@ -24,8 +24,8 @@ - NodeType query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Topology GetPhysicalTopology description: Complete reference of the GetPhysicalTopology API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/topology_site_info.py b/plugins/modules/topology_site_info.py index d63661b43b..d2b797a773 100644 --- a/plugins/modules/topology_site_info.py +++ b/plugins/modules/topology_site_info.py @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Topology GetSiteTopology description: Complete reference of the GetSiteTopology API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/topology_vlan_details_info.py b/plugins/modules/topology_vlan_details_info.py index 555b5b9d8c..0b14eeda28 100644 --- a/plugins/modules/topology_vlan_details_info.py +++ b/plugins/modules/topology_vlan_details_info.py @@ -10,7 +10,7 @@ short_description: Information module for Topology Vlan Details description: - Get all Topology Vlan Details. -- Returns the list of VLAN names. +- Returns the list of VLAN names that are involved in a loop as identified by the Spanning Tree Protocol. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info @@ -20,8 +20,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Topology GetVLANDetails description: Complete reference of the GetVLANDetails API. @@ -49,7 +49,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/transit_peer_network.py b/plugins/modules/transit_peer_network.py index 38125e4d35..42e9f7598d 100644 --- a/plugins/modules/transit_peer_network.py +++ b/plugins/modules/transit_peer_network.py @@ -12,7 +12,7 @@ - Manage operations create and delete of the resource Transit Peer Network. - Add Transit Peer Network in SD-Access. - Delete Transit Peer Network from SD-Access. -version_added: '6.5.0' +version_added: '6.0.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -21,7 +21,7 @@ description: Transit Peer Network's ipTransitSettings. suboptions: autonomousSystemNumber: - description: Autonomous System Number (e.g.,1-65535). + description: Autonomous System Number. type: str routingProtocolName: description: Routing Protocol Name. @@ -49,19 +49,19 @@ description: Transit Peer Network Type. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for AddTransitPeerNetwork +- name: Cisco DNA Center documentation for SDA AddTransitPeerNetwork description: Complete reference of the AddTransitPeerNetwork API. link: https://developer.cisco.com/docs/dna-center/#!add-transit-peer-network -- name: Cisco DNA Center documentation for DeleteTransitPeerNetwork +- name: Cisco DNA Center documentation for SDA DeleteTransitPeerNetwork description: Complete reference of the DeleteTransitPeerNetwork API. link: https://developer.cisco.com/docs/dna-center/#!delete-transit-peer-network notes: - SDK Method used are - ..add_transit_peer_network, - ..delete_transit_peer_network, + sda.Sda.add_transit_peer_network, + sda.Sda.delete_transit_peer_network, - Paths used are post /dna/intent/api/v1/business/sda/transit-peer-network, @@ -103,7 +103,6 @@ transitPeerNetworkType: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/transit_peer_network_info.py b/plugins/modules/transit_peer_network_info.py index 75ca07d7a7..e98d2288fe 100644 --- a/plugins/modules/transit_peer_network_info.py +++ b/plugins/modules/transit_peer_network_info.py @@ -11,7 +11,7 @@ description: - Get all Transit Peer Network. - Get Transit Peer Network Info from SD-Access. -version_added: '6.5.0' +version_added: '6.0.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -24,15 +24,15 @@ - TransitPeerNetworkName query parameter. Transit or Peer Network Name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for GetTransitPeerNetworkInfo +- name: Cisco DNA Center documentation for SDA GetTransitPeerNetworkInfo description: Complete reference of the GetTransitPeerNetworkInfo API. link: https://developer.cisco.com/docs/dna-center/#!get-transit-peer-network-info notes: - SDK Method used are - ..get_transit_peer_network_info, + sda.Sda.get_transit_peer_network_info, - Paths used are get /dna/intent/api/v1/business/sda/transit-peer-network, @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/user.py b/plugins/modules/user.py index 4567de33dd..32809c4f9e 100644 --- a/plugins/modules/user.py +++ b/plugins/modules/user.py @@ -9,10 +9,11 @@ module: user short_description: Resource module for User description: -- Manage operations create and update of the resource User. -- Add a new user for Cisco DNA Center system. -- Update a user for Cisco DNA Center system. -version_added: '6.7.0' +- Manage operations create, update and delete of the resource User. +- Add a new user for Cisco DNA Center System. +- Delete a user from Cisco DNA Center System. +- Update a user for Cisco DNA Center System. +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -40,22 +41,27 @@ description: Username. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for User and Roles AddUserAPI description: Complete reference of the AddUserAPI API. link: https://developer.cisco.com/docs/dna-center/#!add-user-api +- name: Cisco DNA Center documentation for User and Roles DeleteUserAPI + description: Complete reference of the DeleteUserAPI API. + link: https://developer.cisco.com/docs/dna-center/#!delete-user-api - name: Cisco DNA Center documentation for User and Roles UpdateUserAPI description: Complete reference of the UpdateUserAPI API. link: https://developer.cisco.com/docs/dna-center/#!update-user-api notes: - SDK Method used are - user_and_roles.UserandRoles.add_user_ap_i, - user_and_roles.UserandRoles.update_user_ap_i, + userand_roles.UserandRoles.add_user_api, + userand_roles.UserandRoles.delete_user_api, + userand_roles.UserandRoles.update_user_api, - Paths used are post /dna/system/api/v1/user, + delete /dna/system/api/v1/user/{userId}, put /dna/system/api/v1/user, """ @@ -97,8 +103,19 @@ userId: string username: string -""" +- name: Delete by id + cisco.dnac.user: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + userId: string +""" RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/user_enrichment_details_info.py b/plugins/modules/user_enrichment_details_info.py index bcffca7466..84271957b1 100644 --- a/plugins/modules/user_enrichment_details_info.py +++ b/plugins/modules/user_enrichment_details_info.py @@ -22,8 +22,8 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Users GetUserEnrichmentDetails description: Complete reference of the GetUserEnrichmentDetails API. @@ -51,7 +51,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/user_info.py b/plugins/modules/user_info.py index d4c20af69a..94b3205d88 100644 --- a/plugins/modules/user_info.py +++ b/plugins/modules/user_info.py @@ -10,8 +10,8 @@ short_description: Information module for User description: - Get all User. -- Get all users for the Cisco DNA Center system. -version_added: '6.7.0' +- Get all users for the Cisco DNA Center System. +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -21,18 +21,26 @@ type: dict invokeSource: description: - - InvokeSource query parameter. The source that invokes this API. + - > + InvokeSource query parameter. The source that invokes this API. The value of this query parameter must be + set to "external". + type: str + authSource: + description: + - > + AuthSource query parameter. The source that authenticates the user. The value of this query parameter can be + set to "internal" or "external". If not provided, then all users will be returned in the response. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for User and Roles GetUsersAPI description: Complete reference of the GetUsersAPI API. link: https://developer.cisco.com/docs/dna-center/#!get-users-api notes: - SDK Method used are - user_and_roles.UserandRoles.get_users_api, + userand_roles.UserandRoles.get_users_api, - Paths used are get /dna/system/api/v1/user, @@ -51,10 +59,10 @@ dnac_debug: "{{dnac_debug}}" headers: "{{my_headers | from_json}}" invokeSource: string + authSource: string register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/users_external_authentication.py b/plugins/modules/users_external_authentication.py new file mode 100644 index 0000000000..f7cc5f3cf7 --- /dev/null +++ b/plugins/modules/users_external_authentication.py @@ -0,0 +1,61 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: users_external_authentication +short_description: Resource module for Users External Authentication +description: +- Manage operation create of the resource Users External Authentication. +- Enable or disable external authentication on Cisco DNA Center System. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + enable: + description: Enable/disable External Authentication. + type: bool +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for User and Roles ManageExternalAuthenticationSettingAPI + description: Complete reference of the ManageExternalAuthenticationSettingAPI API. + link: https://developer.cisco.com/docs/dna-center/#!manage-external-authentication-setting-api +notes: + - SDK Method used are + userand_roles.UserandRoles.manage_external_authentication_setting_api, + + - Paths used are + post /dna/system/api/v1/users/external-authentication, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.users_external_authentication: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + enable: true + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "message": "string" + } +""" diff --git a/plugins/modules/users_external_authentication_info.py b/plugins/modules/users_external_authentication_info.py new file mode 100644 index 0000000000..b4b93bb26b --- /dev/null +++ b/plugins/modules/users_external_authentication_info.py @@ -0,0 +1,65 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: users_external_authentication_info +short_description: Information module for Users External Authentication +description: +- Get all Users External Authentication. +- Get the External Authentication setting. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for User and Roles GetExternalAuthenticationSettingAPI + description: Complete reference of the GetExternalAuthenticationSettingAPI API. + link: https://developer.cisco.com/docs/dna-center/#!get-external-authentication-setting-api +notes: + - SDK Method used are + userand_roles.UserandRoles.get_external_authentication_setting_api, + + - Paths used are + get /dna/system/api/v1/users/external-authentication, + +""" + +EXAMPLES = r""" +- name: Get all Users External Authentication + cisco.dnac.users_external_authentication_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "external-authentication-flag": [ + { + "enabled": true + } + ] + } +""" diff --git a/plugins/modules/users_external_servers_aaa_attribute.py b/plugins/modules/users_external_servers_aaa_attribute.py new file mode 100644 index 0000000000..3dba589605 --- /dev/null +++ b/plugins/modules/users_external_servers_aaa_attribute.py @@ -0,0 +1,84 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: users_external_servers_aaa_attribute +short_description: Resource module for Users External Servers Aaa Attribute +description: +- Manage operations create and delete of the resource Users External Servers Aaa Attribute. +- > + Add or update the custom AAA attribute for external authentication. Note that if you decide not to set the custom + AAA attribute, a default AAA attribute will be used for authentication based on the protocol supported by your + server. For TACACS servers it will be "cisco-av-pair" and for RADIUS servers it will be "Cisco-AVPair". +- > + Delete the custom AAA attribute that was added. Note that by deleting the AAA attribute, a default AAA attribute + will be used for authentication based on the protocol supported by your server. For TACACS servers it will be + "cisco-av-pair" and for RADIUS servers it will be "Cisco-AVPair". +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + attributeName: + description: Name of the custom AAA attribute. + type: str +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for User and Roles AddAndUpdateAAAAttributeAPI + description: Complete reference of the AddAndUpdateAAAAttributeAPI API. + link: https://developer.cisco.com/docs/dna-center/#!add-and-update-aaa-attribute-api +- name: Cisco DNA Center documentation for User and Roles DeleteAAAAttributeAPI + description: Complete reference of the DeleteAAAAttributeAPI API. + link: https://developer.cisco.com/docs/dna-center/#!delete-aaa-attribute-api +notes: + - SDK Method used are + userand_roles.UserandRoles.add_and_update_a_a_a_attribute_api, + userand_roles.UserandRoles.delete_a_a_a_attribute_api, + + - Paths used are + post /dna/system/api/v1/users/external-servers/aaa-attribute, + delete /dna/system/api/v1/users/external-servers/aaa-attribute, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.users_external_servers_aaa_attribute: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: present + attributeName: string + +- name: Delete all + cisco.dnac.users_external_servers_aaa_attribute: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + state: absent + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "message": "string" + } +""" diff --git a/plugins/modules/users_external_servers_aaa_attribute_info.py b/plugins/modules/users_external_servers_aaa_attribute_info.py new file mode 100644 index 0000000000..e47e055c91 --- /dev/null +++ b/plugins/modules/users_external_servers_aaa_attribute_info.py @@ -0,0 +1,65 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: users_external_servers_aaa_attribute_info +short_description: Information module for Users External Servers Aaa Attribute +description: +- Get all Users External Servers Aaa Attribute. +- Get the current value of the custom AAA attribute. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module_info +author: Rafael Campos (@racampos) +options: + headers: + description: Additional headers. + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for User and Roles GetAAAAttributeAPI + description: Complete reference of the GetAAAAttributeAPI API. + link: https://developer.cisco.com/docs/dna-center/#!get-aaa-attribute-api +notes: + - SDK Method used are + userand_roles.UserandRoles.get_a_a_a_attribute_api, + + - Paths used are + get /dna/system/api/v1/users/external-servers/aaa-attribute, + +""" + +EXAMPLES = r""" +- name: Get all Users External Servers Aaa Attribute + cisco.dnac.users_external_servers_aaa_attribute_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + register: result + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "aaa-attributes": [ + { + "attributeName": "string" + } + ] + } +""" diff --git a/plugins/modules/users_external_servers_info.py b/plugins/modules/users_external_servers_info.py index 0373d2c859..4af30bcfdc 100644 --- a/plugins/modules/users_external_servers_info.py +++ b/plugins/modules/users_external_servers_info.py @@ -11,7 +11,7 @@ description: - Get all Users External Servers. - Get external users authentication servers. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -21,18 +21,20 @@ type: dict invokeSource: description: - - InvokeSource query parameter. The source that invokes this API. + - > + InvokeSource query parameter. The source that invokes this API. The value of this query parameter must be + set to "external". type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for User and Roles GetExternalAuthenticationServersAPI description: Complete reference of the GetExternalAuthenticationServersAPI API. link: https://developer.cisco.com/docs/dna-center/#!get-external-authentication-servers-api notes: - SDK Method used are - user_and_roles.UserandRoles.get_external_authentication_servers_ap_i, + userand_roles.UserandRoles.get_external_authentication_servers_api, - Paths used are get /dna/system/api/v1/users/external-servers, @@ -54,7 +56,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/wireless_accespoint_configuration.py b/plugins/modules/wireless_accespoint_configuration.py index 6a1cf29463..f3341b010c 100644 --- a/plugins/modules/wireless_accespoint_configuration.py +++ b/plugins/modules/wireless_accespoint_configuration.py @@ -10,8 +10,10 @@ short_description: Resource module for Wireless Accespoint Configuration description: - Manage operation create of the resource Wireless Accespoint Configuration. -- User can configure multiple access points with required options using this intent API. -version_added: '6.7.0' +- > + User can configure multiple access points with required options using this intent API. This API does not support + configuration of CleanAir or SI for IOS-XE devices with version greater than or equal to 17.9. +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module author: Rafael Campos (@racampos) @@ -20,10 +22,6 @@ description: Configure the access point's admin status. Set this parameter's value to "true" to enable it and "false" to disable it. type: bool - apHeight: - description: Configure the height of the access point by setting a value between - 3 and height of the floor. - type: int apList: description: Wireless Accespoint Configuration's apList. elements: dict @@ -47,10 +45,6 @@ description: To change the access point's admin status, set this parameter's value to "true". type: bool - configureApHeight: - description: To change the access point's height, set this parameter's value to - "true". - type: bool configureApMode: description: To change the access point's mode, set this parameter's value to "true". type: bool @@ -78,6 +72,10 @@ description: Configure the acess point's failover priority for low, set "1"; for medium, set "2"; for high, set "3"; and for critical, set "4". type: int + isAssignedSiteAsLocation: + description: If AP is assigned to a site, then to assign AP location as the site + name, set this parameter's value to "true". + type: bool ledBrightnessLevel: description: Configure the access point's LED brightness level by setting a value between 1 and 8. @@ -113,31 +111,19 @@ access point. If cable loss needs to be configured, set this parameter's value to "other". type: str - antennaDegree: - description: Configure the antenna degree on the specified radio for an access - point. - type: int - antennaElevAngleDegree: - description: Configure the antenna elevation angle on the specified radio for - an access point. - type: int - antennaElevAngleSign: - description: Configure the antenna elevation angle direction on the specified - radio for an access point for up, set "1"; for down, set "-1". - type: int antennaGain: description: Configure the antenna gain on the specified radio for an access - point by setting a decimal value (in dBi). + point by setting a decimal value (in dBi). To configure "antennaGain", set + "antennaPatternName" value to "other". type: int antennaPatternName: - description: Configure the antenna pattern name on the specified radio for an - access point. If antenna gain needs to be configured, set this parameter's - value to "other". + description: Specify the antenna name on the specified radio for an access point. + The antenna name is used to calculate the gain on the radio slot. type: str cableLoss: description: Configure the cable loss on the specified radio for an access point by setting a decimal value (in dBi). - type: int + type: float channelAssignmentMode: description: Configure the channel assignment mode on the specified radio for an access point for global mode, set "1"; and for custom mode, set "2". @@ -164,13 +150,9 @@ description: To change the antenna cable name on the specified radio for an access point, set this parameter's value to "true". type: bool - configureAntennaDegree: - description: To change the antenna degree on the specified radio for an access - point, set this parameter's value to "true". - type: bool configureAntennaPatternName: - description: To change the antenna pattern name on the specified radio for an - access point, set the value for this parameter to "true". + description: To change the antenna gain on the specified radio for an access + point, set the value for this parameter to "true". type: bool configureChannel: description: To change the channel on the specified radio for an access point, @@ -184,10 +166,6 @@ description: To enable or disable either CleanAir or Spectrum Intelligence on the specified radio for an access point, set this parameter's value to "true". type: bool - configureElevAngleDegree: - description: To change the elevation angle degree on the specified radio for - an access point, set this parameter's value to "true". - type: bool configurePower: description: To change the power assignment mode on the specified radio for an access point, set this parameter's value to "true". @@ -206,11 +184,13 @@ type: int radioBand: description: Configure the band on the specified radio for an access point for - 2.4 GHz, set "RADIO24"; for 5 GHz, set "RADIO5". + 2.4 GHz, set "RADIO24"; for 5 GHz, set "RADIO5". Any other string is invalid, + including empty string. type: str radioRoleAssignment: - description: Configure one of the following roles on the specified radio for - an access point "auto", "serving", or "monitor". + description: Configure only one of the following roles on the specified radio + for an access point as "AUTO", "SERVING", or "MONITOR". Any other string is + invalid, including empty string. type: str radioType: description: Configure an access point's radio band for 2.4 GHz, set "1"; for @@ -238,15 +218,15 @@ type: str type: dict requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: -- name: Cisco DNA Center documentation for Wireless ConfigureAccessPoints - description: Complete reference of the ConfigureAccessPoints API. - link: https://developer.cisco.com/docs/dna-center/#!configure-access-points +- name: Cisco DNA Center documentation for Wireless ConfigureAccessPointsV1 + description: Complete reference of the ConfigureAccessPointsV1 API. + link: https://developer.cisco.com/docs/dna-center/#!configure-access-points-v-1 notes: - SDK Method used are - wireless.Wireless.configure_access_points, + wireless.Wireless.configure_access_points_v1, - Paths used are post /dna/intent/api/v1/wireless/accesspoint-configuration, @@ -264,14 +244,12 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" adminStatus: true - apHeight: 0 apList: - apName: string apNameNew: string macAddress: string apMode: 0 configureAdminStatus: true - configureApHeight: true configureApMode: true configureFailoverPriority: true configureHAController: true @@ -279,6 +257,7 @@ configureLedStatus: true configureLocation: true failoverPriority: 0 + isAssignedSiteAsLocation: true ledBrightnessLevel: 0 ledStatus: true location: string @@ -288,9 +267,6 @@ radioConfigurations: - adminStatus: true antennaCableName: string - antennaDegree: 0 - antennaElevAngleDegree: 0 - antennaElevAngleSign: 0 antennaGain: 0 antennaPatternName: string cableLoss: 0 @@ -300,12 +276,10 @@ cleanAirSI: 0 configureAdminStatus: true configureAntennaCable: true - configureAntennaDegree: true configureAntennaPatternName: true configureChannel: true configureChannelWidth: true configureCleanAirSI: true - configureElevAngleDegree: true configurePower: true configureRadioRoleAssignment: true powerAssignmentMode: 0 @@ -321,7 +295,6 @@ address: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/wireless_accesspoint_configuration_create.py b/plugins/modules/wireless_accesspoint_configuration_create.py new file mode 100644 index 0000000000..dca07464a6 --- /dev/null +++ b/plugins/modules/wireless_accesspoint_configuration_create.py @@ -0,0 +1,328 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: wireless_accesspoint_configuration_create +short_description: Resource module for Wireless Accesspoint Configuration Create +description: +- Manage operation create of the resource Wireless Accesspoint Configuration Create. +- User can configure multiple access points with required options using this intent API. +version_added: '6.14.0' +extends_documentation_fragment: + - cisco.dnac.module +author: Rafael Campos (@racampos) +options: + adminStatus: + description: Configure the access point's admin status. Set this parameter's value + to "true" to enable it and "false" to disable it. + type: bool + apList: + description: Wireless Accesspoint Configuration Create's apList. + elements: dict + suboptions: + apName: + description: The current host name of the access point. + type: str + apNameNew: + description: The modified hostname of the access point. + type: str + macAddress: + description: The ethernet MAC address of the access point. + type: str + type: list + apMode: + description: Configure the access point's mode for local/flexconnect mode, set "0"; + for monitor mode, set "1"; for sniffer mode, set "4"; and for bridge/flex+bridge + mode, set "5". + type: int + cleanAirSI24: + description: Configure clean air status for radios that are in 2.4 Ghz band. Set + this parameter's value to "true" to enable it and "false" to disable it. + type: bool + cleanAirSI5: + description: Configure clean air status for radios that are in 5 Ghz band. Set this + parameter's value to "true" to enable it and "false" to disable it. + type: bool + cleanAirSI6: + description: Configure clean air status for radios that are in 6 Ghz band. Set this + parameter's value to "true" to enable it and "false" to disable it. + type: bool + configureAdminStatus: + description: To change the access point's admin status, set this parameter's value + to "true". + type: bool + configureApMode: + description: To change the access point's mode, set this parameter's value to "true". + type: bool + configureCleanAirSI24Ghz: + description: To change the clean air status for radios that are in 2.4 Ghz band, + set this parameter's value to "true". + type: bool + configureCleanAirSI5Ghz: + description: To change the clean air status for radios that are in 5 Ghz band, set + this parameter's value to "true". + type: bool + configureCleanAirSI6Ghz: + description: To change the clean air status for radios that are in 6 Ghz band, set + this parameter's value to "true". + type: bool + configureFailoverPriority: + description: To change the access point's failover priority, set this parameter's + value to "true". + type: bool + configureHAController: + description: To change the access point's HA controller, set this parameter's value + to "true". + type: bool + configureLedBrightnessLevel: + description: To change the access point's LED brightness level, set this parameter's + value to "true". + type: bool + configureLedStatus: + description: To change the access point's LED status, set this parameter's value + to "true". + type: bool + configureLocation: + description: To change the access point's location, set this parameter's value to + "true". + type: bool + failoverPriority: + description: Configure the acess point's failover priority for low, set "1"; for + medium, set "2"; for high, set "3"; and for critical, set "4". + type: int + isAssignedSiteAsLocation: + description: To configure the access point's location as the site assigned to the + access point, set this parameter's value to "true". + type: bool + ledBrightnessLevel: + description: Configure the access point's LED brightness level by setting a value + between 1 and 8. + type: int + ledStatus: + description: Configure the access point's LED status. Set "true" to enable its status + and "false" to disable it. + type: bool + location: + description: Configure the access point's location. + type: str + primaryControllerName: + description: Configure the hostname for an access point's primary controller. + type: str + primaryIpAddress: + description: Wireless Accesspoint Configuration Create's primaryIpAddress. + suboptions: + address: + description: Configure the IP address for an access point's primary controller. + type: str + type: dict + radioConfigurations: + description: Wireless Accesspoint Configuration Create's radioConfigurations. + elements: dict + suboptions: + adminStatus: + description: Configure the admin status on the specified radio for an access + point. Set this parameter's value to "true" to enable it and "false" to disable + it. + type: bool + antennaCableName: + description: Configure the antenna cable name on the specified radio for an + access point. If cable loss needs to be configured, set this parameter's value + to "other". + type: str + antennaGain: + description: Configure the antenna gain on the specified radio for an access + point by setting a decimal value (in dBi). To configure "antennaGain", set + "antennaPatternName" value to "other". + type: int + antennaPatternName: + description: Specify the antenna name on the specified radio for an access point. + The antenna name is used to calculate the gain on the radio slot. + type: str + cableLoss: + description: Configure the cable loss on the specified radio for an access point + by setting a decimal value (in dBi). + type: float + channelAssignmentMode: + description: Configure the channel assignment mode on the specified radio for + an access point for global mode, set "1"; and for custom mode, set "2". + type: int + channelNumber: + description: Configure the channel number on the specified radio for an access + point. + type: int + channelWidth: + description: Configure the channel width on the specified radio for an access + point for 20 MHz, set "3"; for 40 MHz, set "4"; for 80 MHz, set "5"; and for + 160 MHz, set "6". + type: int + configureAdminStatus: + description: To change the admin status on the specified radio for an access + point, set this parameter's value to "true". + type: bool + configureAntennaCable: + description: To change the antenna cable name on the specified radio for an + access point, set this parameter's value to "true". + type: bool + configureAntennaPatternName: + description: To change the antenna gain on the specified radio for an access + point, set the value for this parameter to "true". + type: bool + configureChannel: + description: To change the channel on the specified radio for an access point, + set this parameter's value to "true". + type: bool + configureChannelWidth: + description: To change the channel width on the specified radio for an access + point, set this parameter's value to "true". + type: bool + configurePower: + description: To change the power assignment mode on the specified radio for + an access point, set this parameter's value to "true". + type: bool + configureRadioRoleAssignment: + description: To change the radio role on the specified radio for an access point, + set this parameter's value to "true". + type: bool + powerAssignmentMode: + description: Configure the power assignment mode on the specified radio for + an access point for global mode, set "1"; and for custom mode, set "2". + type: int + powerlevel: + description: Configure the power level on the specified radio for an access + point by setting a value between 1 and 8. + type: int + radioBand: + description: Configure the band on the specified radio for an access point for + 2.4 GHz, set "RADIO24"; for 5 GHz, set "RADIO5". Any other string is invalid, + including empty string. + type: str + radioRoleAssignment: + description: Configure only one of the following roles on the specified radio + for an access point as "AUTO", "SERVING", or "MONITOR". Any other string is + invalid, including empty string. + type: str + radioType: + description: Configure an access point's radio band for 2.4 GHz, set "1"; for + 5 GHz, set "2"; for XOR, set "3"; and for 6 GHz, set "6". + type: int + type: list + secondaryControllerName: + description: Configure the hostname for an access point's secondary controller. + type: str + secondaryIpAddress: + description: Wireless Accesspoint Configuration Create's secondaryIpAddress. + suboptions: + address: + description: Configure the IP address for an access point's secondary controller. + type: str + type: dict + tertiaryControllerName: + description: Configure the hostname for an access point's tertiary controller. + type: str + tertiaryIpAddress: + description: Wireless Accesspoint Configuration Create's tertiaryIpAddress. + suboptions: + address: + description: Configure the IP address for an access point's tertiary controller. + type: str + type: dict +requirements: +- dnacentersdk >= 2.4.9 +- python >= 3.5 +seealso: +- name: Cisco DNA Center documentation for Wireless ConfigureAccessPointsV2 + description: Complete reference of the ConfigureAccessPointsV2 API. + link: https://developer.cisco.com/docs/dna-center/#!configure-access-points-v-2 +notes: + - SDK Method used are + wireless.Wireless.configure_access_points_v2, + + - Paths used are + post /dna/intent/api/v2/wireless/accesspoint-configuration, + +""" + +EXAMPLES = r""" +- name: Create + cisco.dnac.wireless_accesspoint_configuration_create: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + adminStatus: true + apList: + - apName: string + apNameNew: string + macAddress: string + apMode: 0 + cleanAirSI24: true + cleanAirSI5: true + cleanAirSI6: true + configureAdminStatus: true + configureApMode: true + configureCleanAirSI24Ghz: true + configureCleanAirSI5Ghz: true + configureCleanAirSI6Ghz: true + configureFailoverPriority: true + configureHAController: true + configureLedBrightnessLevel: true + configureLedStatus: true + configureLocation: true + failoverPriority: 0 + isAssignedSiteAsLocation: true + ledBrightnessLevel: 0 + ledStatus: true + location: string + primaryControllerName: string + primaryIpAddress: + address: string + radioConfigurations: + - adminStatus: true + antennaCableName: string + antennaGain: 0 + antennaPatternName: string + cableLoss: 0 + channelAssignmentMode: 0 + channelNumber: 0 + channelWidth: 0 + configureAdminStatus: true + configureAntennaCable: true + configureAntennaPatternName: true + configureChannel: true + configureChannelWidth: true + configurePower: true + configureRadioRoleAssignment: true + powerAssignmentMode: 0 + powerlevel: 0 + radioBand: string + radioRoleAssignment: string + radioType: 0 + secondaryControllerName: string + secondaryIpAddress: + address: string + tertiaryControllerName: string + tertiaryIpAddress: + address: string + +""" +RETURN = r""" +dnac_response: + description: A dictionary or list with the response returned by the Cisco DNAC Python SDK + returned: always + type: dict + sample: > + { + "response": { + "taskId": "string", + "url": "string" + }, + "version": "string" + } +""" diff --git a/plugins/modules/wireless_accesspoint_configuration_summary_info.py b/plugins/modules/wireless_accesspoint_configuration_summary_info.py index ba43fe0526..931c663638 100644 --- a/plugins/modules/wireless_accesspoint_configuration_summary_info.py +++ b/plugins/modules/wireless_accesspoint_configuration_summary_info.py @@ -11,7 +11,7 @@ description: - Get all Wireless Accesspoint Configuration Summary. - Users can query the access point configuration information per device using the ethernet MAC address. -version_added: '6.7.0' +version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -24,8 +24,8 @@ - Key query parameter. The ethernet MAC address of Access point. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless GetAccessPointConfiguration description: Complete reference of the GetAccessPointConfiguration API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/wireless_dynamic_interface.py b/plugins/modules/wireless_dynamic_interface.py index ed933a268b..133d26326e 100644 --- a/plugins/modules/wireless_dynamic_interface.py +++ b/plugins/modules/wireless_dynamic_interface.py @@ -21,14 +21,14 @@ description: Additional headers. type: dict interfaceName: - description: Dynamic-interface name. + description: InterfaceName query parameter. Valid interface-name to be deleted. type: str vlanId: description: Vlan Id. - type: int + type: float requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless CreateUpdateDynamicInterface description: Complete reference of the CreateUpdateDynamicInterface API. @@ -43,12 +43,12 @@ - Paths used are post /dna/intent/api/v1/wireless/dynamic-interface, - delete /dna/intent/api/v1/wireless/dynamic-interface/{interfaceName}, + delete /dna/intent/api/v1/wireless/dynamic-interface, """ EXAMPLES = r""" -- name: Create +- name: Delete all cisco.dnac.wireless_dynamic_interface: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -57,12 +57,11 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" - state: present + state: absent headers: '{{my_headers | from_json}}' interfaceName: string - vlanId: 0 -- name: Delete by name +- name: Create cisco.dnac.wireless_dynamic_interface: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -71,23 +70,20 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" - state: absent - headers: '{{my_headers | from_json}}' + state: present interfaceName: string + vlanId: 0 """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK returned: always - type: list + type: dict sample: > - [ - { - "executionId": "string", - "executionUrl": "string", - "message": "string" - } - ] + { + "executionId": "string", + "executionStatusUrl": "string", + "message": "string" + } """ diff --git a/plugins/modules/wireless_dynamic_interface_info.py b/plugins/modules/wireless_dynamic_interface_info.py index 152b1c339e..d3191e1418 100644 --- a/plugins/modules/wireless_dynamic_interface_info.py +++ b/plugins/modules/wireless_dynamic_interface_info.py @@ -26,8 +26,8 @@ will be retrieved. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless GetDynamicInterface description: Complete reference of the GetDynamicInterface API. @@ -56,7 +56,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/wireless_enterprise_ssid.py b/plugins/modules/wireless_enterprise_ssid.py index f288aaada9..094de30842 100644 --- a/plugins/modules/wireless_enterprise_ssid.py +++ b/plugins/modules/wireless_enterprise_ssid.py @@ -18,20 +18,36 @@ - cisco.dnac.module author: Rafael Campos (@racampos) options: + aaaOverride: + description: Aaa Override. + type: bool + authKeyMgmt: + description: Takes string inputs for the AKMs that should be set true. Possible + AKM values dot1x,dot1x_ft, dot1x_sha, psk, psk_ft, psk_sha, owe, sae, sae_ft. + elements: str + type: list basicServiceSetClientIdleTimeout: - description: Basic Service Set Client Idle Timeout. + description: Basic Service Set Client Idle Timeout (Default 300 if enableBasicServiceSetMaxIdle + is true, 0 otherwise). type: int clientExclusionTimeout: - description: Client Exclusion Timeout. + description: Client Exclusion Timeout(Default 180 if enableClientExclusion is true, + 0 otherwise). type: int + clientRateLimit: + description: Client Rate Limit (in bits per second). + type: float + coverageHoleDetectionEnable: + description: Coverage Hole Detection Enable. + type: bool enableBasicServiceSetMaxIdle: - description: Enable Basic Service Set Max Idle. + description: Enable Basic Service Set Max Idle (Default true). type: bool enableBroadcastSSID: description: Enable Broadcase SSID. type: bool enableClientExclusion: - description: Enable Client Exclusion. + description: Enable Client Exclusion(Default true). type: bool enableDirectedMulticastService: description: Enable Directed Multicast Service. @@ -46,14 +62,34 @@ description: Enable Neighbor List. type: bool enableSessionTimeOut: - description: Enable Session Timeout. + description: Enable Session Timeout(Default true). type: bool fastTransition: description: Fast Transition. type: str + ghz24Policy: + description: Ghz24 Policy. + type: str + ghz6PolicyClientSteering: + description: Ghz6 Policy Client Steering. + type: bool mfpClientProtection: description: Management Frame Protection Client. type: str + multiPSKSettings: + description: Wireless Enterprise Ssid's multiPSKSettings. + elements: dict + suboptions: + passphrase: + description: Passphrase. + type: str + passphraseType: + description: Passphrase Type. + type: str + priority: + description: Priority. + type: int + type: list name: description: SSID NAME. type: str @@ -64,15 +100,34 @@ passphrase: description: Passphrase. type: str + policyProfileName: + description: Policy Profile Name. + type: str + profileName: + description: Profile Name. + type: str + protectedManagementFrame: + description: (Required applicable for Security Type WPA3_PERSONAL, WPA3_ENTERPRISE, + OPEN_SECURED) and (Optional, Required Applicable for Security Type WPA2_WPA3_PERSONAL + and WPA2_WPA3_ENTERPRISE). + type: str radioPolicy: - description: Radio Policy Enum (enum Triple band operation (2.4GHz, 5GHz and 6GHz), - Triple band operation with band select, 5GHz only, 2.4GHz only, 6GHz only). + description: Radio Policy Enum. type: str + rsnCipherSuiteCcmp256: + description: Rsn Cipher Suite Ccmp256. + type: bool + rsnCipherSuiteGcmp128: + description: Rsn Cipher Suite Gcmp 128. + type: bool + rsnCipherSuiteGcmp256: + description: Rsn Cipher Suite Gcmp256. + type: bool securityLevel: description: Security Level. type: str sessionTimeOut: - description: Session Time Out. + description: Session Time Out (Default 1800 if enableSessionTimeOut is true, 0 otherwise). type: int ssidName: description: SsidName path parameter. Enter the SSID name to be deleted. @@ -81,8 +136,8 @@ description: Traffic Type Enum (voicedata or data ). type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless CreateEnterpriseSSID description: Complete reference of the CreateEnterpriseSSID API. @@ -117,8 +172,13 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" state: present + aaaOverride: true + authKeyMgmt: + - string basicServiceSetClientIdleTimeout: 0 clientExclusionTimeout: 0 + clientRateLimit: 0 + coverageHoleDetectionEnable: true enableBasicServiceSetMaxIdle: true enableBroadcastSSID: true enableClientExclusion: true @@ -128,12 +188,24 @@ enableNeighborList: true enableSessionTimeOut: true fastTransition: string + ghz24Policy: string + ghz6PolicyClientSteering: true mfpClientProtection: string + multiPSKSettings: + - passphrase: string + passphraseType: string + priority: 0 name: string nasOptions: - string passphrase: string + policyProfileName: string + profileName: string + protectedManagementFrame: string radioPolicy: string + rsnCipherSuiteCcmp256: true + rsnCipherSuiteGcmp128: true + rsnCipherSuiteGcmp256: true securityLevel: string sessionTimeOut: 0 trafficType: string @@ -148,8 +220,13 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" state: present + aaaOverride: true + authKeyMgmt: + - string basicServiceSetClientIdleTimeout: 0 clientExclusionTimeout: 0 + clientRateLimit: 0 + coverageHoleDetectionEnable: true enableBasicServiceSetMaxIdle: true enableBroadcastSSID: true enableClientExclusion: true @@ -159,12 +236,24 @@ enableNeighborList: true enableSessionTimeOut: true fastTransition: string + ghz24Policy: string + ghz6PolicyClientSteering: true mfpClientProtection: string + multiPSKSettings: + - passphrase: string + passphraseType: string + priority: 0 name: string nasOptions: - string passphrase: string + policyProfileName: string + profileName: string + protectedManagementFrame: string radioPolicy: string + rsnCipherSuiteCcmp256: true + rsnCipherSuiteGcmp128: true + rsnCipherSuiteGcmp256: true securityLevel: string sessionTimeOut: 0 trafficType: string @@ -182,7 +271,6 @@ ssidName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/wireless_enterprise_ssid_info.py b/plugins/modules/wireless_enterprise_ssid_info.py index b277d03bd2..158d9bdb92 100644 --- a/plugins/modules/wireless_enterprise_ssid_info.py +++ b/plugins/modules/wireless_enterprise_ssid_info.py @@ -26,8 +26,8 @@ enterprise SSIDs will be retrieved. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless GetEnterpriseSSID description: Complete reference of the GetEnterpriseSSID API. @@ -56,7 +56,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -96,7 +95,16 @@ "passphrase": "string" } ], - "clientRateLimit": 0 + "clientRateLimit": 0, + "enableSessionTimeOut": true, + "sessionTimeOut": 0, + "enableClientExclusion": true, + "clientExclusionTimeout": 0, + "enableBasicServiceSetMaxIdle": true, + "basicServiceSetClientIdleTimeout": 0, + "enableDirectedMulticastService": true, + "enableNeighborList": true, + "mfpClientProtection": "string" } ], "groupUuid": "string", diff --git a/plugins/modules/wireless_profile.py b/plugins/modules/wireless_profile.py index 7c837cca75..0a611b9c01 100644 --- a/plugins/modules/wireless_profile.py +++ b/plugins/modules/wireless_profile.py @@ -14,7 +14,8 @@ - Delete the Wireless Profile from Cisco DNA Center whose name is provided. - > Updates the wireless Network Profile with updated details provided. All sites to be present in the network profile - should be provided. + should be provided. This API has been deprecated. Please use the new endpoint URL + /dna/intent/api/v2/wireless/profile. version_added: '3.1.0' extends_documentation_fragment: - cisco.dnac.module @@ -51,14 +52,12 @@ description: Interface Name. type: str name: - description: Ssid Name. + description: Ssid Name is required if ssidDetails is passed in PayLoad for + mapping to the Network Profile. type: str policyProfileName: description: Policy Profile Name. type: str - type: - description: Ssid Type(enum Enterprise/Guest). - type: str wlanProfileName: description: WLAN Profile Name. type: str @@ -68,8 +67,8 @@ description: WirelessProfileName path parameter. Wireless Profile Name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless CreateWirelessProfile description: Complete reference of the CreateWirelessProfile API. @@ -128,7 +127,6 @@ interfaceName: string name: string policyProfileName: string - type: string wlanProfileName: string - name: Create @@ -153,11 +151,9 @@ interfaceName: string name: string policyProfileName: string - type: string wlanProfileName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/wireless_profile_info.py b/plugins/modules/wireless_profile_info.py index fb175dedf6..7dcd2196f2 100644 --- a/plugins/modules/wireless_profile_info.py +++ b/plugins/modules/wireless_profile_info.py @@ -24,8 +24,8 @@ - ProfileName query parameter. Wireless Network Profile Name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless GetWirelessProfile description: Complete reference of the GetWirelessProfile API. @@ -54,7 +54,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/wireless_provision_access_point.py b/plugins/modules/wireless_provision_access_point.py index d4651745fb..8bf6d4b63d 100644 --- a/plugins/modules/wireless_provision_access_point.py +++ b/plugins/modules/wireless_provision_access_point.py @@ -36,9 +36,6 @@ rfProfile: description: Radio frequency profile name. type: str - siteId: - description: Site name hierarchy(ex Global/...). - type: str siteNameHierarchy: description: Site name hierarchy(ex Global/...). type: str @@ -47,8 +44,8 @@ type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless APProvision description: Complete reference of the APProvision API. @@ -79,7 +76,6 @@ - string deviceName: string rfProfile: string - siteId: string siteNameHierarchy: string type: string @@ -92,7 +88,7 @@ sample: > { "executionId": "string", - "executionUrl": "string", + "executionStatusUrl": "string", "message": "string" } """ diff --git a/plugins/modules/wireless_provision_device_create.py b/plugins/modules/wireless_provision_device_create.py index 84622d9906..79dd393bc8 100644 --- a/plugins/modules/wireless_provision_device_create.py +++ b/plugins/modules/wireless_provision_device_create.py @@ -28,22 +28,22 @@ elements: dict suboptions: interfaceGateway: - description: Interface Gateway. + description: Interface Gateway. Required for AireOS. type: str interfaceIPAddress: - description: Interface IP Address. + description: Interface IP Address. Required for AireOS. type: str interfaceName: - description: Interface Name. + description: Interface Name. Required for both AireOS and EWLC. type: str interfaceNetmaskInCIDR: - description: Interface Netmask In CIDR. + description: Interface Netmask In CIDR. Required for AireOS. type: int lagOrPortNumber: - description: Lag Or Port Number. + description: Lag Or Port Number. Required for AireOS. type: int vlanId: - description: VLAN ID. + description: VLAN ID. Required for both AireOS and EWLC. type: int type: list managedAPLocations: @@ -55,8 +55,8 @@ type: str type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless Provision description: Complete reference of the Provision API. @@ -94,7 +94,6 @@ site: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -103,14 +102,7 @@ sample: > { "executionId": "string", - "executionUrl": "string", - "provisioningTasks": { - "success": [ - "string" - ], - "failed": [ - "string" - ] - } + "executionStatusUrl": "string", + "message": "string" } """ diff --git a/plugins/modules/wireless_provision_device_update.py b/plugins/modules/wireless_provision_device_update.py index c76487739e..e0b5580cb3 100644 --- a/plugins/modules/wireless_provision_device_update.py +++ b/plugins/modules/wireless_provision_device_update.py @@ -24,39 +24,39 @@ elements: dict suboptions: deviceName: - description: Device Name. + description: Controller Name. type: str dynamicInterfaces: description: Wireless Provision Device Update's dynamicInterfaces. elements: dict suboptions: interfaceGateway: - description: Interface Gateway. + description: Interface Gateway. Required for AireOS. type: str interfaceIPAddress: - description: Interface IPAddress. + description: Interface IP Address. Required for AireOS. type: str interfaceName: - description: Interface Name. + description: Interface Name. Required for AireOS and EWLC. type: str interfaceNetmaskInCIDR: - description: Interface Netmask In CIDR. + description: Interface Netmask In CIDR. Required for AireOS. type: int lagOrPortNumber: - description: Lag Or Port Number. + description: Lag Or Port Number. Required for AireOS. type: int vlanId: - description: Vlan Id. + description: VLAN ID. Required for AireOS and EWLC. type: int type: list managedAPLocations: - description: Managed APLocations. + description: List of managed AP locations (Site Hierarchies). elements: str type: list type: list requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless ProvisionUpdate description: Complete reference of the ProvisionUpdate API. @@ -94,7 +94,6 @@ - string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -103,14 +102,7 @@ sample: > { "executionId": "string", - "executionUrl": "string", - "provisioningTasks": { - "success": [ - "string" - ], - "failed": [ - "string" - ] - } + "executionStatusUrl": "string", + "message": "string" } """ diff --git a/plugins/modules/wireless_provision_ssid_create_provision.py b/plugins/modules/wireless_provision_ssid_create_provision.py index a0627c125e..e9297e90e8 100644 --- a/plugins/modules/wireless_provision_ssid_create_provision.py +++ b/plugins/modules/wireless_provision_ssid_create_provision.py @@ -41,6 +41,11 @@ ssidDetails: description: Wireless Provision Ssid Create Provision's ssidDetails. suboptions: + authKeyMgmt: + description: Takes string inputs for the AKMs that should be set true. Possible + AKM values dot1x,dot1x_ft, dot1x_sha, psk, psk_ft, psk_sha, owe, sae, sae_ft. + elements: str + type: list enableBroadcastSSID: description: Enable Broadcast SSID. type: bool @@ -53,6 +58,12 @@ fastTransition: description: Fast Transition. type: str + ghz24Policy: + description: 2.4 GHz Policy. + type: str + ghz6PolicyClientSteering: + description: 6 Ghz Client Steering. + type: bool name: description: SSID Name. type: str @@ -63,6 +74,15 @@ radioPolicy: description: Radio Policy. type: str + rsnCipherSuiteCcmp256: + description: Rsn Cipher Suite Ccmp256. + type: bool + rsnCipherSuiteGcmp128: + description: Rsn Cipher Suite Gcmp128. + type: bool + rsnCipherSuiteGcmp256: + description: Rsn Cipher Suite Gcmp256. + type: bool securityLevel: description: Security Level(For guest SSID OPEN/WEB_AUTH, For Enterprise SSID ENTERPRISE/PERSONAL/OPEN). @@ -78,8 +98,8 @@ description: SSID Type. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless CreateAndProvisionSSID description: Complete reference of the CreateAndProvisionSSID API. @@ -111,20 +131,26 @@ managedAPLocations: - string ssidDetails: + authKeyMgmt: + - string enableBroadcastSSID: true enableFastLane: true enableMACFiltering: true fastTransition: string + ghz24Policy: string + ghz6PolicyClientSteering: true name: string passphrase: string radioPolicy: string + rsnCipherSuiteCcmp256: true + rsnCipherSuiteGcmp128: true + rsnCipherSuiteGcmp256: true securityLevel: string trafficType: string webAuthURL: string ssidType: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/wireless_provision_ssid_delete_reprovision.py b/plugins/modules/wireless_provision_ssid_delete_reprovision.py index 8d713ce13f..2fb01aeb4f 100644 --- a/plugins/modules/wireless_provision_ssid_delete_reprovision.py +++ b/plugins/modules/wireless_provision_ssid_delete_reprovision.py @@ -20,14 +20,16 @@ description: Additional headers. type: dict managedAPLocations: - description: ManagedAPLocations path parameter. + description: ManagedAPLocations path parameter. List of managed AP locations (Site + Hierarchies). This parameter needs to be encoded as per UTF-8 encoding. type: str ssidName: - description: SsidName path parameter. + description: SsidName path parameter. SSID Name. This parameter needs to be encoded + as per UTF-8 encoding. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless DeleteSSIDAndProvisionItToDevices description: Complete reference of the DeleteSSIDAndProvisionItToDevices API. @@ -56,7 +58,6 @@ ssidName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/wireless_psk_override.py b/plugins/modules/wireless_psk_override.py index 163ea45b5a..1e6c060c46 100644 --- a/plugins/modules/wireless_psk_override.py +++ b/plugins/modules/wireless_psk_override.py @@ -16,26 +16,21 @@ - cisco.dnac.module author: Rafael Campos (@racampos) options: - payload: - description: Wireless Psk Override's payload. - elements: dict - suboptions: - passPhrase: - description: Pass phrase (create/update). - type: str - site: - description: Site name hierarchy (ex Global/aaa/zzz/...). - type: str - ssid: - description: Enterprise ssid name(already created/present). - type: str - wlanProfileName: - description: WLAN Profile Name. - type: str - type: list + passPhrase: + description: Pass phrase (create/update). + type: str + site: + description: Site name hierarchy (ex Global/aaa/zzz/...). + type: str + ssidName: + description: Enterprise SSID Name(already created/present). + type: str + wlanProfileName: + description: WLAN Profile Name. + type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless PSKOverride description: Complete reference of the PSKOverride API. @@ -59,14 +54,12 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" - payload: - - passPhrase: string - site: string - ssid: string - wlanProfileName: string + passPhrase: string + site: string + ssidName: string + wlanProfileName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK diff --git a/plugins/modules/wireless_rf_profile.py b/plugins/modules/wireless_rf_profile.py index 86c7ad953d..b6c4062c8c 100644 --- a/plugins/modules/wireless_rf_profile.py +++ b/plugins/modules/wireless_rf_profile.py @@ -21,7 +21,7 @@ description: Channel Width. type: str defaultRfProfile: - description: Is Default Rf Profile. + description: Default Rf Profile. type: bool enableBrownField: description: Enable Brown Field. @@ -52,16 +52,16 @@ type: str maxPowerLevel: description: Max Power Level. - type: int + type: float minPowerLevel: description: Rx Sop Threshold. - type: int + type: float parentProfile: description: Parent Profile. type: str powerThresholdV1: description: Power Threshold V1. - type: int + type: float radioChannels: description: Radio Channels. type: str @@ -80,16 +80,16 @@ type: str maxPowerLevel: description: Max Power Level. - type: int + type: float minPowerLevel: description: Min Power Level. - type: int + type: float parentProfile: description: Parent Profile. type: str powerThresholdV1: description: Power Threshold V1. - type: int + type: float radioChannels: description: Radio Channels. type: str @@ -108,16 +108,16 @@ type: str maxPowerLevel: description: Max Power Level. - type: int + type: float minPowerLevel: description: Min Power Level. - type: int + type: float parentProfile: description: Parent Profile. type: str powerThresholdV1: description: Power Threshold V1. - type: int + type: float radioChannels: description: Radio Channels. type: str @@ -130,8 +130,8 @@ *non-custom RF profile cannot be deleted. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless CreateOrUpdateRFProfile description: Complete reference of the CreateOrUpdateRFProfile API. @@ -210,7 +210,6 @@ rfProfileName: string """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -219,7 +218,7 @@ sample: > { "executionId": "string", - "executionUrl": "string", + "executionStatusUrl": "string", "message": "string" } """ diff --git a/plugins/modules/wireless_rf_profile_info.py b/plugins/modules/wireless_rf_profile_info.py index 281f87b6dc..21415ca889 100644 --- a/plugins/modules/wireless_rf_profile_info.py +++ b/plugins/modules/wireless_rf_profile_info.py @@ -24,8 +24,8 @@ - Rf-profile-name query parameter. RF Profile Name. type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless RetrieveRFProfiles description: Complete reference of the RetrieveRFProfiles API. @@ -54,46 +54,50 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK returned: always - type: list - elements: dict + type: dict sample: > - [ - { - "name": "string", - "parentProfileA": "string", - "parentProfileB": "string", - "enableARadioType": true, - "enableBRadioType": true, - "enableCRadioType": true, - "channelWidth": "string", - "aRadioChannels": "string", - "bRadioChannels": "string", - "cRadioChannels": "string", - "dataRatesA": "string", - "dataRatesB": "string", - "dataRatesC": "string", - "mandatoryDataRatesA": "string", - "mandatoryDataRatesB": "string", - "mandatoryDataRatesC": "string", - "enableCustom": true, - "minPowerLevelA": "string", - "minPowerLevelB": "string", - "minPowerLevelC": "string", - "maxPowerLevelA": "string", - "maxPowerLevelB": "string", - "powerThresholdV1A": 0, - "powerThresholdV1B": 0, - "powerThresholdV1C": 0, - "rxSopThresholdA": "string", - "rxSopThresholdB": "string", - "rxSopThresholdC": "string", - "defaultRfProfile": true, - "enableBrownField": true - } - ] + { + "name": "string", + "defaultRfProfile": true, + "enableRadioTypeA": true, + "enableRadioTypeB": true, + "channelWidth": "string", + "enableCustom": true, + "enableBrownField": true, + "radioTypeAProperties": { + "parentProfile": "string", + "radioChannels": "string", + "dataRates": "string", + "mandatoryDataRates": "string", + "powerThresholdV1": 0, + "rxSopThreshold": "string", + "minPowerLevel": 0, + "maxPowerLevel": 0 + }, + "radioTypeBProperties": { + "parentProfile": "string", + "radioChannels": "string", + "dataRates": "string", + "mandatoryDataRates": "string", + "powerThresholdV1": 0, + "rxSopThreshold": "string", + "minPowerLevel": 0, + "maxPowerLevel": 0 + }, + "radioTypeCProperties": { + "parentProfile": "string", + "radioChannels": "string", + "dataRates": "string", + "mandatoryDataRates": "string", + "rxSopThreshold": "string", + "minPowerLevel": 0, + "maxPowerLevel": 0, + "powerThresholdV1": 0 + }, + "enableRadioTypeC": true + } """ diff --git a/plugins/modules/wireless_sensor_test_results_info.py b/plugins/modules/wireless_sensor_test_results_info.py index f316a4602c..e4de58e12d 100644 --- a/plugins/modules/wireless_sensor_test_results_info.py +++ b/plugins/modules/wireless_sensor_test_results_info.py @@ -26,18 +26,20 @@ startTime: description: - StartTime query parameter. The epoch time in milliseconds. - type: int + type: float endTime: description: - EndTime query parameter. The epoch time in milliseconds. - type: int + type: float testFailureBy: description: - - TestFailureBy query parameter. Obtain failure statistics group by "area", "building", or "floor". + - > + TestFailureBy query parameter. Obtain failure statistics group by "area", "building", or "floor" (case + insensitive). type: str requirements: -- dnacentersdk >= 2.6.0 -- python >= 3.9 +- dnacentersdk >= 2.4.9 +- python >= 3.5 seealso: - name: Cisco DNA Center documentation for Wireless SensorTestResults description: Complete reference of the SensorTestResults API. @@ -69,7 +71,6 @@ register: result """ - RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK @@ -77,72 +78,75 @@ type: dict sample: > { - "summary": { - "totalTestCount": 0, - "ONBOARDING": { - "AUTH": { - "passCount": 0, - "failCount": 0 + "version": "string", + "response": { + "summary": { + "totalTestCount": 0, + "ONBOARDING": { + "AUTH": { + "passCount": 0, + "failCount": 0 + }, + "DHCP": { + "passCount": 0, + "failCount": 0 + }, + "ASSOC": { + "passCount": 0, + "failCount": 0 + } }, - "DHCP": { - "passCount": 0, - "failCount": 0 + "PERFORMANCE": { + "IPSLASENDER": { + "passCount": 0, + "failCount": 0 + } }, - "ASSOC": { - "passCount": 0, - "failCount": 0 - } - }, - "PERFORMANCE": { - "IPSLASENDER": { - "passCount": 0, - "failCount": 0 - } - }, - "NETWORK_SERVICES": { - "DNS": { - "passCount": 0, - "failCount": 0 - } - }, - "APP_CONNECTIVITY": { - "HOST_REACHABILITY": { - "passCount": 0, - "failCount": 0 + "NETWORK_SERVICES": { + "DNS": { + "passCount": 0, + "failCount": 0 + } }, - "WEBSERVER": { - "passCount": 0, - "failCount": 0 + "APP_CONNECTIVITY": { + "HOST_REACHABILITY": { + "passCount": 0, + "failCount": 0 + }, + "WEBSERVER": { + "passCount": 0, + "failCount": 0 + }, + "FILETRANSFER": { + "passCount": 0, + "failCount": 0 + } }, - "FILETRANSFER": { - "passCount": 0, - "failCount": 0 - } - }, - "RF_ASSESSMENT": { - "DATA_RATE": { - "passCount": 0, - "failCount": 0 + "RF_ASSESSMENT": { + "DATA_RATE": { + "passCount": 0, + "failCount": 0 + }, + "SNR": { + "passCount": 0, + "failCount": 0 + } }, - "SNR": { - "passCount": 0, - "failCount": 0 + "EMAIL": { + "MAILSERVER": { + "passCount": 0, + "failCount": 0 + } } }, - "EMAIL": { - "MAILSERVER": { - "passCount": 0, - "failCount": 0 + "failureStats": [ + { + "errorCode": 0, + "errorTitle": "string", + "testType": "string", + "testCategory": "string" } - } - }, - "failureStats": [ - { - "errorCode": 0, - "errorTitle": "string", - "testType": "string", - "testCategory": "string" - } - ] + ] + } } """ From 9dfdfec2b4cfcea24876d7e21dce9d30fc122ce4 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Sun, 28 Apr 2024 12:32:43 -0400 Subject: [PATCH 294/358] network compliance module --- .../network_compliance_workflow_manager.py | 693 ++++++++++++++---- .../test_network_compliance_management.yml | 7 +- 2 files changed, 543 insertions(+), 157 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index f03a8e6a09..b82067c143 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -84,7 +84,7 @@ default: False requirements: -- dnacentersdk == 2.6.10 +- dnacentersdk >= 2.7.0 - python >= 3.5 notes: - SDK Method used are @@ -296,7 +296,7 @@ "version": "string" } -#Case_2: When compliance check is run, the response of the compliance status +#Case_2: dnac_response: description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK returned: always @@ -310,7 +310,7 @@ "taskId": "string", "url": "string" }, - "data": [list of dictionaries], + "data": dict, "version": "string" } @@ -329,10 +329,8 @@ class NetworkCompliance(DnacBase): def __init__(self, module): """ Initialize an instance of the class. - Parameters: - module: The module associated with the class instance. - Returns: The method does not return a value. """ @@ -341,17 +339,22 @@ def __init__(self, module): def validate_input(self, state=None): """ - Validate the fields provided in the playbook. Checks the - configuration provided in the playbook against a predefined - specification to ensure it adheres to the expected structure - and data types. - + Validate the fields provided in the playbook against a predefined specification + to ensure they adhere to the expected structure and data types. + Parameters: + state (optional): A state parameter that can be used to customize validation + based on different conditions. Returns: - The method returns an instance of the class with updated attributes: - - self.msg: A message describing the validation result. - - self.status: The status of the validation (either 'success' or 'failed'). - - self.validated_config: If successful, a validated version of the - 'config' parameter. + object: An instance of the class with updated attributes: + - self.msg: A message describing the validation result. + - self.status: The status of the validation (either 'success' or 'failed'). + - self.validated_config: If successful, a validated version of the 'config' parameter. + Description: + This method validates the fields provided in the playbook against a predefined specification. + It checks if the required fields are present and if their data types match the expected types. + If any parameter is found to be invalid, it logs an error message and sets the validation status to 'failed'. + If the validation is successful, it logs a success message and returns an instance of the class + with the validated configuration. """ if not self.config: @@ -388,8 +391,15 @@ def validate_input(self, state=None): def validate_ip4_address_list(self, ip_address_list): """ - Validates the IP address list provided in the playbook. + Validates the list of IPv4 addresses provided in the playbook. + Parameters: + ip_address_list (list): A list of IPv4 addresses to be validated. + Description: + This method iterates through each IP address in the list and checks if it is a valid IPv4 address. + If any address is found to be invalid, it logs an error message and fails. + After validating all IP addresses, it logs a success message. """ + for ip in ip_address_list: if not self.is_valid_ipv4(ip): msg = "IP address {0} is not valid".format(ip) @@ -399,40 +409,65 @@ def validate_ip4_address_list(self, ip_address_list): self.log("Successfully validated the IP address/es: {0}".format(ip_address_list), "DEBUG") def validate_run_compliance(self, run_compliance): + """ + Validates the parameters for running compliance checks. + Parameters: + run_compliance (dict): A dictionary containing the parameters for running compliance checks. + Returns: + None + Description: + This method validates the parameters provided for running compliance checks on devices. + It checks if 'trigger_full' and 'categories' parameters are provided and valid. + If any parameter is missing or invalid, an error message is logged, and the module fails. + If all parameters are valid, a success message is logged. + """ + trigger_full = run_compliance.get('trigger_full') categories = run_compliance.get('categories') msg = "" + + # Validate 'trigger_full' parameter if trigger_full not in [True, False]: msg = "trigger_full is a required parameter in order to run compliance check on device(s)" + + # Validate 'categories' parameter when 'trigger_full' is set to False if trigger_full == False and not categories: msg = "Categories is a required paramtere when trigger_full is set to False." + + # Validate 'categories' parameter values + if categories: + valid_categories = ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT', 'EOX', 'NETWORK_SETTINGS'] + if not all(category.upper() in valid_categories for category in categories): + msg = "Invalid category provided. Valid categories are {0}.".format(valid_categories) - if categories and not all(category.upper() in ['INTENT','RUNNING_CONFIG' , 'IMAGE' , 'PSIRT' , 'EOX' , 'NETWORK_SETTINGS'] for category in categories): - msg = "Invalid category provided. Valid categories are ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT', 'EOX', 'NETWORK_SETTINGS']." - + # Log error message and fail if validation fails if msg: self.log(msg, 'ERROR') self.module.fail_json(msg) - self.log("Successfully validated run_compliance parameters.", "DEBUG") - + else: + self.log("Successfully validated run_compliance parameters.", "DEBUG") def site_exists(self, site_name): """ + Checks the existence of a site in Cisco Catalyst Center. Parameters: - self (object): An instance of a class used for interacting with Cisco Catalyst Center. + site_name (str): The name of the site to be checked. Returns: tuple: A tuple containing two values: - - site_exists (bool): A boolean indicating whether the site exists (True) or not (False). - - site_id (str or None): The ID of the site if it exists, or None if the site is not found. + - site_exists (bool): Indicates whether the site exists (True) or not (False). + - site_id (str or None): The ID of the site if it exists, or None if the site is not found. Description: - This method checks the existence of a site in the Catalyst Center. If the site is found,it sets 'site_exists' to True, - retrieves the site's ID, and returns both values in a tuple. If the site does not exist, 'site_exists' is set - to False, and 'site_id' is None. If an exception occurs during the site lookup, an exception is raised. + This method queries Cisco Catalyst Center to determine if a site with the provided name exists. + If the site is found, it sets 'site_exists' to True and retrieves the site's ID. + If the site does not exist, 'site_exists' is set to False, and 'site_id' is None. + If an exception occurs during the site lookup, an error message is logged, and the module fails. """ site_exists = False site_id = None response = None + + # Attempt to retrieve site information from Catalyst Center try: response = self.dnac._exec( family="sites", @@ -440,23 +475,42 @@ def site_exists(self, site_name): op_modifies=True, params={"name": site_name}, ) + + # Process the response if available + if response: + self.log("Received API response from 'get_site': {0}".format(str(response)), "DEBUG") + site = response.get("response") + site_id = site[0].get("id") + site_exists = True + except Exception as e: + # Log an error message and fail if an exception occurs self.msg = "An exception occurred: Site '{0}' does not exist in the Cisco Catalyst Center".format(site_name) self.log(self.msg, "ERROR") self.module.fail_json(msg=self.msg) - if response: - self.log("Received API response from 'get_site': {0}".format(str(response)), "DEBUG") - site = response.get("response") - site_id = site[0].get("id") - site_exists = True - return (site_exists, site_id) def get_device_ids_from_ip(self, ip_address_list): + """ + Retrieves the device IDs based on the provided list of IP addresses from Cisco Catalyst Center. + Parameters: + ip_address_list (list): A list of IP addresses of devices for which you want to retrieve the device IDs. + Returns: + dict: A dictionary mapping management IP addresses to their instance UUIDs. + Description: + This method queries Cisco Catalyst Center for device information using the provided IP addresses. + For each IP address in the list, it attempts to fetch the device information using the 'get_device_list' API. + If the device is found and reachable, it extracts the device ID and maps it to the corresponding IP address. + If any error occurs during the process, it logs an error message and continues to the next IP address. + """ + mgmt_ip_instance_id_map = {} + + # Iterate through the provided list of IP addresses for device_ip in ip_address_list: try: + # Query Cisco Catalyst Center for device information using the IP address response = self.dnac._exec( family="devices", function='get_device_list', @@ -464,6 +518,7 @@ def get_device_ids_from_ip(self, ip_address_list): params={"managementIpAddress": device_ip} ) + # Check if a valid response is received if response.get("response"): self.log("Received API response from 'get_device_list' for device:{0} response: {1}".format(device_ip, str(response)), "DEBUG") response = response.get("response") @@ -474,24 +529,43 @@ def get_device_ids_from_ip(self, ip_address_list): device_id = response[0]["id"] mgmt_ip_instance_id_map[device_ip] = device_id else: + # If unable to retrieve device information, log an error message self.msg = "Unable to retrieve device information for {0}. Please ensure that the device exists and is reachable.".format(device_ip) self.log(self.msg, "ERROR") self.module.fail_json(msg=self.msg) except Exception as e: + # Log an error message if any exception occurs during the process error_message = "Error while fetching device ID for device: '{0}' from Cisco Catalyst Center: {1}".format(device_ip, str(e)) self.log(error_message, "ERROR") return mgmt_ip_instance_id_map def get_device_ids_from_site(self, site_name, site_id): + """ + Retrieves the management IP addresses and their corresponding instance UUIDs of devices associated with a specific site in Cisco Catalyst Center. + + Parameters: + site_name (str): The name of the site whose devices' information is to be retrieved. + site_id (str): The unique identifier of the site. + + Returns: + dict: A dictionary mapping management IP addresses to their instance UUIDs. + + Description: + This method queries Cisco Catalyst Center to fetch the list of devices associated with the provided site. + It then extracts the management IP addresses and their instance UUIDs from the response. + Devices that are not reachable are logged as critical errors, and the function fails. + If no reachable devices are found for the specified site, it logs an error message and fails. + + """ mgmt_ip_instance_id_map = {} site_params = { "site_id": site_id, } - #Get + # Attempt to retrieve device information associated with the site try: response = self.dnac._exec( family="sites", @@ -501,31 +575,23 @@ def get_device_ids_from_site(self, site_name, site_id): ) if response: self.log("Received API response from 'get_membership': {0}".format(str(response)), "DEBUG") - site_response_list = [] - for item in response['device']: + response = response['device'] + # Iterate over the devices in the site membership + for item in response: if item['response']: for item_dict in item['response']: - site_response_list.append(item_dict) - + # Check if the device is reachable + if item_dict["reachabilityStatus"] == "Reachable": + mgmt_ip_instance_id_map[item_dict["managementIpAddress"]] = item_dict["instanceUuid"] + else: + msg = 'Unable to get deviceId for device {0} in site {1} as its status is {2}'.format( + item["managementIpAddress"], site_name, item["reachabilityStatus"]) + self.log(msg, "CRITICAL") + self.module.fail_json(msg=msg) + + # Handle exceptions if unable to fetch device information associated with the site except Exception as e: - self.log("Unable to fetch the device(s) associated to the site '{0}' due to '{1}'".format(site_name, str(e)), "WARNING") - return device_id_list - - self.log("Received API response from 'get_membership': {0}".format(str(response)), "DEBUG") - response = response['device'] - - # Iterate over the devices in the site membership - for item in response: - if item['response']: - for item_dict in item['response']: - # Check if the device is reachable - if item_dict["reachabilityStatus"] == "Reachable": - mgmt_ip_instance_id_map[item_dict["managementIpAddress"]] = item_dict["instanceUuid"] - else: - msg = 'Unable to get deviceId for device {0} in site {1} as its status is {2}'.format( - item["managementIpAddress"], site_name, item["reachabilityStatus"]) - self.log(msg, "CRITICAL") - self.module.fail_json(msg=msg) + self.log("Unable to fetch the device(s) associated to the site '{0}' due to '{1}'".format(site_name, str(e)), "ERROR") if not mgmt_ip_instance_id_map: msg = 'Site: {0} provided in the playbook does not have any reachable devices'.format(site_name) @@ -536,16 +602,27 @@ def get_device_ids_from_site(self, site_name, site_id): def get_device_id_list(self, ip_address_list, site_name): """ - Get the list of unique device IDs for list of specified management IP addresses of devices in Cisco Catalyst Center. + Get the list of unique device IDs for a specified list of management IP addresses or devices associated with a site + in Cisco Catalyst Center. Parameters: - self (object): An instance of a class used for interacting with Cisco Catalyst Center. - device_ips (list): The management IP addresses of devices for which you want to retrieve the device IDs. + ip_address_list (list): The management IP addresses of devices for which you want to retrieve the device IDs. + site_name (str): The name of the site for which you want to retrieve the device IDs. Returns: - list: The list of unique device IDs for the specified devices. + dict: A dictionary mapping management IP addresses to device IDs for the specified devices. Description: - Queries Cisco Catalyst Center to retrieve the unique device ID associated with a device having the specified - IP address. If the device is not found in Cisco Catalyst Center, then print the log message with error severity. + This method queries Cisco Catalyst Center to retrieve the unique device IDs associated with devices having the + specified IP addresses or belonging to the specified site. If both IP addresses and site name are provided, + it first checks if the site exists, retrieves the device IDs associated with devices in that site, and then + filters them based on the provided IP addresses. If only a site name is provided, it retrieves the device IDs + associated with devices in that site. If only IP addresses are provided, it directly retrieves the device IDs + associated with those IP addresses. + Note: If a device is not found in Cisco Catalyst Center, it logs a message with error severity. """ + + # Initialize a dictionary to store management IP addresses and their corresponding device IDs + mgmt_ip_instance_id_map = {} + + # Check if both site name and IP address list are provided if site_name and ip_address_list: (site_exists, site_id) = self.site_exists(site_name) if site_exists: @@ -556,23 +633,70 @@ def get_device_id_list(self, ip_address_list, site_name): for ip, instance_id in iplist_mgmt_ip_instance_id_map.items() if ip in site_mgmt_ip_instance_id_map } + # If only site name is provided elif site_name and not ip_address_list: (site_exists, site_id) = self.site_exists(site_name) if site_exists: + # Retrieve device IDs associated with devices in the site mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) + + # If only IP addresses are provided elif ip_address_list and not site_name: + # Retrieve device IDs associated with devices having specified IP addresses mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) - return mgmt_ip_instance_id_map + def is_sync_required(self, response): + task_name = 'Sync Device Configuration' + + #Validate if sync is required + #response = self.get_compliance_detail(compliance_detail_params_sync) + self.log('Modified {0} Response for device(s) {1} : {2}'.format(task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), 'INFO') + + #Categorize the devices based on status - 'COMPLIANT', 'NON_COMPLIANT', 'OTHER'(status other than COMPLIANT and NON_COMPLIANT) + categorized_devices = {'COMPLIANT': {}, 'NON_COMPLIANT': {}, 'OTHER': {}} + for ip_address, compliance_type in modified_response.items(): + status = compliance_type[0]['status'] + if status == 'NON_COMPLIANT': + categorized_devices['NON_COMPLIANT'][ip_address] = compliance_type + elif status == 'COMPLIANT': + categorized_devices['COMPLIANT'][ip_address] = compliance_type + else: + categorized_devices['OTHER'][ip_address] = compliance_type + + #Validate if all devices are 'COMPLIANT' - then sync not required + if len(categorized_devices['COMPLIANT']) == len(mgmt_ip_instance_id_map): + self.msg = "Device(s) {0} are already compliant with the RUNNING_CONFIG compliance type. Therefore, {1} is not required.".format( + list(mgmt_ip_instance_id_map.keys()), task_name) + self.update_result('success', False, self.msg, 'INFO',categorized_devices) + return self + + elif len(categorized_devices['NON_COMPLIANT']) != len(mgmt_ip_instance_id_map): + self.msg = "The operation {0} cannot be performed on device(s) {1} because the status of the RUNNING_CONFIG compliance type is not as expected; it should be NON_COMPLIANT.".format( + task_name, list(mgmt_ip_instance_id_map.keys())) + self.update_result('failed', False, self.msg, 'INFO',categorized_devices) + + return self + def get_want(self, config): """ + Determines the desired state based on the provided configuration. + Parameters: + config (dict): The configuration specifying the desired state. + Returns: + dict: A dictionary containing the desired state parameters. + Description: + This method processes the provided configuration to determine the desired state. It validates the presence of + either 'ip_address_list' or 'site_name' and constructs parameters for running compliance checks and syncing + device configurations based on the provided configuration. It also logs the desired state for reference. """ + + # Initialize parameters run_compliance_params = {} sync_device_config_params = {} compliance_detail_params = {} - + compliance_detail_params_sync = {} #Validate either ip_address_list OR site_name is present ip_address_list = config.get('ip_address_list') @@ -587,12 +711,26 @@ def get_want(self, config): if ip_address_list: self.validate_ip4_address_list(ip_address_list) + # Retrieve device ID list mgmt_ip_instance_id_map = self.get_device_id_list(ip_address_list, site_name) - self.log('Retrieved device_id_list : {0}'.format(mgmt_ip_instance_id_map), 'DEBUG') + if not mgmt_ip_instance_id_map: + # Log an error message if mgmt_ip_instance_id_map is empty + msg = "Failed to retrieve device IDs for the provided IP addresses: {0} or site name: {1}.".format(ip_address_list, site_name) + self.log(msg, 'ERROR') + self.module.fail_json(msg) + else: + # Log the retrieved device ID list if it's not empty + self.log('Retrieved mgmt_ip_instance_id_map : {0}'.format(mgmt_ip_instance_id_map), 'DEBUG') #Validate run_compliance parameters run_compliance = config.get('run_compliance') sync_device_config = config.get('sync_device_config') + + if not run_compliance and not sync_device_config: + self.msg = "No actions were requested. This network compliance module can perform the following tasks: Run Compliance Check or Sync Device Config." + self.update_result('failed', False, self.msg, 'ERROR') + return self + if run_compliance: run_compliance_params = { 'triggerFull': config.get('run_compliance').get('trigger_full'), @@ -624,8 +762,9 @@ def get_want(self, config): 'deviceUuid': ','.join(list(mgmt_ip_instance_id_map.values())), 'complianceType': 'RUNNING_CONFIG' } + self.is_sync_required(compliance_detail_params_sync, mgmt_ip_instance_id_map) - + # Construct the 'want' dictionary containing the desired state parameters want = {} want = dict( ip_address_list = ip_address_list, @@ -641,6 +780,36 @@ def get_want(self, config): return self + def get_have(self, config): + """ + Retrieve and store compliance details if sync_device_config is enabled. + + Parameters: + config (dict): A dictionary containing configuration details. + + Returns: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Description: + In this method if sync_device_config is enabled, it proceeds to retrieve compliance details using the + specified parameters. The retrieved details are then modified and stored in the 'have' attribute for later reference. + Additionally, a log message is generated to indicate that the compliance details have been successfully retrieved + and stored. + """ + sync_device_config = config.get('sync_device_config') + have = {} + + if sync_device_config: + # Retrieve compliance details + response = self.get_compliance_detail(self.want.get('compliance_detail_params_sync')) + modified_response = self.modify_compliance_response(response, self.want.get('mgmt_ip_instance_id_map')) + + # Store modified compliance details + have['compliance_details'] = modified_response + self.log("Compliance details have been retrieved and stored: {0}.".format(modified_response), "INFO") + self.is_sync_required(modified_response) + self.have = have + return self + def get_compliance_detail(self, compliance_detail_params): response = self.dnac_apply['exec']( family="compliance", @@ -654,11 +823,27 @@ def get_compliance_detail(self, compliance_detail_params): return response def modify_compliance_response(self, response, mgmt_ip_instance_id_map): + """ + Modifies the compliance response by mapping device UUIDs to management IP addresses. + Parameters: + response (list of dict): The original compliance response. + mgmt_ip_instance_id_map (dict): Mapping of management IP addresses to instance IDs. + Returns: + dict: Modified compliance response with management IP addresses as keys. + Description: + This method takes the original compliance response and maps device UUIDs to their corresponding management + IP addresses using the provided mapping. It then constructs a modified response where each IP address is a key + associated with a list of compliance items related to that device. + """ modified_response = {} for item in response: device_uuid = item.get('deviceUuid') + + # Find the corresponding management IP address for the device UUID ip_address = next((ip for ip, uuid in mgmt_ip_instance_id_map.items() if uuid == device_uuid), None) + + # If the IP address is found, add the item to the modified response #if ip_address and item.get('status')!= 'NOT_APPLICABLE': if ip_address: if ip_address not in modified_response: @@ -667,155 +852,284 @@ def modify_compliance_response(self, response, mgmt_ip_instance_id_map): return modified_response - def run_compliance(self, run_compliance_params): + """ + Executes a compliance check operation in Cisco DNA Center. + Parameters: + run_compliance_params (dict): Parameters for running the compliance check. + Returns: + str or None: Task ID of the API task created, or None if unsuccessful. + Description: + This method initiates a compliance check operation in Cisco DNA Center by calling the 'run_compliance' function + from the 'compliance' family of APIs. It passes the provided parameters and updates the result accordingly. + """ - result = self.dnac_apply['exec']( - family="compliance", - function="run_compliance", - params=run_compliance_params, - op_modifies=True, - ) - - self.log("The response received post run_compliancee API call is {0}".format(str(result)), "DEBUG") + # Execute the compliance check operation + try: + result = self.dnac_apply['exec']( + family="compliance", + function="run_compliance", + params=run_compliance_params, + op_modifies=True, + ) + self.log("The response received post run_compliancee API call is {0}".format(str(result)), "DEBUG") + self.result.update(dict(response=result['response'])) + self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") + # Return the task ID of the API task created + return result.response.get('taskId') - self.result.update(dict(response=result['response'])) - self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") - return result.response.get('taskId') + # Log and handle any exceptions that occur during the execution + except Exception as e: + self.log("An error occurred while executing the run_compliance operation: {0}".format(str(e)), "ERROR") + return None def sync_device_config(self, sync_device_config_params): - result = self.dnac_apply['exec']( - family="compliance", - function="commit_device_configuration", - params=sync_device_config_params, - op_modifies=True, - ) - - self.log("The response received post commit_device_configuration API call is {0}".format(str(result)), "DEBUG") + """ + Synchronize the device configuration using the specified parameters. + Parameters: + - sync_device_config_params (dict): Parameters for synchronizing the device configuration. + Returns: + task_id (str): The ID of the task created for the synchronization operation. + Note: + This method initiates the synchronization of device configurations by making an API call to the Cisco DNA Center. + It logs the response received from the API call and extracts the task ID from the response for further monitoring. + If an error occurs during the API call, it will be caught and logged. + """ + # Make an API call to synchronize device configuration + try: + result = self.dnac_apply['exec']( + family="compliance", + function="commit_device_configuration", + params=sync_device_config_params, + op_modifies=True, + ) + self.log("The response received post commit_device_configuration API call is {0}".format(str(result)), "DEBUG") + self.result.update(dict(response=result['response'])) + self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") + # Return the task ID + return result.response.get('taskId') - self.result.update(dict(response=result['response'])) - self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") - return result.response.get('taskId') + # Log the error if an exception occurs during the API call + except Exception as e: + self.log("Error occurred while synchronizing device configuration: {0}".format(str(e)), "ERROR") + return None def get_task_status(self, task_id, task_name): - response = self.dnac_apply['exec']( - family="task", - function='get_task_by_id', - params=dict(task_id=task_id), - op_modifies=True, - ) - response = response.response - self.log("Task status for the task id {0} is {1}, is_error: {2}".format(str(task_id), str(response), str(response.get('isError'))), "INFO") - return response + """ + Retrieve the status of a task by its ID. + Parameters: + - task_id (str): The ID of the task whose status is to be retrieved. + - task_name (str): The name of the task. + Returns: + response (dict): The response containing the status of the task. + Note: + This method makes an API call to retrieve the task status and logs the status information. + If an error occurs during the API call, it will be caught and logged. + """ + + # Make an API call to retrieve the task status + try: + response = self.dnac_apply['exec']( + family="task", + function='get_task_by_id', + params=dict(task_id=task_id), + op_modifies=True, + ) + response = response.response + self.log("Task status for the task id {0} is {1}, is_error: {2}".format(str(task_id), str(response), str(response.get('isError'))), "INFO") + return response + + # Log the error if an exception occurs during the API call + except Exception as e: + self.log("Error occurred while retrieving task status for task id {0}: {1}".format(task_id, str(e)), "ERROR") + return None def update_result(self, status, changed, msg, log_level, data=None): + """ + Update the result of the operation with the provided status, message, and log level. + Parameters: + - status (str): The status of the operation ('success' or 'failed'). + - changed (bool): Indicates whether the operation caused changes. + - msg (str): The message describing the result of the operation. + - log_level (str): The log level at which the message should be logged ('INFO', 'ERROR', 'CRITICAL', etc.). + - data (dict, optional): Additional data related to the operation result. + Returns: + self (object): An instance of the class. + Note: + - If the status is 'failed', the 'failed' key in the result dictionary will be set to True. + - If data is provided, it will be included in the result dictionary. + """ + + # Update the result attributes with the provided values self.status = status self.result['status'] = status self.result['msg'] = msg self.result['changed'] = changed + + # Log the message at the specified log level self.log(msg, log_level) + + # If the status is 'failed', set the 'failed' key to True if status == 'failed': self.result['failed'] = True + + # If additional data is provided, include it in the result dictionary if data: self.result['data'] = data + return self def exit_while_loop(self, start_time, task_id, task_name, response): - if time.time() - start_time > 10: + """ + Check if the elapsed time exceeds the specified timeout period and exit the while loop if it does. + Parameters: + - start_time (float): The time when the while loop started. + - task_id (str): ID of the task being monitored. + - task_name (str): Name of the task being monitored. + - response (dict): Response received from the task status check. + Returns: + bool: True if the elapsed time exceeds the timeout period, False otherwise. + """ + + # If the elapsed time exceeds the timeout period + if time.time() - start_time > 360: if response.get('data'): + # If there is data in the response, include it in the error message self.msg = "Task {0} with task id {1} has not completed within the timeout period. Task Status: {2} ".format( task_name, task_id, response.get('data')) else: + # If there is no data in the response, generate a generic error message self.msg = "Task {0} with task id {1} has not completed within the timeout period.".format( task_name, task_id) + + # Update the result with failure status and log the error message self.update_result('failed', False, self.msg, 'ERROR') return True return False def handle_error(self, task_name, mgmt_ip_instance_id_map, failure_reason=None): + """ + Handle error encountered during task execution. + Parameters: + - task_name (str): Name of the task being performed. + - mgmt_ip_instance_id_map (dict): Mapping of management IP addresses to instance IDs. + - failure_reason (str, optional): Reason for the failure, if available. + Returns: + self (object): An instance of the class used for interacting with Cisco Catalyst Center. + """ + + # If failure reason is provided, include it in the error message if failure_reason: self.msg = "An error occurred while performing {0} on device(s): {1}. The operation failed due to the following reason: {2}".format( task_name, list(mgmt_ip_instance_id_map.keys()), failure_reason) + # If no failure reason is provided, generate a generic error message else: self.msg = "An error occurred while performing {0} on device(s): {1}".format( task_name, list(mgmt_ip_instance_id_map.keys())) + + # Update the result with failure status and log the error message self.update_result('failed', False, self.msg, 'ERROR') return self - def get_compliance_task_status(self, task_id, mgmt_ip_instance_id_map): + """ + This function retrieves the status of compliance check tasks in Cisco Catalyst Center. + Parameters: + - task_id: The ID of the compliance check task. + - mgmt_ip_instance_id_map: A mapping of management IP addresses to instance IDs. + Returns: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Description: + This function continuously checks the status of a compliance check task until completion. + It handles various scenarios such as task completion, task failure, or errors during execution. + Upon successful completion, it logs the modified compliance response and updates the result accordingly. + """ + task_name = 'Run Compliance Check' start_time = time.time() + while True: response = self.get_task_status(task_id, task_name) + # Check if response returned + if not response: + self.msg = 'Error retrieving Task status for the task_name {0} task_id {1}'.format() + self.update_result('failed', False, self.msg, 'ERROR') + break + # Check if the elapsed time exceeds the timeout if self.exit_while_loop(start_time, task_id, task_name, response): break + # Handle error if task execution encounters an error if response.get('isError'): failure_reason = response.get("failureReason") self.handle_error(task_name, mgmt_ip_instance_id_map, failure_reason) break + # Check if task completed successfully elif not response.get('isError') and 'success' in response.get('progress').lower(): + # Task completed successfully self.msg = "{0} has completed successfully on device(s): {1}".format(task_name, list(mgmt_ip_instance_id_map.keys())) + + # Retrieve and modify compliance check details response = self.get_compliance_detail(self.want.get('compliance_detail_params')) modified_response = self.modify_compliance_response(response, mgmt_ip_instance_id_map) self.log('Modified {0} Response for device(s) {1} : {2}'.format(task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), 'INFO') + + # Update result with modified response self.update_result('success', True, self.msg, 'INFO', modified_response) break + #Check if task failed elif 'failed' in response.get('progress').lower(): self.msg = "Failed to {0} on the following device(s): {1}".format(task_name, list(mgmt_ip_instance_id_map.keys())) self.update_result('failed', False, self.msg, 'CRITICAL') break + return self def sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): - task_name = 'Sync Device Configuration' - - #Validate if sync is required - response = self.get_compliance_detail(self.want.get('compliance_detail_params_sync')) - modified_response = self.modify_compliance_response(response, mgmt_ip_instance_id_map) - self.log('Modified {0} Response for device(s) {1} : {2}'.format(task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), 'INFO') - - categorized_devices = {'COMPLIANT': {}, 'NON_COMPLIANT': {}, 'OTHER': {}} - for ip_address, compliance_type in modified_response.items(): - if compliance_type[0]['status'] == 'NON_COMPLIANT': - categorized_devices['NON_COMPLIANT'][ip_address] = compliance_type - elif compliance_type[0]['status'] == 'COMPLIANT': - categorized_devices['COMPLIANT'][ip_address] = compliance_type - else: - categorized_devices['OTHER'][ip_address] = compliance_type + """ + This function manages the status of device configuration synchronization tasks in Cisco Catalyst Center. + Parameters: + - task_id: ID of the synchronization task + - mgmt_ip_instance_id_map: Mapping of management IP addresses to instance IDs + Returns: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Description: + It validates if synchronization is required, categorizes devices based on compliance status, and checks task completion status. + If all devices are already compliant, it logs a success message. If some devices have unexpected statuses, it logs an error. + It continuously checks the task status until completion, updating the result accordingly. + """ - if len(categorized_devices['COMPLIANT']) == len(mgmt_ip_instance_id_map): - self.msg = "Device(s) {0} are already compliant with the RUNNING_CONFIG compliance type. Therefore, {1} is not required.".format( - list(mgmt_ip_instance_id_map.keys()), task_name) - self.update_result('success', False, self.msg, 'INFO',categorized_devices['COMPLIANT']) - return self + task_name = 'Sync Device Configuration' - if categorized_devices['OTHER']: - self.msg = "The operation {0} cannot be performed on device(s) {1} because the status of the RUNNING_CONFIG compliance type is not as expected; it should be NON_COMPLIANT.".format( - task_name, list(mgmt_ip_instance_id_map.keys())) - self.update_result('success', False, self.msg, 'INFO',categorized_devices ) - return self + #Start Sync Operation start_time = time.time() while True: response = self.get_task_status(task_id, task_name) - # Check if the elapsed time exceeds the timeout - if self.exit_while_loop(start_time, task_id, task_name, response): + # Check if response returned + if not response: + self.msg = 'Error retrieving Task status for the task_name {0} task_id {1}'.format() + self.update_result('failed', False, self.msg, 'ERROR') break + # Check if the elapsed time exceeds the timeout + # if self.exit_while_loop(start_time, task_id, task_name, response): + # break + + # Handle error if task execution encounters an error if response.get('isError'): failure_reason = response.get("failureReason") self.handle_error(task_name, mgmt_ip_instance_id_map, failure_reason) break + elif len(mgmt_ip_instance_id_map) == 1: ip_address = next(iter(mgmt_ip_instance_id_map)) progress = response.get('progress', '').lower() @@ -868,41 +1182,101 @@ def sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): return self def get_diff_merged(self): - if self.want.get('run_compliance_params'): - result_task_id = self.run_compliance(self.want.get('run_compliance_params')) - self.get_compliance_task_status(result_task_id, self.want.get('mgmt_ip_instance_id_map')).check_return_status() - - if self.want.get('sync_device_config_params'): - result_task_id = self.sync_device_config(self.want.get('sync_device_config_params')) - self.sync_config_task_status(result_task_id, self.want.get('mgmt_ip_instance_id_map')).check_return_status() - - return self + """ + This method is designed to Perform Network Compliance Actions in Cisco Catalyst Center. + Parameters: None + Returns: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Description: + This method orchestrates compliance check operation and device configuration synchronization tasks specified in a playbook. + It ensures all required tasks are present, executes them, and checks their status, facilitating smooth playbook execution. + """ - # def get_diff_merged(self): - # action_map = { - # 'run_compliance_params': (self.run_compliance, self.get_compliance_task_status), - # 'sync_device_config_params': (self.sync_device_config, self.sync_config_task_status) - # } + # Action map for different network compliance operations + action_map = { + 'run_compliance_params': (self.run_compliance, self.get_compliance_task_status), + 'sync_device_config_params': (self.sync_device_config, self.sync_config_task_status) + } - # if not any(self.want.get(action_param) for action_param in action_map): - # msg = "Network compliance operations are missing from the playbook. You can perform compliance checks or sync device configuration tasks using this module." - # self.log(msg, "ERROR") - # self.module.fail_json(msg) + # Iterate through the action map and execute specified actions + for action_param, (action_func, status_func) in action_map.items(): - # for action_param, (action_func, status_func) in action_map.items(): - # if self.want.get(action_param): - # result_task_id = action_func(self.want.get(action_param)) - # status_func(result_task_id, self.want.get('mgmt_ip_instance_id_map')).check_return_status() + # Execute the action and check its status + if self.want.get(action_param): + result_task_id = action_func(self.want.get(action_param)) + self.log("Performing {0}".format(action_func), 'DEBUG') + if not result_task_id: + self.msg = "An error occurred while retrieving the task_id for the {0} operation.".format(action_func) + self.update_result('failed', False, self.msg, 'CRITICAL') + else: + status_func(result_task_id, self.want.get('mgmt_ip_instance_id_map')).check_return_status() - # return self + return self def verify_diff_merged(self, config): - pass + """ + Verify the success of the 'Sync Device Configuration' operation. + Parameters: + config (dict): A dictionary containing the configuration details. + Returns: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Description: + This method verifies the success of the 'Sync Device Configuration' operation in the context of network compliance management. + It checks if the configuration includes the option to synchronize device configurations (`sync_device_config`). + If this option is present, the function proceeds to compare compliance details before and after executing the synchronization operation. + It logs relevant information at each step and concludes by determining whether the synchronization was successful. + """ + if config.get('sync_device_config'): + # Get compliance details before running sync_device_config + compliance_details_before = self.have.get('compliance_details') + self.log("Compliance details before running sync_device_config: {0}".format(compliance_details_before), "INFO") + + + # Get compliance details after running sync_device_config + response = self.get_compliance_detail(self.want.get('compliance_detail_params_sync')) + compliance_details_after = self.modify_compliance_response(response, self.want.get('mgmt_ip_instance_id_map')) + self.log("Compliance details after running sync_device_config: {}.".format(compliance_details_after), "INFO") + + + all_statuses_before = [] + all_statuses_after = [] + for ip_address, compliance_type in compliance_details_before.items(): + status = compliance_type[0]['status'] + all_statuses_before.append(status) + + if len(set(all_statuses_before)) == 1 and all_statuses_before[0] == 'NON_COMPLIANT': + for ip_address, compliance_type in compliance_details_after.items(): + status = compliance_type[0]['status'] + all_statuses_after.append(status) + if len(set(all_statuses_after)) == 1 and all_statuses_after[0] == 'COMPLIANT': + self.log('Verified the success of the Sync Device Configuration operation.') + else: + self.log("Sync Device Configuration operation may have been unsuccessful since not all devices have 'COMPLIANT' status after the operation.", "WARNING") + else: + self.log("Sync_device_config may not have been performed since devices have status other than 'NON_COMPLIANT'.", "WARNING") + + + + # # Check if 'RUNNING_CONFIG' status of all devices was 'NON_COMPLIANT' before sync_device_config + # all_statuses_before = [device['status'] for devices in compliance_details_before.values() for device in devices] + # if len(set(all_statuses_before)) == 1 and all_statuses_before[0] == 'NON_COMPLIANT': + # # Check if all devices are compliant after sync_device_config + # all_statuses_after = [device['status'] for devices in compliance_details_after.values() for device in devices] + # if len(set(all_statuses_after)) == 1 and all_statuses_after[0] == 'COMPLIANT': + # self.log('Verified the success of the Sync Device Configuration operation.') + # else: + # self.log("Sync Device Configuration operation may have been unsuccessful since not all devices have 'COMPLIANT' status after the operation.", "WARNING") + # else: + # self.log("Sync_device_config may not have been performed since devices have status other than 'NON_COMPLIANT'.", "WARNING") + + return self + def main(): """ main entry point for module execution """ + # Define the specification for the module's arguments element_spec = {'dnac_host': {'required': True, 'type': 'str'}, 'dnac_port': {'type': 'str', 'default': '443'}, 'dnac_username': {'type': 'str', 'default': 'admin', 'aliases': ['user']}, @@ -922,26 +1296,37 @@ def main(): 'state': {'default': 'merged', 'choices': ['merged']} } + # Initialize the Ansible module with the provided argument specifications module = AnsibleModule(argument_spec=element_spec, supports_check_mode=False) + # Initialize the NetworkCompliance object with the module ccc_network_compliance = NetworkCompliance(module) + + # Get the state parameter from the provided parameters state = ccc_network_compliance.params.get("state") + # Check if the state is valid if state not in ccc_network_compliance.supported_states: ccc_network_compliance.status = "invalid" ccc_network_compliance.msg = "State {0} is invalid".format(state) ccc_network_compliance.check_return_status() + # Validate the input parameters and check the return status ccc_network_compliance.validate_input().check_return_status() + + # Get the config_verify parameter from the provided parameters config_verify = ccc_network_compliance.params.get("config_verify") + # Iterate over the validated configuration parameters for config in ccc_network_compliance.validated_config: - ccc_network_compliance.get_want(config) + ccc_network_compliance.get_want(config).check_return_status() + ccc_network_compliance.get_have(config).check_return_status() ccc_network_compliance.get_diff_state_apply[state]().check_return_status() - # if config_verify: - # ccc_network_compliance.verify_diff_state_apply[state](config).check_return_status() + if config_verify: + ccc_network_compliance.verify_diff_state_apply[state](config).check_return_status() + # Exit with the result obtained from the NetworkCompliance object module.exit_json(**ccc_network_compliance.result) diff --git a/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml b/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml index 9a4ed8886e..e853a9fe66 100644 --- a/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml +++ b/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml @@ -33,10 +33,11 @@ <<: *dnac_login dnac_log_append: False config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + - #ip_address_list: ['204.1.2.4', '204.1.2.5'] + ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] #site_name: "Global" - run_compliance: - trigger_full: True + # run_compliance: + # trigger_full: True #trigger_full: True #categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT', 'EOX', 'NETWORK_SETTINGS'] sync_device_config: True From 6e58261b8b78f74cb2e1d6e24c7361a2aaf1564a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 29 Apr 2024 22:45:19 -0400 Subject: [PATCH 295/358] network compliance module --- .../network_compliance_workflow_manager.yml | 124 ++++- .../network_compliance_workflow_manager.py | 506 ++++++++++-------- 2 files changed, 387 insertions(+), 243 deletions(-) diff --git a/playbooks/network_compliance_workflow_manager.yml b/playbooks/network_compliance_workflow_manager.yml index 949e314521..1e24fbad31 100644 --- a/playbooks/network_compliance_workflow_manager.yml +++ b/playbooks/network_compliance_workflow_manager.yml @@ -17,17 +17,129 @@ dnac_debug: "{{ dnac_debug }}" dnac_log: true dnac_log_level: DEBUG + dnac_log_append: False config_verify: true tasks: - - - name: Testing + - name: Run full complaince check using IP address list cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - site_name: "Global" run_compliance: - trigger_full: True - categories: ['INTENT','RUNNING_CONFIG'] - sync_device_config: False + trigger_full: True + + - name: Run full complaince check using Site + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - site: "Global" + run_compliance: + trigger_full: True + + - name: Run full compliance check using both IP address list and Site + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: True + + - name: Run complaince check with specific categories using IP address list + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + + - name: Run complaince check with specific categories using Site + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - site_name: "Global" + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + + - name: Run compliance check with specific categories using both IP address list and Site + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + + - name: Sync Device Configuration using IP address list + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + sync_device_config: True + + - name: Sync Device Configuration using Site + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - site_name: "Global/USA/San Francisco/Building_1/floor_1" + sync_device_config: True + + - name: Sync Device Configuration using both IP address list and Site + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + sync_device_config: True + + - name: Run full Compliance and sync configuration with IP address list + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + run_compliance: + trigger_full: True + sync_device_config: True + + - name: Run full Compliance and sync configuration with Site + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: True + sync_device_config: True + + - name: Run Compliance with specific categories and sync configuration with IP address list + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + sync_device_config: True + + - name: Run Compliance with specific categories and sync configuration with Site + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + sync_device_config: True + + - name: Run Compliance and sync configuration using both IP address list and Site + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: True + sync_device_config: True diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index b82067c143..4111903e8c 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -29,7 +29,7 @@ type: bool default: False state: - description: The state of Cisco Catalyst Center after module completion. + description: State of Cisco Catalyst Center after module completion. type: str choices: [merged] default: merged @@ -71,7 +71,6 @@ Compliance's categories are required when trigger_full is set to False. Category can have any value among ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT' , 'EOX' , 'NETWORK_SETTINGS']. Category 'INTENT' is mapped to compliance types: NETWORK_SETTINGS, NETWORK_PROFILE, WORKFLOW, FABRIC,APPLICATION_VISIBILITY. - required: This parameter is required when trigger_full is set to False. type: bool default: False @@ -91,17 +90,19 @@ compliance.Compliance.run_compliance compliance.Compliance.commit_device_configuration task.Task.get_task_by_id + task.Task.get_task_tree compliance.Compliance.get_compliance_detail - Paths used are post /dna/intent/api/v1/compliance/ post /dna/intent/api/v1/network-device-config/write-memory get /dna/intent/api/v1/task/{taskId} + get /dna get /dna/intent/api/v1/compliance/detail """ EXAMPLES = r""" -- name: Run full compliance check on device(s) in the ip_address_list +- name: Run full compliance check on device(s) using IP address list cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -113,12 +114,12 @@ dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged - config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - run_compliance: - trigger_full: True + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + run_compliance: + trigger_full: True -- name: Run full compliance check on device(s) in the site +- name: Run full compliance check on device(s) using Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -130,12 +131,12 @@ dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged - config: - - site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: True + config: + - site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: True -- name: Run full compliance check on device(s) with both ip_address_list and site +- name: Run full compliance check on device(s) using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -147,13 +148,13 @@ dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged - config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: True + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: True -- name: Run compliance check with specific categories on device(s) in the ip_address_list +- name: Run compliance check with specific categories on device(s) using IP address list cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -165,13 +166,13 @@ dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged - config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] -- name: Run compliance check with specific categories on device(s) in the site +- name: Run compliance check with specific categories on device(s) using Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -183,13 +184,13 @@ dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged - config: - - site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + config: + - site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] -- name: Run compliance check with specific categories on device(s) with both ip_address_list and site +- name: Run compliance check with specific categories on device(s) using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -201,14 +202,14 @@ dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged - config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] - -- name: Sync device configuration on device(s) in the ip_address_list + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + +- name: Sync device configuration on device(s) using IP address list cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -220,11 +221,11 @@ dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged - config: - - site: "Global" - sync_device_config: True + config: + - site_name: "Global" + sync_device_config: True -- name: Sync device configuration on device(s) in the site +- name: Sync device configuration on device(s) using Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -236,11 +237,11 @@ dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged - config: - - site_name: "Global/USA/San Francisco/Building_1/floor_1" - sync_device_config: True + config: + - site_name: "Global/USA/San Francisco/Building_1/floor_1" + sync_device_config: True -- name: Sync device configuration on device(s) with both ip_address_list and site +- name: Sync device configuration on device(s) using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -252,12 +253,12 @@ dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged - config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - site_name: "Global/USA/San Francisco/Building_1/floor_1" - sync_device_config: True + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + sync_device_config: True -- name: Run Compliance and sync configuration with both ip_address_list and site +- name: Run Compliance and sync configuration using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -269,18 +270,18 @@ dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged - config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] - sync_device_config: True + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: + trigger_full: False + categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + sync_device_config: True """ RETURN = r""" -#Case_1: -dnac_response: +#Case_2: When Run Compliance Operation is performed successfully on device(s), Compliance +dnac_response: description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK returned: always type: dict @@ -293,11 +294,12 @@ "taskId": "string", "url": "string" }, + "data": dict, "version": "string" } -#Case_2: -dnac_response: +#Case_1: When Sync Device Config operations is performed successfully on device(s). +dnac_response: description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK returned: always type: dict @@ -310,17 +312,25 @@ "taskId": "string", "url": "string" }, - "data": dict, "version": "string" } +#Case_3: When Error Occurs in performing Run Compliance or Sync Device Configuration operation on device(s). +dnac_response: + description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK + returned: always + type: dict + sample: > + { + "changed": bool, + "msg": "string" + } """ from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.dnac.plugins.module_utils.dnac import ( DnacBase, - validate_list_of_dicts, - get_dict_result, + validate_list_of_dicts ) class NetworkCompliance(DnacBase): @@ -337,7 +347,7 @@ def __init__(self, module): super().__init__(module) - def validate_input(self, state=None): + def validate_input(self): """ Validate the fields provided in the playbook against a predefined specification to ensure they adhere to the expected structure and data types. @@ -402,10 +412,10 @@ def validate_ip4_address_list(self, ip_address_list): for ip in ip_address_list: if not self.is_valid_ipv4(ip): - msg = "IP address {0} is not valid".format(ip) - self.log(msg, "ERROR") - self.module.fail_json(msg) - + self.msg = "IP address {0} is not valid".format(ip) + self.log(self.msg, "ERROR") + self.module.fail_json(self.msg) + self.log("Successfully validated the IP address/es: {0}".format(ip_address_list), "DEBUG") def validate_run_compliance(self, run_compliance): @@ -421,22 +431,21 @@ def validate_run_compliance(self, run_compliance): If any parameter is missing or invalid, an error message is logged, and the module fails. If all parameters are valid, a success message is logged. """ - + valid_categories = ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT', 'EOX', 'NETWORK_SETTINGS'] trigger_full = run_compliance.get('trigger_full') categories = run_compliance.get('categories') msg = "" # Validate 'trigger_full' parameter if trigger_full not in [True, False]: - msg = "trigger_full is a required parameter in order to run compliance check on device(s)" + msg = "trigger_full is a required parameter in order to run compliance check on device(s). Set trigger_full to either True or False" # Validate 'categories' parameter when 'trigger_full' is set to False - if trigger_full == False and not categories: - msg = "Categories is a required paramtere when trigger_full is set to False." - + if trigger_full is False and not categories: + msg = "Categories is a required paramter when trigger_full is set to False. Valid categories are {0} ".format(valid_categories) + # Validate 'categories' parameter values if categories: - valid_categories = ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT', 'EOX', 'NETWORK_SETTINGS'] if not all(category.upper() in valid_categories for category in categories): msg = "Invalid category provided. Valid categories are {0}.".format(valid_categories) @@ -485,9 +494,10 @@ def site_exists(self, site_name): except Exception as e: # Log an error message and fail if an exception occurs - self.msg = "An exception occurred: Site '{0}' does not exist in the Cisco Catalyst Center".format(site_name) - self.log(self.msg, "ERROR") - self.module.fail_json(msg=self.msg) + msg = "Site '{0}' does not exist in the Cisco Catalyst Center".format(site_name) + self.log('An exception occurred: {0}'.format(e), "ERROR") + self.log(msg, 'ERROR') + self.module.fail_json(msg=msg) return (site_exists, site_id) @@ -530,9 +540,9 @@ def get_device_ids_from_ip(self, ip_address_list): mgmt_ip_instance_id_map[device_ip] = device_id else: # If unable to retrieve device information, log an error message - self.msg = "Unable to retrieve device information for {0}. Please ensure that the device exists and is reachable.".format(device_ip) - self.log(self.msg, "ERROR") - self.module.fail_json(msg=self.msg) + msg = "Unable to retrieve device information for {0}. Please ensure that the device exists and is reachable.".format(device_ip) + self.log(msg, "ERROR") + self.module.fail_json(msg=msg) except Exception as e: # Log an error message if any exception occurs during the process @@ -565,7 +575,7 @@ def get_device_ids_from_site(self, site_name, site_id): "site_id": site_id, } - # Attempt to retrieve device information associated with the site + # Attempt to retrieve device information associated with the site try: response = self.dnac._exec( family="sites", @@ -629,8 +639,8 @@ def get_device_id_list(self, ip_address_list, site_name): site_mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) iplist_mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) mgmt_ip_instance_id_map = { - ip: instance_id - for ip, instance_id in iplist_mgmt_ip_instance_id_map.items() + ip: instance_id + for ip, instance_id in iplist_mgmt_ip_instance_id_map.items() if ip in site_mgmt_ip_instance_id_map } # If only site name is provided @@ -644,12 +654,29 @@ def get_device_id_list(self, ip_address_list, site_name): elif ip_address_list and not site_name: # Retrieve device IDs associated with devices having specified IP addresses mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) - + return mgmt_ip_instance_id_map - def is_sync_required(self, response): - task_name = 'Sync Device Configuration' + def is_sync_required(self, modified_response, mgmt_ip_instance_id_map): + """ + Determine if synchronization of device configurations is required. + Args: + modified_response (dict): A dictionary containing modified responses for each device. + mgmt_ip_instance_id_map (dict): A dictionary mapping management IP addresses to instance IDs. + + Returns: + tuple: A tuple containing a boolean indicating whether synchronization is required + and a message explaining the result. + + Note: + This method categorizes devices based on compliance status ('COMPLIANT', 'NON_COMPLIANT', 'OTHER') + and checks if synchronization is necessary. If all devices are 'COMPLIANT', synchronization is not + required. If there are devices that are not 'NON_COMPLIANT', synchronization is also not required. + """ + task_name = 'Sync Device Configuration' + required = True + msg = "" #Validate if sync is required #response = self.get_compliance_detail(compliance_detail_params_sync) self.log('Modified {0} Response for device(s) {1} : {2}'.format(task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), 'INFO') @@ -657,27 +684,29 @@ def is_sync_required(self, response): #Categorize the devices based on status - 'COMPLIANT', 'NON_COMPLIANT', 'OTHER'(status other than COMPLIANT and NON_COMPLIANT) categorized_devices = {'COMPLIANT': {}, 'NON_COMPLIANT': {}, 'OTHER': {}} for ip_address, compliance_type in modified_response.items(): - status = compliance_type[0]['status'] - if status == 'NON_COMPLIANT': - categorized_devices['NON_COMPLIANT'][ip_address] = compliance_type - elif status == 'COMPLIANT': - categorized_devices['COMPLIANT'][ip_address] = compliance_type - else: - categorized_devices['OTHER'][ip_address] = compliance_type + status = compliance_type[0]['status'] + if status == 'NON_COMPLIANT': + categorized_devices['NON_COMPLIANT'][ip_address] = compliance_type + elif status == 'COMPLIANT': + categorized_devices['COMPLIANT'][ip_address] = compliance_type + else: + categorized_devices['OTHER'][ip_address] = compliance_type + self.log("Devices Categorized based on Compliance status: {0}".format(categorized_devices), 'INFO') #Validate if all devices are 'COMPLIANT' - then sync not required if len(categorized_devices['COMPLIANT']) == len(mgmt_ip_instance_id_map): - self.msg = "Device(s) {0} are already compliant with the RUNNING_CONFIG compliance type. Therefore, {1} is not required.".format( + msg = "Device(s) {0} are already compliant with the RUNNING_CONFIG compliance type. Therefore, {1} is not required.".format( list(mgmt_ip_instance_id_map.keys()), task_name) - self.update_result('success', False, self.msg, 'INFO',categorized_devices) - return self + required = False elif len(categorized_devices['NON_COMPLIANT']) != len(mgmt_ip_instance_id_map): - self.msg = "The operation {0} cannot be performed on device(s) {1} because the status of the RUNNING_CONFIG compliance type is not as expected; it should be NON_COMPLIANT.".format( - task_name, list(mgmt_ip_instance_id_map.keys())) - self.update_result('failed', False, self.msg, 'INFO',categorized_devices) - - return self + required = False + msg = ( + "The operation {0} cannot be performed on one or more of the devices " + "{1} because the status of the RUNNING_CONFIG compliance type is not " + "as expected; it should be NON_COMPLIANT." + ).format(task_name, list(mgmt_ip_instance_id_map.keys())) + return required, msg def get_want(self, config): """ @@ -697,6 +726,7 @@ def get_want(self, config): sync_device_config_params = {} compliance_detail_params = {} compliance_detail_params_sync = {} + compliance_details = {} #Validate either ip_address_list OR site_name is present ip_address_list = config.get('ip_address_list') @@ -710,7 +740,9 @@ def get_want(self, config): #Validate valid ip_addresses if ip_address_list: self.validate_ip4_address_list(ip_address_list) - + #Remove Duplicates from list + ip_address_list = list(set(ip_address_list)) + # Retrieve device ID list mgmt_ip_instance_id_map = self.get_device_id_list(ip_address_list, site_name) if not mgmt_ip_instance_id_map: @@ -727,11 +759,13 @@ def get_want(self, config): sync_device_config = config.get('sync_device_config') if not run_compliance and not sync_device_config: - self.msg = "No actions were requested. This network compliance module can perform the following tasks: Run Compliance Check or Sync Device Config." - self.update_result('failed', False, self.msg, 'ERROR') + msg = "No actions were requested. This network compliance module can perform the following tasks: Run Compliance Check or Sync Device Config." + self.log(msg, 'ERROR') + self.module.fail_json(msg) return self if run_compliance: + self.validate_run_compliance(run_compliance) run_compliance_params = { 'triggerFull': config.get('run_compliance').get('trigger_full'), 'deviceUuids': list(mgmt_ip_instance_id_map.values()), @@ -745,7 +779,7 @@ def get_want(self, config): categories_copy = config.get('run_compliance').get('categories').copy() run_compliance_params['categories'] = categories_copy - compliance_types = config.get('run_compliance').get('categories') + compliance_types = config.get('run_compliance').get('categories') if 'INTENT' in compliance_types: compliance_types.remove('INTENT') compliance_types.extend(['NETWORK_PROFILE', 'APPLICATION_VISIBILITY', 'WORKFLOW', 'FABRIC', 'NETWORK_SETTINGS']) @@ -762,7 +796,13 @@ def get_want(self, config): 'deviceUuid': ','.join(list(mgmt_ip_instance_id_map.values())), 'complianceType': 'RUNNING_CONFIG' } - self.is_sync_required(compliance_detail_params_sync, mgmt_ip_instance_id_map) + response = self.get_compliance_detail(compliance_detail_params_sync) + compliance_details = self.modify_compliance_response(response, mgmt_ip_instance_id_map) + required, msg = self.is_sync_required(compliance_details, mgmt_ip_instance_id_map) + if not required: + self.log(msg, 'ERROR') + self.module.fail_json(msg) + return self # Construct the 'want' dictionary containing the desired state parameters want = {} @@ -773,42 +813,43 @@ def get_want(self, config): run_compliance_params=run_compliance_params, sync_device_config_params=sync_device_config_params, compliance_detail_params=compliance_detail_params, - compliance_detail_params_sync=compliance_detail_params_sync + compliance_detail_params_sync=compliance_detail_params_sync, + compliance_details=compliance_details ) self.want = want self.log("Desired State (want): {0}".format(str(self.want)), "INFO") return self - def get_have(self, config): - """ - Retrieve and store compliance details if sync_device_config is enabled. + # def get_have(self, config): + # """ + # Retrieve and store compliance details if sync_device_config is enabled. - Parameters: - config (dict): A dictionary containing configuration details. + # Parameters: + # config (dict): A dictionary containing configuration details. - Returns: - self (object): An instance of a class used for interacting with Cisco Catalyst Center. - Description: - In this method if sync_device_config is enabled, it proceeds to retrieve compliance details using the - specified parameters. The retrieved details are then modified and stored in the 'have' attribute for later reference. - Additionally, a log message is generated to indicate that the compliance details have been successfully retrieved - and stored. - """ - sync_device_config = config.get('sync_device_config') - have = {} + # Returns: + # self (object): An instance of a class used for interacting with Cisco Catalyst Center. + # Description: + # In this method if sync_device_config is enabled, it proceeds to retrieve compliance details using the + # specified parameters. The retrieved details are then modified and stored in the 'have' attribute for later reference. + # Additionally, a log message is generated to indicate that the compliance details have been successfully retrieved + # and stored. + # """ + # sync_device_config = config.get('sync_device_config') + # have = {} - if sync_device_config: - # Retrieve compliance details - response = self.get_compliance_detail(self.want.get('compliance_detail_params_sync')) - modified_response = self.modify_compliance_response(response, self.want.get('mgmt_ip_instance_id_map')) + # if sync_device_config: + # # Retrieve compliance details + # response = self.get_compliance_detail(self.want.get('compliance_detail_params_sync')) + # modified_response = self.modify_compliance_response(response, self.want.get('mgmt_ip_instance_id_map')) - # Store modified compliance details - have['compliance_details'] = modified_response - self.log("Compliance details have been retrieved and stored: {0}.".format(modified_response), "INFO") - self.is_sync_required(modified_response) - self.have = have - return self + # # Store modified compliance details + # have['compliance_details'] = modified_response + # self.log("Compliance details have been retrieved and stored: {0}.".format(modified_response), "INFO") + + # self.have = have + # return self def get_compliance_detail(self, compliance_detail_params): response = self.dnac_apply['exec']( @@ -841,8 +882,8 @@ def modify_compliance_response(self, response, mgmt_ip_instance_id_map): device_uuid = item.get('deviceUuid') # Find the corresponding management IP address for the device UUID - ip_address = next((ip for ip, uuid in mgmt_ip_instance_id_map.items() if uuid == device_uuid), None) - + ip_address = next((ip for ip, uuid in mgmt_ip_instance_id_map.items() if uuid == device_uuid)) + # If the IP address is found, add the item to the modified response #if ip_address and item.get('status')!= 'NOT_APPLICABLE': if ip_address: @@ -927,7 +968,7 @@ def get_task_status(self, task_id, task_name): If an error occurs during the API call, it will be caught and logged. """ - # Make an API call to retrieve the task status + # Make an API call to retrieve the task tree try: response = self.dnac_apply['exec']( family="task", @@ -936,12 +977,42 @@ def get_task_status(self, task_id, task_name): op_modifies=True, ) response = response.response - self.log("Task status for the task id {0} is {1}, is_error: {2}".format(str(task_id), str(response), str(response.get('isError'))), "INFO") + self.log("Task status for the Task {0} with Task id {1} is {2}".format(task_name, str(task_id), str(response)), "INFO") + return response + + # Log the error if an exception occurs during the API call + except Exception as e: + self.log("Error occurred while retrieving task status for Task {0} with Task id {1}: {2}".format(task_name, task_id, str(e)), "ERROR") + return None + + def get_task_tree(self, task_id, task_name): + """ + Retrieve the tree of a task by its ID. + Parameters: + - task_id (str): The ID of the task whose status is to be retrieved. + - task_name (str): The name of the task. + Returns: + response (dict): The response containing the status of the task. + Note: + This method makes an API call to retrieve the task status and logs the status information. + If an error occurs during the API call, it will be caught and logged. + """ + + # Make an API call to retrieve the task status + try: + response = self.dnac_apply['exec']( + family="task", + function='get_task_tree', + params=dict(task_id=task_id), + op_modifies=True, + ) + response = response.response + self.log("Task tree for the Task {0} with Task id {1} is {2}".format(task_name, str(task_id), str(response)), "INFO") return response # Log the error if an exception occurs during the API call except Exception as e: - self.log("Error occurred while retrieving task status for task id {0}: {1}".format(task_id, str(e)), "ERROR") + self.log("Error occurred while retrieving task tree for Task {0} with task id {1}: {2}".format(task_name, task_id, str(e)), "ERROR") return None def update_result(self, status, changed, msg, log_level, data=None): @@ -964,14 +1035,14 @@ def update_result(self, status, changed, msg, log_level, data=None): self.status = status self.result['status'] = status self.result['msg'] = msg - self.result['changed'] = changed + self.result['changed'] = changed # Log the message at the specified log level self.log(msg, log_level) # If the status is 'failed', set the 'failed' key to True if status == 'failed': - self.result['failed'] = True + self.result['failed'] = True # If additional data is provided, include it in the result dictionary if data: @@ -995,17 +1066,17 @@ def exit_while_loop(self, start_time, task_id, task_name, response): if time.time() - start_time > 360: if response.get('data'): # If there is data in the response, include it in the error message - self.msg = "Task {0} with task id {1} has not completed within the timeout period. Task Status: {2} ".format( + msg = "Task {0} with task id {1} has not completed within the timeout period. Task Status: {2} ".format( task_name, task_id, response.get('data')) else: # If there is no data in the response, generate a generic error message - self.msg = "Task {0} with task id {1} has not completed within the timeout period.".format( + msg = "Task {0} with task id {1} has not completed within the timeout period.".format( task_name, task_id) # Update the result with failure status and log the error message - self.update_result('failed', False, self.msg, 'ERROR') + self.update_result('failed', False, msg, 'ERROR') return True - return False + return False def handle_error(self, task_name, mgmt_ip_instance_id_map, failure_reason=None): """ @@ -1053,14 +1124,14 @@ def get_compliance_task_status(self, task_id, mgmt_ip_instance_id_map): # Check if response returned if not response: - self.msg = 'Error retrieving Task status for the task_name {0} task_id {1}'.format() + self.msg = 'Error retrieving Task status for the Task {0} with Task Id: {1}'.format(task_name, task_id) self.update_result('failed', False, self.msg, 'ERROR') break # Check if the elapsed time exceeds the timeout if self.exit_while_loop(start_time, task_id, task_name, response): break - + # Handle error if task execution encounters an error if response.get('isError'): failure_reason = response.get("failureReason") @@ -1071,12 +1142,12 @@ def get_compliance_task_status(self, task_id, mgmt_ip_instance_id_map): elif not response.get('isError') and 'success' in response.get('progress').lower(): # Task completed successfully self.msg = "{0} has completed successfully on device(s): {1}".format(task_name, list(mgmt_ip_instance_id_map.keys())) - + # Retrieve and modify compliance check details response = self.get_compliance_detail(self.want.get('compliance_detail_params')) modified_response = self.modify_compliance_response(response, mgmt_ip_instance_id_map) self.log('Modified {0} Response for device(s) {1} : {2}'.format(task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), 'INFO') - + # Update result with modified response self.update_result('success', True, self.msg, 'INFO', modified_response) break @@ -1089,7 +1160,7 @@ def get_compliance_task_status(self, task_id, mgmt_ip_instance_id_map): return self - def sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): + def get_sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): """ This function manages the status of device configuration synchronization tasks in Cisco Catalyst Center. Parameters: @@ -1104,81 +1175,58 @@ def sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): """ task_name = 'Sync Device Configuration' - - - - #Start Sync Operation start_time = time.time() - while True: - response = self.get_task_status(task_id, task_name) + while True: + response = self.get_task_tree(task_id, task_name) # Check if response returned if not response: - self.msg = 'Error retrieving Task status for the task_name {0} task_id {1}'.format() + self.msg = 'Error retrieving Task Tree for the task_name {0} task_id {1}'.format(task_name, task_id) self.update_result('failed', False, self.msg, 'ERROR') break # Check if the elapsed time exceeds the timeout - # if self.exit_while_loop(start_time, task_id, task_name, response): - # break + if self.exit_while_loop(start_time, task_id, task_name, response): + break # Handle error if task execution encounters an error - if response.get('isError'): + if response[0].get('isError'): failure_reason = response.get("failureReason") self.handle_error(task_name, mgmt_ip_instance_id_map, failure_reason) break + success_devices = [] + failed_devices = [] - elif len(mgmt_ip_instance_id_map) == 1: - ip_address = next(iter(mgmt_ip_instance_id_map)) - progress = response.get('progress', '').lower() - if not response.get('isError') and 'success' in progress: - self.log("Task {0} with task id {1} has completed successfully on device {2}.".format( - task_name, task_id, ip_address), "INFO") - self.msg = "{0} has completed successfully on device: {1}".format(task_name, ip_address) - self.update_result('success', True, self.msg, 'INFO') - break + for item in response[1:]: + progress = item['progress'] + for ip, device_id in mgmt_ip_instance_id_map.items(): + if device_id in progress and "copy_Running_To_Startup=Success" in progress: + success_devices.append(ip) + elif device_id in progress and "copy_Running_To_Startup=Failed" in progress: + failed_devices.append(ip) - elif 'failed' in progress: - self.log('Task {0} with task id {1} has failed on device {2}.'.format( - task_name, task_id, ip_address), "CRITICAL") + success_devices = set(success_devices) + failed_devices = set(failed_devices) + + # Check conditions and print messages accordingly + if len(set(success_devices)) == len(mgmt_ip_instance_id_map): + self.msg = "{0} has completed successfully on device(s): {2}".format(task_id, success_devices) + self.update_result('success', True, self.msg, 'INFO') + break + elif (failed_devices and + len(success_devices) < len(mgmt_ip_instance_id_map) and + len(failed_devices) + len(success_devices) == len(mgmt_ip_instance_id_map)): + self.msg = "{0} has failed on device(s): {2} and succeeded on device(s): {3}".format( + task_id, failed_devices, success_devices) + self.update_result('failed', True, self.msg, 'CRITICAL') + break + elif len(failed_devices) == len(mgmt_ip_instance_id_map): + self.msg = "{0} has failed on device(s): {2}".format(task_id, failed_devices) + self.update_result('failed', False, self.msg, 'CRITICAL') + break - self.msg = "Failed to {0} on the following device(s):".format(task_name, ip_address) - self.update_result('failed', False, self.msg, 'CRITICAL') - break - - elif len(mgmt_ip_instance_id_map) > 1: - data = response.get('data') - if data: - count_values = [count.strip() for count in data.split(',')] - success_count = int(count_values[0].split('=')[1]) - running_count = int(count_values[2].split('=')[1]) - pending_count = int(count_values[3].split('=')[1]) - total_count = int(count_values[-1].split('=')[1]) - - if success_count == len(mgmt_ip_instance_id_map): - self.log("Task {0} with task id {1} has completed successfully on devices: {2}.".format( - task_name, task_id, list(mgmt_ip_instance_id_map.keys())), "INFO") - - self.msg = "{0} has completed successfully on devices: {1}".format(task_name, list(mgmt_ip_instance_id_map.keys())) - self.update_result('success', True, self.msg, 'INFO') - break - - elif running_count == 0 and pending_count == 0 and success_count < len(mgmt_ip_instance_id_map): - status_info = {'Success': {'count': success_count, 'devices': []}, 'Failed': {'count': failure_count, 'devices': []}} - device_actions = response['progress'].split(',') - for action in device_actions: - device_id = action.split('=')[1].strip() - ip_address = next((ip for ip, device_id_map in mgmt_ip_instance_id_map.items() if device_id_map == device_id), None) - if ip_address: - if 'Success' in action: - status_info['Success']['devices'].append({'ip_address': ip_address, 'device_id': device_id}) - elif 'Failed' in action: - status_info['Failure']['devices'].append({'ip_address': ip_address, 'device_id': device_id}) - self.msg = 'Task {0} status: {1}'.format(task_name, status_info) - self.update_result('failed', True, self.msg, 'CRITICAL') - break return self def get_diff_merged(self): @@ -1195,24 +1243,23 @@ def get_diff_merged(self): # Action map for different network compliance operations action_map = { 'run_compliance_params': (self.run_compliance, self.get_compliance_task_status), - 'sync_device_config_params': (self.sync_device_config, self.sync_config_task_status) + 'sync_device_config_params': (self.sync_device_config, self.get_sync_config_task_status) } - # Iterate through the action map and execute specified actions + #Iterate through the action map and execute specified actions for action_param, (action_func, status_func) in action_map.items(): # Execute the action and check its status if self.want.get(action_param): result_task_id = action_func(self.want.get(action_param)) - self.log("Performing {0}".format(action_func), 'DEBUG') + self.log("Performing {0}".format(action_func.__name__), 'DEBUG') if not result_task_id: - self.msg = "An error occurred while retrieving the task_id for the {0} operation.".format(action_func) + self.msg = "An error occurred while retrieving the task_id of the {0} operation.".format(action_func.__name__) self.update_result('failed', False, self.msg, 'CRITICAL') else: status_func(result_task_id, self.want.get('mgmt_ip_instance_id_map')).check_return_status() - return self - + def verify_diff_merged(self, config): """ Verify the success of the 'Sync Device Configuration' operation. @@ -1228,7 +1275,7 @@ def verify_diff_merged(self, config): """ if config.get('sync_device_config'): # Get compliance details before running sync_device_config - compliance_details_before = self.have.get('compliance_details') + compliance_details_before = self.want.get('compliance_details') self.log("Compliance details before running sync_device_config: {0}".format(compliance_details_before), "INFO") @@ -1241,8 +1288,8 @@ def verify_diff_merged(self, config): all_statuses_before = [] all_statuses_after = [] for ip_address, compliance_type in compliance_details_before.items(): - status = compliance_type[0]['status'] - all_statuses_before.append(status) + status = compliance_type[0]['status'] + all_statuses_before.append(status) if len(set(all_statuses_before)) == 1 and all_statuses_before[0] == 'NON_COMPLIANT': for ip_address, compliance_type in compliance_details_after.items(): @@ -1251,27 +1298,13 @@ def verify_diff_merged(self, config): if len(set(all_statuses_after)) == 1 and all_statuses_after[0] == 'COMPLIANT': self.log('Verified the success of the Sync Device Configuration operation.') else: - self.log("Sync Device Configuration operation may have been unsuccessful since not all devices have 'COMPLIANT' status after the operation.", "WARNING") + self.log("Sync Device Configuration operation may have been unsuccessful since " + "not all devices have 'COMPLIANT' status after the operation.", + "WARNING") else: self.log("Sync_device_config may not have been performed since devices have status other than 'NON_COMPLIANT'.", "WARNING") - - - - - # # Check if 'RUNNING_CONFIG' status of all devices was 'NON_COMPLIANT' before sync_device_config - # all_statuses_before = [device['status'] for devices in compliance_details_before.values() for device in devices] - # if len(set(all_statuses_before)) == 1 and all_statuses_before[0] == 'NON_COMPLIANT': - # # Check if all devices are compliant after sync_device_config - # all_statuses_after = [device['status'] for devices in compliance_details_after.values() for device in devices] - # if len(set(all_statuses_after)) == 1 and all_statuses_after[0] == 'COMPLIANT': - # self.log('Verified the success of the Sync Device Configuration operation.') - # else: - # self.log("Sync Device Configuration operation may have been unsuccessful since not all devices have 'COMPLIANT' status after the operation.", "WARNING") - # else: - # self.log("Sync_device_config may not have been performed since devices have status other than 'NON_COMPLIANT'.", "WARNING") - return self - + def main(): """ main entry point for module execution """ @@ -1321,10 +1354,9 @@ def main(): # Iterate over the validated configuration parameters for config in ccc_network_compliance.validated_config: ccc_network_compliance.get_want(config).check_return_status() - ccc_network_compliance.get_have(config).check_return_status() ccc_network_compliance.get_diff_state_apply[state]().check_return_status() if config_verify: - ccc_network_compliance.verify_diff_state_apply[state](config).check_return_status() + ccc_network_compliance.verify_diff_state_apply[state](config).check_return_status() # Exit with the result obtained from the NetworkCompliance object module.exit_json(**ccc_network_compliance.result) From 44433de44fc728863fa88f472ff22ef9d2294451 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 29 Apr 2024 23:28:07 -0400 Subject: [PATCH 296/358] network compliance module --- plugins/modules/network_compliance_workflow_manager.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 4111903e8c..f2e1a7624d 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -1212,18 +1212,18 @@ def get_sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): # Check conditions and print messages accordingly if len(set(success_devices)) == len(mgmt_ip_instance_id_map): - self.msg = "{0} has completed successfully on device(s): {2}".format(task_id, success_devices) + self.msg = "{0} has completed successfully on device(s): {1}".format(task_name, success_devices) self.update_result('success', True, self.msg, 'INFO') break elif (failed_devices and len(success_devices) < len(mgmt_ip_instance_id_map) and len(failed_devices) + len(success_devices) == len(mgmt_ip_instance_id_map)): - self.msg = "{0} has failed on device(s): {2} and succeeded on device(s): {3}".format( - task_id, failed_devices, success_devices) + self.msg = "{0} task has failed on device(s): {1} and succeeded on device(s): {2}".format( + task_name, failed_devices, success_devices) self.update_result('failed', True, self.msg, 'CRITICAL') break elif len(failed_devices) == len(mgmt_ip_instance_id_map): - self.msg = "{0} has failed on device(s): {2}".format(task_id, failed_devices) + self.msg = "{0} task has failed on device(s): {1}".format(task_name, failed_devices) self.update_result('failed', False, self.msg, 'CRITICAL') break From 4e44f2323fcfd3962d12a0c7982fe1974812e888 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 29 Apr 2024 23:31:22 -0400 Subject: [PATCH 297/358] removed .circleci and integration tests --- .circleci/config.yml | 365 ------------- .../defaults/main.yml | 5 - .../meta/main.yml | 1 - .../tasks/main.yml | 34 -- .../tests/test_assign_credentials.yml | 189 ------- .../test_device_credential_management.yml | 125 ----- .../vars/vars_assign_credentials.yml | 61 --- .../vars/vars_credential_management.yml | 102 ---- .../defaults/main.yml | 2 - .../ccc_discovery_management/meta/main.yml | 1 - .../ccc_discovery_management/tasks/main.yml | 34 -- .../tests/test_discovery_management.yml | 286 ---------- .../vars/vars_discovery_management.yml | 164 ------ .../vars/vars_misc.yml | 14 - .../defaults/main.yml | 2 - .../ccc_inventory_management/meta/main.yml | 1 - .../ccc_inventory_management/tasks/main.yml | 34 -- .../tests/test_inventory_management.yml | 492 ------------------ .../vars/vars_inventory_management.yml | 268 ---------- .../defaults/main.yml | 2 - .../meta/main.yml | 1 - .../tasks/main.yml | 34 -- .../test_network_compliance_management.yml | 112 ---- .../vars_network_compliance_management.yml | 3 - .../tests/test_pnp_management.yml | 226 -------- .../vars/vars_pnp_management.yml | 56 -- .../ccc_site_management/defaults/main.yml | 2 - .../ccc_site_management/meta/main.yml | 1 - .../ccc_site_management/tasks/main.yml | 34 -- .../tests/test_site_management.yml | 121 ----- .../vars/vars_site_management.yml | 457 ---------------- .../ccc_swim_management/defaults/main.yml | 2 - .../ccc_swim_management/meta/main.yml | 1 - .../ccc_swim_management/tasks/main.yml | 34 -- .../tests/test_swim_management.yml | 313 ----------- .../vars/vars_swim_management.yml | 122 ----- 36 files changed, 3701 deletions(-) delete mode 100644 .circleci/config.yml delete mode 100644 tests/integration/ccc_device_credential_management/defaults/main.yml delete mode 100644 tests/integration/ccc_device_credential_management/meta/main.yml delete mode 100644 tests/integration/ccc_device_credential_management/tasks/main.yml delete mode 100644 tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml delete mode 100644 tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml delete mode 100644 tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml delete mode 100644 tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml delete mode 100644 tests/integration/ccc_discovery_management/defaults/main.yml delete mode 100644 tests/integration/ccc_discovery_management/meta/main.yml delete mode 100644 tests/integration/ccc_discovery_management/tasks/main.yml delete mode 100644 tests/integration/ccc_discovery_management/tests/test_discovery_management.yml delete mode 100644 tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml delete mode 100644 tests/integration/ccc_discovery_management/vars/vars_misc.yml delete mode 100644 tests/integration/ccc_inventory_management/defaults/main.yml delete mode 100644 tests/integration/ccc_inventory_management/meta/main.yml delete mode 100644 tests/integration/ccc_inventory_management/tasks/main.yml delete mode 100644 tests/integration/ccc_inventory_management/tests/test_inventory_management.yml delete mode 100644 tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml delete mode 100644 tests/integration/ccc_network_compliance_management/defaults/main.yml delete mode 100644 tests/integration/ccc_network_compliance_management/meta/main.yml delete mode 100644 tests/integration/ccc_network_compliance_management/tasks/main.yml delete mode 100644 tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml delete mode 100644 tests/integration/ccc_network_compliance_management/vars/vars_network_compliance_management.yml delete mode 100644 tests/integration/ccc_pnp_management/tests/test_pnp_management.yml delete mode 100644 tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml delete mode 100644 tests/integration/ccc_site_management/defaults/main.yml delete mode 100644 tests/integration/ccc_site_management/meta/main.yml delete mode 100644 tests/integration/ccc_site_management/tasks/main.yml delete mode 100644 tests/integration/ccc_site_management/tests/test_site_management.yml delete mode 100644 tests/integration/ccc_site_management/vars/vars_site_management.yml delete mode 100644 tests/integration/ccc_swim_management/defaults/main.yml delete mode 100644 tests/integration/ccc_swim_management/meta/main.yml delete mode 100644 tests/integration/ccc_swim_management/tasks/main.yml delete mode 100644 tests/integration/ccc_swim_management/tests/test_swim_management.yml delete mode 100644 tests/integration/ccc_swim_management/vars/vars_swim_management.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 7e06379335..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,365 +0,0 @@ -version: 2.1 - -setup: << pipeline.parameters.run-setup >> - -orbs: - path-filtering: circleci/path-filtering@0.1.6 - -parameters: - run-setup: - type: boolean - default: true - run-any: - type: boolean - default: false - run-all: - type: boolean - default: false - run-site: - type: boolean - default: false - run-devicecredential: - type: boolean - default: false - run-discovery: - type: boolean - default: false - run-inventory: - type: boolean - default: false - run-swim: - type: boolean - default: false - run-pnp: - type: boolean - default: false - -jobs: - - pre: - parameters: - ansible_cisco_dnac_version: - type: string - default: "6.13.2" - - machine: true - resource_class: rukapse/dnacenter-ansible - - environment: - CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> - CIRCLE_PROJECT_BRANCHNAME: << pipeline.trigger_parameters.github_app.branch >> - - steps: - - run: - name: Debug information for pre - command: | - set -x - echo "REPO_URL: $REPO_URL" - echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" - echo "CIRCLE_PROJECT_BRANCHNAME: $CIRCLE_PROJECT_BRANCHNAME" - env - - run: - name: Remove existing directory and collection tarball - command: | - set -x - rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME - rm -rf ${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/ - - build: - parameters: - ansible_cisco_dnac_version: - type: string - default: "6.13.2" - - machine: true - resource_class: rukapse/dnacenter-ansible - working_directory: ~/repo - - environment: - REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> - CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> - CIRCLE_PROJECT_BRANCHNAME: << pipeline.trigger_parameters.github_app.branch >> - - steps: - - run: - name: Debug information - command: | - set -x - echo "REPO_URL: $REPO_URL" - echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" - echo "CIRCLE_PROJECT_BRANCHNAME: $CIRCLE_PROJECT_BRANCHNAME" - env - - - run: - name: Custom Git Clone - command: git clone --depth=1 -b $CIRCLE_PROJECT_BRANCHNAME $REPO_URL - - - run: - name: Create Roles File header - command: | - echo "---" > ccc_roles.yml - echo "- hosts: dnac_servers" >> ccc_roles.yml - echo " gather_facts: no" >> ccc_roles.yml - echo " connection: local" >> ccc_roles.yml - echo " " >> ccc_roles.yml - echo " tasks:" >> ccc_roles.yml - echo " " >> ccc_roles.yml - echo " vars:" >> ccc_roles.yml - echo " debug: false" >> ccc_roles.yml - echo " " >> ccc_roles.yml - echo " roles:" >> ccc_roles.yml - - cat ccc_roles.yml - - - run: - name: Copy static files - command: | - mkdir -p group_vars - cp ${HOME}/static/group_vars/dnac_servers.yml group_vars/dnac_servers.yml - cp ${HOME}/static/hosts hosts - - - run: - name: Activate Virtual Environment, Install ansible and Build collection tarball - command: | - set -x - # Activate Virtual Environment - pyenv local ansible - export PYENV_ROOT="$HOME/.pyenv" - export PATH="$PYENV_ROOT/bin:$PATH" - export PATH="$PYENV_ROOT/shims/python3:$PATH" - export PATH="$PYENV_ROOT/shims/python:$PATH" - export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" - export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" - - # Install ansible, dnacentersdk - pip install --upgrade pip - pip install jinja2 PyYAML cryptography paramiko - pip install pyzipper - pip install ansible - pip install dnacentersdk - ansible --version - - # Change directory to dnacenter-ansible - cd $HOME/repo/dnacenter-ansible - - # Build collection and store resulting tarball in directory $HOME/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs - ansible-galaxy collection build --force --output-path "${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs" - - - run: - name: Remove Existing Directory - command: | - set -x - rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME - - addrole: - machine: true - resource_class: rukapse/dnacenter-ansible - working_directory: ~/repo - - steps: - - when: - condition: - or: [ << pipeline.parameters.run-site >>, << pipeline.parameters.run-all >> ] - steps: - - run: - command: | - echo " - ccc_site_management" >> ccc_roles.yml - - - when: - condition: - or: [ << pipeline.parameters.run-devicecredential >>, << pipeline.parameters.run-all >> ] - steps: - - run: - command: | - echo " - ccc_device_credential_management" >> ccc_roles.yml - - - when: - condition: - or: [ << pipeline.parameters.run-discovery >>, << pipeline.parameters.run-all >> ] - steps: - - run: - command: | - echo " - ccc_discovery_management" >> ccc_roles.yml - - - when: - condition: - or: [ << pipeline.parameters.run-inventory >>, << pipeline.parameters.run-all >> ] - steps: - - run: - command: | - echo " - ccc_inventory_management" >> ccc_roles.yml - - - when: - condition: - or: [ << pipeline.parameters.run-swim >>, << pipeline.parameters.run-all >> ] - steps: - - run: - command: | - echo " - ccc_swim_management" >> ccc_roles.yml - - - - when: - condition: - or: [ << pipeline.parameters.run-pnp >>, << pipeline.parameters.run-all >> ] - steps: - - run: - command: | - echo " - ccc_pnp_management" >> ccc_roles.yml - - - - run: - command: cat ccc_roles.yml - - sanity-tests: - parameters: - ansible_cisco_dnac_version: - type: string - default: "6.13.2" - - machine: true - resource_class: rukapse/dnacenter-ansible - working_directory: ~/repo - - environment: - REPO_URL: << pipeline.trigger_parameters.github_app.repo_url >> - CIRCLE_PROJECT_REPONAME: << pipeline.trigger_parameters.github_app.repo_name >> - CIRCLE_PROJECT_BRANCHNAME: << pipeline.trigger_parameters.github_app.branch >> - - steps: - - run: - name: Debug information - command: | - set -x - echo "REPO_URL: $REPO_URL" - echo "CIRCLE_PROJECT_REPONAME: $CIRCLE_PROJECT_REPONAME" - echo "CIRCLE_PROJECT_BRANCHNAME: $CIRCLE_PROJECT_BRANCHNAME" - env - - - run: - name: Custom Git Clone - command: git clone --depth=1 -b $CIRCLE_PROJECT_BRANCHNAME $REPO_URL - - - run: - name: Activate Virtual Environment, Install ansible and Build collection tarball - command: | - set -x - # Activate Virtual Environment - pyenv local ansible - export PYENV_ROOT="$HOME/.pyenv" - export PATH="$PYENV_ROOT/bin:$PATH" - export PATH="$PYENV_ROOT/shims/python3:$PATH" - export PATH="$PYENV_ROOT/shims/python:$PATH" - export PYTHONPATH="$PYENV_ROOT/shims/python3:$PYTHONPATH" - export PYTHONPATH="$PYENV_ROOT/shims/python:$PYTHONPATH" - - export PATH="$HOME/.ansible/collections/:$PATH" - export PYTHONPATH="$HOME/.ansible/collections/:$PYTHONPATH" - - # Install ansible, dnacentersdk - pip install --upgrade pip - pip install jinja2 PyYAML cryptography paramiko - pip install pyzipper - pip install ansible - pip install dnacentersdk - ansible --version - - environment: - PYTHONPATH: $HOME/.ansible/collections/:$PYTHONPATH - - - run: - name: Install the collection tarball - command: | - set -x - pyenv versions - python --version - ansible --version - - ansible-galaxy collection install --force ${HOME}/.cache/v<< parameters.ansible_cisco_dnac_version >>/collection-tarballs/*.tar.gz - - - run: - name: Run sanity tests - command: | - export ANSIBLE_PERSISTENT_CONNECT_TIMEOUT=1000 - export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=1000 - export ANSIBLE_ROLES_PATH=/home/circleci/repo/dnacenter-ansible/tests/integration - - ansible-playbook -i hosts ccc_roles.yml - - no_output_timeout: 120m - - - run: - name: Remove Existing Directory - command: | - set -x - rm -rf ${HOME}/repo/$CIRCLE_PROJECT_REPONAME - - post_pnp_testing: - machine: true - resource_class: rukapse/dnacenter-ansible - working_directory: ~/repo - - steps: - - when: - condition: << pipeline.parameters.run-pnp >> - steps: - - run: - command: | - python ${HOME}/static/pnp_script.py - -workflows: - - pre-testing: - when: << pipeline.parameters.run-setup >> - jobs: - - pre - - - build: - matrix: - parameters: - ansible_cisco_dnac_version: - - "6.13.2" - requires: - - pre - - - path-filtering/filter: - requires: - - build - base-revision: main - config-path: .circleci/config.yml - mapping: | - .* run-setup false - - plugins/.* run-any true - tests/integration/.* run-any true - - plugins/module_utils/.* run-all true - - plugins/modules/site_workflow_manager.py run-site true - plugins/modules/device_credential_workflow_manager.py run-devicecredential true - plugins/modules/discovery_workflow_manager.py run-discovery true - plugins/modules/inventory_workflow_manager.py run-inventory true - plugins/modules/swim_workflow_manager.py run-swim true - plugins/modules/pnp_workflow_manager.py run-pnp true - - tests/integration/ccc_site_management/.* run-site true - tests/integration/ccc_device_credential_management/.* run-devicecredential true - tests/integration/ccc_discovery_management/.* run-discovery true - tests/integration/ccc_inventory_management/.* run-inventory true - tests/integration/ccc_swim_management/.* run-swim true - tests/integration/ccc_pnp_management/.* run-pnp true - - integration-testing: - when: << pipeline.parameters.run-any >> - jobs: - - addrole - - - sanity-tests: - requires: - - addrole - matrix: - parameters: - ansible_cisco_dnac_version: - - "6.13.2" - # - post_pnp_testing: - # requires: - # - sanity-tests diff --git a/tests/integration/ccc_device_credential_management/defaults/main.yml b/tests/integration/ccc_device_credential_management/defaults/main.yml deleted file mode 100644 index e453cb74ee..0000000000 --- a/tests/integration/ccc_device_credential_management/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -testcase: "*" - -debug: - msg: "{{ testcase }}" \ No newline at end of file diff --git a/tests/integration/ccc_device_credential_management/meta/main.yml b/tests/integration/ccc_device_credential_management/meta/main.yml deleted file mode 100644 index 5514b6a40c..0000000000 --- a/tests/integration/ccc_device_credential_management/meta/main.yml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_device_credential_management/tasks/main.yml b/tests/integration/ccc_device_credential_management/tasks/main.yml deleted file mode 100644 index 09e0832ca2..0000000000 --- a/tests/integration/ccc_device_credential_management/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: collect ccc test cases - find: - paths: "{{ role_path }}/tests" - patterns: "{{ testcase }}.yml" - connection: local - register: ccc_cases - tags: sanity - -- debug: - msg: "CCC Cases: {{ ccc_cases }}" - -- set_fact: - test_cases: - files: "{{ ccc_cases.files }}" - tags: sanity - -- debug: - msg: "Test Cases: {{ test_cases }}" - -- name: set test_items - set_fact: - test_items: "{{ test_cases.files | map(attribute='path') | list }}" - tags: sanity - -- debug: - msg: "Test Items: {{ test_items }}" - -- name: run test cases (connection=httpapi) - include_tasks: "{{ test_case_to_run }}" - loop: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml b/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml deleted file mode 100644 index 5bc730ed29..0000000000 --- a/tests/integration/ccc_device_credential_management/tests/test_assign_credentials.yml +++ /dev/null @@ -1,189 +0,0 @@ ---- -- debug: msg="Starting device credential assign management test" -- debug: msg="Role Path {{ role_path }}" - -- block: - - name: Load vars and declare dnac vars - include_vars: - file: "{{ role_path }}/vars/vars_assign_credentials.yml" - name: vars_map - vars: - dnac_login: &dnac_login - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG - config_verify: true - - # - debug: - # msg: "{{ vars_map.credentials_details }}" - # - debug: - # msg: "{{ vars_map.design_sites }}" - -############################################# -# Pre Tests Clean Up # -############################################# - - - name: Clean up site before test - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.design_sites }}" - - - name: Clean up device credentials before test - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - -############################################# -# CREATE SITE # -############################################# - - - name: Create sites from design_sites config - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - register: result_create_site - loop: "{{ vars_map.design_sites }}" - tags: merged - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_site.results }}" - # when: result_create_site is defined - - - name: Assert area creation success for each site - assert: - that: - - item.changed == true - - item.response.status == "SUCCESS" - - "'created successfully' in item.msg" - loop: "{{ result_create_site.results }}" - when: result_create_site is defined - -############################################# -# Create Credentials # -############################################# - - - name: Create Credentials - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - tags: merged - register: result_create_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_credentials.results }}" - # when: result_create_credentials is defined - - - name: Assert Device Credential Creation - assert: - that: - - item.changed == true - - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" - - item.response[0].globalCredential.Validation == "Success" - loop: "{{ result_create_credentials.results }}" - when: result_create_credentials is defined - -############################################# -# Assign Credentials to site # -############################################# - - - name: Assign Credentials to design_sites - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_assign }}" - tags: assign - register: result_assign_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_assign_credentials.results }}" - # when: result_assign_credentials is defined - - - name: Assert assign Credentials to sites - assert: - that: - - item.changed == true - - "'Device Credential Assigned to a site is Successfully' in item.response[0].assignCredential['Assign Credentials'].msg" - loop: "{{ result_assign_credentials.results }}" - when: result_assign_credentials is defined - -############################################# -# DELETE SITE # -############################################# - - - name: Delete site from design_sites config - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - register: result_delete_site - loop: "{{ vars_map.design_sites }}" - tags: deleted - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_site.results }}" - # when: result_delete_site is defined - - - name: Assert deletion of area success for each site - assert: - that: - - item.changed == true - - "'deleted successfully' in item.response" - loop: "{{ result_delete_site.results }}" - when: result_delete_site is defined - -############################################# -# Delete Credentials # -############################################# - - - name: Delete Credentials - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - tags: deleted - register: result_delete_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_credentials.results }}" - # when: result_delete_credentials is defined - - - name: Assert Global Credential Deletion - assert: - that: - - item.changed == true - - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" - - item.response[0].globalCredential.Validation == "Success" - loop: "{{ result_delete_credentials.results }}" - when: result_delete_credentials is defined diff --git a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml b/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml deleted file mode 100644 index f4f9af6f3e..0000000000 --- a/tests/integration/ccc_device_credential_management/tests/test_device_credential_management.yml +++ /dev/null @@ -1,125 +0,0 @@ ---- -- debug: msg="Starting device credential management test" -- debug: msg="Role Path {{ role_path }}" - -- block: - - name: Load vars and declare dnac vars - include_vars: - file: "{{ role_path }}/vars/vars_credential_management.yml" - name: vars_map - vars: - dnac_login: &dnac_login - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG - config_verify: true - - # - debug: - # msg: "{{ vars_map.credentials_details }}" - # - debug: - # msg: "{{ vars_map.credentials_update }}" - -############################################# -# Pre Tests Clean Up # -############################################# - - - name: Clean up device credentials before test - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - -############################################# -# Create Credentials # -############################################# - - - name: Create Credentials - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - tags: merged - register: result_create_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_credentials.results }}" - # when: result_create_credentials is defined - - - name: Assert Device Credential Creation - assert: - that: - - item.changed == true - - "'Created Successfully' in item.response[0].globalCredential.Creation.msg" - - item.response[0].globalCredential.Validation == "Success" - loop: "{{ result_create_credentials.results }}" - when: result_create_credentials is defined - -############################################# -# Update Credentials # -############################################# - - - name: Update Credentials - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_update }}" - tags: update - register: result_update_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_credentials.results }}" - # when: result_update_credentials is defined - - - name: Assert Device Credential Update - assert: - that: - - item.changed == true - - "'Updated Successfully' in item.response[0].globalCredential.Updation.msg" - - item.response[0].globalCredential.Validation == "Success" - loop: "{{ result_update_credentials.results }}" - when: result_update_credentials is defined - -############################################# -# Delete Credentials # -############################################# - - - name: Delete Credentials - cisco.dnac.device_credential_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - with_list: "{{ vars_map.credentials_details }}" - tags: deleted - register: result_delete_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_credentials.results }}" - # when: result_delete_credentials is defined - - - name: Assert Device Credential Deletion - assert: - that: - - item.changed == true - - "'Deleted Successfully' in item.response[0].globalCredential.Deletion.msg" - - item.response[0].globalCredential.Validation == "Success" - loop: "{{ result_delete_credentials.results }}" - when: result_delete_credentials is defined diff --git a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml b/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml deleted file mode 100644 index 2c35a63ea6..0000000000 --- a/tests/integration/ccc_device_credential_management/vars/vars_assign_credentials.yml +++ /dev/null @@ -1,61 +0,0 @@ ---- -design_sites: - - site: - area: - name: TEST_SITE_DEVICE_CREDENTIALS - parent_name: 'Global' - site_type: area - - -credentials_details: - - global_credential_details: - cli_credential: - - description: CLIAssign - username: cli-A - password: "5!meh" - enable_password: "q4^t^" - snmp_v2c_read: - - description: SNMPv2cRead Test Assign - read_community: "j5aj#0z%" - snmp_v2c_write: - - description: SNMPv2cWrite Test Assign - write_community: "n2!y9k38" - snmp_v3: - - description: SNMPv3 Test Assign - auth_password: "hp!x6px&#@2xi5" - auth_type: SHA - snmp_mode: AUTHPRIV - privacy_password: "ai7tpci3j@*j5g" - privacy_type: AES128 - username: admin - https_read: - - description: httpsRead Test Assign - username: admin - password: "2!x85yvqz*7" - port: 443 - https_write: - - description: httpsWrite Test Assign - username: admin - password: "j@5wgm%s5g%" - port: 443 - - -credentials_assign: - - assign_credentials_to_site: # Assign device credentials to sites - cli_credential: - description: CLIAssign - username: cli-A - snmp_v2c_read: - description: SNMPv2cRead Test Assign - snmp_v2c_write: - description: SNMPv2cWrite Test Assign - snmp_v3: - description: SNMPv3 Test Assign - https_read: - username: admin - description: httpsRead Test Assign - https_write: - username: admin - description: httpsWrite Test Assign - site_name: - - Global/TEST_SITE_DEVICE_CREDENTIALS diff --git a/tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml b/tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml deleted file mode 100644 index cd51dd1a85..0000000000 --- a/tests/integration/ccc_device_credential_management/vars/vars_credential_management.yml +++ /dev/null @@ -1,102 +0,0 @@ ---- -credentials_details: #Create multiple credentials for the same protocol - - global_credential_details: - cli_credential: - - description: CLI1 - username: cli-1 - password: "5!meh" - enable_password: "q4^t^" - - description: CLI2 - username: cli-2 - password: "sbs2@" - enable_password: "8b!rn" - - description: CLI3 - username: cli-3 - password: "9%2&g" - enable_password: "9%%4b" - snmp_v2c_read: - - description: SNMPv2cRead Test 1 - read_community: "j5aj#8z%" - - description: SNMPv2cRead Test 2 - read_community: "m!ivyd%4" - - description: SNMPv2cRead Test 3 - read_community: "8hzx4$xw" - snmp_v2c_write: - - description: SNMPv2cWrite Test 1 - write_community: "n2@k8k38" - - description: SNMPv2cWrite Test 2 - write_community: "@&*46me5" - - description: SNMPv2cWrite Test 3 - write_community: "q@s$hl2!" - snmp_v3: - - description: SNMPv3 Test 1 - auth_password: "hp!x6px&#@2xi5" - auth_type: SHA - snmp_mode: AUTHPRIV - privacy_password: "ai7tpci3j@*j5g" - privacy_type: AES128 - username: admin - - description: SNMPv3 Test 2 - auth_password: "pnf$b73g**@j99" - auth_type: SHA - snmp_mode: AUTHPRIV - privacy_password: "gadcr!w!up7" - privacy_type: AES128 - username: admin - - description: SNMPv3 Test 3 - auth_password: "fgn8v#rj#y6" - auth_type: SHA - snmp_mode: AUTHPRIV - privacy_password: "q#nk^u$oy58" - privacy_type: AES128 - username: admin - https_read: - - description: httpsRead Test 1 - username: admin - password: "2!x89yvzz*7" - port: 443 - - description: httpsRead Test 2 - username: admin - password: "67q!bsnm*#o" - port: 443 - - description: httpsRead Test 3 - username: admin - password: "97w!fwy85#b" - port: 443 - https_write: - - description: httpsWrite Test 1 - username: admin - password: "j@8wgm%s2z%" - port: 443 - -credentials_update: - - global_credential_details: - cli_credential: - - description: CLI1 - username: cli-1 - password: "r*55*z8d2%6" - enable_password: "3^p@9*84nen" - snmp_v2c_read: - - description: SNMPv2cRead Test 1 - read_community: "mwn&k&$g%8g" - snmpV2cWrite: - - description: SNMPv2cWrite Test 1 - write_community: "n&9c3csirhu" - snmpV3: - - description: SNMPv3 Test 1 - auth_password: "j$4@2%2wgrv6f3z" - auth_type: SHA - snmp_mode: AUTHNOPRIV - privacy_password: "muqzks@3y$fco#w" - privacy_type: AES192 - username: admin - https_read: - - description: httpsRead Test 1 - username: admin - password: "2xg%iqt&fu@d6mh" - port: 443 - https_write: - - description: httpsWrite Test 1 - username: admin - password: "*#s&n2r9x$s@i8@" - port: 443 diff --git a/tests/integration/ccc_discovery_management/defaults/main.yml b/tests/integration/ccc_discovery_management/defaults/main.yml deleted file mode 100644 index 55a93fc23d..0000000000 --- a/tests/integration/ccc_discovery_management/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_discovery_management/meta/main.yml b/tests/integration/ccc_discovery_management/meta/main.yml deleted file mode 100644 index 5514b6a40c..0000000000 --- a/tests/integration/ccc_discovery_management/meta/main.yml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_discovery_management/tasks/main.yml b/tests/integration/ccc_discovery_management/tasks/main.yml deleted file mode 100644 index 09e0832ca2..0000000000 --- a/tests/integration/ccc_discovery_management/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: collect ccc test cases - find: - paths: "{{ role_path }}/tests" - patterns: "{{ testcase }}.yml" - connection: local - register: ccc_cases - tags: sanity - -- debug: - msg: "CCC Cases: {{ ccc_cases }}" - -- set_fact: - test_cases: - files: "{{ ccc_cases.files }}" - tags: sanity - -- debug: - msg: "Test Cases: {{ test_cases }}" - -- name: set test_items - set_fact: - test_items: "{{ test_cases.files | map(attribute='path') | list }}" - tags: sanity - -- debug: - msg: "Test Items: {{ test_items }}" - -- name: run test cases (connection=httpapi) - include_tasks: "{{ test_case_to_run }}" - loop: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml b/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml deleted file mode 100644 index 2663f741ac..0000000000 --- a/tests/integration/ccc_discovery_management/tests/test_discovery_management.yml +++ /dev/null @@ -1,286 +0,0 @@ ---- -- debug: msg="Starting discovery management test" -- debug: msg="Role Path {{ role_path }}" - -- block: - - name: Load vars and declare dnac vars - include_vars: - file: "{{ role_path }}/vars/vars_discovery_management.yml" - name: vars_map - - vars: - dnac_login: &dnac_login - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG - config_verify: True - - - name: Clean up vars - include_vars: - file: "{{ role_path }}/vars/vars_misc.yml" - name: vars_map_delete - - # - debug: - # msg: "{{ vars_map.single_ip }}" - # - debug: - # msg: "{{ vars_map.ip_range }}" - # - debug: - # msg: "{{ vars_map.multi_range }}" - # - debug: - # msg: "{{ vars_map.cdp }}" - # - debug: - # msg: "{{ vars_map.lldp }}" - # - debug: - # msg: "{{ vars_map.cidr }}" - -############################################# -# Pre Tests Clean Up # -############################################# - - - name: Delete discoveries before test - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map_delete.delete_discoveries }}" - -############################################# -# Create Single IP Address Discovery # -############################################# - - - name: Discover a single IP Address - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.single_ip }}" - register: result_singleip_discovery - - # - name: Debug item - # debug: - # var: result_singleip_discovery - - - name: Check single IP discovery creation - assert: - that: - - result_singleip_discovery.changed == true - - "'Discovery Created Successfully' in result_singleip_discovery.results | map(attribute='msg') | list" - when: result_singleip_discovery is defined - -############################################# -# Create Range IP Address Discovery # -############################################# - - - name: Discover an IP Address Range - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.ip_range }}" - register: result_ip_range_discovery - - # - name: Debug item - # debug: - # var: result_ip_range_discovery - - - name: Check IP address range discovery creation - assert: - that: - - result_ip_range_discovery.changed == true - - "'Discovery Created Successfully' in result_ip_range_discovery.results | map(attribute='msg') | list" - when: result_ip_range_discovery is defined - -############################################# -# Create Multi Range IP Address Discovery # -############################################# - - - name: Discover Multi IP Address Ranges - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.multi_range }}" - register: result_multi_range_discovery - - # - name: Debug item - # debug: - # var: result_multi_range_discovery - - - name: Check multi range IP address discovery creation - assert: - that: - - result_multi_range_discovery.changed == true - - "'Discovery Created Successfully' in result_multi_range_discovery.results | map(attribute='msg') | list" - when: result_multi_range_discovery is defined - -############################################# -# Create Discovery using CDP # -############################################# - - - name: Discover using CDP - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.cdp }}" - register: result_cdp_discovery - - # - name: Debug item - # debug: - # var: result_cdp_discovery - - - name: Check CDP discovery creation - assert: - that: - - result_cdp_discovery.changed == true - - "'Discovery Created Successfully' in result_cdp_discovery.results | map(attribute='msg') | list" - when: result_cdp_discovery is defined - -############################################# -# Create Discovery using LLDP # -############################################# - - - name: Discover using LLDP - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.lldp }}" - register: result_lldp_discovery - - # - name: Debug item - # debug: - # var: result_lldp_discovery - - - name: Check LLDP discovery creation - assert: - that: - - result_lldp_discovery.changed == true - - "'Discovery Created Successfully' in result_lldp_discovery.results | map(attribute='msg') | list" - when: result_lldp_discovery is defined - -############################################# -# Create Discovery using CIDR # -############################################# - - - name: Discover using CIDR - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.cidr }}" - register: result_cidr_discovery - - # - name: Debug item - # debug: - # var: result_cidr_discovery - - - name: Check CIDR discovery creation - assert: - that: - - result_cidr_discovery.changed == true - - "'Discovery Created Successfully' in result_cidr_discovery.results | map(attribute='msg') | list" - when: result_cidr_discovery is defined - -############################################# -# Create Multiple Discoveries # -############################################# - - - name: Add new item with "preferred_mgmt_ip_method" - set_fact: - vars_map_preferred_mgmt: {} - - - name: Add preferred_mgmt_ip_method to vars_map_preferred_mgmt - set_fact: - vars_map_preferred_mgmt: "{{ vars_map_preferred_mgmt | combine({item + '_preferred_mgmt': vars_map[item] | map('combine', {'preferred_mgmt_ip_method': 'UseLoopBack'}) | map('combine', {'discovery_name': vars_map[item][0]['discovery_name'] + ' - preferred_mgmt' }) | list}) }}" - loop: "{{ vars_map.keys() }}" - tags: multiple_discoveries - - - name: Set vars_map_multiple - set_fact: - vars_map_multiple: "{{ vars_map | combine(vars_map_preferred_mgmt) }}" - tags: multiple_discoveries - - - name: Print the updated vars_map_multiple - debug: - var: vars_map_multiple - tags: multiple_discoveries - - - name: Create multiple Discoveries - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ vars_map_multiple[item][0] }}" - with_items: "{{ vars_map_multiple }}" - tags: multiple_discoveries - register: result_multiple_discoveries - - # - name: Debug item - # debug: - # var: result_multiple_discoveries - # when: result_multiple_discoveries is defined - - - name: Check if multiple discoveries were successfull - assert: - that: - - item.changed == true - - "'Discovery Created Successfully' in item.msg" - loop: "{{ result_multiple_discoveries.results }}" - when: result_multiple_discoveries is defined - -############################################# -# Delete Discovery by name # -############################################# - - - name: Delete all discovery - cisco.dnac.discovery_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map_delete.delete_discoveries }}" - register: result_delete_discoveries - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_discoveries.results }}" - - - name: Check if discovery was successfully deleted - assert: - that: - - item.changed == true - - "'Successfully deleted discovery' in item.msg" - loop: "{{ result_delete_discoveries.results }}" - when: result_delete_discoveries is defined - -############################################ -# Delete ALL Discoveries # -############################################ - - # - name: Delete all discoveries that were created - # cisco.dnac.discovery_workflow_manager: - # <<: *dnac_login - # state: deleted - # config: - # - delete_all: True - # register: result_delete_all - - # - name: Debug item - # debug: - # var: result_delete_all - # when: result_delete_all is defined diff --git a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml b/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml deleted file mode 100644 index b9a587e452..0000000000 --- a/tests/integration/ccc_discovery_management/vars/vars_discovery_management.yml +++ /dev/null @@ -1,164 +0,0 @@ ---- -single_ip: - - discovery_name: Single IP Discovery - discovery_type: "SINGLE" - ip_address_list: - - 204.1.2.5 - protocol_order: ssh - global_credentials: - cli_credentials_list: - - description: CLIa - username: cli-a - snmp_v3_credential_list: - - description: SNMPv3 Test a - username: admin - retry: 1 - timeout: 1 - - -ip_range: - - discovery_name: Single Range Discovery 1 - discovery_type: "RANGE" - ip_address_list: - - 204.1.2.1-204.1.2.5 - ip_filter_list: - - 204.1.2.3 - protocol_order: ssh - discovery_specific_credentials: - cli_credentials_list: - - username: cisco - password: Cisco#123 - enable_password: Cisco#123 - http_read_credential: - username: wlcaccess - password: Lablab#123 - port: 443 - secure: True - snmp_v2_read_credential: - desc: SNMPv2c Read - community: "j5aj#0z%" - snmp_v2_write_credential: - desc: SNMPv2c Write - community: "n2!y9k38" - snmp_v3_credential: - username: v3Public2 - snmp_mode: AUTHPRIV - auth_type: SHA - auth_password: Lablab#1234 - privacy_type: AES256 - privacy_password: Lablab#1234 - start_index: 1 - records_to_return: 1000 - snmp_version: v2 - retry: 1 - timeout: 2 - - # Single IP Discovery an already existing discovery. - # Test case - deleted and recreated when discovery with same name. - - discovery_name: Single IP Discovery - discovery_type: "RANGE" - ip_address_list: - - 204.1.2.3 - protocol_order: ssh - global_cli_len: 3 - retry: 1 - timeout: 1 - - -multi_range: - - discovery_name: Multi Range Discovery - discovery_type: "MULTI RANGE" - ip_address_list: - - 204.1.2.1-204.1.2.5 - - 204.192.3.40 - - 204.192.4.200 - - 204.1.2.6 - - 204.1.2.7 - - 204.1.2.8 - - 204.1.2.9 - ip_filter_list: - - 204.1.2.3 - protocol_order: ssh - discovery_specific_credentials: - cli_credentials_list: - - username: cisco - password: Cisco#123 - enable_password: Cisco#123 - snmp_v3_credential: - username: v3Public2 - snmp_mode: AUTHPRIV - auth_type: SHA - auth_password: Lablab#1234 - privacy_type: AES256 - privacy_password: Lablab#1234 - retry: 1 - timeout: 1 - - -cdp: - - discovery_name: CDP Discovery - discovery_type: "CDP" - ip_address_list: - - 204.1.2.1 - cdp_level: 1 - protocol_order: ssh - discovery_specific_credentials: - cli_credentials_list: - - username: cisco - password: Cisco#123 - enable_password: Cisco#123 - snmp_v3_credential: - username: v3Public2 - snmp_mode: AUTHPRIV - auth_type: SHA - auth_password: Lablab#1234 - privacy_type: AES256 - privacy_password: Lablab#1234 - retry: 1 - timeout: 1 - - -lldp: - - discovery_name: LLDP Discovery - discovery_type: "LLDP" - ip_address_list: - - 204.1.2.1 - lldp_level: 16 - protocol_order: ssh - discovery_specific_credentials: - cli_credentials_list: - - username: cisco - password: Cisco#123 - enable_password: Cisco#123 - snmp_v3_credential: - username: v3Public2 - snmp_mode: AUTHPRIV - auth_type: SHA - auth_password: Lablab#1234 - privacy_type: AES256 - privacy_password: Lablab#1234 - retry: 1 - timeout: 1 - - -cidr: - - discovery_name: CIDR Discovery - discovery_type: "CIDR" - ip_address_list: - - 204.1.2.0/24 - prefix_length: 30 - protocol_order: ssh - discovery_specific_credentials: - cli_credentials_list: - - username: cisco - password: Cisco#123 - enable_password: Cisco#123 - snmp_v3_credential: - username: v3Public2 - snmp_mode: AUTHPRIV - auth_type: SHA - auth_password: Lablab#1234 - privacy_type: AES256 - privacy_password: Lablab#1234 - retry: 1 - timeout: 1 diff --git a/tests/integration/ccc_discovery_management/vars/vars_misc.yml b/tests/integration/ccc_discovery_management/vars/vars_misc.yml deleted file mode 100644 index 4c9ca90bb6..0000000000 --- a/tests/integration/ccc_discovery_management/vars/vars_misc.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -delete_discoveries: - - discovery_name: Single IP Discovery - - discovery_name: Single Range Discovery 1 - - discovery_name: Multi Range Discovery - - discovery_name: CDP Discovery - - discovery_name: LLDP Discovery - - discovery_name: CIDR Discovery - - discovery_name: Single IP Discovery - preferred_mgmt - - discovery_name: Single Range Discovery 1 - preferred_mgmt - - discovery_name: Multi Range Discovery - preferred_mgmt - - discovery_name: CDP Discovery - preferred_mgmt - - discovery_name: LLDP Discovery - preferred_mgmt - - discovery_name: CIDR Discovery - preferred_mgmt diff --git a/tests/integration/ccc_inventory_management/defaults/main.yml b/tests/integration/ccc_inventory_management/defaults/main.yml deleted file mode 100644 index 55a93fc23d..0000000000 --- a/tests/integration/ccc_inventory_management/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_inventory_management/meta/main.yml b/tests/integration/ccc_inventory_management/meta/main.yml deleted file mode 100644 index 5514b6a40c..0000000000 --- a/tests/integration/ccc_inventory_management/meta/main.yml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_inventory_management/tasks/main.yml b/tests/integration/ccc_inventory_management/tasks/main.yml deleted file mode 100644 index 09e0832ca2..0000000000 --- a/tests/integration/ccc_inventory_management/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: collect ccc test cases - find: - paths: "{{ role_path }}/tests" - patterns: "{{ testcase }}.yml" - connection: local - register: ccc_cases - tags: sanity - -- debug: - msg: "CCC Cases: {{ ccc_cases }}" - -- set_fact: - test_cases: - files: "{{ ccc_cases.files }}" - tags: sanity - -- debug: - msg: "Test Cases: {{ test_cases }}" - -- name: set test_items - set_fact: - test_items: "{{ test_cases.files | map(attribute='path') | list }}" - tags: sanity - -- debug: - msg: "Test Items: {{ test_items }}" - -- name: run test cases (connection=httpapi) - include_tasks: "{{ test_case_to_run }}" - loop: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml b/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml deleted file mode 100644 index 121a208c83..0000000000 --- a/tests/integration/ccc_inventory_management/tests/test_inventory_management.yml +++ /dev/null @@ -1,492 +0,0 @@ ---- -- debug: msg="Starting inventory management test" -- debug: msg="Role Path {{ role_path }}" - -- block: - - name: Load vars and declare dnac vars - include_vars: - file: "{{ role_path }}/vars/vars_inventory_management.yml" - name: vars_map - vars: - dnac_login: &dnac_login - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG - config_verify: true - - # - debug: - # msg: "{{ vars_map.device_details }}" - # - debug: - # msg: "{{ vars_map.device_credential_updates }}" - # - debug: - # msg: "{{ vars_map.device_interface_updates }}" - # - debug: - # msg: "{{ vars_map.delete_devices }}" - -############################################# -# Clean Up # -############################################# - - - name: Delete device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_devices }}" - - - name: Delete site - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_sites }}" - -############################################# -# Add Devices # -############################################# - - - name: Add new device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.device_details }}" - register: result_add_device - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_add_device.results }}" - - - name: Assert device addition success - assert: - that: - - item.changed == true - - "'added to Cisco Catalyst Center' in item.msg" - loop: "{{ result_add_device.results }}" - when: result_add_device is defined - -############################################# -# Update Device Credential Details # -############################################# - - - name: Update device details - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.device_credential_updates }}" - register: result_update_device_credentials - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_credentials.results }}" - # when: result_update_device_credentials is defined - - - name: Assert update - assert: - that: - - item.changed == true - loop: "{{ result_update_device_credentials.results }}" - when: result_update_device_credentials is defined - -############################################ -# Update Device Interface Detials # -############################################# - - # - name: Pause for 60 seconds before updating interfaces - # pause: - # seconds: 60 - - # - name: Update device interface details - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_interface_updates }}" - # register: result_update_device_interface - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined - - # - name: Assert update - # assert: - # that: - # - item.changed == true - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined - -############################################# -# Update Device Role Detials # -############################################# - - - name: Update device role details - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.device_role_updates }}" - register: result_update_device_role - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_role.results }}" - # when: result_update_device_role is defined - - # - name: Assert device role update - # assert: - # that: - # - item.changed == true - # - "'role updated successfully' in item.response" - # loop: "{{ result_update_device_role.results }}" - # when: result_update_device_role is defined - -############################################# -# Update Device Interface Description # -############################################# - - # - name: Pause for 60 seconds before updating interfaces - # pause: - # seconds: 60 - - # - name: Update device interface description post changing role to non-access - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.device_int_update_post_rolechange }}" - # register: result_update_device_interface - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined - - # - name: Assert update - # assert: - # that: - # - item.changed == true - # loop: "{{ result_update_device_interface.results }}" - # when: result_update_device_interface is defined - -############################################# -# Resync Device # -############################################# - - - name: Resync Device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.device_resync }}" - register: result_resync_device - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_resync_device.results }}" - # when: result_resync_device is defined - - - name: Assert device resync - assert: - that: - - result_resync_device.changed == true - - "'Synced devices' in item.response.progress" - loop: "{{ result_resync_device.results }}" - when: result_resync_device is defined - -############################################# -# Create & Assign User Defined Field # -############################################# - - - name: Create & Assign user defined field - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.create_assign_udf }}" - register: result_create_assign_udf - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_assign_udf.results }}" - # when: result_create_assign_udf is defined - - - name: Assert user defined field creation and assignment - assert: - that: - - item.changed == true - loop: "{{ result_create_assign_udf.results }}" - when: result_create_assign_udf is defined - -############################################# -# Update User Defined Field # -############################################# - - - name: Update user defined field - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.update_udf }}" - register: result_update_udf - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_assign_udf.results }}" - # when: result_update_udf is defined - - - name: Assert user defined field updated - assert: - that: - - item.changed == true - loop: "{{ result_update_udf.results }}" - when: result_update_udf is defined - - -############################################# -# Delete User Defined Field # -############################################# - - - name: Delete user defined field - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_udf }}" - register: result_delete_udf - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_udf.results }}" - # when: result_delete_udf is defined - - - name: Assert user defined field deletion - assert: - that: - - result_delete_udf.changed == true - - "'deleted successfully' in item.response.progress" - loop: "{{ result_delete_udf.results }}" - when: result_delete_udf is defined - - -############################################# -# Export Device Details # -############################################# - - - name: Export Device Details in a CSV file - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.export_device_details }}" - register: result_export_details - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_export_details.results }}" - # when: result_export_details is defined - - - name: Assert device details export - assert: - that: - - item.changed == true - loop: "{{ result_export_details.results }}" - when: result_export_details is defined - -############################################# -# Export Device Credential Details # -############################################# - - - name: Export Credential Device Details in a CSV file - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.export_credential_details }}" - register: result_export_credential_details - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_export_credential_details.results }}" - # when: result_export_credential_details is defined - - - name: Assert device credential details export - assert: - that: - - item.changed == true - loop: "{{ result_export_credential_details.results }}" - when: result_export_credential_details is defined - - -############################################# -# CREATE SITE # -############################################# - - - name: Create sites from design_sites config - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.design_sites }}" - register: result_create_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_site.results }}" - # when: result_create_site is defined - - - name: Assert area creation success for each site - assert: - that: - - item.changed == true - - item.response.status == "SUCCESS" - - "'created successfully' in item.msg" - loop: "{{ result_create_site.results }}" - when: result_create_site is defined - -############################################# -# ASSOCIATE WIRED DEVICE TO SITE # -############################################# - - - name: Assign wired device to site and then provision - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.associate_wired_device }}" - register: result_associate_device - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_associate_device.results }}" - # when: result_associate_device is defined - - - name: Assert Assign wired device to site and then provision - assert: - that: - - item.changed == true - loop: "{{ result_associate_device.results }}" - when: result_associate_device is defined - - -############################################# -# ASSOCIATE WIRELESS DEVICE TO SITE # -############################################# - - # - name: Assign wireless device to site and then provision - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.associate_wireless_device }}" - # register: result_associate_device - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_associate_device.results }}" - # when: result_associate_device is defined - - # - name: Assert Assign wireless device to site and then provision - # assert: - # that: - # - item.changed == true - # loop: "{{ result_associate_device.results }}" - # when: result_associate_device is defined - -############################################# -# Delete Device # -############################################# - - - name: Delete device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_devices }}" - register: result_device_deleted - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_device_deleted.results }}" - # when: result_device_deleted is defined - - - name: Assert device deletion success - assert: - that: - - item.changed == true - loop: "{{ result_device_deleted.results }}" - when: result_device_deleted is defined - -############################################# -# PAUSE # -############################################# - - - name: Pause for 120 seconds - pause: - seconds: 120 - -############################################# -# DELETE SITE # -############################################# - - - name: Delete sites from design_sites config - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_sites }}" - register: result_delete_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_site.results }}" - # when: result_delete_site is defined - - - name: Assert deletion of area success for each site - assert: - that: - - item.changed == true - - "'deleted successfully' in item.response" - loop: "{{ result_delete_site.results }}" - when: result_delete_site is defined diff --git a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml b/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml deleted file mode 100644 index e18d865aa8..0000000000 --- a/tests/integration/ccc_inventory_management/vars/vars_inventory_management.yml +++ /dev/null @@ -1,268 +0,0 @@ ---- -device_details: - - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5"] - device_added: True - # CLI Credentials - username: "cisco" - password: "Cisco#123" - enable_password: "Cisco#123" - # SNMP Credentials - snmp_version: v3 - snmp_username: "v3Public2" - snmp_mode: "AUTHPRIV" - snmp_auth_protocol: "SHA" - snmp_auth_passphrase: "Lablab#1234" - snmp_priv_protocol: "CISCOAES256" - snmp_priv_passphrase: "Lablab#1234" - #SNMP Retry and Timeout - snmp_retry: 3 - snmp_timeout: 5 - #CLI Transport (ssh, Telnet) - cli_transport: "ssh" - netconf_port: 830 - - # - type: "NETWORK_DEVICE" - # ip_address_list: ["204.192.6.200"] - # device_added: True - # # CLI Credentials - # username: "cisco" - # password: "Cisco#123" - # enable_password: "Cisco#123" - # # HTTP Credentials - # http_username: "wlcaccess" - # http_password: "Lablab#123" - # http_port: "443" - # http_secure: False - # # SNMP Credentials - # snmp_version: v3 - # snmp_username: "v3Public2" - # snmp_mode: "AUTHPRIV" - # snmp_auth_protocol: "SHA" - # snmp_auth_passphrase: "Lablab#1234" - # snmp_priv_protocol: "AES256" - # snmp_priv_passphrase: "Lablab#1234" - # #SNMP Retry and Timeout - # snmp_retry: 3 - # snmp_timeout: 5 - # #CLI Transport (ssh, Telnet) - # cli_transport: "ssh"s - # netconf_port: 830 - - -device_credential_updates: - # Update CLI password - - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5"] - credential_update: True - # CLI Credentials - password: "Cisco#1234" - - - # Update SNMP privacy type - - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5"] - credential_update: True - # SNMP Credentials - snmp_priv_protocol: "AES192" - - - # Update SNMP username - - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5"] - credential_update: True - # SNMP Credentials - snmp_username: "v3Public2-2" - - - # Update SNMP mode - - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5"] - credential_update: True - # SNMP Credentials - snmp_version: v3 - snmp_mode: "NOAUTHNOPRIV" - - # Update cli_transport - - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5"] - credential_update: True - #change cli_transport from ssh to telnet - cli_transport: telnet - - # SNMPv2 credentials - - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5"] - credential_update: True - snmp_version: v2 - snmp_ro_community: 'j5aj#0z%' - snmp_rw_community: 'j5aj#0z%' - - # Reverse changes - - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.5"] - credential_update: True - # CLI Credentials - username: "cisco" - password: "Cisco#123" - enable_password: "Cisco#123" - # SNMP Credentials - snmp_version: v3 - snmp_username: "v3Public2" - snmp_mode: "AUTHPRIV" - snmp_auth_protocol: "SHA" - snmp_auth_passphrase: "Lablab#1234" - snmp_priv_protocol: "CISCOAES256" - snmp_priv_passphrase: "Lablab#1234" - #CLI Transport (ssh, Telnet) - cli_transport: "ssh" - netconf_port: 830 - - - -device_interface_updates: - # Update Interface Details - - ip_address_list: ["204.1.2.5"] - # Interface details - update_interface_details: - interface_name: ["GigabitEthernet1/0/8"] - description: "Testing for updating interface details" - vlan_id: 23 - voice_vlan_id: 45 - admin_status: "UP" - - -device_role_updates: - #Update role from access to core - - ip_address_list: ["204.1.2.5"] - role: ACCESS - - -device_int_update_post_rolechange: - # Update Interface description - - ip_address_list: ["204.1.2.5"] - # Interface details - update_interface_details: - interface_name: ["GigabitEthernet1/0/23"] - description: "Testing for updating interface description post changing role" - - -device_resync: - # Resync the device - - ip_address_list: ["204.1.2.5"] - device_resync: True - force_sync: False - - -create_assign_udf: - - ip_address_list: ["204.1.2.5"] - add_user_defined_field: - # User defined fields - - name: Test123 - description: "Added first udf for testing" - value: "value123" - - name: Test321 - description: "Added second udf for testing" - value: "value321" - - -update_udf: - - ip_address_list: ["204.1.2.5"] - add_user_defined_field: - # User defined fields - - name: Test123 - description: "modified first udf for testing" - value: "value124" - - name: Test321 - description: "modified second udf for testing" - value: "value421" - - -delete_udf: - # User defined fields - - ip_address_list: ["204.1.2.5"] - add_user_defined_field: - - name: "Test123" - - ip_address_list: ["204.1.2.5"] - add_user_defined_field: - - name: "Test321" - - -export_device_details: - - ip_address_list: ["204.1.2.5"] - export_device_list: - operation_enum: 1 - password: "Password123!" - - -export_credential_details: - - ip_address_list: ["204.1.2.5"] - export_device_list: - operation_enum: "0" - password: "Password123$" - - -design_sites: - # Create site to associate device to - - site: - area: - name: ITest_Area - parent_name: Global - site_type: area - - site: - building: - name: ITest_Building - parent_name: Global/ITest_Area - address: Bengaluru, Karnataka, India - latitude: 12.969910 - longitude: 77.597960 - country: India - site_type: building - - site: - floor: - name: ITest_Floor1 - parent_name: Global/ITest_Area/ITest_Building - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - -associate_wired_device: - - provision_wired_device: - - device_ip: "204.1.2.5" - site_name: "Global/ITest_Area/ITest_Building/ITest_Floor1" - resync_retry_count: 200 - resync_interval: 2 - - -associate_wireless_device: - - provision_wireless_device: - - device_ip: "204.192.6.200" - site_name: "Global/ITest_Inventory_P_Area/ITest_Inventory_Building/ITest_Inventory_Floor1" - managed_ap_locations: ["Global/ITest_Inventory_P_Area/ITest_Inventory_Building/ITest_Inventory_Floor1", "Global/ITest_Inventory_S_Area/ITest_Inventory_Building/ITest_Inventory_Floor1"] - dynamic_interfaces: - - interface_ip_address: 23.23.21.12 - interface_netmask_in_cidr: 24 - interface_gateway: "gateway" - lag_or_port_number: 12 - vlan_id: 99 - interface_name: "management" - resync_retry_count: 200 - resync_retry_interval: 2 - - -delete_sites: - - site: - area: - name: ITest_Area - parent_name: Global - site_type: area - - -delete_devices: - - ip_address_list: ["204.1.2.5"] - #ip_address_list: ["204.1.2.5", "204.192.6.200"] - clean_config: False diff --git a/tests/integration/ccc_network_compliance_management/defaults/main.yml b/tests/integration/ccc_network_compliance_management/defaults/main.yml deleted file mode 100644 index 55a93fc23d..0000000000 --- a/tests/integration/ccc_network_compliance_management/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_network_compliance_management/meta/main.yml b/tests/integration/ccc_network_compliance_management/meta/main.yml deleted file mode 100644 index 5514b6a40c..0000000000 --- a/tests/integration/ccc_network_compliance_management/meta/main.yml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_network_compliance_management/tasks/main.yml b/tests/integration/ccc_network_compliance_management/tasks/main.yml deleted file mode 100644 index 09e0832ca2..0000000000 --- a/tests/integration/ccc_network_compliance_management/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: collect ccc test cases - find: - paths: "{{ role_path }}/tests" - patterns: "{{ testcase }}.yml" - connection: local - register: ccc_cases - tags: sanity - -- debug: - msg: "CCC Cases: {{ ccc_cases }}" - -- set_fact: - test_cases: - files: "{{ ccc_cases.files }}" - tags: sanity - -- debug: - msg: "Test Cases: {{ test_cases }}" - -- name: set test_items - set_fact: - test_items: "{{ test_cases.files | map(attribute='path') | list }}" - tags: sanity - -- debug: - msg: "Test Items: {{ test_items }}" - -- name: run test cases (connection=httpapi) - include_tasks: "{{ test_case_to_run }}" - loop: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml b/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml deleted file mode 100644 index e853a9fe66..0000000000 --- a/tests/integration/ccc_network_compliance_management/tests/test_network_compliance_management.yml +++ /dev/null @@ -1,112 +0,0 @@ ---- -- debug: msg="Starting network compliance management test" -- debug: msg="Role Path {{ role_path }}" - -- block: - - name: Load vars and declare dnac vars - include_vars: - file: "{{ role_path }}/vars/vars_network_compliance_management.yml" - name: vars_map - vars: - dnac_login: &dnac_login - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG - config_verify: true - - # - debug: - # msg: "{{ vars_map. }}" - - -############################################# -# Run Full Compliance on IP List # -############################################# - - - name: Run full complaince check - cisco.dnac.network_compliance_workflow_manager: - <<: *dnac_login - dnac_log_append: False - config: - - #ip_address_list: ['204.1.2.4', '204.1.2.5'] - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - #site_name: "Global" - # run_compliance: - # trigger_full: True - #trigger_full: True - #categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT', 'EOX', 'NETWORK_SETTINGS'] - sync_device_config: True - -############################################# -# Run Full Compliance on Site # -############################################# - -# - name: Run full complaince check on Site -# cisco.dnac.network_compliance_workflow_manager: -# <<: *dnac_login -# dnac_log_append: False -# config: -# - site: "Global" -# run_compliance: -# trigger_full: True - -# ############################################# -# # Run Compliance with Categories on IP List # -# ############################################# - -# - name: Run complaince check with specific categories on IP list -# cisco.dnac.network_compliance_workflow_manager: -# <<: *dnac_login -# dnac_log_append: False -# config: -# - #ip_address_list: ['204.1.2.5'] -# ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] -# run_compliance: -# trigger_full: False -# categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] - -# ############################################# -# # Run Compliance with Categories on Site # -# ############################################# - -# - name: Run full complaince check -# cisco.dnac.network_compliance_workflow_manager: -# <<: *dnac_login -# dnac_log_append: False -# config: -# - site_name: "Global" -# run_compliance: -# trigger_full: False -# categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] - -# ############################################# -# # Sync Device Config on IP List # -# ############################################# - -# - name: Run full complaince check -# cisco.dnac.network_compliance_workflow_manager: -# <<: *dnac_login -# dnac_log_append: False -# config: -# - #ip_address_list: ['204.1.2.5'] -# ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] -# sync_device_config: True - -# ############################################# -# # Sync Device Config on Site # -# ############################################# - -# - name: Run full complaince check -# cisco.dnac.network_compliance_workflow_manager: -# <<: *dnac_login -# dnac_log_append: False -# config: -# - site_name: "Global" -# sync_device_config: True - -# \ No newline at end of file diff --git a/tests/integration/ccc_network_compliance_management/vars/vars_network_compliance_management.yml b/tests/integration/ccc_network_compliance_management/vars/vars_network_compliance_management.yml deleted file mode 100644 index 849169c71a..0000000000 --- a/tests/integration/ccc_network_compliance_management/vars/vars_network_compliance_management.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - - diff --git a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml b/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml deleted file mode 100644 index 2fa02a6b51..0000000000 --- a/tests/integration/ccc_pnp_management/tests/test_pnp_management.yml +++ /dev/null @@ -1,226 +0,0 @@ ---- -- debug: msg="Starting pnp management test" -- debug: msg="Role Path {{ role_path }}" - -- block: - - name: Load vars and declare dnac vars - include_vars: - file: "{{ role_path }}/vars/vars_pnp_management.yml" - name: vars_map - vars: - dnac_login: &dnac_login - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG - config_verify: true - - # - debug: - # msg: "{{ vars_map.pnp_delete }}" - # - debug: - # msg: "{{ vars_map.pnp_claim }}" - # - debug: - # msg: "{{ vars_map.bulk }}" - # - debug: - # msg: "{{ vars_map.delete_devices }}" - -############################################# -# Clean Up # -############################################# - - - name: Delete PnP devices - cisco.dnac.pnp_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.pnp_delete.delete }}" - - - name: Delete PnP devices - cisco.dnac.pnp_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.bulk.add }}" - - # - name: Delete device from Inventory - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: deleted - # config: - # - "{{ item }}" - # loop: "{{ vars_map.delete_devices }}" - -############################################# -# Add device but not Claim PNP Device # -############################################# - - - name: Adding devices but not claiming - cisco.dnac.pnp_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.pnp_delete.add }}" - register: result_add_device - - # - name: Debug Adding devices but not claiming - # debug: - # var: item - # loop: "{{ result_add_device.results }}" - # when: result_add_device is defined - - - name: Assert adding devices but not claiming - assert: - that: - - item.changed == true - - "'Only Device Added Successfully' in item.msg" - loop: "{{ result_add_device.results }}" - when: result_add_device is defined - -############################################# -# Delete Unclaimed Devices # -############################################# - - - name: Delete PnP devices - cisco.dnac.pnp_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.pnp_delete.delete }}" - register: result_delete_device - - # - name: Debug delete unclaimed devices - # debug: - # var: item - # loop: "{{ result_delete_device.results }}" - # when: result_delete_device is defined - - - name: Assert deletion of unclaimed PnP devices - assert: - that: - - item.changed == true - - "'Deleted Successfully' in item.msg" - loop: "{{ result_delete_device.results }}" - when: result_delete_device is defined - -############################################# -# Bulk Add device but not Claim PNP Device # -############################################# - - - name: Bulk Adding devices but not claiming - cisco.dnac.pnp_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.bulk.add }}" - register: result_add_device - - # - name: Debug Bulk Adding devices but not claiming - # debug: - # var: item - # loop: "{{ result_add_device.results }}" - # when: result_add_device is defined - - - name: Assert bulk adding devices but not claiming - assert: - that: - - item.changed == true - - "'imported successfully' in item.msg" - loop: "{{ result_add_device.results }}" - when: result_add_device is defined - -############################################# -# Bulk Delete Unclaimed Devices # -############################################# - - - name: Delete Bulk Unclaimed PnP devices - cisco.dnac.pnp_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.bulk.add }}" - register: result_delete_device - - # - name: Debug Bulk delete unclaimed devices - # debug: - # var: item - # loop: "{{ result_delete_device.results }}" - # when: result_delete_device is defined - - - name: Assert Bulk deletion of unclaimed PnP devices - assert: - that: - - item.changed == true - - "'Deleted Successfully' in item.msg" - loop: "{{ result_delete_device.results }}" - when: result_delete_device is defined - -############################################# -# Add and Claim PNP Device # -############################################# - - # - name: Add and Claim PnP devices - # cisco.dnac.pnp_workflow_manager: - # <<: *dnac_login - # state: merged - # config: - # - "{{ item }}" - # loop: "{{ vars_map.pnp_claim.cat9k }}" - # register: result_claim_device - - # - name: Debug Add and Claim device - # debug: - # var: item - # loop: "{{ result_claim_device.results }}" - # when: result_claim_device is defined - - # - name: Assert Add and Claim device - # assert: - # that: - # - item.changed == true - # - "'Claimed Successfully' in item.msg" - # loop: "{{ result_claim_device.results }}" - # when: result_claim_device is defined - -############################################# -# Pause to Complete Provisioning # -############################################# - - # - name: Pause for 10 minutes - # pause: - # seconds: 600 - -############################################# -# Delete Devices # -############################################# - - # - name: Delete device - # cisco.dnac.inventory_workflow_manager: - # <<: *dnac_login - # state: deleted - # config: - # - "{{ item }}" - # loop: "{{ vars_map.delete_devices }}" - # register: result_device_deleted - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_device_deleted.results }}" - # when: result_device_deleted is defined - - # - name: Assert device deletion success - # assert: - # that: - # - result_device_deleted.changed == true - # when: result_device_deleted is defined diff --git a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml b/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml deleted file mode 100644 index 40708dcf32..0000000000 --- a/tests/integration/ccc_pnp_management/vars/vars_pnp_management.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- -pnp_delete: - add: - - device_info: - - serial_number: FJC2721271T - hostname: SJ-EN-9300 - state: Unclaimed - pid: C9300-48T - - delete: - - device_info: - - serial_number: FJC2721271T - hostname: SJ-EN-9300 - state: Unclaimed - pid: C9300-48T - - -pnp_claim: - cat9k: - - device_info: - - serial_number: FJC2721271T - hostname: Switch - state: Unclaimed - pid: C9300-48T - site_name: Global/ITest_PnP_Area/ITest_PnP_Building - template_name: "Ansible_PNP_Switch" - project_name: Onboarding Configuration - template_params: - hostname: SJ-EN-9300 - interface: GigabitEthernet1/1/4 - - -bulk: - add: - - device_info: - - serial_number: FOX2639PAYD - hostname: SJ-EWLC-1 - state: Unclaimed - pid: C9800-40-K9 - - serial_number: FJC271924D9 - hostname: SJ-EN-9300 - state: Unclaimed - pid: C9300-48UXM - - serial_number: FJC271925Q1 - hostname: NY-EN-9300 - state: Unclaimed - pid: C9300-48UXM - - serial_number: FJC2402A0TX - hostname: SF-BN-ISR - state: Unclaimed - pid: ISR4451-X/K9 - - -delete_devices: - - ip_address_list: ["204.1.2.1"] - clean_config: False diff --git a/tests/integration/ccc_site_management/defaults/main.yml b/tests/integration/ccc_site_management/defaults/main.yml deleted file mode 100644 index 55a93fc23d..0000000000 --- a/tests/integration/ccc_site_management/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_site_management/meta/main.yml b/tests/integration/ccc_site_management/meta/main.yml deleted file mode 100644 index 5514b6a40c..0000000000 --- a/tests/integration/ccc_site_management/meta/main.yml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_site_management/tasks/main.yml b/tests/integration/ccc_site_management/tasks/main.yml deleted file mode 100644 index 09e0832ca2..0000000000 --- a/tests/integration/ccc_site_management/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: collect ccc test cases - find: - paths: "{{ role_path }}/tests" - patterns: "{{ testcase }}.yml" - connection: local - register: ccc_cases - tags: sanity - -- debug: - msg: "CCC Cases: {{ ccc_cases }}" - -- set_fact: - test_cases: - files: "{{ ccc_cases.files }}" - tags: sanity - -- debug: - msg: "Test Cases: {{ test_cases }}" - -- name: set test_items - set_fact: - test_items: "{{ test_cases.files | map(attribute='path') | list }}" - tags: sanity - -- debug: - msg: "Test Items: {{ test_items }}" - -- name: run test cases (connection=httpapi) - include_tasks: "{{ test_case_to_run }}" - loop: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_site_management/tests/test_site_management.yml b/tests/integration/ccc_site_management/tests/test_site_management.yml deleted file mode 100644 index 6f703e4e70..0000000000 --- a/tests/integration/ccc_site_management/tests/test_site_management.yml +++ /dev/null @@ -1,121 +0,0 @@ ---- -- debug: msg="Starting site management test" -- debug: msg="Role Path {{ role_path }}" - -- block: - - name: Load vars and declare dnac vars - include_vars: - file: "{{ role_path }}/vars/vars_site_management.yml" - name: vars_map - vars: - dnac_login: &dnac_login - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG - config_verify: true - - # - debug: - # msg: "{{ vars_map.design_sites }}" - # - debug: - # msg: "{{ vars_map.update_sites }}" - # - debug: - # msg: "{{ vars_map.delete_sites }}" - -############################################# -# Clean Up # -############################################# - - - name: Clean up before test - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_sites }}" - -############################################# -# CREATE SITES # -############################################# - - - name: Create sites - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.design_sites }}" - register: result_create_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_site.results }}" - # when: result_create_site is defined - - - name: Assert area creation success for each site - assert: - that: - - item.changed == true - - "'created successfully' in item.msg" - loop: "{{ result_create_site.results }}" - when: result_create_site is defined - -############################################# -# UPDATE SITES # -############################################# - - - name: Update sites - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.update_sites }}" - register: result_update_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_update_site.results }}" - # when: result_update_site is defined - - - name: Assert area update success for each site - assert: - that: - - item.changed == true - - "'Updated Successfully' in item.msg" - loop: "{{ result_update_site.results }}" - when: result_update_site is defined - -############################################# -# DELETE SITES # -############################################# - - - name: Delete sites - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_sites }}" - register: result_delete_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_site.results }}" - # when: result_delete_site is defined - - - name: Assert deletion success for each site - assert: - that: - - item.changed == true - - "'deleted successfully' in item.response" - loop: "{{ result_delete_site.results }}" - when: result_delete_site is defined diff --git a/tests/integration/ccc_site_management/vars/vars_site_management.yml b/tests/integration/ccc_site_management/vars/vars_site_management.yml deleted file mode 100644 index 88cee28a78..0000000000 --- a/tests/integration/ccc_site_management/vars/vars_site_management.yml +++ /dev/null @@ -1,457 +0,0 @@ ---- -design_sites: - # USA-Test Site Hierarchy - - site: - area: - name: USA-Test - parent_name: Global - site_type: area - - site: - area: - name: SAN JOSE - parent_name: Global/USA-Test - site_type: area - - site: - area: - name: RTP - parent_name: Global/USA-Test - site_type: area - - site: - area: - name: BayAreaGuest - parent_name: Global/USA-Test - site_type: area - - site: - area: - name: New York - parent_name: Global/USA-Test - site_type: area - - site: - area: - name: SAN-FRANCISCO - parent_name: Global/USA-Test - site_type: area - - site: - area: - name: BERKELEY - parent_name: Global/USA-Test - site_type: area - - site: - building: - name: BLD10 - parent_name: Global/USA-Test/RTP - address: Ev Chargers Bldg 10, 7200-10 Kit Creek Rd, Morrisville, North Carolina 27560, United States - latitude: 35.85992111421487 - longitude: -78.8829258991226 - country: United States - site_type: building - - site: - building: - name: BLD11 - parent_name: Global/USA-Test/RTP - address: Cisco Systems, 7200 Kit Creek Rd, Morrisville, North Carolina 27560, United States - latitude: 35.86059627310624 - longitude: -78.88105620286412 - country: United States - site_type: building - - site: - building: - name: BLD12 - parent_name: Global/USA-Test/RTP - address: Cisco Systems, 7200-12 Kit Creek Rd, Morrisville, North Carolina 27560, United States - latitude: 35.8611847591779 - longitude: -78.88217248318003 - country: United States - site_type: building - - site: - building: - name: BLD23 - parent_name: Global/USA-Test/SAN JOSE - address: McCarthy Blvd, San Jose, California 95131, United States - latitude: 37.398188 - longitude: -121.912974 - country: United States - site_type: building - - site: - building: - name: BLD20 - parent_name: Global/USA-Test/SAN JOSE - address: 725 Alder Drive, Milpitas, California 95035, United States - latitude: 37.415947 - longitude: -121.916327 - country: United States - site_type: building - - site: - building: - name: BLD_GB - parent_name: Global/USA-Test/BayAreaGuest - address: 725 Alder Drive, Milpitas, California 95035, United States - latitude: 37.415947 - longitude: -121.916327 - country: United States - site_type: building - - site: - building: - name: BLDNYC - parent_name: Global/USA-Test/New York - address: McCarthy Blvd, San Jose, California 95131, United States - latitude: 37.398188 - longitude: -121.912974 - country: United States - site_type: building - - site: - building: - name: BLD_SF - parent_name: Global/USA-Test/SAN-FRANCISCO - address: McCarthy Blvd, San Jose, California 95131, United States - latitude: 37.398188 - longitude: -121.912974 - country: United States - site_type: building - - site: - building: - name: BLD_SF1 - parent_name: Global/USA-Test/SAN-FRANCISCO - address: McCarthy Blvd, San Jose, California 95131, United States - latitude: 37.398188 - longitude: -121.912974 - country: United States - site_type: building - - site: - building: - name: BLDBERK - parent_name: Global/USA-Test/BERKELEY - address: 725 Alder Drive, Milpitas, California 95035, United States - latitude: 37.415947 - longitude: -121.916327 - country: United States - site_type: building - - site: - floor: - name: BLD10_FLOOR1 - parent_name: Global/USA-Test/RTP/BLD10 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - site: - floor: - name: BLD10_FLOOR2 - parent_name: Global/USA-Test/RTP/BLD10 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 2 - site_type: floor - - site: - floor: - name: BLD10_FLOOR3 - parent_name: Global/USA-Test/RTP/BLD10 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 3 - site_type: floor - - site: - floor: - name: BLD11_FLOOR1 - parent_name: Global/USA-Test/RTP/BLD11 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - site: - floor: - name: BLD11_FLOOR2 - parent_name: Global/USA-Test/RTP/BLD11 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 2 - site_type: floor - - site: - floor: - name: BLD11_FLOOR3 - parent_name: Global/USA-Test/RTP/BLD11 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 3 - site_type: floor - - site: - floor: - name: BLD12_FLOOR1 - parent_name: Global/USA-Test/RTP/BLD12 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - site: - floor: - name: BLD12_FLOOR2 - parent_name: Global/USA-Test/RTP/BLD12 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 2 - site_type: floor - - site: - floor: - name: BLD12_FLOOR3 - parent_name: Global/USA-Test/RTP/BLD12 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 3 - site_type: floor - - site: - floor: - name: FLOOR1_LEVEL1 - parent_name: Global/USA-Test/SAN JOSE/BLD23 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - site: - floor: - name: FLOOR1_LEVEL2 - parent_name: Global/USA-Test/SAN JOSE/BLD23 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - site: - floor: - name: FLOOR1_LEVEL3 - parent_name: Global/USA-Test/SAN JOSE/BLD23 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - site: - floor: - name: FLOOR1_LEVEL4 - parent_name: Global/USA-Test/SAN JOSE/BLD23 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - site: - floor: - name: BLD20_FLOOR1 - parent_name: Global/USA-Test/SAN JOSE/BLD20 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - site: - floor: - name: BLD20_FLOOR2 - parent_name: Global/USA-Test/SAN JOSE/BLD20 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 2 - site_type: floor - - site: - floor: - name: FLOOR1 - parent_name: Global/USA-Test/New York/BLDNYC - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - site: - floor: - name: FLOOR2 - parent_name: Global/USA-Test/New York/BLDNYC - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 2 - site_type: floor - - site: - floor: - name: FLOOR1 - parent_name: Global/USA-Test/SAN-FRANCISCO/BLD_SF - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - site: - floor: - name: FLOOR2 - parent_name: Global/USA-Test/SAN-FRANCISCO/BLD_SF - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 2 - site_type: floor - - site: - floor: - name: FLOOR1 - parent_name: Global/USA-Test/SAN-FRANCISCO/BLD_SF1 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - site: - floor: - name: FLOOR2 - parent_name: Global/USA-Test/SAN-FRANCISCO/BLD_SF1 - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 2 - site_type: floor - - site: - floor: - name: FLOOR1_LEVEL1 - parent_name: Global/USA-Test/BERKELEY/BLDBERK - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - #India-Test Site Hierarchy - - site: - area: - name: India-Test - parent_name: Global - site_type: area - - site: - area: - name: Bangalore - parent_name: Global/India-Test - site_type: area - - site: - building: - name: Mantri Square - parent_name: Global/India-Test/Bangalore - address: Bengaluru, Karnataka, India - latitude: 12.969910 - longitude: 77.597960 - country: India - site_type: building - - site: - floor: - name: Floor1 - parent_name: Global/India-Test/Bangalore/Mantri Square - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - #Mexico Site Hierarchy - - site: - area: - name: Mexico-Test - parent_name: Global - site_type: area - - #Canada Site Hierarchy - - site: - area: - name: Canada-Test - parent_name: Global - site_type: area - - -update_sites: - - site: - building: - name: BLD12 - parent_name: Global/USA-Test/RTP - address: Cisco Systems, 7200-12 Kit Creek Rd, Morrisville, North Carolina 27560, United States - latitude: 38.8611847591779 - longitude: 72.88217248318003 - country: United States - site_type: building - - site: - floor: - name: FLOOR1 - parent_name: Global/USA-Test/SAN-FRANCISCO/BLD_SF - rf_model: Cubes And Walled Offices - width: 200.00 - length: 200.00 - height: 20.00 - floor_number: 1 - site_type: floor - - site: - building: - name: Mantri Square - parent_name: Global/India-Test/Bangalore - address: Bengaluru, Karnataka, India - latitude: 18.969910 - longitude: 20.597960 - country: India - site_type: building - - site: - floor: - name: Floor1 - parent_name: Global/India-Test/Bangalore/Mantri Square - rf_model: Cubes And Walled Offices - width: 200.00 - length: 200.00 - height: 20.00 - floor_number: 1 - site_type: floor - - -delete_sites: - - site: - area: - name: USA-Test - parent_name: Global - site_type: area - - site: - area: - name: India-Test - parent_name: Global - site_type: area - - site: - area: - name: Mexico-Test - parent_name: Global - site_type: area - - site: - area: - name: Canada-Test - parent_name: Global - site_type: area diff --git a/tests/integration/ccc_swim_management/defaults/main.yml b/tests/integration/ccc_swim_management/defaults/main.yml deleted file mode 100644 index 55a93fc23d..0000000000 --- a/tests/integration/ccc_swim_management/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" \ No newline at end of file diff --git a/tests/integration/ccc_swim_management/meta/main.yml b/tests/integration/ccc_swim_management/meta/main.yml deleted file mode 100644 index 5514b6a40c..0000000000 --- a/tests/integration/ccc_swim_management/meta/main.yml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/ccc_swim_management/tasks/main.yml b/tests/integration/ccc_swim_management/tasks/main.yml deleted file mode 100644 index 09e0832ca2..0000000000 --- a/tests/integration/ccc_swim_management/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: collect ccc test cases - find: - paths: "{{ role_path }}/tests" - patterns: "{{ testcase }}.yml" - connection: local - register: ccc_cases - tags: sanity - -- debug: - msg: "CCC Cases: {{ ccc_cases }}" - -- set_fact: - test_cases: - files: "{{ ccc_cases.files }}" - tags: sanity - -- debug: - msg: "Test Cases: {{ test_cases }}" - -- name: set test_items - set_fact: - test_items: "{{ test_cases.files | map(attribute='path') | list }}" - tags: sanity - -- debug: - msg: "Test Items: {{ test_items }}" - -- name: run test cases (connection=httpapi) - include_tasks: "{{ test_case_to_run }}" - loop: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: sanity \ No newline at end of file diff --git a/tests/integration/ccc_swim_management/tests/test_swim_management.yml b/tests/integration/ccc_swim_management/tests/test_swim_management.yml deleted file mode 100644 index f729fa02ca..0000000000 --- a/tests/integration/ccc_swim_management/tests/test_swim_management.yml +++ /dev/null @@ -1,313 +0,0 @@ ---- -- debug: msg="Starting swim management test" -- debug: msg="Role Path {{ role_path }}" - -- block: - - name: Load vars and declare dnac vars - include_vars: - file: "{{ role_path }}/vars/vars_swim_management.yml" - name: vars_map - vars: - dnac_login: &dnac_login - dnac_host: "{{ dnac_host }}" - dnac_username: "{{ dnac_username }}" - dnac_password: "{{ dnac_password }}" - dnac_verify: "{{ dnac_verify }}" - dnac_port: "{{ dnac_port }}" - dnac_version: "{{ dnac_version }}" - dnac_debug: "{{ dnac_debug }}" - dnac_log: true - dnac_log_level: DEBUG - - # - debug: - # msg: "{{ vars_map. }}" - # - debug: - # msg: "{{ vars_map. }}" - # - debug: - # msg: "{{ vars_map. }}" - -############################################# -# Clean Up # -############################################# - - - name: Delete device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_devices }}" - register: result_device_deleted - - - name: Delete site - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_sites }}" - register: result_delete_site - -############################################# -# CREATE SITE # -############################################# - - - name: Create sites - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.design_sites }}" - register: result_create_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_create_site.results }}" - # when: result_create_site is defined - - - name: Assert area creation success for each site - assert: - that: - - item.changed == true - - "'created successfully' in item.msg" - loop: "{{ result_create_site.results }}" - when: result_create_site is defined - -############################################# -# Add Devices # -############################################# - - - name: Add new device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.device_details }}" - register: result_add_device - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_add_device.results }}" - - - name: Assert device addition success - assert: - that: - - item.changed == true - - "'added to Cisco Catalyst Center' in item.msg" - loop: "{{ result_add_device.results }}" - when: result_add_device is defined - -############################################# -# ASSOCIATE WIRED DEVICE TO SITE # -############################################# - - - name: Assign wired device to site and then provision - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: merged - config: - - "{{ item }}" - loop: "{{ vars_map.associate_wired_device }}" - register: result_associate_device - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_associate_device.results }}" - # when: result_associate_device is defined - - - name: Assert Assign wired device to site and then provision - assert: - that: - - item.changed == true - loop: "{{ result_associate_device.results }}" - when: result_associate_device is defined - - -############################################# -# IMPORT IMAGE # -############################################# - - - name: SWIM task - import - cisco.dnac.swim_workflow_manager: - <<: *dnac_login - config: - - "{{ item }}" - loop: "{{ vars_map.image_details }}" - register: result_import_image - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_import_image.results }}" - - # - name: Assert import images - # assert: - # that: - # - item.changed == true - # - '"imported successfully" in item.msg' - # loop: "{{ result_import_image.results }}" - # when: result_import_image is defined - -############################################# -# TAG IMAGE # -############################################# - - - name: SWIM task - tag - cisco.dnac.swim_workflow_manager: - <<: *dnac_login - config: - - "{{ item }}" - loop: "{{ vars_map.image_golden_tagging_details}}" - register: result_tag_image - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_tag_image.results }}" - - - name: Assert tag images - assert: - that: - - item.changed == true - - '"Tagging image" in item.msg' - loop: "{{ result_tag_image.results }}" - when: result_tag_image is defined - -############################################# -# DISTRIBUTE # -############################################# - - - name: SWIM task - distribute stack - cisco.dnac.swim_workflow_manager: - <<: *dnac_login - config: - - "{{ item }}" - loop: "{{ vars_map.image_distributation_details }}" - register: result_distribute_stack - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_distribute_stack.results }}" - - - name: Assert distribution - assert: - that: - - item.changed == true - loop: "{{ result_distribute_stack.results }}" - when: result_distribute_stack is defined - -############################################# -# ACTIVATE IMAGE # -############################################# - - - name: SWIM task - activate - cisco.dnac.swim_workflow_manager: - <<: *dnac_login - config: - - "{{ item }}" - loop: "{{ vars_map.image_activation_details }}" - register: result_activate_image - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_activate_image.results }}" - - - name: Assert image activation - assert: - that: - - item.changed == true - loop: "{{ result_activate_image.results }}" - when: result_activate_image is defined - -############################################# -# UNTAG IMAGE # -############################################# - - - name: SWIM task - untag - cisco.dnac.swim_workflow_manager: - <<: *dnac_login - config: - - "{{ item }}" - loop: "{{ vars_map.image_golden_untagging_details }}" - register: result_untag_image - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_untag_image.results }}" - - - name: Assert untag images - assert: - that: - - item.changed == true - - '"Untagging of image" in item.msg' - - '"successful" in item.msg' - loop: "{{ result_untag_image.results }}" - when: result_untag_image is defined - -############################################# -# Delete Device # -############################################# - - - name: Delete device - cisco.dnac.inventory_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_devices }}" - register: result_device_deleted - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_device_deleted.results }}" - # when: result_device_deleted is defined - - - name: Assert device deletion success - assert: - that: - - result_device_deleted.changed == true - when: result_device_deleted is defined - -############################################# -# PAUSE # -############################################# - - - name: Pause for 120 seconds - pause: - seconds: 120 - -############################################# -# DELETE SITE # -############################################# - - - name: Delete sites from design_sites config - cisco.dnac.site_workflow_manager: - <<: *dnac_login - state: deleted - config: - - "{{ item }}" - loop: "{{ vars_map.delete_sites }}" - register: result_delete_site - - # - name: Debug item - # debug: - # var: item - # loop: "{{ result_delete_site.results }}" - # when: result_delete_site is defined - - - name: Assert deletion of area success for each site - assert: - that: - - item.changed == true - - "'deleted successfully' in item.response" - loop: "{{ result_delete_site.results }}" - when: result_delete_site is defined diff --git a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml b/tests/integration/ccc_swim_management/vars/vars_swim_management.yml deleted file mode 100644 index ca884bd85e..0000000000 --- a/tests/integration/ccc_swim_management/vars/vars_swim_management.yml +++ /dev/null @@ -1,122 +0,0 @@ ---- -image_details: - - import_image_details: - type: "remote" - url_details: - payload: - - source_url: http://172.21.236.183/swim/V1712_2_CCO/cat9k_iosxe.17.12.02.SPA.bin - third_party: False - - import_image_details: - type: "remote" - url_details: - payload: - - source_url: http://10.197.156.28/stda/abimishr/cat9k_iosxe.17.12.01.SPA.bin - third_party: False - -image_golden_tagging_details: - - tagging_details: - image_name: "cat9k_iosxe.17.12.01.SPA.bin" - site_name: "Global/ITest_Swim_Area/ITest_Swim_Building/ITest_Swim_Floor1" - device_role: "DISTRIBUTION" - device_image_family_name: "Cisco Catalyst 9300 Switch" - tagging: True - -image_distributation_details: - - image_distribution_details: - image_name: "cat9k_lite_iosxe.17.12.01.SPA.bin" - site_name: "Global/ITest_Swim_Area/ITest_Swim_Building/ITest_Swim_Floor1" - device_role: "DISTRIBUTION" - device_family_name: "Switches and Hubs" - device_series_name: "Cisco Catalyst 9300 Series Switches" - -image_activation_details: - - image_activation_details: - image_name: "cat9k_iosxe.17.12.02.SPA.bin" - site_name: "Global/ITest_Swim_Area/ITest_Swim_Building/ITest_Swim_Floor1" - device_role: "DISTRIBUTION" - device_family_name: "Switches and Hubs" - device_series_name: "Cisco Catalyst 9300 Series Switches" - scehdule_validate: False - distribute_if_needed: True - -image_golden_untagging_details: - - tagging_details: - image_name: "cat9k_iosxe.17.12.01.SPA.bin" - site_name: "Global/ITest_Swim_Area/ITest_Swim_Building/ITest_Swim_Floor1" - device_role: "DISTRIBUTION" - device_image_family_name: "Cisco Catalyst 9300 Switch" - tagging: False - - -design_sites: - # Create site to associate device to - - site: - area: - name: ITest_Swim_Area - parent_name: Global - site_type: area - - site: - building: - name: ITest_Swim_Building - parent_name: Global/ITest_Swim_Area - address: Bengaluru, Karnataka, India - latitude: 12.969910 - longitude: 77.597960 - country: India - site_type: building - - site: - floor: - name: ITest_Swim_Floor1 - parent_name: Global/ITest_Swim_Area/ITest_Swim_Building - rf_model: Cubes And Walled Offices - width: 100.00 - length: 100.00 - height: 10.00 - floor_number: 1 - site_type: floor - - -device_details: - - type: "NETWORK_DEVICE" - ip_address_list: ["204.1.2.3"] - device_added: True - # CLI Credentials - username: "cisco" - password: "Cisco#123" - enable_password: "Cisco#123" - # SNMP Credentials - snmp_version: v3 - snmp_username: "v3Public2" - snmp_mode: "AUTHPRIV" - snmp_auth_protocol: "SHA" - snmp_auth_passphrase: "Lablab#1234" - snmp_priv_protocol: "CISCOAES256" - snmp_priv_passphrase: "Lablab#1234" - #SNMP Retry and Timeout - snmp_retry: 3 - snmp_timeout: 5 - #CLI Transport (ssh, Telnet) - cli_transport: "ssh" - netconf_port: 830 - - -associate_wired_device: - - provision_wired_device: - - device_ip: "204.1.2.3" - site_name: "Global/ITest_Swim_Area/ITest_Swim_Building/ITest_Swim_Floor1" - resync_retry_count: 200 - resync_interval: 2 - - -delete_sites: - - site: - area: - name: ITest_Swim_Area - parent_name: Global - site_type: area - - -delete_devices: - - ip_address_list: ["204.1.2.3"] - #ip_address_list: ["204.1.2.5", "204.192.6.200"] - clean_config: False From 709d554b107840ddd714e06e042510f87afeaefc Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Mon, 29 Apr 2024 23:42:09 -0400 Subject: [PATCH 298/358] documentation changes --- .../network_compliance_workflow_manager.py | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index f2e1a7624d..9a8b62a83f 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -40,43 +40,41 @@ required: True suboptions: ip_address_list: - description: List of IP addresses of devices to Run Compliance check on or Sync Device Configuration. - Either ip_address_list or site_name is required for module to execute. - If both ip_address_list and site_name are provided, ip_address_list takes precedence, and the operations are executed - on devices that are in the ip_address_list, but only those from the specified site + description: List of IP addresses of devices to run a compliance check on or synchronize device configurations. + Either 'ip_address_list' or 'site_name' is required for module to execute. + If both 'ip_address_list' and 'site_name' are provided, 'ip_address_list' takes precedence. + Operations are executed only on devices that are in the 'ip_address_list', but only those from the specified site elements: str type: list site_name: - description: When site_name is specified, the module executes the operation on all the devices located within the specified site. + description: When 'site_name' is specified, the module executes the operation on all the devices located within the specified site. This is a string value that should represent the complete hierarchical path of the site. For example: "Global/USA/San Francisco/Building_2/floor_1" - Either site_name or ip_address_list is required for module to execute. - If both site_name and ip_address_list are provided, ip_address_list takes precedence, and the operations are executed - on devices that are in the ip_address_list, but only those from the specified site + Either 'site_name' or 'ip_address_list' is required for module to execute. + If both 'site_name' and 'ip_address_list' are provided, 'ip_address_list' takes precedence. + Operations are executed only on devices that are in the 'ip_address_list', but only those from the specified site type: str run_compliance: - description: Configuration for running a compliance check on the devices specified in the ip_address_list. + description: Configuration for running a compliance check on the devices specified in the 'ip_address_list'. type: dict suboptions: trigger_full: description: Determines if a full compliance check should be triggered. This parameter is required when running a compliance check. if it is True then compliance will be triggered for all categories. - If it is False then compliance will be triggered for categories mentioned in categories section. - required: This paramter is required in order to run compliance check on device(s). + If it is False then compliance will be triggered for categories mentioned in 'categories' section. type: bool default: False categories: description: Specifying compliance categories allows you to trigger compliance checks only for the mentioned categories. - Compliance's categories are required when trigger_full is set to False. + Compliance's categories are required when 'trigger_full' is set to False. Category can have any value among ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT' , 'EOX' , 'NETWORK_SETTINGS']. Category 'INTENT' is mapped to compliance types: NETWORK_SETTINGS, NETWORK_PROFILE, WORKFLOW, FABRIC,APPLICATION_VISIBILITY. - required: This parameter is required when trigger_full is set to False. type: bool default: False sync_device_config: - description: Determines whether to synchronize the device configuration on the devices specified in the ip_address_list. - This operation, known as "Sync device configuration," primarily addresses the status of the `RUNNING_CONFIG`. + description: Determines whether to synchronize the device configuration on the devices specified in the 'ip_address_list'. + Sync device configuration, primarily addresses the status of the `RUNNING_CONFIG`. If set to True, and if `RUNNING_CONFIG` status is non-compliant this operation would commit device running configuration to startup by issuing "write memory" to device. type: bool From 983c2e1532384dc758207e58492fe376c927c017 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 30 Apr 2024 00:39:01 -0400 Subject: [PATCH 299/358] addressed code sanity issues --- .../network_compliance_workflow_manager.yml | 10 +- .../network_compliance_workflow_manager.py | 154 +++++++----------- 2 files changed, 67 insertions(+), 97 deletions(-) diff --git a/playbooks/network_compliance_workflow_manager.yml b/playbooks/network_compliance_workflow_manager.yml index 1e24fbad31..03e25dd760 100644 --- a/playbooks/network_compliance_workflow_manager.yml +++ b/playbooks/network_compliance_workflow_manager.yml @@ -53,7 +53,7 @@ - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] run_compliance: trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] - name: Run complaince check with specific categories using Site cisco.dnac.network_compliance_workflow_manager: @@ -62,7 +62,7 @@ - site_name: "Global" run_compliance: trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] - name: Run compliance check with specific categories using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: @@ -72,7 +72,7 @@ site_name: "Global/USA/San Francisco/Building_1/floor_1" run_compliance: trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] - name: Sync Device Configuration using IP address list cisco.dnac.network_compliance_workflow_manager: @@ -121,7 +121,7 @@ - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] run_compliance: trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] sync_device_config: True - name: Run Compliance with specific categories and sync configuration with Site @@ -131,7 +131,7 @@ - site_name: "Global/USA/San Francisco/Building_1/floor_1" run_compliance: trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] sync_device_config: True - name: Run Compliance and sync configuration using both IP address list and Site diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 9a8b62a83f..e59c3ed900 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -13,7 +13,7 @@ DOCUMENTATION = r""" --- module: network_compliance_workflow_manager -short_description: Network Compliance module for managing network compliance tasks on reachable device(s) in Cisco Catalyst Center. +short_description: Network Compliance module for managing network compliance tasks on reachable device(s) in Cisco Catalyst Center. description: - Perform compliance checks or sync configurations on reachable devices using IP Address(s) or Site. - API to perform full compliance checks or specific category checks on reachable device(s). @@ -31,7 +31,7 @@ state: description: State of Cisco Catalyst Center after module completion. type: str - choices: [merged] + choices: [ merged ] default: merged config: description: List of device details for running a compliance check or synchronizing device configuration. @@ -39,7 +39,7 @@ elements: dict required: True suboptions: - ip_address_list: + ip_address_list: description: List of IP addresses of devices to run a compliance check on or synchronize device configurations. Either 'ip_address_list' or 'site_name' is required for module to execute. If both 'ip_address_list' and 'site_name' are provided, 'ip_address_list' takes precedence. @@ -49,7 +49,7 @@ site_name: description: When 'site_name' is specified, the module executes the operation on all the devices located within the specified site. This is a string value that should represent the complete hierarchical path of the site. - For example: "Global/USA/San Francisco/Building_2/floor_1" + (e.g. "Global/USA/San Francisco/Building_2/floor_1") Either 'site_name' or 'ip_address_list' is required for module to execute. If both 'site_name' and 'ip_address_list' are provided, 'ip_address_list' takes precedence. Operations are executed only on devices that are in the 'ip_address_list', but only those from the specified site @@ -58,10 +58,10 @@ description: Configuration for running a compliance check on the devices specified in the 'ip_address_list'. type: dict suboptions: - trigger_full: + trigger_full: description: Determines if a full compliance check should be triggered. This parameter is required when running a compliance check. - if it is True then compliance will be triggered for all categories. + if it is True then compliance will be triggered for all categories. If it is False then compliance will be triggered for categories mentioned in 'categories' section. type: bool default: False @@ -90,7 +90,7 @@ task.Task.get_task_by_id task.Task.get_task_tree compliance.Compliance.get_compliance_detail - + - Paths used are post /dna/intent/api/v1/compliance/ post /dna/intent/api/v1/network-device-config/write-memory @@ -117,7 +117,7 @@ run_compliance: trigger_full: True -- name: Run full compliance check on device(s) using Site +- name: Run full compliance check on device(s) using Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -152,7 +152,7 @@ run_compliance: trigger_full: True -- name: Run compliance check with specific categories on device(s) using IP address list +- name: Run compliance check with specific categories on device(s) using IP address list cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -170,7 +170,7 @@ trigger_full: False categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] -- name: Run compliance check with specific categories on device(s) using Site +- name: Run compliance check with specific categories on device(s) using Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -223,7 +223,7 @@ - site_name: "Global" sync_device_config: True -- name: Sync device configuration on device(s) using Site +- name: Sync device configuration on device(s) using Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -278,7 +278,7 @@ """ RETURN = r""" -#Case_2: When Run Compliance Operation is performed successfully on device(s), Compliance +#Case_2: When Run Compliance Operation is performed successfully on device/s, Compliance report is returned via data. dnac_response: description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK returned: always @@ -296,8 +296,8 @@ "version": "string" } -#Case_1: When Sync Device Config operations is performed successfully on device(s). -dnac_response: +#Case_1: When Sync Device Config operations is performed successfully on device/s. +dnac_response: description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK returned: always type: dict @@ -313,7 +313,7 @@ "version": "string" } -#Case_3: When Error Occurs in performing Run Compliance or Sync Device Configuration operation on device(s). +#Case_3: When Error Occurs in performing Run Compliance or Sync Device Configuration operation on device/s. dnac_response: description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK returned: always @@ -331,12 +331,13 @@ validate_list_of_dicts ) + class NetworkCompliance(DnacBase): """Class containing member attributes for network_compliance_workflow_manager module""" def __init__(self, module): """ - Initialize an instance of the class. + Initialize an instance of the class. Parameters: - module: The module associated with the class instance. Returns: @@ -374,7 +375,7 @@ def validate_input(self): temp_spec = { 'ip_address_list': {'type': 'list', 'elements': 'str', 'required': False}, 'site_name': {'type': 'str', 'required': False}, - 'run_compliance': {'type': 'dict','required': False}, + 'run_compliance': {'type': 'dict', 'required': False}, 'sync_device_config': {'type': 'bool', 'required': False, 'default': False}, } @@ -593,7 +594,7 @@ def get_device_ids_from_site(self, site_name, site_id): mgmt_ip_instance_id_map[item_dict["managementIpAddress"]] = item_dict["instanceUuid"] else: msg = 'Unable to get deviceId for device {0} in site {1} as its status is {2}'.format( - item["managementIpAddress"], site_name, item["reachabilityStatus"]) + item["managementIpAddress"], site_name, item["reachabilityStatus"]) self.log(msg, "CRITICAL") self.module.fail_json(msg=msg) @@ -634,7 +635,7 @@ def get_device_id_list(self, ip_address_list, site_name): if site_name and ip_address_list: (site_exists, site_id) = self.site_exists(site_name) if site_exists: - site_mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) + site_mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) iplist_mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) mgmt_ip_instance_id_map = { ip: instance_id @@ -646,7 +647,7 @@ def get_device_id_list(self, ip_address_list, site_name): (site_exists, site_id) = self.site_exists(site_name) if site_exists: # Retrieve device IDs associated with devices in the site - mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) + mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) # If only IP addresses are provided elif ip_address_list and not site_name: @@ -675,11 +676,12 @@ def is_sync_required(self, modified_response, mgmt_ip_instance_id_map): task_name = 'Sync Device Configuration' required = True msg = "" - #Validate if sync is required - #response = self.get_compliance_detail(compliance_detail_params_sync) + + # Validate if sync is required + # response = self.get_compliance_detail(compliance_detail_params_sync) self.log('Modified {0} Response for device(s) {1} : {2}'.format(task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), 'INFO') - #Categorize the devices based on status - 'COMPLIANT', 'NON_COMPLIANT', 'OTHER'(status other than COMPLIANT and NON_COMPLIANT) + # Categorize the devices based on status - 'COMPLIANT', 'NON_COMPLIANT', 'OTHER'(status other than COMPLIANT and NON_COMPLIANT) categorized_devices = {'COMPLIANT': {}, 'NON_COMPLIANT': {}, 'OTHER': {}} for ip_address, compliance_type in modified_response.items(): status = compliance_type[0]['status'] @@ -691,7 +693,7 @@ def is_sync_required(self, modified_response, mgmt_ip_instance_id_map): categorized_devices['OTHER'][ip_address] = compliance_type self.log("Devices Categorized based on Compliance status: {0}".format(categorized_devices), 'INFO') - #Validate if all devices are 'COMPLIANT' - then sync not required + # Validate if all devices are 'COMPLIANT' - then sync not required if len(categorized_devices['COMPLIANT']) == len(mgmt_ip_instance_id_map): msg = "Device(s) {0} are already compliant with the RUNNING_CONFIG compliance type. Therefore, {1} is not required.".format( list(mgmt_ip_instance_id_map.keys()), task_name) @@ -699,11 +701,10 @@ def is_sync_required(self, modified_response, mgmt_ip_instance_id_map): elif len(categorized_devices['NON_COMPLIANT']) != len(mgmt_ip_instance_id_map): required = False - msg = ( - "The operation {0} cannot be performed on one or more of the devices " - "{1} because the status of the RUNNING_CONFIG compliance type is not " - "as expected; it should be NON_COMPLIANT." - ).format(task_name, list(mgmt_ip_instance_id_map.keys())) + msg = ("The operation {0} cannot be performed on one or more of the devices " + "{1} because the status of the RUNNING_CONFIG compliance type is not " + "as expected; it should be NON_COMPLIANT." + ).format(task_name, list(mgmt_ip_instance_id_map.keys())) return required, msg def get_want(self, config): @@ -726,16 +727,16 @@ def get_want(self, config): compliance_detail_params_sync = {} compliance_details = {} - #Validate either ip_address_list OR site_name is present + # Validate either ip_address_list OR site_name is present ip_address_list = config.get('ip_address_list') site_name = config.get('site_name') if not ip_address_list and not site_name: - msg = 'ip_address_list is {} and site_name is {}. Either the ip_address_list or the site_name must be provided.'.format(ip_address_list, site_name) + msg = 'ip_address_list is {0} and site_name is {1}. Either the ip_address_list or the site_name must be provided.'.format(ip_address_list, site_name) self.log(msg, "ERROR") self.module.fail_json(msg=msg) - #Validate valid ip_addresses + # Validate valid ip_addresses if ip_address_list: self.validate_ip4_address_list(ip_address_list) #Remove Duplicates from list @@ -752,7 +753,7 @@ def get_want(self, config): # Log the retrieved device ID list if it's not empty self.log('Retrieved mgmt_ip_instance_id_map : {0}'.format(mgmt_ip_instance_id_map), 'DEBUG') - #Validate run_compliance parameters + # Validate run_compliance parameters run_compliance = config.get('run_compliance') sync_device_config = config.get('sync_device_config') @@ -766,7 +767,7 @@ def get_want(self, config): self.validate_run_compliance(run_compliance) run_compliance_params = { 'triggerFull': config.get('run_compliance').get('trigger_full'), - 'deviceUuids': list(mgmt_ip_instance_id_map.values()), + 'deviceUuids': list(mgmt_ip_instance_id_map.values()), } compliance_detail_params = { @@ -805,9 +806,9 @@ def get_want(self, config): # Construct the 'want' dictionary containing the desired state parameters want = {} want = dict( - ip_address_list = ip_address_list, - site_name = site_name, - mgmt_ip_instance_id_map = mgmt_ip_instance_id_map, + ip_address_list=ip_address_list, + site_name=site_name, + mgmt_ip_instance_id_map=mgmt_ip_instance_id_map, run_compliance_params=run_compliance_params, sync_device_config_params=sync_device_config_params, compliance_detail_params=compliance_detail_params, @@ -819,36 +820,6 @@ def get_want(self, config): return self - # def get_have(self, config): - # """ - # Retrieve and store compliance details if sync_device_config is enabled. - - # Parameters: - # config (dict): A dictionary containing configuration details. - - # Returns: - # self (object): An instance of a class used for interacting with Cisco Catalyst Center. - # Description: - # In this method if sync_device_config is enabled, it proceeds to retrieve compliance details using the - # specified parameters. The retrieved details are then modified and stored in the 'have' attribute for later reference. - # Additionally, a log message is generated to indicate that the compliance details have been successfully retrieved - # and stored. - # """ - # sync_device_config = config.get('sync_device_config') - # have = {} - - # if sync_device_config: - # # Retrieve compliance details - # response = self.get_compliance_detail(self.want.get('compliance_detail_params_sync')) - # modified_response = self.modify_compliance_response(response, self.want.get('mgmt_ip_instance_id_map')) - - # # Store modified compliance details - # have['compliance_details'] = modified_response - # self.log("Compliance details have been retrieved and stored: {0}.".format(modified_response), "INFO") - - # self.have = have - # return self - def get_compliance_detail(self, compliance_detail_params): response = self.dnac_apply['exec']( family="compliance", @@ -882,8 +853,8 @@ def modify_compliance_response(self, response, mgmt_ip_instance_id_map): # Find the corresponding management IP address for the device UUID ip_address = next((ip for ip, uuid in mgmt_ip_instance_id_map.items() if uuid == device_uuid)) - # If the IP address is found, add the item to the modified response - #if ip_address and item.get('status')!= 'NOT_APPLICABLE': + # If the IP address is found, add the item to the modified response + # If ip_address and item.get('status')!= 'NOT_APPLICABLE': if ip_address: if ip_address not in modified_response: modified_response[ip_address] = [] @@ -910,11 +881,10 @@ def run_compliance(self, run_compliance_params): function="run_compliance", params=run_compliance_params, op_modifies=True, - ) + ) self.log("The response received post run_compliancee API call is {0}".format(str(result)), "DEBUG") self.result.update(dict(response=result['response'])) self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") - # Return the task ID of the API task created return result.response.get('taskId') # Log and handle any exceptions that occur during the execution @@ -941,7 +911,7 @@ def sync_device_config(self, sync_device_config_params): function="commit_device_configuration", params=sync_device_config_params, op_modifies=True, - ) + ) self.log("The response received post commit_device_configuration API call is {0}".format(str(result)), "DEBUG") self.result.update(dict(response=result['response'])) self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") @@ -969,11 +939,11 @@ def get_task_status(self, task_id, task_name): # Make an API call to retrieve the task tree try: response = self.dnac_apply['exec']( - family="task", - function='get_task_by_id', - params=dict(task_id=task_id), - op_modifies=True, - ) + family="task", + function='get_task_by_id', + params=dict(task_id=task_id), + op_modifies=True, + ) response = response.response self.log("Task status for the Task {0} with Task id {1} is {2}".format(task_name, str(task_id), str(response)), "INFO") return response @@ -999,10 +969,10 @@ def get_task_tree(self, task_id, task_name): # Make an API call to retrieve the task status try: response = self.dnac_apply['exec']( - family="task", - function='get_task_tree', - params=dict(task_id=task_id), - op_modifies=True, + family="task", + function='get_task_tree', + params=dict(task_id=task_id), + op_modifies=True, ) response = response.response self.log("Task tree for the Task {0} with Task id {1} is {2}".format(task_name, str(task_id), str(response)), "INFO") @@ -1160,15 +1130,15 @@ def get_compliance_task_status(self, task_id, mgmt_ip_instance_id_map): def get_sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): """ - This function manages the status of device configuration synchronization tasks in Cisco Catalyst Center. - Parameters: + This function manages the status of device configuration synchronization tasks in Cisco Catalyst Center. + Parameters: - task_id: ID of the synchronization task - mgmt_ip_instance_id_map: Mapping of management IP addresses to instance IDs Returns: self (object): An instance of a class used for interacting with Cisco Catalyst Center. - Description: - It validates if synchronization is required, categorizes devices based on compliance status, and checks task completion status. - If all devices are already compliant, it logs a success message. If some devices have unexpected statuses, it logs an error. + Description: + It validates if synchronization is required, categorizes devices based on compliance status, and checks task completion status. + If all devices are already compliant, it logs a success message. If some devices have unexpected statuses, it logs an error. It continuously checks the task status until completion, updating the result accordingly. """ @@ -1176,6 +1146,9 @@ def get_sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): start_time = time.time() while True: + success_devices = [] + failed_devices = [] + response = self.get_task_tree(task_id, task_name) # Check if response returned @@ -1194,9 +1167,6 @@ def get_sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): self.handle_error(task_name, mgmt_ip_instance_id_map, failure_reason) break - success_devices = [] - failed_devices = [] - for item in response[1:]: progress = item['progress'] for ip, device_id in mgmt_ip_instance_id_map.items(): @@ -1233,8 +1203,8 @@ def get_diff_merged(self): Parameters: None Returns: self (object): An instance of a class used for interacting with Cisco Catalyst Center. - Description: - This method orchestrates compliance check operation and device configuration synchronization tasks specified in a playbook. + Description: + This method orchestrates compliance check operation and device configuration synchronization tasks specified in a playbook. It ensures all required tasks are present, executes them, and checks their status, facilitating smooth playbook execution. """ @@ -1280,7 +1250,7 @@ def verify_diff_merged(self, config): # Get compliance details after running sync_device_config response = self.get_compliance_detail(self.want.get('compliance_detail_params_sync')) compliance_details_after = self.modify_compliance_response(response, self.want.get('mgmt_ip_instance_id_map')) - self.log("Compliance details after running sync_device_config: {}.".format(compliance_details_after), "INFO") + self.log("Compliance details after running sync_device_config: {0}.".format(compliance_details_after), "INFO") all_statuses_before = [] From b12b00120c6af374948df2f92099a769ddc90850 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 30 Apr 2024 00:50:44 -0400 Subject: [PATCH 300/358] addressed code sanity issues --- .../network_compliance_workflow_manager.py | 57 ++++++++++--------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index e59c3ed900..09c9f46a8b 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -65,14 +65,14 @@ If it is False then compliance will be triggered for categories mentioned in 'categories' section. type: bool default: False - categories: + categories: description: Specifying compliance categories allows you to trigger compliance checks only for the mentioned categories. Compliance's categories are required when 'trigger_full' is set to False. Category can have any value among ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT' , 'EOX' , 'NETWORK_SETTINGS']. - Category 'INTENT' is mapped to compliance types: NETWORK_SETTINGS, NETWORK_PROFILE, WORKFLOW, FABRIC,APPLICATION_VISIBILITY. + Category 'INTENT' is mapped to compliance types 'NETWORK_SETTINGS', 'NETWORK_PROFILE', 'WORKFLOW', 'FABRIC', 'APPLICATION_VISIBILITY'. type: bool default: False - sync_device_config: + sync_device_config: description: Determines whether to synchronize the device configuration on the devices specified in the 'ip_address_list'. Sync device configuration, primarily addresses the status of the `RUNNING_CONFIG`. If set to True, and if `RUNNING_CONFIG` status is non-compliant this operation would commit device running configuration @@ -279,7 +279,7 @@ RETURN = r""" #Case_2: When Run Compliance Operation is performed successfully on device/s, Compliance report is returned via data. -dnac_response: +sample_response_1: description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK returned: always type: dict @@ -297,7 +297,7 @@ } #Case_1: When Sync Device Config operations is performed successfully on device/s. -dnac_response: +sample_response_2: description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK returned: always type: dict @@ -314,7 +314,7 @@ } #Case_3: When Error Occurs in performing Run Compliance or Sync Device Configuration operation on device/s. -dnac_response: +sample_response_3: description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK returned: always type: dict @@ -702,9 +702,9 @@ def is_sync_required(self, modified_response, mgmt_ip_instance_id_map): elif len(categorized_devices['NON_COMPLIANT']) != len(mgmt_ip_instance_id_map): required = False msg = ("The operation {0} cannot be performed on one or more of the devices " - "{1} because the status of the RUNNING_CONFIG compliance type is not " - "as expected; it should be NON_COMPLIANT." - ).format(task_name, list(mgmt_ip_instance_id_map.keys())) + "{1} because the status of the RUNNING_CONFIG compliance type is not " + "as expected; it should be NON_COMPLIANT." + ).format(task_name, list(mgmt_ip_instance_id_map.keys())) return required, msg def get_want(self, config): @@ -732,14 +732,15 @@ def get_want(self, config): site_name = config.get('site_name') if not ip_address_list and not site_name: - msg = 'ip_address_list is {0} and site_name is {1}. Either the ip_address_list or the site_name must be provided.'.format(ip_address_list, site_name) + msg = 'ip_address_list is {0} and site_name is {1}. Either the ip_address_list or the site_name must be provided.'.format( + ip_address_list, site_name) self.log(msg, "ERROR") self.module.fail_json(msg=msg) # Validate valid ip_addresses if ip_address_list: self.validate_ip4_address_list(ip_address_list) - #Remove Duplicates from list + # Remove Duplicates from list ip_address_list = list(set(ip_address_list)) # Retrieve device ID list @@ -822,11 +823,11 @@ def get_want(self, config): def get_compliance_detail(self, compliance_detail_params): response = self.dnac_apply['exec']( - family="compliance", - function='get_compliance_detail', - params=compliance_detail_params, - op_modifies=True, - ) + family="compliance", + function='get_compliance_detail', + params=compliance_detail_params, + op_modifies=True + ) response = response.response self.log("The response received post get_compliance_detail API call is {0}".format(str(response)), "DEBUG") @@ -881,7 +882,7 @@ def run_compliance(self, run_compliance_params): function="run_compliance", params=run_compliance_params, op_modifies=True, - ) + ) self.log("The response received post run_compliancee API call is {0}".format(str(result)), "DEBUG") self.result.update(dict(response=result['response'])) self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") @@ -911,7 +912,7 @@ def sync_device_config(self, sync_device_config_params): function="commit_device_configuration", params=sync_device_config_params, op_modifies=True, - ) + ) self.log("The response received post commit_device_configuration API call is {0}".format(str(result)), "DEBUG") self.result.update(dict(response=result['response'])) self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") @@ -943,7 +944,7 @@ def get_task_status(self, task_id, task_name): function='get_task_by_id', params=dict(task_id=task_id), op_modifies=True, - ) + ) response = response.response self.log("Task status for the Task {0} with Task id {1} is {2}".format(task_name, str(task_id), str(response)), "INFO") return response @@ -973,7 +974,7 @@ def get_task_tree(self, task_id, task_name): function='get_task_tree', params=dict(task_id=task_id), op_modifies=True, - ) + ) response = response.response self.log("Task tree for the Task {0} with Task id {1} is {2}".format(task_name, str(task_id), str(response)), "INFO") return response @@ -1035,9 +1036,9 @@ def exit_while_loop(self, start_time, task_id, task_name, response): if response.get('data'): # If there is data in the response, include it in the error message msg = "Task {0} with task id {1} has not completed within the timeout period. Task Status: {2} ".format( - task_name, task_id, response.get('data')) + task_name, task_id, response.get('data')) else: - # If there is no data in the response, generate a generic error message + # If there is no data in the response, generate a generic error message msg = "Task {0} with task id {1} has not completed within the timeout period.".format( task_name, task_id) @@ -1120,7 +1121,7 @@ def get_compliance_task_status(self, task_id, mgmt_ip_instance_id_map): self.update_result('success', True, self.msg, 'INFO', modified_response) break - #Check if task failed + # Check if task failed elif 'failed' in response.get('progress').lower(): self.msg = "Failed to {0} on the following device(s): {1}".format(task_name, list(mgmt_ip_instance_id_map.keys())) self.update_result('failed', False, self.msg, 'CRITICAL') @@ -1246,13 +1247,11 @@ def verify_diff_merged(self, config): compliance_details_before = self.want.get('compliance_details') self.log("Compliance details before running sync_device_config: {0}".format(compliance_details_before), "INFO") - # Get compliance details after running sync_device_config response = self.get_compliance_detail(self.want.get('compliance_detail_params_sync')) compliance_details_after = self.modify_compliance_response(response, self.want.get('mgmt_ip_instance_id_map')) self.log("Compliance details after running sync_device_config: {0}.".format(compliance_details_after), "INFO") - all_statuses_before = [] all_statuses_after = [] for ip_address, compliance_type in compliance_details_before.items(): @@ -1267,14 +1266,16 @@ def verify_diff_merged(self, config): self.log('Verified the success of the Sync Device Configuration operation.') else: self.log("Sync Device Configuration operation may have been unsuccessful since " - "not all devices have 'COMPLIANT' status after the operation.", - "WARNING") + "not all devices have 'COMPLIANT' status after the operation.", + "WARNING") else: self.log("Sync_device_config may not have been performed since devices have status other than 'NON_COMPLIANT'.", "WARNING") return self + def main(): - """ main entry point for module execution + """ + main entry point for module execution """ # Define the specification for the module's arguments From b3116f6708b465ec9f7bf9af297f910699b1ce8b Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 30 Apr 2024 00:58:59 -0400 Subject: [PATCH 301/358] addressed code sanity issues --- .../network_compliance_workflow_manager.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 09c9f46a8b..a50d984ef8 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -5,7 +5,6 @@ """Ansible module to perform Network Compliance Operations on devices in Cisco Catalyst Center.""" from __future__ import absolute_import, division, print_function -import time __metaclass__ = type __author__ = ("Rugvedi Kapse, Madhan Sankaranarayanan") @@ -75,7 +74,7 @@ sync_device_config: description: Determines whether to synchronize the device configuration on the devices specified in the 'ip_address_list'. Sync device configuration, primarily addresses the status of the `RUNNING_CONFIG`. - If set to True, and if `RUNNING_CONFIG` status is non-compliant this operation would commit device running configuration + If set to True, and if `RUNNING_CONFIG` status is non-compliant this operation would commit device running configuration to startup by issuing "write memory" to device. type: bool default: False @@ -325,6 +324,7 @@ } """ +import time from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.dnac.plugins.module_utils.dnac import ( DnacBase, @@ -702,9 +702,9 @@ def is_sync_required(self, modified_response, mgmt_ip_instance_id_map): elif len(categorized_devices['NON_COMPLIANT']) != len(mgmt_ip_instance_id_map): required = False msg = ("The operation {0} cannot be performed on one or more of the devices " - "{1} because the status of the RUNNING_CONFIG compliance type is not " - "as expected; it should be NON_COMPLIANT." - ).format(task_name, list(mgmt_ip_instance_id_map.keys())) + "{1} because the status of the RUNNING_CONFIG compliance type is not " + "as expected; it should be NON_COMPLIANT." + ).format(task_name, list(mgmt_ip_instance_id_map.keys())) return required, msg def get_want(self, config): @@ -1215,7 +1215,7 @@ def get_diff_merged(self): 'sync_device_config_params': (self.sync_device_config, self.get_sync_config_task_status) } - #Iterate through the action map and execute specified actions + # Iterate through the action map and execute specified actions for action_param, (action_func, status_func) in action_map.items(): # Execute the action and check its status @@ -1266,15 +1266,15 @@ def verify_diff_merged(self, config): self.log('Verified the success of the Sync Device Configuration operation.') else: self.log("Sync Device Configuration operation may have been unsuccessful since " - "not all devices have 'COMPLIANT' status after the operation.", - "WARNING") + "not all devices have 'COMPLIANT' status after the operation.", + "WARNING") else: self.log("Sync_device_config may not have been performed since devices have status other than 'NON_COMPLIANT'.", "WARNING") return self def main(): - """ + """ main entry point for module execution """ From cfac685e1693d8ea140d16e1cd3d57ad79df51d3 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 30 Apr 2024 01:05:18 -0400 Subject: [PATCH 302/358] addressed code sanity issues --- plugins/modules/network_compliance_workflow_manager.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index a50d984ef8..fd1658ba15 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -702,9 +702,9 @@ def is_sync_required(self, modified_response, mgmt_ip_instance_id_map): elif len(categorized_devices['NON_COMPLIANT']) != len(mgmt_ip_instance_id_map): required = False msg = ("The operation {0} cannot be performed on one or more of the devices " - "{1} because the status of the RUNNING_CONFIG compliance type is not " - "as expected; it should be NON_COMPLIANT." - ).format(task_name, list(mgmt_ip_instance_id_map.keys())) + "{1} because the status of the RUNNING_CONFIG compliance type is not " + "as expected; it should be NON_COMPLIANT." + ).format(task_name, list(mgmt_ip_instance_id_map.keys())) return required, msg def get_want(self, config): @@ -1265,8 +1265,7 @@ def verify_diff_merged(self, config): if len(set(all_statuses_after)) == 1 and all_statuses_after[0] == 'COMPLIANT': self.log('Verified the success of the Sync Device Configuration operation.') else: - self.log("Sync Device Configuration operation may have been unsuccessful since " - "not all devices have 'COMPLIANT' status after the operation.", + self.log("Sync Device Configuration operation may have been unsuccessful since not all devices have 'COMPLIANT' status after the operation.", "WARNING") else: self.log("Sync_device_config may not have been performed since devices have status other than 'NON_COMPLIANT'.", "WARNING") From 9577d85f9834058b018fdfb7daa79a34b00d25e2 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 30 Apr 2024 01:08:28 -0400 Subject: [PATCH 303/358] addressed code sanity issues --- plugins/modules/network_compliance_workflow_manager.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index fd1658ba15..29f5c1441c 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -1265,8 +1265,11 @@ def verify_diff_merged(self, config): if len(set(all_statuses_after)) == 1 and all_statuses_after[0] == 'COMPLIANT': self.log('Verified the success of the Sync Device Configuration operation.') else: - self.log("Sync Device Configuration operation may have been unsuccessful since not all devices have 'COMPLIANT' status after the operation.", - "WARNING") + self.log( + "Sync Device Configuration operation may have been unsuccessful " + "since not all devices have 'COMPLIANT' status after the operation.", + "WARNING" + ) else: self.log("Sync_device_config may not have been performed since devices have status other than 'NON_COMPLIANT'.", "WARNING") return self From e483b99b40be4518594bbcbdba5e0d1513d4ff5f Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 30 Apr 2024 06:51:01 -0400 Subject: [PATCH 304/358] doc change --- .../network_compliance_workflow_manager.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 29f5c1441c..b7d1989d3c 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -42,9 +42,9 @@ description: List of IP addresses of devices to run a compliance check on or synchronize device configurations. Either 'ip_address_list' or 'site_name' is required for module to execute. If both 'ip_address_list' and 'site_name' are provided, 'ip_address_list' takes precedence. - Operations are executed only on devices that are in the 'ip_address_list', but only those from the specified site - elements: str + Operations are executed only on devices that are in the 'ip_address_list', but only those from the specified site. type: list + elements: str site_name: description: When 'site_name' is specified, the module executes the operation on all the devices located within the specified site. This is a string value that should represent the complete hierarchical path of the site. @@ -63,14 +63,14 @@ if it is True then compliance will be triggered for all categories. If it is False then compliance will be triggered for categories mentioned in 'categories' section. type: bool - default: False + default: True categories: description: Specifying compliance categories allows you to trigger compliance checks only for the mentioned categories. Compliance's categories are required when 'trigger_full' is set to False. Category can have any value among ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT' , 'EOX' , 'NETWORK_SETTINGS']. Category 'INTENT' is mapped to compliance types 'NETWORK_SETTINGS', 'NETWORK_PROFILE', 'WORKFLOW', 'FABRIC', 'APPLICATION_VISIBILITY'. - type: bool - default: False + type: list + elements: str sync_device_config: description: Determines whether to synchronize the device configuration on the devices specified in the 'ip_address_list'. Sync device configuration, primarily addresses the status of the `RUNNING_CONFIG`. @@ -375,7 +375,10 @@ def validate_input(self): temp_spec = { 'ip_address_list': {'type': 'list', 'elements': 'str', 'required': False}, 'site_name': {'type': 'str', 'required': False}, - 'run_compliance': {'type': 'dict', 'required': False}, + 'run_compliance': { + 'type': 'dict', + 'required': False, + }, 'sync_device_config': {'type': 'bool', 'required': False, 'default': False}, } From 037160c74490e977ee1ba74650f7605928a2287b Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 30 Apr 2024 06:56:23 -0400 Subject: [PATCH 305/358] addressed code sanity issues --- plugins/modules/network_compliance_workflow_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index b7d1989d3c..45126f7f2e 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -376,7 +376,7 @@ def validate_input(self): 'ip_address_list': {'type': 'list', 'elements': 'str', 'required': False}, 'site_name': {'type': 'str', 'required': False}, 'run_compliance': { - 'type': 'dict', + 'type': 'dict', 'required': False, }, 'sync_device_config': {'type': 'bool', 'required': False, 'default': False}, From fb3e5b7ecc9ca907a315a0939282da2818b8f50c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 30 Apr 2024 10:22:02 -0400 Subject: [PATCH 306/358] addressed PR review comments --- .../network_compliance_workflow_manager.py | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 45126f7f2e..44db985752 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -17,7 +17,7 @@ - Perform compliance checks or sync configurations on reachable devices using IP Address(s) or Site. - API to perform full compliance checks or specific category checks on reachable device(s). - API to sync device configuration on device(s). -version_added: '6.6.0' +version_added: '6.8.0' extends_documentation_fragment: - cisco.dnac.workflow_manager_params author: Rugvedi Kapse (@rukapse) @@ -753,9 +753,6 @@ def get_want(self, config): msg = "Failed to retrieve device IDs for the provided IP addresses: {0} or site name: {1}.".format(ip_address_list, site_name) self.log(msg, 'ERROR') self.module.fail_json(msg) - else: - # Log the retrieved device ID list if it's not empty - self.log('Retrieved mgmt_ip_instance_id_map : {0}'.format(mgmt_ip_instance_id_map), 'DEBUG') # Validate run_compliance parameters run_compliance = config.get('run_compliance') @@ -825,16 +822,31 @@ def get_want(self, config): return self def get_compliance_detail(self, compliance_detail_params): - response = self.dnac_apply['exec']( - family="compliance", - function='get_compliance_detail', - params=compliance_detail_params, - op_modifies=True - ) - response = response.response + """ + Execute the GET compliance detail operation. + Args: + compliance_detail_params (dict): A dictionary containing parameters for the compliance detail operation. + Returns: + dict: A dictionary containing details of the compliance detail response. + Returns None if there is an error. + """ + # Execute the GET compliance detial operation + try: + response = self.dnac_apply['exec']( + family="compliance", + function='get_compliance_detail', + params=compliance_detail_params, + op_modifies=True + ) + response = response.response + + self.log("The response received post get_compliance_detail API call is {0}".format(str(response)), "DEBUG") + return response - self.log("The response received post get_compliance_detail API call is {0}".format(str(response)), "DEBUG") - return response + # Log and handle any exceptions that occur during the execution + except Exception as e: + self.log("An error occurred while retrieving Compliance Details using get_compliance_detail API call: {0}".format(str(e)), "ERROR") + return None def modify_compliance_response(self, response, mgmt_ip_instance_id_map): """ @@ -1048,6 +1060,7 @@ def exit_while_loop(self, start_time, task_id, task_name, response): # Update the result with failure status and log the error message self.update_result('failed', False, msg, 'ERROR') return True + return False def handle_error(self, task_name, mgmt_ip_instance_id_map, failure_reason=None): @@ -1072,6 +1085,7 @@ def handle_error(self, task_name, mgmt_ip_instance_id_map, failure_reason=None): # Update the result with failure status and log the error message self.update_result('failed', False, self.msg, 'ERROR') + return self def get_compliance_task_status(self, task_id, mgmt_ip_instance_id_map): @@ -1230,6 +1244,7 @@ def get_diff_merged(self): self.update_result('failed', False, self.msg, 'CRITICAL') else: status_func(result_task_id, self.want.get('mgmt_ip_instance_id_map')).check_return_status() + return self def verify_diff_merged(self, config): @@ -1275,6 +1290,8 @@ def verify_diff_merged(self, config): ) else: self.log("Sync_device_config may not have been performed since devices have status other than 'NON_COMPLIANT'.", "WARNING") + else: + self.log("Verification of configuration is not required.", "INFO") return self From 8e919199dd12a805ae7cfc35e1a798622ed2610a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Tue, 30 Apr 2024 10:29:13 -0400 Subject: [PATCH 307/358] addressed PR review comments --- plugins/modules/network_compliance_workflow_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 44db985752..652bb10d69 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -54,7 +54,7 @@ Operations are executed only on devices that are in the 'ip_address_list', but only those from the specified site type: str run_compliance: - description: Configuration for running a compliance check on the devices specified in the 'ip_address_list'. + description: Configuration for running a compliance check on the devices specified in the 'ip_address_list' and/or 'site_name'. type: dict suboptions: trigger_full: @@ -1291,7 +1291,7 @@ def verify_diff_merged(self, config): else: self.log("Sync_device_config may not have been performed since devices have status other than 'NON_COMPLIANT'.", "WARNING") else: - self.log("Verification of configuration is not required.", "INFO") + self.log("Verification of configuration is not required.", "INFO") return self From 32b8da0269bb93837bdc983dfdfac4c30cdb95b6 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 1 May 2024 17:06:00 -0400 Subject: [PATCH 308/358] combined both iplist and site --- .../network_compliance_workflow_manager.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 652bb10d69..13d16c6aa8 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -41,8 +41,8 @@ ip_address_list: description: List of IP addresses of devices to run a compliance check on or synchronize device configurations. Either 'ip_address_list' or 'site_name' is required for module to execute. - If both 'ip_address_list' and 'site_name' are provided, 'ip_address_list' takes precedence. - Operations are executed only on devices that are in the 'ip_address_list', but only those from the specified site. + If both 'site_name' and 'ip_address_list' are provided, operations are performed on devices that are present in both the + 'ip_address_list' and the specified site, with consideration given to devices that appear in both sources. type: list elements: str site_name: @@ -50,8 +50,8 @@ This is a string value that should represent the complete hierarchical path of the site. (e.g. "Global/USA/San Francisco/Building_2/floor_1") Either 'site_name' or 'ip_address_list' is required for module to execute. - If both 'site_name' and 'ip_address_list' are provided, 'ip_address_list' takes precedence. - Operations are executed only on devices that are in the 'ip_address_list', but only those from the specified site + If both 'site_name' and 'ip_address_list' are provided, operations are performed on devices that are present in both the + 'ip_address_list' and the specified site, with consideration given to devices that appear in both sources. type: str run_compliance: description: Configuration for running a compliance check on the devices specified in the 'ip_address_list' and/or 'site_name'. @@ -640,11 +640,9 @@ def get_device_id_list(self, ip_address_list, site_name): if site_exists: site_mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) iplist_mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) - mgmt_ip_instance_id_map = { - ip: instance_id - for ip, instance_id in iplist_mgmt_ip_instance_id_map.items() - if ip in site_mgmt_ip_instance_id_map - } + # Retrieve device IDs associated with devices from the IP address list and the site + mgmt_ip_instance_id_map = {**site_mgmt_ip_instance_id_map, **iplist_mgmt_ip_instance_id_map} + # If only site name is provided elif site_name and not ip_address_list: (site_exists, site_id) = self.site_exists(site_name) From 742d419fadfbea2537955f0877b41bfb1935c456 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 1 May 2024 17:18:04 -0400 Subject: [PATCH 309/358] modification to support py2.7 --- plugins/modules/network_compliance_workflow_manager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 13d16c6aa8..872afaca30 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -637,11 +637,12 @@ def get_device_id_list(self, ip_address_list, site_name): # Check if both site name and IP address list are provided if site_name and ip_address_list: (site_exists, site_id) = self.site_exists(site_name) + # Retrieve device IDs associated with devices from the IP address list and the site if site_exists: site_mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) + mgmt_ip_instance_id_map = site_mgmt_ip_instance_id_map.copy() iplist_mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) - # Retrieve device IDs associated with devices from the IP address list and the site - mgmt_ip_instance_id_map = {**site_mgmt_ip_instance_id_map, **iplist_mgmt_ip_instance_id_map} + mgmt_ip_instance_id_map.update(iplist_mgmt_ip_instance_id_map) # If only site name is provided elif site_name and not ip_address_list: From 5e1a258e70e28e007c1c40219b88cf225def7d6c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 1 May 2024 17:33:01 -0400 Subject: [PATCH 310/358] modification to support py2.7 --- .../network_compliance_workflow_manager.py | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 872afaca30..471340bab7 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -623,38 +623,24 @@ def get_device_id_list(self, ip_address_list, site_name): dict: A dictionary mapping management IP addresses to device IDs for the specified devices. Description: This method queries Cisco Catalyst Center to retrieve the unique device IDs associated with devices having the - specified IP addresses or belonging to the specified site. If both IP addresses and site name are provided, - it first checks if the site exists, retrieves the device IDs associated with devices in that site, and then - filters them based on the provided IP addresses. If only a site name is provided, it retrieves the device IDs - associated with devices in that site. If only IP addresses are provided, it directly retrieves the device IDs - associated with those IP addresses. - Note: If a device is not found in Cisco Catalyst Center, it logs a message with error severity. + specified IP addresses or belonging to the specified site. """ # Initialize a dictionary to store management IP addresses and their corresponding device IDs mgmt_ip_instance_id_map = {} # Check if both site name and IP address list are provided - if site_name and ip_address_list: - (site_exists, site_id) = self.site_exists(site_name) - # Retrieve device IDs associated with devices from the IP address list and the site - if site_exists: - site_mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) - mgmt_ip_instance_id_map = site_mgmt_ip_instance_id_map.copy() - iplist_mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) - mgmt_ip_instance_id_map.update(iplist_mgmt_ip_instance_id_map) - - # If only site name is provided - elif site_name and not ip_address_list: + if site_name: (site_exists, site_id) = self.site_exists(site_name) if site_exists: # Retrieve device IDs associated with devices in the site - mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) + site_mgmt_ip_instance_id_map = self.get_device_ids_from_site(site_name, site_id) + mgmt_ip_instance_id_map.update(site_mgmt_ip_instance_id_map) - # If only IP addresses are provided - elif ip_address_list and not site_name: + if ip_address_list: # Retrieve device IDs associated with devices having specified IP addresses - mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) + iplist_mgmt_ip_instance_id_map = self.get_device_ids_from_ip(ip_address_list) + mgmt_ip_instance_id_map.update(iplist_mgmt_ip_instance_id_map) return mgmt_ip_instance_id_map From bbfca63644c44e73ebddb0cb5510c502ba059a4a Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Wed, 1 May 2024 17:36:17 -0400 Subject: [PATCH 311/358] code sanity issue fixed --- plugins/modules/network_compliance_workflow_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 471340bab7..a5a0d5838e 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -623,7 +623,7 @@ def get_device_id_list(self, ip_address_list, site_name): dict: A dictionary mapping management IP addresses to device IDs for the specified devices. Description: This method queries Cisco Catalyst Center to retrieve the unique device IDs associated with devices having the - specified IP addresses or belonging to the specified site. + specified IP addresses or belonging to the specified site. """ # Initialize a dictionary to store management IP addresses and their corresponding device IDs From 4df74916cae0dd1412e4bc8c568b892c06247542 Mon Sep 17 00:00:00 2001 From: Abinash Date: Thu, 2 May 2024 09:44:51 +0000 Subject: [PATCH 312/358] Resolving review comments for device configs backup --- .../device_configs_backup_workflow_manager.py | 54 ++++++++++++++++--- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/plugins/modules/device_configs_backup_workflow_manager.py b/plugins/modules/device_configs_backup_workflow_manager.py index 8764c7bfaa..6ff70e0607 100644 --- a/plugins/modules/device_configs_backup_workflow_manager.py +++ b/plugins/modules/device_configs_backup_workflow_manager.py @@ -14,7 +14,7 @@ module: device_configs_backup_workflow_manager short_description: Resource module for device_configs_backup functions description: -- Manage operation related to image importation, distribution, activation and tagging image as golden +- Manage operation related to taking the backup of running config, static config and vlan.dat.bat version_added: '6.13.0' extends_documentation_fragment: - cisco.dnac.workflow_manager_params @@ -32,7 +32,8 @@ default: merged config: description: - - List of details of device being managed. + - List of details regarding the device configuration backups being taken + - Alteast one of the paramters mentioned in the suboptions must be passed in config type: list elements: dict required: true @@ -64,6 +65,13 @@ file_path: description: Location of the path or folder where the configs need to be exported in local system. type: str + default: tmp + file_password: + description: + - Optional file password for zipping and unzipping the config file. + - Minimum password length is 8 and it should contain atleast one lower case letter, one uppercase + letter, one digit and one special characters from -=\\\\\\\\;,./~!@$%^&*()_+{}[]|:?" + type: str requirements: - dnacentersdk == 2.6.10 - python >= 3.5 @@ -199,7 +207,8 @@ def validate_input(self): 'type': {'type': 'str', 'required': False}, 'series': {'type': 'str', 'required': False}, 'collection_status': {'type': 'str', 'required': False}, - 'file_path': {'type': 'str', 'required': False, 'default': 'tmp'} + 'file_path': {'type': 'str', 'required': False, 'default': 'tmp'}, + 'file_password': {'type': 'str', 'required': False} } # Validate device_configs_backup params valid_device_configs_backup, invalid_params = validate_list_of_dicts( @@ -268,6 +277,7 @@ def get_device_ids_list(self): msg = "Please provide atleast one device parameter as mentioned in the documentation to fetch device configs" self.log(msg, "CRITICAL") self.module.fail_json(msg=msg) + response = self.dnac_apply['exec']( family="devices", function='get_device_list', @@ -279,7 +289,7 @@ def get_device_ids_list(self): self.log("Length of the device list fetched from the API 'get_device_list' is {0}".format(str(device_list)), "INFO") if len(device_list) == 0: - msg = "No devices with the given paramters couldn't be found in the inventory" + msg = "Couldn't find any devices in the inventory that match the given parameters." self.log(msg, "CRITICAL") self.module.fail_json(msg=msg) @@ -316,6 +326,20 @@ def password_generator(self): self.log("File password is generated using the password generator API", "INFO") return password + def validate_password(self, password=None): + """ + Validates the user-defined password for Cisco catalyst Center's requirements + Min password length is 8 and it should contain atleast one lower case letter, + one uppercase letter, one digit and one special characters from -=\\\\;,./~!@#$%^&*()_+{}[]|:? + """ + + pattern = r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[-=\\;,./~!@#$%^&*()_+{}[\]|:?\"]).{8,}$" + self.log("User defined password is {0}".format(password), "DEBUG") + if re.match(pattern, password): + return True + else: + return False + def get_want(self): """ Get all device_configs_backup related informantion from the playbook and preprare it to call @@ -336,7 +360,20 @@ def get_want(self): self.want = {} self.want["deviceId"] = self.get_device_ids_list() - self.want["password"] = self.password_generator() + if self.validated_config[0].get("file_password"): + password = self.validated_config[0].get("file_password") + if self.validate_password(password=password) is True: + self.want["password"] = password + + else: + msg = "Invalid input as Invalid password. Min password length is 8 and it should contain" + \ + "atleast one lower case letter, one uppercase letter, one digit and one special characters" + \ + "from -=\\\\\\\\;,./~!@#$%^&*()_+{}[]|:?" + self.log(msg, "CRITICAL") + self.module.fail_json(msg=msg) + + else: + self.want["password"] = self.password_generator() self.msg = "Successfully collected all parameters from playbook " + \ "for comparison" @@ -405,11 +442,12 @@ def get_task_status(self, task_id=None): self.log("Task status for the task id (before checking status) {0} is {1}".format(str(task_id), str(response)), "INFO") progress = response.get('progress') + self.log("Progress of the task is {0}".format(str(progress)), "DEBUG") if progress == "Device configuration Successfully exported as password protected ZIP.": result = True additionalStatusURL = response.get("additionalStatusURL") - self.log("The backup process process is completed", "INFO") + self.log("The backup process is completed", "INFO") self.result.update(dict(backup_task=response)) return (result, additionalStatusURL) @@ -481,8 +519,10 @@ class instance for further use. if self.have.get('management_ip_address'): self.validate_ipv4_address() + task_id = self.get_device_config() result, additionalStatusURL = self.get_task_status(task_id=task_id) + if result is True: download_status = self.download_file(additionalStatusURL=additionalStatusURL) if download_status is True: @@ -555,7 +595,6 @@ def main(): module = AnsibleModule(argument_spec=element_spec, supports_check_mode=False) ccc_device_configs_backup = Device_configs_backup(module) - config_verify = ccc_device_configs_backup.params.get("config_verify") state = ccc_device_configs_backup.params.get("state") if state not in ccc_device_configs_backup.supported_states: @@ -563,6 +602,7 @@ def main(): ccc_device_configs_backup.msg = "State {0} is invalid".format(state) ccc_device_configs_backup.check_return_status() + config_verify = ccc_device_configs_backup.params.get("config_verify") ccc_device_configs_backup.validate_input().check_return_status() for config in ccc_device_configs_backup.validated_config: From a65246ccb84afa071cbfc8c93dde0a1ccba20108 Mon Sep 17 00:00:00 2001 From: Abinash Date: Thu, 2 May 2024 14:55:21 +0000 Subject: [PATCH 313/358] Resolving review comments for device configs backup --- plugins/modules/device_configs_backup_workflow_manager.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/modules/device_configs_backup_workflow_manager.py b/plugins/modules/device_configs_backup_workflow_manager.py index 6ff70e0607..7c64a2bd5b 100644 --- a/plugins/modules/device_configs_backup_workflow_manager.py +++ b/plugins/modules/device_configs_backup_workflow_manager.py @@ -63,7 +63,10 @@ description: Specifies the collection status of the device(s) on the GUI of Cisco Catalyst Center type: str file_path: - description: Location of the path or folder where the configs need to be exported in local system. + description: + - Location of the path or folder where the configs need to be exported in local system. + - If file_path is not given, it will store the backup file(s) in a folder named tmp in the + same directory of the playbook. type: str default: tmp file_password: From d5cb7464a6790d8b339489ec8a7dd10b13eeb64d Mon Sep 17 00:00:00 2001 From: Abinash Date: Thu, 2 May 2024 15:01:02 +0000 Subject: [PATCH 314/358] Resolving review comments for device configs backup --- plugins/modules/device_configs_backup_workflow_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/device_configs_backup_workflow_manager.py b/plugins/modules/device_configs_backup_workflow_manager.py index 7c64a2bd5b..dbecf4a500 100644 --- a/plugins/modules/device_configs_backup_workflow_manager.py +++ b/plugins/modules/device_configs_backup_workflow_manager.py @@ -65,8 +65,8 @@ file_path: description: - Location of the path or folder where the configs need to be exported in local system. - - If file_path is not given, it will store the backup file(s) in a folder named tmp in the - same directory of the playbook. + - If the file_path is not provided, the backup file(s) will be stored in a directory named + "tmp" in the same directory as the playbook. type: str default: tmp file_password: From d70727dad22dbf91dd2060a6bf1894464a397b74 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Fri, 3 May 2024 02:58:21 -0400 Subject: [PATCH 315/358] paramter change suggested by Madhan --- .../network_compliance_workflow_manager.yml | 80 +- .../network_compliance_workflow_manager.py | 687 +++++++++--------- 2 files changed, 401 insertions(+), 366 deletions(-) diff --git a/playbooks/network_compliance_workflow_manager.yml b/playbooks/network_compliance_workflow_manager.yml index 03e25dd760..18a5d814de 100644 --- a/playbooks/network_compliance_workflow_manager.yml +++ b/playbooks/network_compliance_workflow_manager.yml @@ -16,130 +16,130 @@ dnac_version: "{{ dnac_version }}" dnac_debug: "{{ dnac_debug }}" dnac_log: true - dnac_log_level: DEBUG + dnac_log_level: INFO dnac_log_append: False config_verify: true tasks: - - name: Run full complaince check using IP address list + - name: Run Compliance check using IP address list cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - run_compliance: - trigger_full: True + run_compliance: True - - name: Run full complaince check using Site + + - name: Run Compliance check using Site cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - site: "Global" - run_compliance: - trigger_full: True + run_compliance: True + - - name: Run full compliance check using both IP address list and Site + - name: Run Compliance check using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: True + run_compliance: True - - name: Run complaince check with specific categories using IP address list + + - name: Run Compliance check with specific categories using IP address list cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] + run_compliance_categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] + - - name: Run complaince check with specific categories using Site + - name: Run Compliance check with specific categories using Site cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - site_name: "Global" - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] + run_compliance_categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] - - name: Run compliance check with specific categories using both IP address list and Site + + - name: Run Compliance check with specific categories using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] + run_compliance_categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] + - name: Sync Device Configuration using IP address list cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + run_compliance: False sync_device_config: True + - name: Sync Device Configuration using Site cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: False sync_device_config: True + - name: Sync Device Configuration using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] site_name: "Global/USA/San Francisco/Building_1/floor_1" + run_compliance: False sync_device_config: True - - name: Run full Compliance and sync configuration with IP address list + + - name: Run Compliance and Sync Device Configuration with IP address list cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - run_compliance: - trigger_full: True + run_compliance: True sync_device_config: True - - name: Run full Compliance and sync configuration with Site + + - name: Run Compliance and Sync Device Configuration with Site cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: True + run_compliance: True sync_device_config: True - - name: Run Compliance with specific categories and sync configuration with IP address list + + - name: Run Compliance with specific categories and Sync Device Configuration with IP address list cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] + run_compliance_categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] sync_device_config: True - - - name: Run Compliance with specific categories and sync configuration with Site + + + - name: Run Compliance with specific categories and Sync Device Configuration with Site cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] + run_compliance_categories: ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT'] sync_device_config: True - - name: Run Compliance and sync configuration using both IP address list and Site + + - name: Run Compliance and Sync Device Configuration using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login config: - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: True + run_compliance: True sync_device_config: True diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index a5a0d5838e..989ca02cba 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -17,7 +17,7 @@ - Perform compliance checks or sync configurations on reachable devices using IP Address(s) or Site. - API to perform full compliance checks or specific category checks on reachable device(s). - API to sync device configuration on device(s). -version_added: '6.8.0' +version_added: "6.13.0" extends_documentation_fragment: - cisco.dnac.workflow_manager_params author: Rugvedi Kapse (@rukapse) @@ -40,50 +40,49 @@ suboptions: ip_address_list: description: List of IP addresses of devices to run a compliance check on or synchronize device configurations. - Either 'ip_address_list' or 'site_name' is required for module to execute. - If both 'site_name' and 'ip_address_list' are provided, operations are performed on devices that are present in both the - 'ip_address_list' and the specified site, with consideration given to devices that appear in both sources. + Either "ip_address_list" or "site_name" is required for module to execute. + If both "site_name" and "ip_address_list" are provided, operations are performed on devices that are present in both the + "ip_address_list" and the specified site. + (e.g. ["204.1.2.2", "204.1.2.5", "204.1.2.4"]) type: list elements: str site_name: - description: When 'site_name' is specified, the module executes the operation on all the devices located within the specified site. + description: When "site_name" is specified, the module executes the operation on all the devices located within the specified site. This is a string value that should represent the complete hierarchical path of the site. + Either "site_name" or "ip_address_list" is required for module to execute. + If both "site_name" and "ip_address_list" are provided, operations are performed on devices that are present in both the + "ip_address_list" and the specified site. (e.g. "Global/USA/San Francisco/Building_2/floor_1") - Either 'site_name' or 'ip_address_list' is required for module to execute. - If both 'site_name' and 'ip_address_list' are provided, operations are performed on devices that are present in both the - 'ip_address_list' and the specified site, with consideration given to devices that appear in both sources. type: str run_compliance: - description: Configuration for running a compliance check on the devices specified in the 'ip_address_list' and/or 'site_name'. - type: dict - suboptions: - trigger_full: - description: Determines if a full compliance check should be triggered. - This parameter is required when running a compliance check. - if it is True then compliance will be triggered for all categories. - If it is False then compliance will be triggered for categories mentioned in 'categories' section. - type: bool - default: True - categories: - description: Specifying compliance categories allows you to trigger compliance checks only for the mentioned categories. - Compliance's categories are required when 'trigger_full' is set to False. - Category can have any value among ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT' , 'EOX' , 'NETWORK_SETTINGS']. - Category 'INTENT' is mapped to compliance types 'NETWORK_SETTINGS', 'NETWORK_PROFILE', 'WORKFLOW', 'FABRIC', 'APPLICATION_VISIBILITY'. - type: list - elements: str + description: Determines if a full compliance check should be triggered on the devices specified in the "ip_address_list" and/or "site_name". + This parameter is required when running a compliance check. + if it is True then compliance will be triggered for all categories. + If it is False then compliance will be not be triggered for all categories. + type: bool + default: True + Choices: [True, False] + run_compliance_categories: + description: Specifying compliance categories allows you to trigger compliance checks only for the mentioned categories. + Category can have one or more values from among the following options "INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX" and "NETWORK_SETTINGS". + Category "INTENT" is mapped to compliance types "NETWORK_SETTINGS", "NETWORK_PROFILE", "WORKFLOW", "FABRIC", "APPLICATION_VISIBILITY". + (e.g. ["INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX", "NETWORK_SETTINGS"]) + type: list + elements: str sync_device_config: - description: Determines whether to synchronize the device configuration on the devices specified in the 'ip_address_list'. + description: Determines whether to synchronize the device configuration on the devices specified in the "ip_address_list" and/or "site_name". Sync device configuration, primarily addresses the status of the `RUNNING_CONFIG`. If set to True, and if `RUNNING_CONFIG` status is non-compliant this operation would commit device running configuration to startup by issuing "write memory" to device. type: bool default: False + Choices: [True, False] requirements: - dnacentersdk >= 2.7.0 - python >= 3.5 notes: - - SDK Method used are + - SDK Methods used are compliance.Compliance.run_compliance compliance.Compliance.commit_device_configuration task.Task.get_task_by_id @@ -94,12 +93,12 @@ post /dna/intent/api/v1/compliance/ post /dna/intent/api/v1/network-device-config/write-memory get /dna/intent/api/v1/task/{taskId} - get /dna + get /dna/intent/api/v1/task/{taskId}/tree get /dna/intent/api/v1/compliance/detail """ EXAMPLES = r""" -- name: Run full compliance check on device(s) using IP address list +- name: Run Compliance check on device(s) using IP address list cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -110,13 +109,11 @@ dnac_debug: "{{dnac_debug}}" dnac_log_level: "{{dnac_log_level}}" dnac_log: False - state: merged config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - run_compliance: - trigger_full: True + - ip_address_list: ["204.1.2.2", "204.1.2.5", "204.1.2.4"] + run_compliance: True -- name: Run full compliance check on device(s) using Site +- name: Run Compliance check on device(s) using Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -127,13 +124,11 @@ dnac_debug: "{{dnac_debug}}" dnac_log_level: "{{dnac_log_level}}" dnac_log: False - state: merged config: - site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: True + run_compliance: True -- name: Run full compliance check on device(s) using both IP address list and Site +- name: Run Compliance check on device(s) using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -144,14 +139,12 @@ dnac_debug: "{{dnac_debug}}" dnac_log_level: "{{dnac_log_level}}" dnac_log: False - state: merged config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + - ip_address_list: ["204.1.2.2", "204.1.2.5", "204.1.2.4"] site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: True + run_compliance: True -- name: Run compliance check with specific categories on device(s) using IP address list +- name: Run Compliance check with specific categories on device(s) using IP address list cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -162,14 +155,12 @@ dnac_debug: "{{dnac_debug}}" dnac_log_level: "{{dnac_log_level}}" dnac_log: False - state: merged config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + - ip_address_list: ["204.1.2.2", "204.1.2.5", "204.1.2.4"] + run_compliance: True + run_compliance_categories: ["INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT"] -- name: Run compliance check with specific categories on device(s) using Site +- name: Run Compliance check with specific categories on device(s) using Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -180,14 +171,12 @@ dnac_debug: "{{dnac_debug}}" dnac_log_level: "{{dnac_log_level}}" dnac_log: False - state: merged config: - site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + run_compliance: True + run_compliance_categories: ["INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT"] -- name: Run compliance check with specific categories on device(s) using both IP address list and Site +- name: Run Compliance check with specific categories on device(s) using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -198,15 +187,13 @@ dnac_debug: "{{dnac_debug}}" dnac_log_level: "{{dnac_log_level}}" dnac_log: False - state: merged config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + - ip_address_list: ["204.1.2.2", "204.1.2.5", "204.1.2.4"] site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + run_compliance: True + run_compliance_categories: ["INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT"] -- name: Sync device configuration on device(s) using IP address list +- name: Sync Device Configuration on device(s) using IP address list cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -217,12 +204,12 @@ dnac_debug: "{{dnac_debug}}" dnac_log_level: "{{dnac_log_level}}" dnac_log: False - state: merged config: - site_name: "Global" sync_device_config: True + run_compliance: False -- name: Sync device configuration on device(s) using Site +- name: Sync Device Configuration on device(s) using Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -233,12 +220,12 @@ dnac_debug: "{{dnac_debug}}" dnac_log_level: "{{dnac_log_level}}" dnac_log: False - state: merged config: - site_name: "Global/USA/San Francisco/Building_1/floor_1" sync_device_config: True + run_compliance: False -- name: Sync device configuration on device(s) using both IP address list and Site +- name: Sync Device Configuration on device(s) using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -249,13 +236,13 @@ dnac_debug: "{{dnac_debug}}" dnac_log_level: "{{dnac_log_level}}" dnac_log: False - state: merged config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + - ip_address_list: ["204.1.2.2", "204.1.2.5", "204.1.2.4"] site_name: "Global/USA/San Francisco/Building_1/floor_1" sync_device_config: True + run_compliance: False -- name: Run Compliance and sync configuration using both IP address list and Site +- name: Run Compliance and Sync Device Configuration using both IP address list and Site cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -266,36 +253,16 @@ dnac_debug: "{{dnac_debug}}" dnac_log_level: "{{dnac_log_level}}" dnac_log: False - state: merged config: - - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + - ip_address_list: ["204.1.2.2", "204.1.2.5", "204.1.2.4"] site_name: "Global/USA/San Francisco/Building_1/floor_1" - run_compliance: - trigger_full: False - categories: ['INTENT', 'RUNNING_CONFIG' , 'IMAGE' , 'PSIRT'] + run_compliance: True + run_compliance_categories: ["INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT"] sync_device_config: True """ RETURN = r""" -#Case_2: When Run Compliance Operation is performed successfully on device/s, Compliance report is returned via data. -sample_response_1: - description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK - returned: always - type: dict - sample: > - { - "status": "string", - "changed": bool, - "msg": "string" - "response": { - "taskId": "string", - "url": "string" - }, - "data": dict, - "version": "string" - } - -#Case_1: When Sync Device Config operations is performed successfully on device/s. +#Case_1: Response when Network Compliance operations are performed successfully on device/s. sample_response_2: description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK returned: always @@ -312,7 +279,7 @@ "version": "string" } -#Case_3: When Error Occurs in performing Run Compliance or Sync Device Configuration operation on device/s. +#Case_2: Response when Error Occurs in performing Run Compliance or Sync Device Configuration operation on device/s. sample_response_3: description: A dictionary with the response returned by the Cisco Catalyst Center Python SDK returned: always @@ -356,12 +323,12 @@ def validate_input(self): Returns: object: An instance of the class with updated attributes: - self.msg: A message describing the validation result. - - self.status: The status of the validation (either 'success' or 'failed'). - - self.validated_config: If successful, a validated version of the 'config' parameter. + - self.status: The status of the validation (either "success" or "failed"). + - self.validated_config: If successful, a validated version of the "config" parameter. Description: This method validates the fields provided in the playbook against a predefined specification. It checks if the required fields are present and if their data types match the expected types. - If any parameter is found to be invalid, it logs an error message and sets the validation status to 'failed'. + If any parameter is found to be invalid, it logs an error message and sets the validation status to "failed". If the validation is successful, it logs a success message and returns an instance of the class with the validated configuration. """ @@ -373,13 +340,11 @@ def validate_input(self): return self temp_spec = { - 'ip_address_list': {'type': 'list', 'elements': 'str', 'required': False}, - 'site_name': {'type': 'str', 'required': False}, - 'run_compliance': { - 'type': 'dict', - 'required': False, - }, - 'sync_device_config': {'type': 'bool', 'required': False, 'default': False}, + "ip_address_list": {"type": "list", "elements": "str", "required": False}, + "site_name": {"type": "str", "required": False}, + "run_compliance": {"type": "bool", "required": False, "default": True}, + "run_compliance_categories": {"type": "list", "elements": "str","required": False}, + "sync_device_config": {"type": "bool", "required": False, "default": False}, } # Validate device params @@ -420,43 +385,66 @@ def validate_ip4_address_list(self, ip_address_list): self.log("Successfully validated the IP address/es: {0}".format(ip_address_list), "DEBUG") - def validate_run_compliance(self, run_compliance): + def validate_run_compliance_paramters(self, mgmt_ip_instance_id_map, run_compliance, run_compliance_categories): """ - Validates the parameters for running compliance checks. + Validate and prepare parameters for running compliance checks. Parameters: - run_compliance (dict): A dictionary containing the parameters for running compliance checks. + - mgmt_ip_instance_id_map (dict): A dictionary mapping management IP addresses to device instance IDs. + - run_compliance (bool or None): A boolean indicating whether to run compliance checks. + - run_compliance_categories (list): A list of compliance categories to check. Returns: - None - Description: - This method validates the parameters provided for running compliance checks on devices. - It checks if 'trigger_full' and 'categories' parameters are provided and valid. - If any parameter is missing or invalid, an error message is logged, and the module fails. - If all parameters are valid, a success message is logged. + tuple: A tuple containing two dictionaries: + - run_compliance_params: Parameters for running compliance checks. + - compliance_detail_params: Parameters for compliance detail. + Notes: + - This method prepares parameters for running compliance checks based on the provided inputs. + - If invalid categories are provided in `run_compliance_categories`, a `ValueError` is raised. + - If `run_compliance_categories` is provided and neither `run_compliance` nor `run_compliance_categories` is set, an error + is logged and the method fails. + - If `run_compliance` is set and `run_compliance_categories` is not, full compliance checks are triggered. + - If both `run_compliance` and `run_compliance_categories` are set, compliance checks are triggered for specific categories. """ - valid_categories = ['INTENT', 'RUNNING_CONFIG', 'IMAGE', 'PSIRT', 'EOX', 'NETWORK_SETTINGS'] - trigger_full = run_compliance.get('trigger_full') - categories = run_compliance.get('categories') - msg = "" + run_compliance_params = {} + compliance_detail_params = {} + valid_categories = ["INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX", "NETWORK_SETTINGS"] - # Validate 'trigger_full' parameter - if trigger_full not in [True, False]: - msg = "trigger_full is a required parameter in order to run compliance check on device(s). Set trigger_full to either True or False" + if run_compliance_categories: + if not all(category.upper() in valid_categories for category in run_compliance_categories): + msg = "Invalid category provided. Valid categories are {0}.".format(valid_categories) + self.log(msg, "ERROR") + self.module.fail_json(msg) - # Validate 'categories' parameter when 'trigger_full' is set to False - if trigger_full is False and not categories: - msg = "Categories is a required paramter when trigger_full is set to False. Valid categories are {0} ".format(valid_categories) + if run_compliance is None or run_compliance: + #run_compliance_params + run_compliance_params["deviceUuids"] = list(mgmt_ip_instance_id_map.values()) + run_compliance_params["triggerFull"] = False + categories_copy = run_compliance_categories.copy() + run_compliance_params["categories"] = categories_copy + + #compliance_detail_params + compliance_detail_params["deviceUuids"] = ",".join(list(mgmt_ip_instance_id_map.values())) + compliance_types = run_compliance_categories + if "INTENT" in compliance_types: + compliance_types.remove("INTENT") + compliance_types.extend(["NETWORK_PROFILE", "APPLICATION_VISIBILITY", "WORKFLOW", "FABRIC", "NETWORK_SETTINGS"]) + compliance_types = list(set(compliance_types)) + compliance_detail_params["complianceType"] = "', '".join(compliance_types) + compliance_detail_params["complianceType"] = "'" + compliance_detail_params['complianceType'] + "'" + else: + msg = "No actions were requested. This network compliance module can perform the following tasks: Run Compliance Check or Sync Device Config." + self.log(msg, "ERROR") + self.module.fail_json(msg) + return self - # Validate 'categories' parameter values - if categories: - if not all(category.upper() in valid_categories for category in categories): - msg = "Invalid category provided. Valid categories are {0}.".format(valid_categories) + if run_compliance and not run_compliance_categories: + #run_compliance_params + run_compliance_params["deviceUuids"] = list(mgmt_ip_instance_id_map.values()) + run_compliance_params["triggerFull"] = True - # Log error message and fail if validation fails - if msg: - self.log(msg, 'ERROR') - self.module.fail_json(msg) - else: - self.log("Successfully validated run_compliance parameters.", "DEBUG") + #compliance_detail_params + compliance_detail_params["deviceUuids"] = ",".join(list(mgmt_ip_instance_id_map.values())) + + return run_compliance_params, compliance_detail_params def site_exists(self, site_name): """ @@ -469,8 +457,8 @@ def site_exists(self, site_name): - site_id (str or None): The ID of the site if it exists, or None if the site is not found. Description: This method queries Cisco Catalyst Center to determine if a site with the provided name exists. - If the site is found, it sets 'site_exists' to True and retrieves the site's ID. - If the site does not exist, 'site_exists' is set to False, and 'site_id' is None. + If the site is found, it sets "site_exists" to True and retrieves the site"s ID. + If the site does not exist, "site_exists" is set to False, and "site_id" is None. If an exception occurs during the site lookup, an error message is logged, and the module fails. """ @@ -482,23 +470,27 @@ def site_exists(self, site_name): try: response = self.dnac._exec( family="sites", - function='get_site', + function="get_site", op_modifies=True, params={"name": site_name}, ) + self.log("Response received post 'get_site' API call: {0}".format(str(response)), "DEBUG") # Process the response if available if response: - self.log("Received API response from 'get_site': {0}".format(str(response)), "DEBUG") site = response.get("response") site_id = site[0].get("id") site_exists = True + else: + self.log( "No response received from the 'get_site' API call.", "ERROR") except Exception as e: # Log an error message and fail if an exception occurs - msg = "Site '{0}' does not exist in the Cisco Catalyst Center".format(site_name) - self.log('An exception occurred: {0}'.format(e), "ERROR") - self.log(msg, 'ERROR') + self.log("An error occurred while retrieving site details for Site '{0}' using 'get_site' API call: {1}".format(site_name, str(e)), "ERROR") + + if not site_exists: + msg = "An error occurred while retrieving site details for Site '{0}'. Please verify that the site exists.".format(site_name) + self.log(msg, "ERROR") self.module.fail_json(msg=msg) return (site_exists, site_id) @@ -512,7 +504,7 @@ def get_device_ids_from_ip(self, ip_address_list): dict: A dictionary mapping management IP addresses to their instance UUIDs. Description: This method queries Cisco Catalyst Center for device information using the provided IP addresses. - For each IP address in the list, it attempts to fetch the device information using the 'get_device_list' API. + For each IP address in the list, it attempts to fetch the device information using the "get_device_list" API. If the device is found and reachable, it extracts the device ID and maps it to the corresponding IP address. If any error occurs during the process, it logs an error message and continues to the next IP address. """ @@ -525,14 +517,14 @@ def get_device_ids_from_ip(self, ip_address_list): # Query Cisco Catalyst Center for device information using the IP address response = self.dnac._exec( family="devices", - function='get_device_list', + function="get_device_list", op_modifies=True, params={"managementIpAddress": device_ip} ) + self.log("Response received post 'get_device_list' API call: {} ".format(str(response)), "DEBUG") # Check if a valid response is received if response.get("response"): - self.log("Received API response from 'get_device_list' for device:{0} response: {1}".format(device_ip, str(response)), "DEBUG") response = response.get("response") if not response: continue @@ -542,14 +534,17 @@ def get_device_ids_from_ip(self, ip_address_list): mgmt_ip_instance_id_map[device_ip] = device_id else: # If unable to retrieve device information, log an error message - msg = "Unable to retrieve device information for {0}. Please ensure that the device exists and is reachable.".format(device_ip) - self.log(msg, "ERROR") - self.module.fail_json(msg=msg) + self.log("Unable to retrieve device information for {0}. Please ensure that the device exists and is reachable.".format(device_ip), "ERROR") except Exception as e: # Log an error message if any exception occurs during the process - error_message = "Error while fetching device ID for device: '{0}' from Cisco Catalyst Center: {1}".format(device_ip, str(e)) - self.log(error_message, "ERROR") + self.log("Error while fetching device ID for device: '{0}' from Cisco Catalyst Center: {1}".format(device_ip, str(e)), "ERROR") + + if not mgmt_ip_instance_id_map: + msg = "Error occurred while retrieving device details (Device UUID) using the 'get_device_list' API " + msg += "for the following device(s): {0}".format(ip_address_list) + self.log(msg, "ERROR") + self.module.fail_json(msg=msg) return mgmt_ip_instance_id_map @@ -558,7 +553,7 @@ def get_device_ids_from_site(self, site_name, site_id): Retrieves the management IP addresses and their corresponding instance UUIDs of devices associated with a specific site in Cisco Catalyst Center. Parameters: - site_name (str): The name of the site whose devices' information is to be retrieved. + site_name (str): The name of the site whose devices" information is to be retrieved. site_id (str): The unique identifier of the site. Returns: @@ -581,32 +576,37 @@ def get_device_ids_from_site(self, site_name, site_id): try: response = self.dnac._exec( family="sites", - function='get_membership', + function="get_membership", op_modifies=True, params=site_params, ) + self.log("Response received post 'get_membership' API Call: {} ".format(str(response)), "DEBUG") + + # Process the response if available if response: - self.log("Received API response from 'get_membership': {0}".format(str(response)), "DEBUG") - response = response['device'] + response = response["device"] # Iterate over the devices in the site membership for item in response: - if item['response']: - for item_dict in item['response']: + if item["response"]: + for item_dict in item["response"]: # Check if the device is reachable if item_dict["reachabilityStatus"] == "Reachable": mgmt_ip_instance_id_map[item_dict["managementIpAddress"]] = item_dict["instanceUuid"] else: - msg = 'Unable to get deviceId for device {0} in site {1} as its status is {2}'.format( + msg = "Unable to get deviceId for device {0} in site {1} as its status is {2}".format( item["managementIpAddress"], site_name, item["reachabilityStatus"]) self.log(msg, "CRITICAL") self.module.fail_json(msg=msg) + else: + # If unable to retrieve device information, log an error message + self.log("No response received from API call to get membership information for site. {0}".format(site_name), "ERROR") - # Handle exceptions if unable to fetch device information associated with the site except Exception as e: - self.log("Unable to fetch the device(s) associated to the site '{0}' due to '{1}'".format(site_name, str(e)), "ERROR") + # Log an error message if any exception occurs during the process + self.log("Unable to fetch the device(s) associated to the site '{0}' due to {1}".format(site_name, str(e)), "ERROR") if not mgmt_ip_instance_id_map: - msg = 'Site: {0} provided in the playbook does not have any reachable devices'.format(site_name) + msg = "Error retrieving device details using the 'get_membership' API from Site: {0}".format(site_name) self.log(msg, "ERROR") self.module.fail_json(msg=msg) @@ -657,42 +657,43 @@ def is_sync_required(self, modified_response, mgmt_ip_instance_id_map): and a message explaining the result. Note: - This method categorizes devices based on compliance status ('COMPLIANT', 'NON_COMPLIANT', 'OTHER') - and checks if synchronization is necessary. If all devices are 'COMPLIANT', synchronization is not - required. If there are devices that are not 'NON_COMPLIANT', synchronization is also not required. + This method categorizes devices based on compliance status ("COMPLIANT", "NON_COMPLIANT", "OTHER") + and checks if synchronization is necessary. If all devices are "COMPLIANT", synchronization is not + required. If there are devices that are not "NON_COMPLIANT", synchronization is also not required. """ - task_name = 'Sync Device Configuration' + task_name = "Sync Device Configuration" required = True msg = "" # Validate if sync is required - # response = self.get_compliance_detail(compliance_detail_params_sync) - self.log('Modified {0} Response for device(s) {1} : {2}'.format(task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), 'INFO') + self.log("Compliance Report for {0} operation for device(s) {1} : {2}".format( + task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), "INFO") - # Categorize the devices based on status - 'COMPLIANT', 'NON_COMPLIANT', 'OTHER'(status other than COMPLIANT and NON_COMPLIANT) - categorized_devices = {'COMPLIANT': {}, 'NON_COMPLIANT': {}, 'OTHER': {}} + # Categorize the devices based on status - "COMPLIANT", "NON_COMPLIANT", "OTHER"(status other than COMPLIANT and NON_COMPLIANT) + categorized_devices = {"COMPLIANT": {}, "NON_COMPLIANT": {}, "OTHER": {}} for ip_address, compliance_type in modified_response.items(): - status = compliance_type[0]['status'] - if status == 'NON_COMPLIANT': - categorized_devices['NON_COMPLIANT'][ip_address] = compliance_type - elif status == 'COMPLIANT': - categorized_devices['COMPLIANT'][ip_address] = compliance_type + status = compliance_type[0]["status"] + if status == "NON_COMPLIANT": + categorized_devices["NON_COMPLIANT"][ip_address] = compliance_type + elif status == "COMPLIANT": + categorized_devices["COMPLIANT"][ip_address] = compliance_type else: - categorized_devices['OTHER'][ip_address] = compliance_type - self.log("Devices Categorized based on Compliance status: {0}".format(categorized_devices), 'INFO') + categorized_devices["OTHER"][ip_address] = compliance_type + + self.log("Devices Categorized based on Compliance status: {0}".format(categorized_devices), "INFO") - # Validate if all devices are 'COMPLIANT' - then sync not required - if len(categorized_devices['COMPLIANT']) == len(mgmt_ip_instance_id_map): + # Validate if all devices are "COMPLIANT" - then sync not required + if len(categorized_devices["COMPLIANT"]) == len(mgmt_ip_instance_id_map): msg = "Device(s) {0} are already compliant with the RUNNING_CONFIG compliance type. Therefore, {1} is not required.".format( list(mgmt_ip_instance_id_map.keys()), task_name) required = False - - elif len(categorized_devices['NON_COMPLIANT']) != len(mgmt_ip_instance_id_map): + elif len(categorized_devices["NON_COMPLIANT"]) != len(mgmt_ip_instance_id_map): required = False msg = ("The operation {0} cannot be performed on one or more of the devices " "{1} because the status of the RUNNING_CONFIG compliance type is not " "as expected; it should be NON_COMPLIANT." ).format(task_name, list(mgmt_ip_instance_id_map.keys())) + return required, msg def get_want(self, config): @@ -704,7 +705,7 @@ def get_want(self, config): dict: A dictionary containing the desired state parameters. Description: This method processes the provided configuration to determine the desired state. It validates the presence of - either 'ip_address_list' or 'site_name' and constructs parameters for running compliance checks and syncing + either "ip_address_list" or "site_name" and constructs parameters for running compliance checks and syncing device configurations based on the provided configuration. It also logs the desired state for reference. """ @@ -715,16 +716,27 @@ def get_want(self, config): compliance_detail_params_sync = {} compliance_details = {} - # Validate either ip_address_list OR site_name is present - ip_address_list = config.get('ip_address_list') - site_name = config.get('site_name') + #Store input parameters + ip_address_list = config.get("ip_address_list") + site_name = config.get("site_name") + run_compliance = config.get("run_compliance") + run_compliance_categories = config.get("run_compliance_categories") + sync_device_config = config.get("sync_device_config") - if not ip_address_list and not site_name: - msg = 'ip_address_list is {0} and site_name is {1}. Either the ip_address_list or the site_name must be provided.'.format( + # Validate either ip_address_list OR site_name is present + if not any([ip_address_list, site_name]): + msg = "ip_address_list is {0} and site_name is {1}. Either the ip_address_list or the site_name must be provided.".format( ip_address_list, site_name) self.log(msg, "ERROR") self.module.fail_json(msg=msg) + # Validate if a network compliance operation is present + if not any([run_compliance, run_compliance_categories, sync_device_config]): + msg = "No actions were requested. This network compliance module can perform the following tasks: Run Compliance Check or Sync Device Config." + self.log(msg, "ERROR") + self.module.fail_json(msg) + return self + # Validate valid ip_addresses if ip_address_list: self.validate_ip4_address_list(ip_address_list) @@ -736,60 +748,39 @@ def get_want(self, config): if not mgmt_ip_instance_id_map: # Log an error message if mgmt_ip_instance_id_map is empty msg = "Failed to retrieve device IDs for the provided IP addresses: {0} or site name: {1}.".format(ip_address_list, site_name) - self.log(msg, 'ERROR') - self.module.fail_json(msg) - - # Validate run_compliance parameters - run_compliance = config.get('run_compliance') - sync_device_config = config.get('sync_device_config') - - if not run_compliance and not sync_device_config: - msg = "No actions were requested. This network compliance module can perform the following tasks: Run Compliance Check or Sync Device Config." - self.log(msg, 'ERROR') + self.log(msg, "ERROR") self.module.fail_json(msg) - return self - - if run_compliance: - self.validate_run_compliance(run_compliance) - run_compliance_params = { - 'triggerFull': config.get('run_compliance').get('trigger_full'), - 'deviceUuids': list(mgmt_ip_instance_id_map.values()), - } - - compliance_detail_params = { - 'deviceUuid': ','.join(list(mgmt_ip_instance_id_map.values())), - } - if config.get('run_compliance').get('categories'): - categories_copy = config.get('run_compliance').get('categories').copy() - run_compliance_params['categories'] = categories_copy - - compliance_types = config.get('run_compliance').get('categories') - if 'INTENT' in compliance_types: - compliance_types.remove('INTENT') - compliance_types.extend(['NETWORK_PROFILE', 'APPLICATION_VISIBILITY', 'WORKFLOW', 'FABRIC', 'NETWORK_SETTINGS']) - compliance_types = list(set(compliance_types)) - compliance_detail_params['complianceType'] = "', '".join(compliance_types) - compliance_detail_params['complianceType'] = "'" + compliance_detail_params['complianceType'] + "'" + # Run Compliance Paramters + run_compliance_params, compliance_detail_params = self.validate_run_compliance_paramters( + mgmt_ip_instance_id_map, run_compliance, run_compliance_categories) + # Sync Device Configuration Parameters if sync_device_config: sync_device_config_params = { - 'deviceId': list(mgmt_ip_instance_id_map.values()) + "deviceId": list(mgmt_ip_instance_id_map.values()) } compliance_detail_params_sync = { - 'deviceUuid': ','.join(list(mgmt_ip_instance_id_map.values())), - 'complianceType': 'RUNNING_CONFIG' + "deviceUuid": ",".join(list(mgmt_ip_instance_id_map.values())), + "complianceType": "RUNNING_CONFIG" } + + # Validate if Sync Device Configuration is required on the device(s) response = self.get_compliance_detail(compliance_detail_params_sync) + if not response: + msg = "Error occurred when retrieving Compliance Report to identify if Sync Device Config Operation " + msg += "is required on device(s): {0}".format(list(mgmt_ip_instance_id_map.keys())) + self.log(msg) + self.module.fail_json(msg) + compliance_details = self.modify_compliance_response(response, mgmt_ip_instance_id_map) required, msg = self.is_sync_required(compliance_details, mgmt_ip_instance_id_map) if not required: - self.log(msg, 'ERROR') + self.log(msg, "ERROR") self.module.fail_json(msg) - return self - # Construct the 'want' dictionary containing the desired state parameters + # Construct the "want" dictionary containing the desired state parameters want = {} want = dict( ip_address_list=ip_address_list, @@ -817,21 +808,26 @@ def get_compliance_detail(self, compliance_detail_params): """ # Execute the GET compliance detial operation try: - response = self.dnac_apply['exec']( + response = self.dnac_apply["exec"]( family="compliance", - function='get_compliance_detail', + function="get_compliance_detail", params=compliance_detail_params, op_modifies=True ) - response = response.response + self.log("Response received post 'get_compliance_detail' API call: {0}".format(str(response)), "DEBUG") - self.log("The response received post get_compliance_detail API call is {0}".format(str(response)), "DEBUG") + if response: + response = response.response + else: + self.log("No response received from the 'get_compliance_detail' API call.", "ERROR") return response # Log and handle any exceptions that occur during the execution except Exception as e: - self.log("An error occurred while retrieving Compliance Details using get_compliance_detail API call: {0}".format(str(e)), "ERROR") - return None + self.msg = "An error occurred while retrieving Compliance Details using 'get_compliance_detail' API call " + self.msg += "for {0}: {1}".format(compliance_detail_params, str(e)) + self.update_result("failed", False, self.msg, "ERROR") + self.check_return_status() def modify_compliance_response(self, response, mgmt_ip_instance_id_map): """ @@ -847,15 +843,19 @@ def modify_compliance_response(self, response, mgmt_ip_instance_id_map): associated with a list of compliance items related to that device. """ modified_response = {} + ip_address = None for item in response: - device_uuid = item.get('deviceUuid') + device_uuid = item.get("deviceUuid") # Find the corresponding management IP address for the device UUID - ip_address = next((ip for ip, uuid in mgmt_ip_instance_id_map.items() if uuid == device_uuid)) + for ip, uuid in mgmt_ip_instance_id_map.items(): + if uuid == device_uuid: + ip_address = ip + break # If the IP address is found, add the item to the modified response - # If ip_address and item.get('status')!= 'NOT_APPLICABLE': + # If ip_address and item.get("status")!= "NOT_APPLICABLE": if ip_address: if ip_address not in modified_response: modified_response[ip_address] = [] @@ -871,27 +871,33 @@ def run_compliance(self, run_compliance_params): Returns: str or None: Task ID of the API task created, or None if unsuccessful. Description: - This method initiates a compliance check operation in Cisco DNA Center by calling the 'run_compliance' function - from the 'compliance' family of APIs. It passes the provided parameters and updates the result accordingly. + This method initiates a compliance check operation in Cisco DNA Center by calling the "run_compliance" function + from the "compliance" family of APIs. It passes the provided parameters and updates the result accordingly. """ # Execute the compliance check operation try: - result = self.dnac_apply['exec']( + response = self.dnac_apply["exec"]( family="compliance", function="run_compliance", params=run_compliance_params, op_modifies=True, ) - self.log("The response received post run_compliancee API call is {0}".format(str(result)), "DEBUG") - self.result.update(dict(response=result['response'])) - self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") - return result.response.get('taskId') + self.log("Response received post 'run_compliancee' API call is {0}".format(str(response)), "DEBUG") + + if response: + self.result.update(dict(response=response["response"])) + self.log("Task Id for the 'run_compliance' task is {0}".format(response.response.get("taskId")), "INFO") + return response.response.get("taskId") + else: + self.log("No response received from the 'run_compliance' API call.", "ERROR") + return None # Log and handle any exceptions that occur during the execution except Exception as e: - self.log("An error occurred while executing the run_compliance operation: {0}".format(str(e)), "ERROR") - return None + self.msg = "An error occurred while executing the 'run_compliance' operation for {0}: {1}".format(run_compliance_params, str(e)) + self.update_result("failed", False, self.msg, "ERROR") + self.check_return_status() def sync_device_config(self, sync_device_config_params): """ @@ -907,22 +913,28 @@ def sync_device_config(self, sync_device_config_params): """ # Make an API call to synchronize device configuration try: - result = self.dnac_apply['exec']( + response = self.dnac_apply["exec"]( family="compliance", function="commit_device_configuration", params=sync_device_config_params, op_modifies=True, ) - self.log("The response received post commit_device_configuration API call is {0}".format(str(result)), "DEBUG") - self.result.update(dict(response=result['response'])) - self.log("Task Id of the API task created is {0}".format(result.response.get('taskId')), "INFO") - # Return the task ID - return result.response.get('taskId') + self.log("Response received post 'commit_device_configuration' API call is {0}".format(str(response)), "DEBUG") + + if response: + self.result.update(dict(response=response["response"])) + self.log("Task Id for the 'commit_device_configuration' task is {0}".format(response.response.get("taskId")), "INFO") + # Return the task ID + return response.response.get("taskId") + else: + self.log("No response received from the 'commit_device_configuration' API call.", "ERROR") + return None # Log the error if an exception occurs during the API call except Exception as e: - self.log("Error occurred while synchronizing device configuration: {0}".format(str(e)), "ERROR") - return None + self.msg = "Error occurred while synchronizing device configuration for {0}: {0}".format(sync_device_config_params, str(e)) + self.update_result("failed", False, self.msg, "ERROR") + self.check_return_status() def get_task_status(self, task_id, task_name): """ @@ -939,20 +951,26 @@ def get_task_status(self, task_id, task_name): # Make an API call to retrieve the task tree try: - response = self.dnac_apply['exec']( + response = self.dnac_apply["exec"]( family="task", - function='get_task_by_id', + function="get_task_by_id", params=dict(task_id=task_id), op_modifies=True, ) - response = response.response - self.log("Task status for the Task {0} with Task id {1} is {2}".format(task_name, str(task_id), str(response)), "INFO") + self.log("Response received post 'get_task_by_id' API Call for the Task {0} with Task id {1} " + "is {2}".format(task_name, str(task_id), str(response)), "DEBUG") + + if response: + response = response.response + else: + self.log("No response received from the 'get_task_by_id' API call.", "CRITICAL") return response # Log the error if an exception occurs during the API call except Exception as e: - self.log("Error occurred while retrieving task status for Task {0} with Task id {1}: {2}".format(task_name, task_id, str(e)), "ERROR") - return None + self.msg = "Error occurred while retrieving 'get_task_by_id' for Task {0} with Task id {1}: {2}".format(task_name, task_id, str(e)) + self.update_result("failed", False, self.msg, "ERROR") + self.check_return_status() def get_task_tree(self, task_id, task_name): """ @@ -969,53 +987,58 @@ def get_task_tree(self, task_id, task_name): # Make an API call to retrieve the task status try: - response = self.dnac_apply['exec']( + response = self.dnac_apply["exec"]( family="task", - function='get_task_tree', + function="get_task_tree", params=dict(task_id=task_id), op_modifies=True, ) - response = response.response - self.log("Task tree for the Task {0} with Task id {1} is {2}".format(task_name, str(task_id), str(response)), "INFO") + self.log("Response received post 'get_task_tree' API call for the Task {0} with Task id {1} " + "is {2}".format(task_name, str(task_id), str(response)), "DEBUG") + if response: + response = response.response + else: + self.log("No response received from the 'get_task_tree' API call.", "CRITICAL") return response # Log the error if an exception occurs during the API call except Exception as e: - self.log("Error occurred while retrieving task tree for Task {0} with task id {1}: {2}".format(task_name, task_id, str(e)), "ERROR") - return None + self.msg = "Error occurred while retrieving 'get_task_tree' for Task {0} with task id {1}: {2}".format(task_name, task_id, str(e)) + self.update_result("failed", False, self.msg, "ERROR") + self.check_return_status() def update_result(self, status, changed, msg, log_level, data=None): """ Update the result of the operation with the provided status, message, and log level. Parameters: - - status (str): The status of the operation ('success' or 'failed'). + - status (str): The status of the operation ("success" or "failed"). - changed (bool): Indicates whether the operation caused changes. - msg (str): The message describing the result of the operation. - - log_level (str): The log level at which the message should be logged ('INFO', 'ERROR', 'CRITICAL', etc.). + - log_level (str): The log level at which the message should be logged ("INFO", "ERROR", "CRITICAL", etc.). - data (dict, optional): Additional data related to the operation result. Returns: self (object): An instance of the class. Note: - - If the status is 'failed', the 'failed' key in the result dictionary will be set to True. + - If the status is "failed", the "failed" key in the result dictionary will be set to True. - If data is provided, it will be included in the result dictionary. """ # Update the result attributes with the provided values self.status = status - self.result['status'] = status - self.result['msg'] = msg - self.result['changed'] = changed + self.result["status"] = status + self.result["msg"] = msg + self.result["changed"] = changed # Log the message at the specified log level self.log(msg, log_level) - # If the status is 'failed', set the 'failed' key to True - if status == 'failed': - self.result['failed'] = True + # If the status is "failed", set the "failed" key to True + if status == "failed": + self.result["failed"] = True # If additional data is provided, include it in the result dictionary if data: - self.result['data'] = data + self.result["data"] = data return self @@ -1033,17 +1056,17 @@ def exit_while_loop(self, start_time, task_id, task_name, response): # If the elapsed time exceeds the timeout period if time.time() - start_time > 360: - if response.get('data'): + if response.get("data"): # If there is data in the response, include it in the error message - msg = "Task {0} with task id {1} has not completed within the timeout period. Task Status: {2} ".format( - task_name, task_id, response.get('data')) + self.msg = "Task {0} with task id {1} has not completed within the timeout period. Task Status: {2} ".format( + task_name, task_id, response.get("data")) else: # If there is no data in the response, generate a generic error message - msg = "Task {0} with task id {1} has not completed within the timeout period.".format( + self.msg = "Task {0} with task id {1} has not completed within the timeout period.".format( task_name, task_id) # Update the result with failure status and log the error message - self.update_result('failed', False, msg, 'ERROR') + self.update_result("failed", False, self.msg, "ERROR") return True return False @@ -1069,7 +1092,7 @@ def handle_error(self, task_name, mgmt_ip_instance_id_map, failure_reason=None): task_name, list(mgmt_ip_instance_id_map.keys())) # Update the result with failure status and log the error message - self.update_result('failed', False, self.msg, 'ERROR') + self.update_result("failed", False, self.msg, "ERROR") return self @@ -1087,7 +1110,7 @@ def get_compliance_task_status(self, task_id, mgmt_ip_instance_id_map): Upon successful completion, it logs the modified compliance response and updates the result accordingly. """ - task_name = 'Run Compliance Check' + task_name = "Run Compliance Check" start_time = time.time() while True: @@ -1095,8 +1118,8 @@ def get_compliance_task_status(self, task_id, mgmt_ip_instance_id_map): # Check if response returned if not response: - self.msg = 'Error retrieving Task status for the Task {0} with Task Id: {1}'.format(task_name, task_id) - self.update_result('failed', False, self.msg, 'ERROR') + self.msg = "Error retrieving Task status for {0} with Task Id: {1}".format(task_name, task_id) + self.update_result("failed", False, self.msg, "ERROR") break # Check if the elapsed time exceeds the timeout @@ -1104,29 +1127,36 @@ def get_compliance_task_status(self, task_id, mgmt_ip_instance_id_map): break # Handle error if task execution encounters an error - if response.get('isError'): + if response.get("isError"): failure_reason = response.get("failureReason") self.handle_error(task_name, mgmt_ip_instance_id_map, failure_reason) break # Check if task completed successfully - elif not response.get('isError') and 'success' in response.get('progress').lower(): + elif not response.get("isError") and "success" in response.get("progress").lower(): # Task completed successfully self.msg = "{0} has completed successfully on device(s): {1}".format(task_name, list(mgmt_ip_instance_id_map.keys())) # Retrieve and modify compliance check details - response = self.get_compliance_detail(self.want.get('compliance_detail_params')) + response = self.get_compliance_detail(self.want.get("compliance_detail_params")) + if not response: + self.msg = "Error Occurred when retrieving Compliance Report after {0} with Task Id {1} for device(s) {2}".format( + task_name, task_id, list(mgmt_ip_instance_id_map.keys())) + self.update_result("failed", False, self.msg, "ERROR") + break + modified_response = self.modify_compliance_response(response, mgmt_ip_instance_id_map) - self.log('Modified {0} Response for device(s) {1} : {2}'.format(task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), 'INFO') + self.log("Compliance Report for {0} operation for device(s) {1} : {2}".format( + task_name, list(mgmt_ip_instance_id_map.keys()), modified_response), "INFO") # Update result with modified response - self.update_result('success', True, self.msg, 'INFO', modified_response) + self.update_result("success", True, self.msg, "INFO") break # Check if task failed - elif 'failed' in response.get('progress').lower(): + elif "failed" in response.get("progress").lower(): self.msg = "Failed to {0} on the following device(s): {1}".format(task_name, list(mgmt_ip_instance_id_map.keys())) - self.update_result('failed', False, self.msg, 'CRITICAL') + self.update_result("failed", False, self.msg, "CRITICAL") break return self @@ -1145,7 +1175,7 @@ def get_sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): It continuously checks the task status until completion, updating the result accordingly. """ - task_name = 'Sync Device Configuration' + task_name = "Sync Device Configuration" start_time = time.time() while True: @@ -1156,8 +1186,8 @@ def get_sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): # Check if response returned if not response: - self.msg = 'Error retrieving Task Tree for the task_name {0} task_id {1}'.format(task_name, task_id) - self.update_result('failed', False, self.msg, 'ERROR') + self.msg = "Error retrieving Task Tree for the task_name {0} task_id {1}".format(task_name, task_id) + self.update_result("failed", False, self.msg, "ERROR") break # Check if the elapsed time exceeds the timeout @@ -1165,13 +1195,13 @@ def get_sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): break # Handle error if task execution encounters an error - if response[0].get('isError'): + if response[0].get("isError"): failure_reason = response.get("failureReason") self.handle_error(task_name, mgmt_ip_instance_id_map, failure_reason) break for item in response[1:]: - progress = item['progress'] + progress = item["progress"] for ip, device_id in mgmt_ip_instance_id_map.items(): if device_id in progress and "copy_Running_To_Startup=Success" in progress: success_devices.append(ip) @@ -1184,18 +1214,18 @@ def get_sync_config_task_status(self, task_id, mgmt_ip_instance_id_map): # Check conditions and print messages accordingly if len(set(success_devices)) == len(mgmt_ip_instance_id_map): self.msg = "{0} has completed successfully on device(s): {1}".format(task_name, success_devices) - self.update_result('success', True, self.msg, 'INFO') + self.update_result("success", True, self.msg, "INFO") break elif (failed_devices and len(success_devices) < len(mgmt_ip_instance_id_map) and len(failed_devices) + len(success_devices) == len(mgmt_ip_instance_id_map)): self.msg = "{0} task has failed on device(s): {1} and succeeded on device(s): {2}".format( task_name, failed_devices, success_devices) - self.update_result('failed', True, self.msg, 'CRITICAL') + self.update_result("failed", True, self.msg, "CRITICAL") break elif len(failed_devices) == len(mgmt_ip_instance_id_map): self.msg = "{0} task has failed on device(s): {1}".format(task_name, failed_devices) - self.update_result('failed', False, self.msg, 'CRITICAL') + self.update_result("failed", False, self.msg, "CRITICAL") break return self @@ -1213,8 +1243,8 @@ def get_diff_merged(self): # Action map for different network compliance operations action_map = { - 'run_compliance_params': (self.run_compliance, self.get_compliance_task_status), - 'sync_device_config_params': (self.sync_device_config, self.get_sync_config_task_status) + "run_compliance_params": (self.run_compliance, self.get_compliance_task_status), + "sync_device_config_params": (self.sync_device_config, self.get_sync_config_task_status) } # Iterate through the action map and execute specified actions @@ -1223,50 +1253,55 @@ def get_diff_merged(self): # Execute the action and check its status if self.want.get(action_param): result_task_id = action_func(self.want.get(action_param)) - self.log("Performing {0}".format(action_func.__name__), 'DEBUG') + self.log("Performing {0}".format(action_func.__name__), "DEBUG") if not result_task_id: self.msg = "An error occurred while retrieving the task_id of the {0} operation.".format(action_func.__name__) - self.update_result('failed', False, self.msg, 'CRITICAL') + self.update_result("failed", False, self.msg, "CRITICAL") else: - status_func(result_task_id, self.want.get('mgmt_ip_instance_id_map')).check_return_status() + status_func(result_task_id, self.want.get("mgmt_ip_instance_id_map")).check_return_status() return self def verify_diff_merged(self, config): """ - Verify the success of the 'Sync Device Configuration' operation. + Verify the success of the "Sync Device Configuration" operation. Parameters: config (dict): A dictionary containing the configuration details. Returns: self (object): An instance of a class used for interacting with Cisco Catalyst Center. Description: - This method verifies the success of the 'Sync Device Configuration' operation in the context of network compliance management. + This method verifies the success of the "Sync Device Configuration" operation in the context of network compliance management. It checks if the configuration includes the option to synchronize device configurations (`sync_device_config`). If this option is present, the function proceeds to compare compliance details before and after executing the synchronization operation. It logs relevant information at each step and concludes by determining whether the synchronization was successful. """ - if config.get('sync_device_config'): + if config.get("sync_device_config"): # Get compliance details before running sync_device_config - compliance_details_before = self.want.get('compliance_details') + compliance_details_before = self.want.get("compliance_details") self.log("Compliance details before running sync_device_config: {0}".format(compliance_details_before), "INFO") # Get compliance details after running sync_device_config - response = self.get_compliance_detail(self.want.get('compliance_detail_params_sync')) - compliance_details_after = self.modify_compliance_response(response, self.want.get('mgmt_ip_instance_id_map')) + response = self.get_compliance_detail(self.want.get("compliance_detail_params_sync")) + if not response: + self.msg = "Error occured when Retrieving Compliance Details after for verifying configuration." + self.update("failed", False, self.msg, "ERROR") + self.check_return_status() + + compliance_details_after = self.modify_compliance_response(response, self.want.get("mgmt_ip_instance_id_map")) self.log("Compliance details after running sync_device_config: {0}.".format(compliance_details_after), "INFO") all_statuses_before = [] all_statuses_after = [] for ip_address, compliance_type in compliance_details_before.items(): - status = compliance_type[0]['status'] + status = compliance_type[0]["status"] all_statuses_before.append(status) - if len(set(all_statuses_before)) == 1 and all_statuses_before[0] == 'NON_COMPLIANT': + if len(set(all_statuses_before)) == 1 and all_statuses_before[0] == "NON_COMPLIANT": for ip_address, compliance_type in compliance_details_after.items(): - status = compliance_type[0]['status'] + status = compliance_type[0]["status"] all_statuses_after.append(status) - if len(set(all_statuses_after)) == 1 and all_statuses_after[0] == 'COMPLIANT': - self.log('Verified the success of the Sync Device Configuration operation.') + if len(set(all_statuses_after)) == 1 and all_statuses_after[0] == "COMPLIANT": + self.log("Verified the success of the Sync Device Configuration operation.") else: self.log( "Sync Device Configuration operation may have been unsuccessful " @@ -1285,24 +1320,24 @@ def main(): main entry point for module execution """ - # Define the specification for the module's arguments - element_spec = {'dnac_host': {'required': True, 'type': 'str'}, - 'dnac_port': {'type': 'str', 'default': '443'}, - 'dnac_username': {'type': 'str', 'default': 'admin', 'aliases': ['user']}, - 'dnac_password': {'type': 'str', 'no_log': True}, - 'dnac_verify': {'type': 'bool', 'default': 'True'}, - 'dnac_version': {'type': 'str', 'default': '2.2.3.3'}, - 'dnac_debug': {'type': 'bool', 'default': False}, - 'dnac_log_level': {'type': 'str', 'default': 'WARNING'}, - "dnac_log_file_path": {"type": 'str', "default": 'dnac.log'}, - "dnac_log_append": {"type": 'bool', "default": True}, - 'dnac_log': {'type': 'bool', 'default': False}, - 'validate_response_schema': {'type': 'bool', 'default': True}, - 'config_verify': {'type': 'bool', "default": False}, - 'dnac_api_task_timeout': {'type': 'int', "default": 1200}, - 'dnac_task_poll_interval': {'type': 'int', "default": 2}, - 'config': {'required': True, 'type': 'list', 'elements': 'dict'}, - 'state': {'default': 'merged', 'choices': ['merged']} + # Define the specification for the module"s arguments + element_spec = {"dnac_host": {"required": True, "type": "str"}, + "dnac_port": {"type": "str", "default": "443"}, + "dnac_username": {"type": "str", "default": "admin", "aliases": ["user"]}, + "dnac_password": {"type": "str", "no_log": True}, + "dnac_verify": {"type": "bool", "default": "True"}, + "dnac_version": {"type": "str", "default": "2.2.3.3"}, + "dnac_debug": {"type": "bool", "default": False}, + "dnac_log_level": {"type": "str", "default": "WARNING"}, + "dnac_log_file_path": {"type": "str", "default": "dnac.log"}, + "dnac_log_append": {"type": "bool", "default": True}, + "dnac_log": {"type": "bool", "default": False}, + "validate_response_schema": {"type": "bool", "default": True}, + "config_verify": {"type": "bool", "default": False}, + "dnac_api_task_timeout": {"type": "int", "default": 1200}, + "dnac_task_poll_interval": {"type": "int", "default": 2}, + "config": {"required": True, "type": "list", "elements": "dict"}, + "state": {"default": "merged", "choices": ["merged"]} } # Initialize the Ansible module with the provided argument specifications From c0d9106690f77b8dcf96dd359b23fcd70ca1f836 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Fri, 3 May 2024 03:08:44 -0400 Subject: [PATCH 316/358] paramter change suggested by Madhan --- .../network_compliance_workflow_manager.py | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 989ca02cba..1487c39a11 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -61,10 +61,9 @@ If it is False then compliance will be not be triggered for all categories. type: bool default: True - Choices: [True, False] run_compliance_categories: description: Specifying compliance categories allows you to trigger compliance checks only for the mentioned categories. - Category can have one or more values from among the following options "INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX" and "NETWORK_SETTINGS". + Category can have one or more values from among the following options "INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX", "NETWORK_SETTINGS". Category "INTENT" is mapped to compliance types "NETWORK_SETTINGS", "NETWORK_PROFILE", "WORKFLOW", "FABRIC", "APPLICATION_VISIBILITY". (e.g. ["INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX", "NETWORK_SETTINGS"]) type: list @@ -76,7 +75,6 @@ to startup by issuing "write memory" to device. type: bool default: False - Choices: [True, False] requirements: - dnacentersdk >= 2.7.0 @@ -399,7 +397,7 @@ def validate_run_compliance_paramters(self, mgmt_ip_instance_id_map, run_complia Notes: - This method prepares parameters for running compliance checks based on the provided inputs. - If invalid categories are provided in `run_compliance_categories`, a `ValueError` is raised. - - If `run_compliance_categories` is provided and neither `run_compliance` nor `run_compliance_categories` is set, an error + - If `run_compliance_categories` is provided and neither `run_compliance` nor `run_compliance_categories` is set, an error is logged and the method fails. - If `run_compliance` is set and `run_compliance_categories` is not, full compliance checks are triggered. - If both `run_compliance` and `run_compliance_categories` are set, compliance checks are triggered for specific categories. @@ -415,13 +413,13 @@ def validate_run_compliance_paramters(self, mgmt_ip_instance_id_map, run_complia self.module.fail_json(msg) if run_compliance is None or run_compliance: - #run_compliance_params + # run_compliance_params run_compliance_params["deviceUuids"] = list(mgmt_ip_instance_id_map.values()) run_compliance_params["triggerFull"] = False categories_copy = run_compliance_categories.copy() run_compliance_params["categories"] = categories_copy - #compliance_detail_params + # compliance_detail_params compliance_detail_params["deviceUuids"] = ",".join(list(mgmt_ip_instance_id_map.values())) compliance_types = run_compliance_categories if "INTENT" in compliance_types: @@ -437,11 +435,11 @@ def validate_run_compliance_paramters(self, mgmt_ip_instance_id_map, run_complia return self if run_compliance and not run_compliance_categories: - #run_compliance_params + # run_compliance_params run_compliance_params["deviceUuids"] = list(mgmt_ip_instance_id_map.values()) run_compliance_params["triggerFull"] = True - #compliance_detail_params + # compliance_detail_params compliance_detail_params["deviceUuids"] = ",".join(list(mgmt_ip_instance_id_map.values())) return run_compliance_params, compliance_detail_params @@ -482,7 +480,7 @@ def site_exists(self, site_name): site_id = site[0].get("id") site_exists = True else: - self.log( "No response received from the 'get_site' API call.", "ERROR") + self.log("No response received from the 'get_site' API call.", "ERROR") except Exception as e: # Log an error message and fail if an exception occurs @@ -521,7 +519,7 @@ def get_device_ids_from_ip(self, ip_address_list): op_modifies=True, params={"managementIpAddress": device_ip} ) - self.log("Response received post 'get_device_list' API call: {} ".format(str(response)), "DEBUG") + self.log("Response received post 'get_device_list' API call: {0} ".format(str(response)), "DEBUG") # Check if a valid response is received if response.get("response"): @@ -580,7 +578,7 @@ def get_device_ids_from_site(self, site_name, site_id): op_modifies=True, params=site_params, ) - self.log("Response received post 'get_membership' API Call: {} ".format(str(response)), "DEBUG") + self.log("Response received post 'get_membership' API Call: {0} ".format(str(response)), "DEBUG") # Process the response if available if response: @@ -716,7 +714,7 @@ def get_want(self, config): compliance_detail_params_sync = {} compliance_details = {} - #Store input parameters + # Store input parameters ip_address_list = config.get("ip_address_list") site_name = config.get("site_name") run_compliance = config.get("run_compliance") @@ -932,7 +930,7 @@ def sync_device_config(self, sync_device_config_params): # Log the error if an exception occurs during the API call except Exception as e: - self.msg = "Error occurred while synchronizing device configuration for {0}: {0}".format(sync_device_config_params, str(e)) + self.msg = "Error occurred while synchronizing device configuration for {0}: {1}".format(sync_device_config_params, str(e)) self.update_result("failed", False, self.msg, "ERROR") self.check_return_status() From 02cb69265ac6ce3864edce2a0433778cb97a315c Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Fri, 3 May 2024 03:20:08 -0400 Subject: [PATCH 317/358] doc review changes --- .../network_compliance_workflow_manager.yml | 6 ++++++ .../network_compliance_workflow_manager.py | 19 ++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/playbooks/network_compliance_workflow_manager.yml b/playbooks/network_compliance_workflow_manager.yml index 18a5d814de..7bbe82f6c5 100644 --- a/playbooks/network_compliance_workflow_manager.yml +++ b/playbooks/network_compliance_workflow_manager.yml @@ -21,6 +21,12 @@ config_verify: true tasks: + - name: Run Compliance check using IP address list (run_compliance by default is True) + cisco.dnac.network_compliance_workflow_manager: + <<: *dnac_login + config: + - ip_address_list: ['204.1.2.2', '204.1.2.5', '204.1.2.4'] + - name: Run Compliance check using IP address list cisco.dnac.network_compliance_workflow_manager: <<: *dnac_login diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 1487c39a11..4b205fe9fc 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -56,14 +56,13 @@ type: str run_compliance: description: Determines if a full compliance check should be triggered on the devices specified in the "ip_address_list" and/or "site_name". - This parameter is required when running a compliance check. if it is True then compliance will be triggered for all categories. If it is False then compliance will be not be triggered for all categories. type: bool default: True run_compliance_categories: description: Specifying compliance categories allows you to trigger compliance checks only for the mentioned categories. - Category can have one or more values from among the following options "INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX", "NETWORK_SETTINGS". + Category can have one or more values from among the options "INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX", "NETWORK_SETTINGS". Category "INTENT" is mapped to compliance types "NETWORK_SETTINGS", "NETWORK_PROFILE", "WORKFLOW", "FABRIC", "APPLICATION_VISIBILITY". (e.g. ["INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX", "NETWORK_SETTINGS"]) type: list @@ -96,6 +95,20 @@ """ EXAMPLES = r""" +- name: Run Compliance check on device(s) using IP address list (run_compliance by default is True) + cisco.dnac.network_compliance_workflow_manager: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" + dnac_log: False + config: + - ip_address_list: ["204.1.2.2", "204.1.2.5", "204.1.2.4"] + - name: Run Compliance check on device(s) using IP address list cisco.dnac.network_compliance_workflow_manager: dnac_host: "{{dnac_host}}" @@ -341,7 +354,7 @@ def validate_input(self): "ip_address_list": {"type": "list", "elements": "str", "required": False}, "site_name": {"type": "str", "required": False}, "run_compliance": {"type": "bool", "required": False, "default": True}, - "run_compliance_categories": {"type": "list", "elements": "str","required": False}, + "run_compliance_categories": {"type": "list", "elements": "str", "required": False}, "sync_device_config": {"type": "bool", "required": False, "default": False}, } From 77ca77d48eaf8b3ec0c807fb5a52034adcc81f73 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Fri, 3 May 2024 14:28:31 +0530 Subject: [PATCH 318/358] Address the review comments --- ...nts_and_notifications_workflow_manager.yml | 30 +- playbooks/input_events_and_notification.yml | 16 +- ...ents_and_notifications_workflow_manager.py | 940 ++++++++++-------- 3 files changed, 557 insertions(+), 429 deletions(-) diff --git a/playbooks/events_and_notifications_workflow_manager.yml b/playbooks/events_and_notifications_workflow_manager.yml index ac96041e5d..a30918474b 100644 --- a/playbooks/events_and_notifications_workflow_manager.yml +++ b/playbooks/events_and_notifications_workflow_manager.yml @@ -24,41 +24,41 @@ - syslog_destination: name: "{{item.syslog_destination.name}}" description: "{{item.syslog_destination.description}}" - host: "{{item.syslog_destination.host}}" + server_address: "{{item.syslog_destination.server_address}}" protocol: "{{item.syslog_destination.protocol}}" port: "{{item.syslog_destination.port}}" - rest_webhook_destination: - name: "{{item.rest_webhook_destination.name}}" - description: "{{item.rest_webhook_destination.description}}" - url: "{{item.rest_webhook_destination.url}}" - method: "{{item.rest_webhook_destination.method}}" - trust_cert: "{{item.rest_webhook_destination.trust_cert}}" + webhook_destination: + name: "{{item.webhook_destination.name}}" + description: "{{item.webhook_destination.description}}" + url: "{{item.webhook_destination.url}}" + method: "{{item.webhook_destination.method}}" + trust_cert: "{{item.webhook_destination.trust_cert}}" email_destination: from_email: "{{item.email_destination.from_email}}" to_email: "{{item.email_destination.to_email}}" subject: "{{item.email_destination.subject}}" primary_smtp_config: - hostname: "{{item.email_destination.primary_smtp_config.hostname}}" + server_address: "{{item.email_destination.primary_smtp_config.server_address}}" port: "{{item.email_destination.primary_smtp_config.port}}" snmp_destination: name: "{{item.snmp_destination.name}}" description: "{{item.snmp_destination.description}}" - ip_address: "{{item.snmp_destination.ip_address}}" + server_address: "{{item.snmp_destination.server_address}}" port: "{{item.snmp_destination.port}}" snmp_version: "{{item.snmp_destination.snmp_version}}" username: "{{item.snmp_destination.username}}" - snmp_mode: "{{item.snmp_destination.snmp_mode}}" - snmp_auth_type: "{{item.snmp_destination.snmp_auth_type}}" + mode: "{{item.snmp_destination.mode}}" + auth_type: "{{item.snmp_destination.auth_type}}" auth_password: "{{item.snmp_destination.auth_password}}" - snmp_privacy_type: "{{item.snmp_destination.snmp_privacy_type}}" + privacy_type: "{{item.snmp_destination.privacy_type}}" privacy_password: "{{item.snmp_destination.privacy_password}}" itsm_setting: - name: "{{item.itsm_setting.name}}" + instance_name: "{{item.itsm_setting.instance_name}}" description: "{{item.itsm_setting.description}}" connection_settings: url: "{{item.itsm_setting.connection_settings.url}}" - auth_username: "{{item.itsm_setting.connection_settings.username}}" - auth_password: "{{item.itsm_setting.connection_settings.password}}" + username: "{{item.itsm_setting.connection_settings.username}}" + password: "{{item.itsm_setting.connection_settings.password}}" with_items: "{{ events_notification }}" tags: diff --git a/playbooks/input_events_and_notification.yml b/playbooks/input_events_and_notification.yml index 2cae229c01..3642c4ce09 100644 --- a/playbooks/input_events_and_notification.yml +++ b/playbooks/input_events_and_notification.yml @@ -3,10 +3,10 @@ events_notification: - syslog_destination: name: Syslog Demo test description: "Adding syslog destination for testing" - host: "10.30.0.90" + server_address: "10.30.0.90" protocol: "TCP" port: 652 - rest_webhook_destination: + webhook_destination: name: "webhook demo 19" description: "webhhok description for testing" url: "https://10.195.227.14/dna" @@ -17,22 +17,22 @@ events_notification: to_email: "abmahesh@cisco.com" subject: "Ansible testing" primary_smtp_config: - hostname: "outbound.cisco.com" + server_address: "outbound.cisco.com" port: '25' snmp_destination: name: Snmp test description: "Adding snmp destination for testing for update" - ip_address: "10.30.0.91" + server_address: "10.30.0.91" port: '265' snmp_version: "V3" username: cisco123 - snmp_mode: AUTH_PRIVACY - snmp_auth_type: SHA + mode: AUTH_PRIVACY + auth_type: SHA auth_password: authpass123 - snmp_privacy_type: AES128 + privacy_type: AES128 privacy_password: privacy123 itsm_setting: - name: "Playbook itsm demo" + instance_name: "Playbook itsm demo" description: "ITSM description for testing" connection_settings: url: "https://catalystcente1.com" diff --git a/plugins/modules/events_and_notifications_workflow_manager.py b/plugins/modules/events_and_notifications_workflow_manager.py index 8c1c7b9bfe..de5d9e47b5 100644 --- a/plugins/modules/events_and_notifications_workflow_manager.py +++ b/plugins/modules/events_and_notifications_workflow_manager.py @@ -12,15 +12,19 @@ DOCUMENTATION = r""" --- module: events_and_notifications_workflow_manager -short_description: Resource module for Network Device +short_description: Configure various types of destinations to deliver event notifications from Cisco Catalyst Center Platform. description: -- Manage operations create, update and delete of the resource Network Device. -- Adds the device with given credential. -- Deletes the network device for the given Id. -- Sync the devices provided as input. -version_added: '6.8.0' +- Configure various types of destinations to deliver event notifications from Cisco Catalyst Center Platform. +- Configuring/Updating the Webhook destination details in Cisco Catalyst Center. +- Configuring/Updating the Email destination details in Cisco Catalyst Center. +- Configuring/Updating the Syslog destination details in Cisco Catalyst Center. +- Configuring/Updating the SNMP destination details in Cisco Catalyst Center. +- Configuring/Updating the ITSM Integration Settings in Cisco Catalyst Center. +- Deletes the ITSM Integration Settings from Cisco Catalyst Center. +- Create/Update Notification using the above destination in Cisco Catalyst Center. + extends_documentation_fragment: - - cisco.dnac.intent_params + - cisco.dnac.workflow_manager_params author: Abhishek Maheshwari (@abmahesh) Madhan Sankaranarayanan (@madhansansel) options: @@ -39,194 +43,238 @@ elements: dict required: True suboptions: - syslog_destination: - description: Dictionary containing the details for configuring/updating syslog destination in Cisco Catalyst Center. + webhook_destination: + description: Dictionary containing the details for configuring/updating the REST Endpoint to receive Audit logs and + Events from Cisco Catalyst Center Platform. type: dict suboptions: name: - description: Name of the syslog destination. - type: str - description: - description: Description of the syslog destination. - type: str - host: - description: Hostname or IP address of the syslog server. - type: str - protocol: - description: Protocol used for sending syslog messages (e.g., UDP, TCP). - Transmission Control Protocol (TCP) - It is a connection-oriented protocol used for reliable and ordered communication - between devices on a network. It provides error-checking, retransmission of lost packets, and ensures that data is - delivered in the correct order. - User Datagram Protocol (UDP) - It is a connectionless protocol used for sending datagrams between devices on a network. - It provides a lightweight, best-effort delivery mechanism without guaranteeing delivery or ordering of packets. UDP - is commonly used for real-time applications such as streaming media, online gaming, and VoIP. - type: str - port: - description: Port number on which the syslog server is listening. It must be in the range of 1-65536. - type: int - snmp_destination: - description: Dictionary containing the details for configuring/updating SNMP destination in Cisco Catalyst Center. - type: dict - suboptions: - name: - description: Name of the SNMP destination. - type: str - description: - description: Description of the SNMP destination. - type: str - ip_address: - description: IP address of the SNMP server. - type: str - port: - description: Port number on which the SNMP server is listening. - type: str - snmp_version: - description: SNMP version used for communication (e.g., SNMPv1, SNMPv2c, SNMPv3). - v2 - In this communication between the SNMP manager (such as Cisco Catalyst) and the managed devices - (such as routers, switches, or access points) is based on community strings.Community strings serve - as form of authentication and they are transmitted in clear text, providing no encryption. - v3 - It is the most secure version of SNMP, providing authentication, integrity, and encryption features. - It allows for the use of usernames, authentication passwords, and encryption keys, providing stronger - security compared to v2. - type: str - community: - description: SNMP community string for authentication (Required only if snmpVersion is V2C). - type: str - username: - description: Username for SNMP authentication (Required only if snmpVersion is V3). - type: str - snmp_mode: - description: AUTH_PRIVACY, AUTH_NO_PRIVACY, NO_AUTH_NO_PRIVACY). If snmpVersion is V3 it is required and cannot be NONE. - NO_AUTH_NO_PRIVACY - This mode provides no authentication or encryption for SNMP messages. It means that devices communicating using SNMPv1 do - not require any authentication (username/password) or encryption (data confidentiality). This makes it the least secure option. - AUTH_NO_PRIVACY - This mode provides authentication but no encryption for SNMP messages. Authentication involves validating the source of the - SNMP messages using a community string (similar to a password). However, the data transmitted between devices is not encrypted, - so it's susceptible to eavesdropping. - AUTH_PRIVACY - This mode provides both authentication and encryption for SNMP messages. It offers the highest level of security among the three - options. Authentication ensures that the source of the messages is genuine, and encryption ensures that the data exchanged between - devices is confidential and cannot be intercepted by unauthorized parties. - type: str - snmp_auth_type: - description: SNMP authentication type (e.g., MD5, SHA). - SHA (Secure Hash Algorithm) - It represents a family of cryptographic hash functions designed by the National Security Agency (NSA) - to ensure stronger security. - MD5 (Message Digest Algorithm 5) - is a widely used cryptographic hash function that produces a 128-bit (16-byte) hash value. - In the context of SNMPv3, it is used to authenticate the integrity and authenticity of the messages. - type: str - auth_password: - description: Password for SNMP authentication. - type: str - snmp_privacy_type: - description: SNMP privacy type (e.g., AES128). - type: str - privacy_password: - description: Privacy password for snmp authentication. - type: str - rest_webhook_destination: - description: Dictionary containing the details for configuring/updating Rest Webhook destination in Cisco Catalyst Center. - type: dict - suboptions: - name: - description: The name of the webhook destination. It identifies the webhook within the system. + description: Name of the webhook destination. A unique identifier for the webhook destination within the system. type: str + required: True description: description: A brief explanation of what the webhook destination is used for. type: str url: - description: The URL to which the webhook will send the request. It should be a fully qualified URL(e.g., https://ciscocatalyst.com). + description: Fully qualified URL to which the webhook will send requests (e.g., "https://ciscocatalyst.com"). type: str + required: True method: description: The HTTP method used by the webhook when sending requests (e.g., POST, PUT). + POST - It is typically used to create a new webhook destination. When you set up a new webhook in Cisco Catalyst Center, + you would use the POST method to send the necessary configuration details (like URL, headers, payload format, etc.) + to the server. + PUT - It is used to update an existing webhook destination. If a webhook destination is already configured and you need to + change any of its settings—such as modifying the URL, adjusting headers, or changing the payload format. type: str trust_cert: - description: A boolean indicating whether the SSL/TLS certificate of the URL should be verified. Set to true to bypass certificate verification. + description: A boolean that indicates whether to verify the SSL/TLS certificate of the URL, setting this to true will bypass + certificate verification. By default, it is set to false. type: bool headers: description: A list of HTTP headers to be included in the webhook request. Each header is represented as a dictionary. + While giving the headers details we can categorize them into - "Basic, Token and No Auth". + Basic Authentication - It is used to ensure that the receiving server can validate the identity of the requesting server by checking + the credentials against its store. This method is straightforward but less secure compared to others since credentials are sent + encoded but not encrypted. + Token Authentication - It involves security tokens which are typically generated by the server. A client must send this token in the + HTTP header to access resources. It is more secure than Basic Authentication as it allows the server to issue tokens that can have + a limited lifetime, be revoked, and carry specific permissions without exposing user credentials. + No Auth - It implies that no authentication method is required to access the webhook destination. This setting can be used in environments + where security is either handled by other means (such as network isolation) or where the data being transmitted is not sensitive. type: list elements: dict suboptions: name: - description: The name of the HTTP header. + description: Name of the HTTP header. type: str value: - description: The value assigned to the HTTP header. + description: Value assigned to the HTTP header. type: str default_value: - description: A default value for the HTTP header that can be used if no specific value is provided. + description: Default value for the HTTP header that can be used if no specific value is provided. type: str encrypt: description: Indicates whether the value of the header should be encrypted. Useful for sensitive data. type: bool is_proxy_route: - description: A boolean that determines whether the request should be routed through a proxy. True if routing through a proxy; otherwise, false." + description: A boolean value indicating if the request should use a proxy server. It will set to true for proxy routing, and false for direct + connection. By default, it is set to True. type: bool email_destination: - description: List containing the subscription configuration for events, notification on site through one or more channels. Also we can create or - configure email destination in Cisco Catalyst Center only once then later we can just modify it. + description: Configure settings to send out emails from Cisco Catalyst Center. Also we can create or configure email destination in Cisco Catalyst + Center only once then later we can just modify it. type: dict suboptions: primary_smtp_config: description: Add the primary configuration for smtp while creating/updating email destination. type: dict suboptions: - hostname: - description: Name of the host used for configuring smtp while creating/updating email destination. - type: str - port: - description: Name of the port used for configuring smtp while creating/updating email destination. + server_address: + description: Hostname or IP address of the primary SMTP server. Supports both IPv4 and IPv6. type: str + required: True smtp_type: - description: The type of SMTP server connection. Options include(DEFAULT,TLS, SSL). - DEFAULT - This one is selected for basic SMTP connection without encryption. - TLS - This one is selected for secure SMTP communication that begins unencrypted and then upgrades to encrypted using TLS if possible. - SSL - This one is selected for secure SMTP communication that starts encrypted using SSL." + description: The type of connection used for the SMTP server, with options being DEFAULT, TLS, or SSL. By default, it is set to DEFAULT. + DEFAULT - Chooses a standard SMTP connection without encryption. If it's selected then port will be 25 only. + TLS - Initiates an unencrypted SMTP connection and upgrades to TLS encryption when available. If it's selected then port will be + either 465 or 587. + SSL - Begins with an encrypted SMTP connection using SSL from the start. If it's selected then port will be + either 465 or 587. + type: str + required: True + port: + description: Port number used for configuring Primary SMTP Server. Also there is a mapping of smtype and port if snmp_type is DEFAULT + then port is 25 and for smtp_type TLS or SSL we can choose either 465 or 587 as port number. type: str username: - description: Name of the username used for configuring smtp while creating/updating email destination. + description: Username for Authenticating Primary SMTP Server. type: str password: - description: Password used for configuring smtp while creating/updating email destination. + description: Password for Authenticating Primary SMTP Server. type: str secondary_smtp_config: - description: Add the secondary configuration for smtp while creating/updating email destination. + description: Include an optional secondary SMTP configuration when creating or updating an email destination. type: dict suboptions: - hostname: - description: Name of the host used for configuring smtp while creating/updating email destination. - type: str - port: - description: Name of the port used for configuring smtp while creating/updating email destination. + server_address: + description: Hostname or IP address of the secondary SMTP server. Supports both IPv4 and IPv6. type: str smtp_type: - description: The type of SMTP server connection. Options include(DEFAULT,TLS, SSL). - DEFAULT - This one is selected for basic SMTP connection without encryption. - TLS - This one is selected for secure SMTP communication that begins unencrypted and then upgrades to encrypted using TLS if possible. - SSL - This one is selected for secure SMTP communication that starts encrypted using SSL." + description: The type of connection used for the SMTP server, with options being DEFAULT, TLS, or SSL. By default, it is set to DEFAULT. + DEFAULT - Chooses a standard SMTP connection without encryption. If it's selected then port will be 25 only. + TLS - Initiates an unencrypted SMTP connection and upgrades to TLS encryption when available. If it's selected then port will be + either 465 or 587. + SSL - Begins with an encrypted SMTP connection using SSL from the start. If it's selected then port will be + either 465 or 587. + type: str + port: + description: Port number used for configuring Secondary SMTP Server. Also there is a mapping of smtype and port if snmp_type is DEFAULT + then port is 25 and for smtp_type TLS or SSL we can choose either 465 or 587 as port number. type: str username: - description: Name of the username used for configuring smtp while creating/updating email destination. + description: Username for Authenticating Secondary SMTP Server. type: str password: - description: Password used for configuring smtp while creating/updating email destination. + description: Password for Authenticating Secondary SMTP Server. type: str from_email: - description: Email address from which mail to be sent while creating/updating email destination. + description: Sender's email address used when setting up or modifying an email destination. type: str + required: True to_email: - description: Email address which receives mail while creating/updating email destination. + description: Recipient's email address that will receive emails when an email destination is created or updated. type: str + required: True subject: - description: Subject of the email used for sending mail while creating/updating email destination. + description: Subject line of the email to be used when sending emails from the specified email destination. type: str - itsm_setting: - description: Dictionary containing the configuration details necessary for integrating with an IT Service Management (ITSM) system. + required: True + syslog_destination: + description: Dictionary containing the details for configuring/updating the Syslog Server to collect Audit logs and Events + from the Cisco Catalyst Center. + type: dict + suboptions: + name: + description: Name of the syslog destination. + type: str + required: True + description: + description: A brief explanation detailing the purpose of the syslog destination. + type: str + required: True + server_address: + description: Port number that the syslog server listens on, which must fall within the range of 1 to 65535. + type: str + required: True + protocol: + description: Protocol used for sending syslog messages (e.g., UDP, TCP). + Transmission Control Protocol (TCP) - It is a connection-oriented protocol used for reliable and ordered communication + between devices on a network. It provides error-checking, retransmission of lost packets, and ensures that data is + delivered in the correct order. + User Datagram Protocol (UDP) - It is a connectionless protocol used for sending datagrams between devices on a network. + It provides a lightweight, best-effort delivery mechanism without guaranteeing delivery or ordering of packets. UDP + is commonly used for real-time applications such as streaming media, online gaming, and VoIP. + type: str + required: True + port: + description: Port number on which the syslog server is listening. It must be in the range of 1-65535. If not given any port then + we will use 514 as default port. + type: int + required: True + snmp_destination: + description: Dictionary containing the details for configuring/updating the SNMP Trap Server to receive Audit logs and Events from + Cisco Catalyst Center. type: dict suboptions: name: + description: Name of the SNMP destination. + type: str + required: True + description: + description: Description of the SNMP destination. + type: str + required: True + server_address: + description: IP address of the SNMP server. + type: str + required: True + port: + description: Port number on which the SNMP server is listening. + type: str + required: True + snmp_version: + description: The SNMP protocol version used for network management and monitoring, selectable between SNMPv2c and SNMPv3. + V2C - Utilizes community strings for the authentication between the SNMP manager (like Cisco Catalyst) and managed network + devices (routers, switches, access points), without encryption, as strings are sent in plain text. + V3 - Offers enhanced security features over V2C, including authentication, integrity, and encryption, using usernames, + passwords, and encryption keys for secure communications. + type: str + community: + description: SNMP community string used for authentication, necessary only when the snmp_version is set to V2C. + type: str + username: + description: Username required for SNMP authentication, applicable exclusively when the snmp_version is configured to V3. + type: str + mode: + description: The security mode for SNMP communication (options - AUTH_PRIVACY, AUTH_NO_PRIVACY, NO_AUTH_NO_PRIVACY). + Mandatory for snmp_version V3 and must not be set to NONE. + AUTH_PRIVACY - The most secure mode, providing both verification of the message source through authentication and protection of + message contents with encryption. + If this option is selected, must need to provide auth_type, auth_password, privacy_type, privacy_password parameter in the playbook. + AUTH_NO_PRIVACY - This mode ensures the authenticity of SNMP messages via a community string for validation but does not encrypt + the data, leaving it vulnerable to interception. + If this option is selected, must need to provide auth_type, auth_password parameter in the playbook. + NO_AUTH_NO_PRIVACY - In this mode, SNMP messages are neither authenticated nor encrypted, making it the least secure as it requires no + credentials or data protection. + If this option is selected, not need to provide auth_type, auth_password, privacy_type, privacy_password parameter in the playbook. + type: str + auth_type: + description: Type of SNMP authentication protocol to use, such as MD5 or SHA. + SHA - Stands for Secure Hash Algorithm, a suite of cryptographic hash functions developed by the National Security Agency (NSA) offering + enhanced security. + MD5 - Refers to Message Digest Algorithm 5, a well-established cryptographic hash function generating a 128-bit hash value, employed in + SNMPv3 for message authenticity and integrity verification. + type: str + auth_password: + description: Password used for SNMP authentication. + type: str + privacy_type: + description: Encryption algorithm used for SNMP privacy, such as AES128. + type: str + privacy_password: + description: Password used for encryption in SNMP privacy. + type: str + itsm_setting: + description: Dictionary containing the configuration details to configure the ServiceNow/BMCRemedy settings to automatically create + incidents/problems/RFC's from Cisco Catalyst Center. + type: dict + suboptions: + instance_name: description: The name of the ITSM configuration. This helps in identifying the integration within the system. Also while deleting the ITSM Intergration setting from Cisco Catalyst Center. type: str + required: True description: description: A brief description of the ITSM settings, outlining its purpose or usage within the organization. type: str @@ -237,12 +285,15 @@ url: description: The URL of the ITSM system API endpoint. This is the base URL used for ITSM service requests. type: str + required: True username: description: The username used for authentication with the ITSM system. This is required for accessing the API. type: str + required: True password: description: The password associated with the username for API authentication. It is recommended to handle this data securely. type: str + required: True requirements: @@ -260,11 +311,19 @@ events.Events.get_webhook_destination, events.Events.create_webhook_destination, events.Events.update_webhook_destination, + events.Events.get_email_destination, + events.Events.create_email_destination, + events.Events.get_status_api_for_events, + events.Events.get_all_itsm_integration_settings, + events.Events.get_itsm_integration_setting_by_id, + events.Events.create_itsm_integration_setting, + events.Events.update_itsm_integration_setting, + events.Events.delete_itsm_integration_setting """ EXAMPLES = r""" -- name: Create Syslog destination with given name. +- name: Create Rest Webhook destination with given name. cisco.dnac.events_and_notifications_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -277,14 +336,14 @@ dnac_log: False state: merged config: - - syslog_destination: - name: Syslog test - description: "Adding syslog destination" - host: "10.30.0.90" - protocol: "TCP" - port: 6553 + - webhook_destination: + name: "webhook test" + description: "creating webhook for testing" + url: "https://10.195.227.14/dna" + method: "POST" + trust_cert: False -- name: Update Syslog destination with given name. +- name: Updating Rest Webhook destination with given name. cisco.dnac.events_and_notifications_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -297,11 +356,12 @@ dnac_log: False state: merged config: - - syslog_destination: - name: Syslog test - description: "Updating syslog destination." + - webhook_destination: + name: "webhook test" + description: "updating webhook for testing" -- name: Create SNMP destination with given name. + +- name: Configuring the email destination in the system. cisco.dnac.events_and_notifications_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -314,20 +374,16 @@ dnac_log: False state: merged config: - - snmp_destination: - name: Snmp test - description: "Adding snmp destination for testing." - ip_address: "10.30.0.90" - port: "25" - snmp_version: "V3" - username: cisco - snmp_mode: AUTH_PRIVACY - snmp_auth_type: SHA - auth_password: authpass123 - snmp_privacy_type: AES128 - privacy_password: privacy123 + - email_destination: + from_email: "test@cisco.com" + to_email: "demo@cisco.com" + subject: "Ansible testing" + primary_smtp_config: + server_address: "outbound.cisco.com" + port: "25" + smtp_type: "DEFAULT" -- name: Update SNMP destination with given name. +- name: Updating the email destination in the system. cisco.dnac.events_and_notifications_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -340,15 +396,12 @@ dnac_log: False state: merged config: - - snmp_destination: - name: Snmp test - description: "Updating snmp destination with snmp version v2." - ip_address: "10.30.0.90" - port: "25" - snmp_version: "V2C" - community: "public123" + - email_destination: + from_email: "test@cisco.com" + to_email: "demo123@cisco.com" + subject: "Ansible updated email config testing" -- name: Configuring the email destination in the system. +- name: Create Syslog destination with given name. cisco.dnac.events_and_notifications_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -361,16 +414,14 @@ dnac_log: False state: merged config: - - email_destination: - from_email: "test@cisco.com" - to_email: "demo@cisco.com" - subject: "Ansible testing" - primary_smtp_config: - hostname: "outbound.cisco.com" - port: "25" - smtp_type: "DEFAULT" + - syslog_destination: + name: Syslog test + description: "Adding syslog destination" + server_address: "10.30.0.90" + protocol: "TCP" + port: 6553 -- name: Updating the email destination in the system. +- name: Update Syslog destination with given name. cisco.dnac.events_and_notifications_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -383,12 +434,11 @@ dnac_log: False state: merged config: - - email_destination: - from_email: "test@cisco.com" - to_email: "demo123@cisco.com" - subject: "Ansible updated email config testing" + - syslog_destination: + name: Syslog test + description: "Updating syslog destination." -- name: Create Rest Webhook destination with given name. +- name: Create SNMP destination with given name. cisco.dnac.events_and_notifications_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -401,14 +451,20 @@ dnac_log: False state: merged config: - - rest_webhook_destination: - name: "webhook test" - description: "creating webhook for testing" - url: "https://10.195.227.14/dna" - method: "GET" - trust_cert: False + - snmp_destination: + name: Snmp test + description: "Adding snmp destination for testing." + server_address: "10.30.0.90" + port: "25" + snmp_version: "V3" + username: cisco + mode: AUTH_PRIVACY + auth_type: SHA + auth_password: authpass123 + privacy_type: AES128 + privacy_password: privacy123 -- name: Updating Rest Webhook destination with given name. +- name: Update SNMP destination with given name. cisco.dnac.events_and_notifications_workflow_manager: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" @@ -421,9 +477,13 @@ dnac_log: False state: merged config: - - rest_webhook_destination: - name: "webhook test" - description: "updating webhook for testing" + - snmp_destination: + name: Snmp test + description: "Updating snmp destination with snmp version v2." + server_address: "10.30.0.90" + port: "25" + snmp_version: "V2C" + community: "public123" - name: Create ITSM Integration Setting with given name in the system. cisco.dnac.events_and_notifications_workflow_manager: @@ -439,7 +499,7 @@ state: merged config: - itsm_setting: - name: "ITSM test" + instance_name: "ITSM test" description: "ITSM description for testing" connection_settings: url: "http/catalystcenter.com" @@ -460,7 +520,7 @@ state: merged config: - itsm_setting: - name: "ITSM test" + instance_name: "ITSM test" connection_settings: url: "http/catalystcenterupdate.com" password: "catalyst@123" @@ -479,7 +539,7 @@ state: deleted config: - itsm_setting: - name: "ITSM test" + instance_name: "ITSM test" """ @@ -534,42 +594,36 @@ def validate_input(self): """ temp_spec = { - 'syslog_destination': { - 'type': 'dict', - 'name': {'type': 'str'}, - 'description': {'type': 'str'}, - 'host': {'type': 'str'}, - 'protocol': {'type': 'str'}, - 'port': {'type': 'int'}, - }, - 'snmp_destination': { + 'webhook_destination': { 'type': 'dict', 'name': {'type': 'str'}, 'description': {'type': 'str'}, - 'ip_address': {'type': 'str'}, - 'port': {'type': 'str'}, - 'snmp_version': {'type': 'str'}, - 'community': {'type': 'str'}, - 'username': {'type': 'str'}, - 'snmp_mode': {'type': 'str'}, - 'snmp_auth_type': {'type': 'str'}, - 'auth_password': {'type': 'str'}, - 'snmp_privacy_type': {'type': 'str'}, - 'privacy_password': {'type': 'str'}, + 'url': {'type': 'str'}, + 'method': {'type': 'str', 'default': 'POST'}, + 'trust_cert': {'type': 'bool', 'default': False}, + 'headers': { + 'type': 'list', + 'elements': 'dict', + 'name': {'type': 'str'}, + 'value': {'type': 'str'}, + 'default_value': {'type': 'str'}, + 'encrypt': {'type': 'bool'}, + }, + 'is_proxy_route': {'type': 'bool', 'default': True} }, 'email_destination': { 'type': 'dict', 'primary_smtp_config': { 'type': 'dict', - 'hostname': {'type': 'str'}, - 'port': {'type': 'str'}, - 'smtp_type': {'type': 'str'}, + 'server_address': {'type': 'str'}, + 'port': {'type': 'str', 'default': '25'}, + 'smtp_type': {'type': 'str', 'default': 'DEFAULT'}, 'username': {'type': 'str'}, 'password': {'type': 'str'}, }, 'secondary_smtp_config': { 'type': 'dict', - 'hostname': {'type': 'str'}, + 'server_address': {'type': 'str'}, 'port': {'type': 'str'}, 'smtp_type': {'type': 'str'}, 'username': {'type': 'str'}, @@ -579,32 +633,38 @@ def validate_input(self): 'to_email': {'type': 'str'}, 'subject': {'type': 'str'}, }, - 'rest_webhook_destination': { + 'syslog_destination': { 'type': 'dict', 'name': {'type': 'str'}, 'description': {'type': 'str'}, - 'url': {'type': 'str'}, - 'method': {'type': 'str'}, - 'trust_cert': {'type': 'bool'}, - 'headers': { - 'type': 'list', - 'elements': 'dict', - 'name': {'type': 'str'}, - 'value': {'type': 'str'}, - 'default_value': {'type': 'str'}, - 'encrypt': {'type': 'bool'}, - }, - 'is_proxy_route': {'type': 'bool'} + 'server_address': {'type': 'str'}, + 'protocol': {'type': 'str'}, + 'port': {'type': 'int', 'default': 514}, }, - 'itsm_setting': { + 'snmp_destination': { 'type': 'dict', 'name': {'type': 'str'}, 'description': {'type': 'str'}, + 'server_address': {'type': 'str'}, + 'port': {'type': 'str'}, + 'snmp_version': {'type': 'str'}, + 'community': {'type': 'str'}, + 'username': {'type': 'str'}, + 'mode': {'type': 'str'}, + 'auth_type': {'type': 'str'}, + 'auth_password': {'type': 'str'}, + 'privacy_type': {'type': 'str'}, + 'privacy_password': {'type': 'str'}, + }, + 'itsm_setting': { + 'type': 'dict', + 'instance_name': {'type': 'str'}, + 'description': {'type': 'str'}, 'connection_settings': { 'type': 'dict', 'url': {'type': 'str'}, - 'auth_username': {'type': 'str'}, - 'auth_password': {'type': 'str'}, + 'username': {'type': 'str'}, + 'password': {'type': 'str'}, }, }, } @@ -615,7 +675,7 @@ def validate_input(self): ) if invalid_params: - self.msg = "Invalid parameters in playbook: {0}".format(invalid_params) + self.msg = "The playbook contains invalid parameters: {0}".format(invalid_params) self.log(self.msg, "ERROR") self.status = "failed" return self @@ -649,24 +709,29 @@ def get_have(self, config): have = {} if config.get('syslog_destination'): - if self.get_syslog_destination_in_ccc(): - have['syslog_destinations'] = self.get_syslog_destination_in_ccc() + syslog_destination = self.get_syslog_destination_in_ccc() + if syslog_destination: + have['syslog_destinations'] = syslog_destination if config.get('snmp_destination'): - if self.get_snmp_destination_in_ccc(): - have['snmp_destinations'] = self.get_snmp_destination_in_ccc() + snmp_destinations = self.get_snmp_destination_in_ccc() + if snmp_destinations: + have['snmp_destinations'] = snmp_destinations - if config.get('rest_webhook_destination'): - if self.get_rest_webhook_destination_in_ccc(): - have['webhook_destinations'] = self.get_rest_webhook_destination_in_ccc() + if config.get('webhook_destination'): + webhook_destinations = self.get_webhook_destination_in_ccc() + if webhook_destinations: + have['webhook_destinations'] = webhook_destinations if config.get('email_destination'): - if self.get_email_destination_in_ccc(): - have['email_destination'] = self.get_email_destination_in_ccc() + email_destination = self.get_email_destination_in_ccc() + if email_destination: + have['email_destination'] = email_destination if config.get('itsm_setting'): - if self.get_itsm_settings_in_ccc(): - have['itsm_setting'] = self.get_itsm_settings_in_ccc() + itsm_setting = self.get_itsm_settings_in_ccc() + if itsm_setting: + have['itsm_setting'] = itsm_setting self.have = have self.log("Current State (have): {0}".format(str(self.have)), "INFO") @@ -688,14 +753,19 @@ def get_want(self, config): """ want = {} + if config.get('syslog_destination'): want['syslog_details'] = config.get('syslog_destination') + if config.get('snmp_destination'): want['snmp_details'] = config.get('snmp_destination') - if config.get('rest_webhook_destination'): - want['webhook_details'] = config.get('rest_webhook_destination') + + if config.get('webhook_destination'): + want['webhook_details'] = config.get('webhook_destination') + if config.get('email_destination'): want['email_details'] = config.get('email_destination') + if config.get('itsm_setting'): want['itsm_details'] = config.get('itsm_setting') @@ -823,9 +893,8 @@ def add_syslog_destination(self, syslog_details): try: name = syslog_details.get('name') description = syslog_details.get('description') - host = syslog_details.get('host') + server_address = syslog_details.get('server_address') protocol = syslog_details.get('protocol') - port = syslog_details.get('port', 514) if not protocol: self.status = "failed" @@ -836,15 +905,16 @@ def add_syslog_destination(self, syslog_details): protocol = protocol.upper() if protocol not in ["TCP", "UDP"]: self.status = "failed" - self.msg = """Invalid protocol name '{0}' for creating/updating syslog destination in Cisco Catalyst Center. + self.msg = """Invalid protocol name '{0}' for creating syslog destination in Cisco Catalyst Center. Select one of the following protocol 'TCP/UDP'.""".format(protocol) self.log(self.msg, "ERROR") return self + port = syslog_details.get('port', 514) add_syslog_params = { 'name': name, 'description': description, - 'host': host, + 'host': server_address, 'protocol': protocol, 'port': int(port) } @@ -904,12 +974,19 @@ def update_syslog_destination(self, syslog_details, syslog_details_in_ccc): update_syslog_params = {} update_syslog_params['name'] = syslog_details.get('name') or syslog_details_in_ccc.get('name') update_syslog_params['description'] = syslog_details.get('description') or syslog_details_in_ccc.get('description') - update_syslog_params['host'] = syslog_details.get('host') or syslog_details_in_ccc.get('host') + update_syslog_params['host'] = syslog_details.get('server_address') or syslog_details_in_ccc.get('host') update_syslog_params['protocol'] = syslog_details.get('protocol') or syslog_details_in_ccc.get('protocol') update_syslog_params['port'] = int(syslog_details.get('port') or syslog_details_in_ccc.get('port')) update_syslog_params['configId'] = syslog_details_in_ccc.get('configId') name = update_syslog_params.get('name') + if update_syslog_params.get('protocol').upper() not in ["TCP", "UDP"]: + self.status = "failed" + self.msg = """Invalid protocol name '{0}' for updating syslog destination in Cisco Catalyst Center. + Select one of the following protocol 'TCP/UDP'.""".format(update_syslog_params.get('protocol')) + self.log(self.msg, "ERROR") + return self + response = self.dnac._exec( family="event_management", function='update_syslog_destination', @@ -992,23 +1069,24 @@ def collect_snmp_playbook_params(self, snmp_details): playbook_params = { 'name': snmp_details.get('name'), 'description': snmp_details.get('description'), - 'ipAddress': snmp_details.get('ip_address'), + 'ipAddress': snmp_details.get('server_address'), 'port': snmp_details.get('port'), 'snmpVersion': snmp_details.get('snmp_version') } - if playbook_params['snmpVersion'] == "V2C": + if playbook_params.get('snmpVersion') == "V2C": playbook_params['community'] = snmp_details.get('community') - else: + elif playbook_params.get('snmpVersion') == "V3": playbook_params['userName'] = snmp_details.get('username') - playbook_params['snmpMode'] = snmp_details.get('snmp_mode') + playbook_params['snmpMode'] = snmp_details.get('mode') + if playbook_params['snmpMode'] == "AUTH_PRIVACY": - playbook_params['snmpAuthType'] = snmp_details.get('snmp_auth_type') + playbook_params['snmpAuthType'] = snmp_details.get('auth_type') playbook_params['authPassword'] = snmp_details.get('auth_password') - playbook_params['snmpPrivacyType'] = snmp_details.get('snmp_privacy_type', 'AES128') + playbook_params['snmpPrivacyType'] = snmp_details.get('privacy_type', 'AES128') playbook_params['privacyPassword'] = snmp_details.get('privacy_password') elif playbook_params['snmpMode'] == "AUTH_NO_PRIVACY": - playbook_params['snmpAuthType'] = snmp_details.get('snmp_auth_type') + playbook_params['snmpAuthType'] = snmp_details.get('auth_type') playbook_params['authPassword'] = snmp_details.get('auth_password') return playbook_params @@ -1098,9 +1176,10 @@ def add_snmp_destination(self, snmp_params): return self self.status = "failed" - try: - failure_msg = response.get('errorMessage').get('errors') - except Exception as e: + error_messages = response.get('errorMessage') + if error_messages: + failure_msg = error_messages.get('errors') + else: failure_msg = "Unable to Add SNMP destination with name '{0}' in Cisco Catalyst Center".format(snmp_params.get('name')) self.log(failure_msg, "ERROR") @@ -1174,13 +1253,13 @@ def update_snmp_destination(self, snmp_params, snmp_dest_detail_in_ccc): port = int(snmp_params.get('port')) if port not in range(1, 65536): self.status = "failed" - self.msg = "Invalid Notification trap port '{0}' given in playbook. Select port from the number range(1, 65536)".format(port) + self.msg = "Invalid Notification trap port '{0}' given in playbook. Select port from the number range(1, 65535)".format(port) self.log(self.msg, "ERROR") return self except Exception as e: self.status = "failed" self.msg = """Invalid datatype for the Notification trap port '{0}' given in playbook. Select port with correct datatype from the - number range(1, 65536).""".format(port) + number range(1, 65535).""".format(port) self.log(self.msg, "ERROR") return self @@ -1218,9 +1297,10 @@ def update_snmp_destination(self, snmp_params, snmp_dest_detail_in_ccc): return self self.status = "failed" - try: - failure_msg = response.get('errorMessage').get('errors') - except Exception as e: + error_messages = response.get('errorMessage') + if error_messages: + failure_msg = error_messages.get('errors') + else: failure_msg = "Unable to update SNMP destination with name '{0}' in Cisco Catalyst Center".format(update_snmp_params.get('name')) self.log(failure_msg, "ERROR") @@ -1233,7 +1313,7 @@ def update_snmp_destination(self, snmp_params, snmp_dest_detail_in_ccc): return self - def get_rest_webhook_destination_in_ccc(self): + def get_webhook_destination_in_ccc(self): """ Retrieve details of Rest Webhook destinations present in Cisco Catalyst Center. Args: @@ -1294,7 +1374,7 @@ def collect_webhook_playbook_params(self, webhook_details): for headers in headers_list: temp_dict = { 'name': headers.get('name'), - 'value': headers.get('name'), + 'value': headers.get('value'), 'defaultValue': headers.get('default_value'), 'encrypt': headers.get('encrypt') } @@ -1338,9 +1418,10 @@ def add_webhook_destination(self, webhook_params): return self self.status = "failed" - try: - failure_msg = response.get('errorMessage').get('errors') - except Exception as e: + error_messages = response.get('errorMessage') + if error_messages: + failure_msg = error_messages.get('errors') + else: failure_msg = "Unable to Add Webhook destination with name '{0}' in Cisco Catalyst Center".format(webhook_params.get('name')) self.log(failure_msg, "ERROR") @@ -1408,12 +1489,12 @@ def remove_duplicates(self, headers_in_ccc): return unique_dicts - def update_webhook_destination(self, webhook_details, webhook_dest_detail_in_ccc): + def update_webhook_destination(self, webhook_params, webhook_dest_detail_in_ccc): """ Update a webhook destination in Cisco Catalyst Center with the provided details. Args: self (object): An instance of a class used for interacting with Cisco Catalyst Center. - webhook_details (dict): A dictionary containing the details of the webhook destination to be updated. + webhook_params (dict): A dictionary containing the details of the webhook destination to be updated. webhook_dest_detail_in_ccc (dict): A dictionary containing the details of the webhook destination in Cisco Catalyst Center. Returns: self (object): An instance of a class representing the status of the operation, including whether it was @@ -1428,13 +1509,13 @@ def update_webhook_destination(self, webhook_details, webhook_dest_detail_in_ccc try: update_webhook_params = {} - update_webhook_params['name'] = webhook_details.get('name') or webhook_dest_detail_in_ccc.get('name') - update_webhook_params['description'] = webhook_details.get('description') or webhook_dest_detail_in_ccc.get('description') - update_webhook_params['url'] = webhook_details.get('url') or webhook_dest_detail_in_ccc.get('url') - update_webhook_params['method'] = webhook_details.get('method') or webhook_dest_detail_in_ccc.get('method') - update_webhook_params['trust_cert'] = webhook_details.get('trustCert') or webhook_dest_detail_in_ccc.get('trustCert') - update_webhook_params['is_proxy_route'] = webhook_details.get('isProxyRoute') or webhook_dest_detail_in_ccc.get('isProxyRoute') - playbook_headers = webhook_details.get('headers') + update_webhook_params['name'] = webhook_params.get('name') or webhook_dest_detail_in_ccc.get('name') + update_webhook_params['description'] = webhook_params.get('description') or webhook_dest_detail_in_ccc.get('description') + update_webhook_params['url'] = webhook_params.get('url') or webhook_dest_detail_in_ccc.get('url') + update_webhook_params['method'] = webhook_params.get('method') or webhook_dest_detail_in_ccc.get('method') + update_webhook_params['trustCert'] = webhook_params.get('trustCert') or webhook_dest_detail_in_ccc.get('trustCert') + update_webhook_params['isProxyRoute'] = webhook_params.get('isProxyRoute') or webhook_dest_detail_in_ccc.get('isProxyRoute') + playbook_headers = webhook_params.get('headers') headers_in_ccc = webhook_dest_detail_in_ccc.get('headers') final_headers_list = [] @@ -1470,9 +1551,11 @@ def update_webhook_destination(self, webhook_details, webhook_dest_detail_in_ccc return self self.status = "failed" - try: - failure_msg = response.get('errorMessage').get('errors') - except Exception as e: + error_messages = response.get('errorMessage') + + if error_messages: + failure_msg = error_messages.get('errors') + else: failure_msg = "Unable to update rest webhook destination with name '{0}' in Cisco Catalyst Center".format(name) self.log(failure_msg, "ERROR") @@ -1541,18 +1624,26 @@ def collect_email_playbook_params(self, email_details): if email_details.get('primary_smtp_config'): primary_smtp_details = email_details.get('primary_smtp_config') playbook_params['primarySMTPConfig'] = {} - playbook_params['primarySMTPConfig']['hostName'] = primary_smtp_details.get('hostname') - playbook_params['primarySMTPConfig']['port'] = primary_smtp_details.get('port', "25") + playbook_params['primarySMTPConfig']['hostName'] = primary_smtp_details.get('server_address') playbook_params['primarySMTPConfig']['smtpType'] = primary_smtp_details.get('smtp_type', "DEFAULT") + + if playbook_params['primarySMTPConfig']['smtpType'] == 'DEFAULT': + playbook_params['primarySMTPConfig']['port'] = "25" + else: + playbook_params['primarySMTPConfig']['port'] = primary_smtp_details.get('port') playbook_params['primarySMTPConfig']['userName'] = primary_smtp_details.get('username', '') playbook_params['primarySMTPConfig']['password'] = primary_smtp_details.get('password', '') if email_details.get('seconday_smtp_config'): secondary_smtp_details = email_details.get('secondary_smtp_config') playbook_params['secondarySMTPConfig'] = {} - playbook_params['secondarySMTPConfig']['hostName'] = secondary_smtp_details.get('hostname') - playbook_params['secondarySMTPConfig']['port'] = secondary_smtp_details.get('port') + playbook_params['secondarySMTPConfig']['hostName'] = secondary_smtp_details.get('server_address') playbook_params['secondarySMTPConfig']['smtpType'] = secondary_smtp_details.get('smtp_type', "DEFAULT") + + if playbook_params['secondarySMTPConfig']['smtpType'] == 'DEFAULT': + playbook_params['secondarySMTPConfig']['port'] = "25" + else: + playbook_params['secondarySMTPConfig']['port'] = secondary_smtp_details.get('port') playbook_params['secondarySMTPConfig']['userName'] = secondary_smtp_details.get('username', '') playbook_params['secondarySMTPConfig']['password'] = secondary_smtp_details.get('password', '') @@ -1604,10 +1695,12 @@ def add_email_destination(self, email_params): return self self.status = "failed" - try: - failure_msg = response.get('errorMessage').get('errors') - except Exception as e: - failure_msg = "Unable to Add Email destination in Cisco Catalyst Center" + error_messages = response.get('errorMessage') + + if error_messages: + failure_msg = error_messages.get('errors') + else: + failure_msg = "Unable to Add Email destination in Cisco Catalyst Center." self.log(failure_msg, "ERROR") self.result['response'] = failure_msg @@ -1703,10 +1796,12 @@ def update_email_destination(self, email_details, email_dest_detail_in_ccc): return self self.status = "failed" - try: - failure_msg = response.get('errorMessage').get('errors') - except Exception as e: - failure_msg = "Unable to update Email destination in Cisco Catalyst Center" + error_messages = response.get('errorMessage') + + if error_messages: + failure_msg = error_messages.get('errors') + else: + failure_msg = "Unable to update Email destination in Cisco Catalyst Center." self.log(failure_msg, "ERROR") self.result['response'] = failure_msg @@ -1741,7 +1836,7 @@ def get_itsm_settings_in_ccc(self): self.log("Received API response from 'get_all_itsm_integration_settings': {0}".format(str(response)), "DEBUG") response = response.get('data') if not response: - self.log("There is no ISTM Integration settings present in Cisco Catalyst Center", "INFO") + self.log("There is no ITSM Integration settings present in Cisco Catalyst Center", "INFO") return response @@ -1776,7 +1871,7 @@ def get_itsm_settings_by_id(self, itsm_id): self.log("Received API response from 'get_itsm_integration_setting_by_id': {0}".format(str(response)), "DEBUG") if not response: - self.log("There is no ISTM Integration settings with given ID present in Cisco Catalyst Center", "INFO") + self.log("There is no ITSM Integration settings with given ID present in Cisco Catalyst Center", "INFO") return response @@ -1801,18 +1896,18 @@ def collect_itsm_playbook_params(self, itsm_details): """ playbook_params = { - 'name': itsm_details.get('name'), + 'name': itsm_details.get('instance_name'), 'description': itsm_details.get('description'), 'dypName': 'ServiceNowConnection' } playbook_params['data'] = {} + connection_details = itsm_details.get('connection_settings') - if itsm_details.get('connection_settings'): - connection_details = itsm_details.get('connection_settings') + if connection_details: playbook_params['data']['ConnectionSettings'] = {} playbook_params['data']['ConnectionSettings']['Url'] = connection_details.get('url') - playbook_params['data']['ConnectionSettings']['Auth_UserName'] = connection_details.get('auth_username') - playbook_params['data']['ConnectionSettings']['Auth_Password'] = connection_details.get('auth_password') + playbook_params['data']['ConnectionSettings']['Auth_UserName'] = connection_details.get('username') + playbook_params['data']['ConnectionSettings']['Auth_Password'] = connection_details.get('password') return playbook_params @@ -1881,9 +1976,9 @@ def create_itsm_integration_setting(self, itsm_params): return self self.status = "failed" - try: - failure_msg = response.get('errors') - except Exception as e: + failure_msg = response.get('errors') + + if not failure_msg: failure_msg = "Unable to create ITSM Integration Settings with name '{0}' in Cisco Catalyst Center".format(instance_name) self.log(failure_msg, "ERROR") @@ -1949,7 +2044,7 @@ def update_itsm_integration_setting(self, itsm_params, itsm_in_ccc): Description: This method updates existing ITSM integration settings in the Cisco Catalyst Center using the provided new parameters. The method performs several checks: - - It verifies that the 'Auth_Password' is provided when updating the connection settings. If not, it sets the status + - It verifies that the 'password' is provided when updating the connection settings. If not, it sets the status to 'failed' and logs an informational message. - It validates that the provided URL starts with 'https://'. If the URL is invalid, it sets the status to 'failed' and logs an informational message. @@ -1989,8 +2084,8 @@ def update_itsm_integration_setting(self, itsm_params, itsm_in_ccc): if not re.match(regex_pattern, url): self.status = "failed" - self.msg = "Given url '{0}' is invalid url for ITSM Intergartion setting.It must starts with 'https://'".format(url) - self.log(self.msg, "INFO") + self.msg = "Given url '{0}' is invalid url for ITSM Intergartion setting. It must starts with 'https://'".format(url) + self.log(self.msg, "ERROR") return self itsm_param_dict = { @@ -2018,9 +2113,9 @@ def update_itsm_integration_setting(self, itsm_params, itsm_in_ccc): return self self.status = "failed" - try: - failure_msg = response.get('errors') - except Exception as e: + failure_msg = response.get('errors') + + if not failure_msg: failure_msg = "Unable to update ITSM Integration Settings with name '{0}' in Cisco Catalyst Center".format(update_itsm_params.get('name')) self.log(failure_msg, "ERROR") @@ -2061,7 +2156,7 @@ def delete_itsm_integration_setting(self, itsm_name, itsm_id): self.log("Received API response from 'delete_itsm_integration_setting': {0}".format(str(response)), "DEBUG") if "successfully" in response: - self.msg = "ISTM Integration settings instance with name '{0}' deleted successfully from Cisco Catalyst Center".format(itsm_name) + self.msg = "ITSM Integration settings instance with name '{0}' deleted successfully from Cisco Catalyst Center".format(itsm_name) self.status = "success" self.log(self.msg, "INFO") self.result['changed'] = True @@ -2069,7 +2164,7 @@ def delete_itsm_integration_setting(self, itsm_name, itsm_id): return self self.status = "failed" - self.msg = "Cannot delete ISTM Integration settings instance with name '{0}' from Cisco Catalyst Center".format(itsm_name) + self.msg = "Cannot delete ITSM Integration settings instance with name '{0}' from Cisco Catalyst Center".format(itsm_name) self.log(self.msg, "ERROR") except Exception as e: @@ -2102,6 +2197,101 @@ def get_diff_merged(self, config): or invalid configurations, updating the internal state to reflect these errors. """ + # Create/Update Rest Webhook destination in Cisco Catalyst Center + if config.get('webhook_destination'): + webhook_details = self.want.get('webhook_details') + destination_name = webhook_details.get('name') + + if not destination_name: + self.status = "failed" + self.msg = "Name is required parameter for adding/updating Webhook destination for creating/updating the event." + self.log(self.msg, "ERROR") + return self + + is_destination_exist = False + for webhook_dict in self.have.get('webhook_destinations'): + if webhook_dict['name'] == destination_name: + webhook_dest_detail_in_ccc = webhook_dict + is_destination_exist = True + break + webhook_params = self.collect_webhook_playbook_params(webhook_details) + + if webhook_params.get('method') not in ["POST", "PUT"]: + self.status = "failed" + self.msg = """Invalid Webhook method name '{0}' for creating/updating Webhook destination in Cisco Catalyst Center. + Select one of the following method 'POST/PUT'.""".format(webhook_params.get('method')) + self.log(self.msg, "ERROR") + return self + + regex_pattern = r'https://\S+' + url = webhook_params.get('url') + + if not re.match(regex_pattern, url): + self.status = "failed" + self.msg = "Given url '{0}' is invalid url for Creating/Updating Webhook destination. It must starts with 'https://'".format(url) + self.log(self.msg, "ERROR") + return self + + if not is_destination_exist: + # Need to Add snmp destination in Cisco Catalyst Center with given playbook params + if not url: + self.status = "failed" + self.msg = "Url is required parameter for creating Webhook destination for creating/updating the event in Cisco Catalyst Center." + self.log(self.msg, "ERROR") + return self + + self.add_webhook_destination(webhook_params).check_return_status() + else: + # Check destination needs update and if yes then update SNMP Destination + webhook_need_update = self.webhook_dest_needs_update(webhook_params, webhook_dest_detail_in_ccc) + + if not webhook_need_update: + self.msg = "Webhook Destination with name '{0}' needs no update in Cisco Catalyst Center".format(destination_name) + self.log(self.msg, "INFO") + self.result['changed'] = False + self.result['response'] = self.msg + else: + # Update the syslog destination with given + self.update_webhook_destination(webhook_params, webhook_dest_detail_in_ccc).check_return_status() + + # Create/Update Email destination in Cisco Catalyst Center + if config.get('email_destination'): + email_details = self.want.get('email_details') + email_params = self.collect_email_playbook_params(email_details) + + if not self.have.get('email_destination'): + # Need to Add snmp destination in Cisco Catalyst Center with given playbook params + required_params = ['fromEmail', 'toEmail', 'subject'] + invalid_email_params = [] + for item in required_params: + if not email_params[item]: + invalid_email_params.append(item) + if email_params.get('primarySMTPConfig') and not email_params.get('primarySMTPConfig').get('hostName'): + invalid_email_params.append('server_address') + + if invalid_email_params: + self.status = "failed" + self.msg = """Required parameter '{0}' for configuring Email Destination in Cisco Catalyst Center + is missing.""".format(str(invalid_email_params)) + self.log(self.msg, "ERROR") + self.result['response'] = self.msg + return self + self.log("Required parameter validated successfully for adding Email Destination in Cisco Catalyst Center.", "INFO") + self.add_email_destination(email_params).check_return_status() + else: + # Check destination needs update and if yes then update Email Destination + email_dest_detail_in_ccc = self.have.get('email_destination') + email_need_update = self.email_dest_needs_update(email_params, email_dest_detail_in_ccc) + + if not email_need_update: + self.msg = "Email Destination needs no update in Cisco Catalyst Center" + self.log(self.msg, "INFO") + self.result['changed'] = False + self.result['response'] = self.msg + else: + # Update the email destination with given details in the playbook + self.update_email_destination(email_params, email_dest_detail_in_ccc).check_return_status() + # Create/Update Syslog destination in Cisco Catalyst Center if config.get('syslog_destination'): syslog_details = self.want.get('syslog_details') @@ -2116,7 +2306,7 @@ def get_diff_merged(self, config): if not port.isdigit() or (isinstance(port, int) and port not in range(1, 65536)): self.status = "failed" - self.msg = "Invalid Syslog destination port '{0}' given in playbook. Select port from the number range(1, 65536)".format(port) + self.msg = "Invalid Syslog destination port '{0}' given in playbook. Select port from the number range(1, 65535)".format(port) self.log(self.msg, "ERROR") return self @@ -2160,12 +2350,12 @@ def get_diff_merged(self, config): port = int(snmp_params.get('port')) if port not in range(1, 65536): self.status = "failed" - self.msg = "Invalid Notification trap port '{0}' given in playbook. Select port from the number range(1, 65536)".format(port) + self.msg = "Invalid Notification trap port '{0}' given in playbook. Select port from the number range(1, 65535)".format(port) self.log(self.msg, "ERROR") return self except Exception as e: self.status = "failed" - self.msg = "Invalid Notification trap port '{0}' given in playbook. Select port from the number range(1, 65536)".format(port) + self.msg = "Invalid Notification trap port '{0}' given in playbook. Select port from the number range(1, 65535)".format(port) self.log(self.msg, "ERROR") return self @@ -2187,96 +2377,10 @@ def get_diff_merged(self, config): # Update the email destination with given details in the playbook self.update_snmp_destination(snmp_params, snmp_dest_detail_in_ccc).check_return_status() - # Create/Update Rest Webhook destination in Cisco Catalyst Center - if config.get('rest_webhook_destination'): - webhook_details = self.want.get('webhook_details') - destination_name = webhook_details.get('name') - - if not destination_name: - self.status = "failed" - self.msg = "Name is required parameter for adding/updating Webhook destination for creating/updating the event." - self.log(self.msg, "ERROR") - return self - - is_destination_exist = False - for webhook_dict in self.have.get('webhook_destinations'): - if webhook_dict['name'] == destination_name: - webhook_dest_detail_in_ccc = webhook_dict - is_destination_exist = True - break - webhook_params = self.collect_webhook_playbook_params(webhook_details) - - if webhook_params.get('method') not in ["POST", "PUT"]: - self.status = "failed" - self.msg = """Invalid Webhook method name '{0}' for creating/updating Webhook destination in Cisco Catalyst Center. - Select one of the following method 'POST/PUT'.""".format(webhook_params.get('method')) - self.log(self.msg, "ERROR") - return self - - if not is_destination_exist: - # Need to Add snmp destination in Cisco Catalyst Center with given playbook params - if not webhook_params['url']: - self.status = "failed" - self.msg = "Url is required parameter for creating Webhook destination for creating/updating the event in Cisco Catalyst Center." - self.log(self.msg, "ERROR") - return self - - self.add_webhook_destination(webhook_params).check_return_status() - else: - # Check destination needs update and if yes then update SNMP Destination - webhook_need_update = self.webhook_dest_needs_update(webhook_params, webhook_dest_detail_in_ccc) - - if not webhook_need_update: - self.msg = "Webhook Destination with name '{0}' needs no update in Cisco Catalyst Center".format(destination_name) - self.log(self.msg, "INFO") - self.result['changed'] = False - self.result['response'] = self.msg - else: - # Update the syslog destination with given - self.update_webhook_destination(webhook_details, webhook_dest_detail_in_ccc).check_return_status() - - # Create/Update Email destination in Cisco Catalyst Center - if config.get('email_destination'): - email_details = self.want.get('email_details') - email_params = self.collect_email_playbook_params(email_details) - - if not self.have.get('email_destination'): - # Need to Add snmp destination in Cisco Catalyst Center with given playbook params - required_params = ['fromEmail', 'toEmail', 'subject'] - invalid_email_params = [] - for item in required_params: - if not email_params[item]: - invalid_email_params.append(item) - if not email_params.get('primarySMTPConfig').get('hostName'): - invalid_email_params.append('hostName') - - if invalid_email_params: - self.status = "failed" - self.msg = """Required parameter '{0}' for configuring Email Destination in Cisco Catalyst Center - is missing.""".format(str(invalid_email_params)) - self.log(self.msg, "ERROR") - self.result['response'] = self.msg - return self - self.log("Required parameter validated successfully for adding Email Destination in Cisco Catalyst Center.", "INFO") - self.add_email_destination(email_params).check_return_status() - else: - # Check destination needs update and if yes then update Email Destination - email_dest_detail_in_ccc = self.have.get('email_destination') - email_need_update = self.email_dest_needs_update(email_params, email_dest_detail_in_ccc) - - if not email_need_update: - self.msg = "Email Destination needs no update in Cisco Catalyst Center" - self.log(self.msg, "INFO") - self.result['changed'] = False - self.result['response'] = self.msg - else: - # Update the email destination with given details in the playbook - self.update_email_destination(email_params, email_dest_detail_in_ccc).check_return_status() - # Create/Update ITSM Integration Settings in Cisco Catalyst Center if config.get('itsm_setting'): itsm_details = self.want.get('itsm_details') - itsm_name = itsm_details.get('name') + itsm_name = itsm_details.get('instance_name') if not itsm_name: self.status = "failed" self.msg = "Instance name is required parameter for adding/updating ITSM integration setting in Cisco Catalyst Center." @@ -2308,8 +2412,8 @@ def get_diff_merged(self, config): if not re.match(regex_pattern, url): self.status = "failed" - self.msg = "Given url '{0}' is invalid url for ITSM Intergartion setting.It must starts with 'https://'".format(url) - self.log(self.msg, "INFO") + self.msg = "Given url '{0}' is invalid url for ITSM Intergartion setting. It must starts with 'https://'".format(url) + self.log(self.msg, "ERROR") return self if invalid_itsm_params: @@ -2339,7 +2443,7 @@ def get_diff_merged(self, config): self.result['changed'] = False self.result['response'] = self.msg else: - # Update the email destination with given details in the playbook + # Update the ITSM integration settings with given details in the playbook self.update_itsm_integration_setting(itsm_params, itsm_in_ccc).check_return_status() return self @@ -2359,9 +2463,33 @@ def get_diff_deleted(self, config): status and results to reflect that no change was needed. """ + if config.get('webhook_destination'): + self.status = "failed" + self.msg = "Deleting the Webhook destination is not supported in Cisco Catalyst Center because of API limitations" + self.log(self.msg, "ERROR") + self.result['changed'] = False + + if config.get('email_destination'): + self.status = "failed" + self.msg = "Deleting the Email destination is not supported in Cisco Catalyst Center because of API limitations" + self.log(self.msg, "ERROR") + self.result['changed'] = False + + if config.get('syslog_destination'): + self.status = "failed" + self.msg = "Deleting the Syslog destination is not supported in Cisco Catalyst Center because of API limitations" + self.log(self.msg, "ERROR") + self.result['changed'] = False + + if config.get('snmp_destination'): + self.status = "failed" + self.msg = "Deleting the SNMP destination is not supported in Cisco Catalyst Center because of API limitations" + self.log(self.msg, "ERROR") + self.result['changed'] = False + if config.get('itsm_setting'): itsm_details = self.want.get('itsm_details') - itsm_name = itsm_details.get('name') + itsm_name = itsm_details.get('instance_name') itsm_detail_in_ccc = self.have.get('itsm_setting') if not itsm_detail_in_ccc: self.status = "success" @@ -2438,7 +2566,7 @@ def verify_diff_merged(self, config): self.log("""Playbook's input does not match with Cisco Catalyst Center, indicating that the SNMP destination with name '{0}' addition/updation task may not have executed successfully.""".format(snmp_dest_name), "INFO") - if config.get('rest_webhook_destination'): + if config.get('webhook_destination'): webhook_details = self.want.get('webhook_details') webhook_name = webhook_details.get('name') @@ -2469,7 +2597,7 @@ def verify_diff_merged(self, config): if config.get('itsm_setting'): itsm_details = self.want.get('itsm_details') - itsm_name = itsm_details.get('name') + itsm_name = itsm_details.get('instance_name') is_itsm_exist = False itsm_detail_in_ccc = self.have.get('itsm_setting') @@ -2512,7 +2640,7 @@ def verify_diff_deleted(self, config): if config.get('itsm_setting'): itsm_details = self.want.get('itsm_details') - itsm_name = itsm_details.get('name') + itsm_name = itsm_details.get('instance_name') itsm_detail_in_ccc = self.have.get('itsm_setting') itsm_deleted = True From 621f964ea080cc0146d73d0ab337e4d1f597d003 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Fri, 3 May 2024 15:28:29 +0530 Subject: [PATCH 319/358] Enhanced log messages for site instead of showing last messages show all possible operation on each site and handle provision for wired device not present in Catalyst Center --- plugins/modules/inventory_intent.py | 18 +++- plugins/modules/inventory_workflow_manager.py | 18 +++- plugins/modules/site_intent.py | 93 +++++++++++------- plugins/modules/site_workflow_manager.py | 96 ++++++++++++------- 4 files changed, 158 insertions(+), 67 deletions(-) diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index f807d53a23..ce6f0c2e2a 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -2899,10 +2899,26 @@ def get_diff_merged(self, config): credential_update = self.config[0].get("credential_update", False) config['type'] = device_type + config['ip_address_list'] = devices_to_add if device_type == "FIREPOWER_MANAGEMENT_SYSTEM": config['http_port'] = self.config[0].get("http_port", "443") - config['ip_address_list'] = devices_to_add + if self.config[0].get('provision_wired_device'): + provision_wired_list = self.config[0]['provision_wired_device'] + device_not_available = [] + device_in_ccc = self.device_exists_in_dnac() + + for prov_dict in provision_wired_list: + device_ip = prov_dict['device_ip'] + if device_ip not in device_in_ccc: + device_not_available.append(device_ip) + if device_not_available: + self.status = "failed" + self.msg = """Unable to Provision Wired Device(s) because the device(s) listed: {0} are not present in the + Cisco Catalyst Center.""".format(str(device_not_available)) + self.result['response'] = self.msg + self.log(self.msg, "ERROR") + return self if self.config[0].get('update_mgmt_ipaddresslist'): device_ip = self.config[0].get('update_mgmt_ipaddresslist')[0].get('existMgmtIpAddress') diff --git a/plugins/modules/inventory_workflow_manager.py b/plugins/modules/inventory_workflow_manager.py index 2d3176c932..b1bbc8b067 100644 --- a/plugins/modules/inventory_workflow_manager.py +++ b/plugins/modules/inventory_workflow_manager.py @@ -2890,10 +2890,26 @@ def get_diff_merged(self, config): credential_update = self.config[0].get("credential_update", False) config['type'] = device_type + config['ip_address_list'] = devices_to_add if device_type == "FIREPOWER_MANAGEMENT_SYSTEM": config['http_port'] = self.config[0].get("http_port", "443") - config['ip_address_list'] = devices_to_add + if self.config[0].get('provision_wired_device'): + provision_wired_list = self.config[0]['provision_wired_device'] + device_not_available = [] + device_in_ccc = self.device_exists_in_ccc() + + for prov_dict in provision_wired_list: + device_ip = prov_dict['device_ip'] + if device_ip not in device_in_ccc: + device_not_available.append(device_ip) + if device_not_available: + self.status = "failed" + self.msg = """Unable to Provision Wired Device(s) because the device(s) listed: {0} are not present in the + Cisco Catalyst Center.""".format(str(device_not_available)) + self.result['response'] = self.msg + self.log(self.msg, "ERROR") + return self if self.config[0].get('update_mgmt_ipaddresslist'): device_ip = self.config[0].get('update_mgmt_ipaddresslist')[0].get('existMgmtIpAddress') diff --git a/plugins/modules/site_intent.py b/plugins/modules/site_intent.py index b9b5d8081a..2288a5c280 100644 --- a/plugins/modules/site_intent.py +++ b/plugins/modules/site_intent.py @@ -342,6 +342,8 @@ class DnacSite(DnacBase): def __init__(self, module): super().__init__(module) self.supported_states = ["merged", "deleted"] + self.created_site_list, self.updated_site_list, self.update_not_neeeded_sites = [], [], [] + self.deleted_site_list, self.site_absent_list = [], [] def validate_input(self): """ @@ -449,7 +451,7 @@ def get_current_site(self, site): width=map_geometry.get("attributes").get("width"), length=map_geometry.get("attributes").get("length"), height=map_geometry.get("attributes").get("height"), - floorNumber=map_geometry.get("attributes").get("floor_number", "") + floorNumber=map_summary.get('attributes').get('floorIndex') ) ) @@ -666,7 +668,7 @@ def is_floor_updated(self, updated_site, requested_site): """ keys_to_compare = ['length', 'width', 'height'] - if updated_site['name'] != requested_site['name'] or updated_site['rf_model'] != requested_site['rfModel']: + if updated_site['name'] != requested_site['name'] or updated_site.get('rf_model') != requested_site.get('rfModel'): return False for key in keys_to_compare: @@ -781,6 +783,7 @@ def get_diff_merged(self, config): site_updated = False site_created = False + site_name = self.want.get("site_name") # check if the given site exists and/or needs to be updated/created. if self.have.get("site_exists"): @@ -795,14 +798,13 @@ def get_diff_merged(self, config): op_modifies=True, params=site_params, ) + self.log("Received API response from 'update_site': {0}".format(str(response)), "DEBUG") site_updated = True else: # Site does not neet update - self.result['response'] = self.have.get("current_site") - self.msg = "Site - {0} does not need any update".format(self.have.get("current_site")) - self.log(self.msg, "INFO") - self.result['msg'] = self.msg + self.update_not_neeeded_sites.append(site_name) + self.log("Site - {0} does not need any update".format(site_name), "INFO") return self else: @@ -817,9 +819,9 @@ def get_diff_merged(self, config): site_params['site']['building'] = building_details except Exception as e: site_type = site_params['type'] - site_name = site_params['site'][site_type]['name'] + name = site_params['site'][site_type]['name'] self.log("""The site '{0}' is not categorized as a building; hence, there is no need to filter out 'None' - values from the 'site_params' dictionary.""".format(site_name), "INFO") + values from the 'site_params' dictionary.""".format(name), "INFO") response = self.dnac._exec( family="sites", @@ -837,7 +839,6 @@ def get_diff_merged(self, config): execution_details = self.get_execution_details(executionid) if execution_details.get("status") == "SUCCESS": self.result['changed'] = True - self.result['response'] = execution_details break elif execution_details.get("bapiError"): @@ -846,21 +847,15 @@ def get_diff_merged(self, config): break if site_updated: - self.msg = "Site - {0} Updated Successfully".format(self.want.get("site_name")) - self.log(self.msg, "INFO") - self.result['msg'] = self.msg - self.result['response'].update({"siteId": self.have.get("site_id")}) - + self.updated_site_list.append(site_name) + self.log("Site - {0} Updated Successfully".format(site_name), "INFO") else: # Get the site id of the newly created site. (site_exists, current_site) = self.site_exists() if site_exists: - self.msg = "Site '{0}' created successfully".format(self.want.get("site_name")) - self.log(self.msg, "INFO") - self.log("Current site (have): {0}".format(str(current_site)), "DEBUG") - self.result['msg'] = self.msg - self.result['response'].update({"siteId": current_site.get('site_id')}) + self.created_site_list.append(site_name) + self.log("Site '{0}' created successfully".format(site_name), "INFO") return self @@ -895,11 +890,9 @@ def delete_single_site(self, site_id, site_name): while True: execution_details = self.get_execution_details(executionid) if execution_details.get("status") == "SUCCESS": - self.msg = "Site '{0}' deleted successfully".format(site_name) - self.result['changed'] = True - self.result['response'] = self.msg self.status = "success" - self.log(self.msg, "INFO") + self.deleted_site_list.append(site_name) + self.log("Site '{0}' deleted successfully".format(site_name), "INFO") break elif execution_details.get("bapiError"): self.log("Error response for 'delete_site' execution: {0}".format(execution_details.get("bapiError")), "ERROR") @@ -935,12 +928,8 @@ def get_diff_deleted(self, config): site_name = self.want.get("site_name") if not site_exists: self.status = "success" - self.msg = "Unable to delete site '{0}' as it's not found in Cisco Catalyst Center".format(site_name) - self.result.update({'changed': False, - 'response': self.msg, - 'msg': self.msg}) - self.log(self.msg, "INFO") - + self.site_absent_list.append(site_name) + self.log("Unable to delete site '{0}' as it's not found in Cisco Catalyst Center".format(site_name), "INFO") return self # Check here if the site have the childs then fetch it using get membership API and then sort it @@ -952,6 +941,7 @@ def get_diff_deleted(self, config): op_modifies=True, params={"site_id": site_id}, ) + self.log("Received API response from 'get_membership': {0}".format(str(mem_response)), "DEBUG") site_response = mem_response.get("site").get("response") self.log("Site {0} response along with it's child sites: {1}".format(site_name, str(site_response)), "DEBUG") @@ -968,9 +958,7 @@ def get_diff_deleted(self, config): # Delete the final parent site self.delete_single_site(site_id, site_name) - self.msg = "The site '{0}' and its child sites have been deleted successfully".format(site_name) - self.result['response'] = self.msg - self.log(self.msg, "INFO") + self.log("The site '{0}' and its child sites have been deleted successfully".format(site_name), "INFO") return self @@ -1090,6 +1078,47 @@ def main(): if config_verify: dnac_site.verify_diff_state_apply[state](config).check_return_status() + if dnac_site.created_site_list and dnac_site.updated_site_list: + dnac_site.result['changed'] = True + if dnac_site.update_not_neeeded_sites: + msg = """Site(s) '{0}' created successfully as well as Site(s) '{1}' updated successully and the some site(s) + '{2}' needs no update in Cisco Catalyst Center""" + dnac_site.msg = msg.format(str(dnac_site.created_site_list), str(dnac_site.updated_site_list), str(dnac_site.update_not_neeeded_sites)) + else: + dnac_site.msg = """Site(s) '{0}' created successfully in Cisco Catalyst Center as well as Site(s) '{1}' updated successully in + Cisco Catalyst Center""".format(str(dnac_site.created_site_list), str(dnac_site.updated_site_list)) + elif dnac_site.created_site_list: + dnac_site.result['changed'] = True + if dnac_site.update_not_neeeded_sites: + dnac_site.msg = """Site(s) '{0}' created successfully and some site(s) '{1}' not needs any update in Cisco Catalyst + Center.""".format(str(dnac_site.created_site_list), str(dnac_site.update_not_neeeded_sites)) + else: + dnac_site.msg = "Site(s) '{0}' created successfully in Cisco Catalyst Center.".format(str(dnac_site.created_site_list)) + elif dnac_site.updated_site_list: + dnac_site.result['changed'] = True + if dnac_site.update_not_neeeded_sites: + dnac_site.msg = """Site(s) '{0}' updated successfully and some site(s) '{1}' not needs any update in Cisco Catalyst + Center.""".format(str(dnac_site.updated_site_list), str(dnac_site.update_not_neeeded_sites)) + else: + dnac_site.msg = "Site(s) '{0}' updated successfully in Cisco Catalyst Center.".format(str(dnac_site.updated_site_list)) + elif dnac_site.update_not_neeeded_sites: + dnac_site.result['changed'] = False + dnac_site.msg = "Site(s) '{0}' not needs any update in Cisco Catalyst Center.".format(str(dnac_site.update_not_neeeded_sites)) + elif dnac_site.deleted_site_list and dnac_site.site_absent_list: + dnac_site.result['changed'] = True + dnac_site.msg = """Given site(s) '{0}' deleted successfully from Cisco Catalyst Center and unable to deleted some site(s) '{1}' as they + are not found in Cisco Catalyst Center.""".format(str(dnac_site.deleted_site_list), str(dnac_site.site_absent_list)) + elif dnac_site.deleted_site_list: + dnac_site.result['changed'] = True + dnac_site.msg = "Given site(s) '{0}' deleted successfully from Cisco Catalyst Center".format(str(dnac_site.deleted_site_list)) + else: + dnac_site.result['changed'] = False + dnac_site.msg = "Unable to delete site(s) '{0}' as it's not found in Cisco Catalyst Center.".format(str(dnac_site.site_absent_list)) + + dnac_site.status = "success" + dnac_site.result['response'] = dnac_site.msg + dnac_site.result['msg'] = dnac_site.msg + module.exit_json(**dnac_site.result) diff --git a/plugins/modules/site_workflow_manager.py b/plugins/modules/site_workflow_manager.py index 5a6e0bd0b1..ebcceb5d18 100644 --- a/plugins/modules/site_workflow_manager.py +++ b/plugins/modules/site_workflow_manager.py @@ -342,6 +342,8 @@ class Site(DnacBase): def __init__(self, module): super().__init__(module) self.supported_states = ["merged", "deleted"] + self.created_site_list, self.updated_site_list, self.update_not_neeeded_sites = [], [], [] + self.deleted_site_list, self.site_absent_list = [], [] def validate_input(self): """ @@ -448,7 +450,7 @@ def get_current_site(self, site): width=map_geometry.get("attributes").get("width"), length=map_geometry.get("attributes").get("length"), height=map_geometry.get("attributes").get("height"), - floorNumber=map_geometry.get("attributes").get("floor_number", "") + floorNumber=map_summary.get('attributes').get('floorIndex') ) ) @@ -665,7 +667,9 @@ def is_floor_updated(self, updated_site, requested_site): """ keys_to_compare = ['length', 'width', 'height'] - if updated_site['name'] != requested_site['name'] or updated_site['rf_model'] != requested_site['rfModel']: + if updated_site['name'] != requested_site['name'] or updated_site.get('rf_model') != requested_site.get('rfModel'): + return False + if requested_site.get('floorNumber') and int(requested_site.get('floorNumber')) != int(updated_site.get('floorNumber')): return False for key in keys_to_compare: @@ -780,6 +784,7 @@ def get_diff_merged(self, config): site_updated = False site_created = False + site_name = self.want.get("site_name") # check if the given site exists and/or needs to be updated/created. if self.have.get("site_exists"): @@ -794,14 +799,12 @@ def get_diff_merged(self, config): op_modifies=True, params=site_params, ) + self.log("Received API response from 'update_site': {0}".format(str(response)), "DEBUG") site_updated = True - else: # Site does not neet update - self.result['response'] = self.have.get("current_site") - self.msg = "Site - {0} does not need any update".format(self.have.get("current_site")) - self.log(self.msg, "INFO") - self.result['msg'] = self.msg + self.update_not_neeeded_sites.append(site_name) + self.log("Site - {0} does not need any update".format(site_name), "INFO") return self else: @@ -816,9 +819,9 @@ def get_diff_merged(self, config): site_params['site']['building'] = building_details except Exception as e: site_type = site_params['type'] - site_name = site_params['site'][site_type]['name'] + name = site_params['site'][site_type]['name'] self.log("""The site '{0}' is not categorized as a building; hence, there is no need to filter out 'None' - values from the 'site_params' dictionary.""".format(site_name), "INFO") + values from the 'site_params' dictionary.""".format(name), "INFO") response = self.dnac._exec( family="sites", @@ -836,7 +839,6 @@ def get_diff_merged(self, config): execution_details = self.get_execution_details(executionid) if execution_details.get("status") == "SUCCESS": self.result['changed'] = True - self.result['response'] = execution_details break elif execution_details.get("bapiError"): @@ -845,21 +847,15 @@ def get_diff_merged(self, config): break if site_updated: - self.msg = "Site - {0} Updated Successfully".format(self.want.get("site_name")) - self.log(self.msg, "INFO") - self.result['msg'] = self.msg - self.result['response'].update({"siteId": self.have.get("site_id")}) - + self.updated_site_list.append(site_name) + self.log("Site - {0} Updated Successfully".format(site_name), "INFO") else: # Get the site id of the newly created site. (site_exists, current_site) = self.site_exists() if site_exists: - self.msg = "Site '{0}' created successfully".format(self.want.get("site_name")) - self.log(self.msg, "INFO") - self.log("Current site (have): {0}".format(str(current_site)), "DEBUG") - self.result['msg'] = self.msg - self.result['response'].update({"siteId": current_site.get('site_id')}) + self.created_site_list.append(site_name) + self.log("Site '{0}' created successfully".format(site_name), "INFO") return self @@ -894,11 +890,9 @@ def delete_single_site(self, site_id, site_name): while True: execution_details = self.get_execution_details(executionid) if execution_details.get("status") == "SUCCESS": - self.msg = "Site '{0}' deleted successfully".format(site_name) - self.result['changed'] = True - self.result['response'] = self.msg self.status = "success" - self.log(self.msg, "INFO") + self.deleted_site_list.append(site_name) + self.log("Site '{0}' deleted successfully".format(site_name), "INFO") break elif execution_details.get("bapiError"): self.log("Error response for 'delete_site' execution: {0}".format(execution_details.get("bapiError")), "ERROR") @@ -934,12 +928,8 @@ def get_diff_deleted(self, config): site_name = self.want.get("site_name") if not site_exists: self.status = "success" - self.msg = "Unable to delete site '{0}' as it's not found in Cisco Catalyst Center".format(site_name) - self.result.update({'changed': False, - 'response': self.msg, - 'msg': self.msg}) - self.log(self.msg, "INFO") - + self.site_absent_list.append(site_name) + self.log("Unable to delete site '{0}' as it's not found in Cisco Catalyst Center".format(site_name), "INFO") return self # Check here if the site have the childs then fetch it using get membership API and then sort it @@ -951,6 +941,7 @@ def get_diff_deleted(self, config): op_modifies=True, params={"site_id": site_id}, ) + self.log("Received API response from 'get_membership': {0}".format(str(mem_response)), "DEBUG") site_response = mem_response.get("site").get("response") self.log("Site {0} response along with it's child sites: {1}".format(site_name, str(site_response)), "DEBUG") @@ -967,9 +958,7 @@ def get_diff_deleted(self, config): # Delete the final parent site self.delete_single_site(site_id, site_name) - self.msg = "The site '{0}' and its child sites have been deleted successfully".format(site_name) - self.result['response'] = self.msg - self.log(self.msg, "INFO") + self.log("The site '{0}' and its child sites have been deleted successfully".format(site_name), "INFO") return self @@ -1089,6 +1078,47 @@ def main(): if config_verify: ccc_site.verify_diff_state_apply[state](config).check_return_status() + if ccc_site.created_site_list and ccc_site.updated_site_list: + ccc_site.result['changed'] = True + if ccc_site.update_not_neeeded_sites: + msg = """Site(s) '{0}' created successfully as well as Site(s) '{1}' updated successully and the some site(s) + '{2}' needs no update in Cisco Catalyst Center""" + ccc_site.msg = msg.format(str(ccc_site.created_site_list), str(ccc_site.updated_site_list), str(ccc_site.update_not_neeeded_sites)) + else: + ccc_site.msg = """Site(s) '{0}' created successfully in Cisco Catalyst Center as well as Site(s) '{1}' updated successully in + Cisco Catalyst Center""".format(str(ccc_site.created_site_list), str(ccc_site.updated_site_list)) + elif ccc_site.created_site_list: + ccc_site.result['changed'] = True + if ccc_site.update_not_neeeded_sites: + ccc_site.msg = """Site(s) '{0}' created successfully and some site(s) '{1}' not needs any update in Cisco Catalyst + Center.""".format(str(ccc_site.created_site_list), str(ccc_site.update_not_neeeded_sites)) + else: + ccc_site.msg = "Site(s) '{0}' created successfully in Cisco Catalyst Center.".format(str(ccc_site.created_site_list)) + elif ccc_site.updated_site_list: + ccc_site.result['changed'] = True + if ccc_site.update_not_neeeded_sites: + ccc_site.msg = """Site(s) '{0}' updated successfully and some site(s) '{1}' not needs any update in Cisco Catalyst + Center.""".format(str(ccc_site.updated_site_list), str(ccc_site.update_not_neeeded_sites)) + else: + ccc_site.msg = "Site(s) '{0}' updated successfully in Cisco Catalyst Center.".format(str(ccc_site.updated_site_list)) + elif ccc_site.update_not_neeeded_sites: + ccc_site.result['changed'] = False + ccc_site.msg = "Site(s) '{0}' not needs any update in Cisco Catalyst Center.".format(str(ccc_site.update_not_neeeded_sites)) + elif ccc_site.deleted_site_list and ccc_site.site_absent_list: + ccc_site.result['changed'] = True + ccc_site.msg = """Given site(s) '{0}' deleted successfully from Cisco Catalyst Center and unable to deleted some site(s) '{1}' as they + are not found in Cisco Catalyst Center.""".format(str(ccc_site.deleted_site_list), str(ccc_site.site_absent_list)) + elif ccc_site.deleted_site_list: + ccc_site.result['changed'] = True + ccc_site.msg = "Given site(s) '{0}' deleted successfully from Cisco Catalyst Center".format(str(ccc_site.deleted_site_list)) + else: + ccc_site.result['changed'] = False + ccc_site.msg = "Unable to delete site(s) '{0}' as it's not found in Cisco Catalyst Center.".format(str(ccc_site.site_absent_list)) + + ccc_site.status = "success" + ccc_site.result['response'] = ccc_site.msg + ccc_site.result['msg'] = ccc_site.msg + module.exit_json(**ccc_site.result) From fd4f5b5e1288b43366707e3786f604a736eef357 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Fri, 3 May 2024 18:57:04 +0530 Subject: [PATCH 320/358] Write API for returning the status of site events including creation/deletion/updation --- plugins/modules/site_intent.py | 99 ++++++++++++++---------- plugins/modules/site_workflow_manager.py | 99 ++++++++++++++---------- 2 files changed, 118 insertions(+), 80 deletions(-) diff --git a/plugins/modules/site_intent.py b/plugins/modules/site_intent.py index 2288a5c280..c26f4a3a0f 100644 --- a/plugins/modules/site_intent.py +++ b/plugins/modules/site_intent.py @@ -1032,6 +1032,63 @@ def verify_diff_deleted(self, config): return self + def update_site_messages(self): + """ + Update site messages based on the status of created, updated, and deleted sites. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Returns: + self (object): An instance of a class representing the status of the operation, including whether it was + successful or failed, any error messages encountered during operation. + Description: + This method updates the messages related to site creation, updating, and deletion in the Cisco Catalyst Center. + It evaluates the status of created sites, updated sites, and sites that are no longer needed for update to + determine the appropriate message to be set. The messages are then stored in the 'msg' attribute of the object. + """ + + if self.created_site_list and self.updated_site_list: + self.result['changed'] = True + if self.update_not_neeeded_sites: + msg = """Site(s) '{0}' created successfully as well as Site(s) '{1}' updated successully and the some site(s) + '{2}' needs no update in Cisco Catalyst Center""" + self.msg = msg.format(str(self.created_site_list), str(self.updated_site_list), str(self.update_not_neeeded_sites)) + else: + self.msg = """Site(s) '{0}' created successfully in Cisco Catalyst Center as well as Site(s) '{1}' updated successully in + Cisco Catalyst Center""".format(str(self.created_site_list), str(self.updated_site_list)) + elif self.created_site_list: + self.result['changed'] = True + if self.update_not_neeeded_sites: + self.msg = """Site(s) '{0}' created successfully and some site(s) '{1}' not needs any update in Cisco Catalyst + Center.""".format(str(self.created_site_list), str(self.update_not_neeeded_sites)) + else: + self.msg = "Site(s) '{0}' created successfully in Cisco Catalyst Center.".format(str(self.created_site_list)) + elif self.updated_site_list: + self.result['changed'] = True + if self.update_not_neeeded_sites: + self.msg = """Site(s) '{0}' updated successfully and some site(s) '{1}' not needs any update in Cisco Catalyst + Center.""".format(str(self.updated_site_list), str(self.update_not_neeeded_sites)) + else: + self.msg = "Site(s) '{0}' updated successfully in Cisco Catalyst Center.".format(str(self.updated_site_list)) + elif self.update_not_neeeded_sites: + self.result['changed'] = False + self.msg = "Site(s) '{0}' not needs any update in Cisco Catalyst Center.".format(str(self.update_not_neeeded_sites)) + elif self.deleted_site_list and self.site_absent_list: + self.result['changed'] = True + self.msg = """Given site(s) '{0}' deleted successfully from Cisco Catalyst Center and unable to deleted some site(s) '{1}' as they + are not found in Cisco Catalyst Center.""".format(str(self.deleted_site_list), str(self.site_absent_list)) + elif self.deleted_site_list: + self.result['changed'] = True + self.msg = "Given site(s) '{0}' deleted successfully from Cisco Catalyst Center".format(str(self.deleted_site_list)) + else: + self.result['changed'] = False + self.msg = "Unable to delete site(s) '{0}' as it's not found in Cisco Catalyst Center.".format(str(self.site_absent_list)) + + self.status = "success" + self.result['response'] = self.msg + self.result['msg'] = self.msg + + return self + def main(): """ main entry point for module execution @@ -1078,46 +1135,8 @@ def main(): if config_verify: dnac_site.verify_diff_state_apply[state](config).check_return_status() - if dnac_site.created_site_list and dnac_site.updated_site_list: - dnac_site.result['changed'] = True - if dnac_site.update_not_neeeded_sites: - msg = """Site(s) '{0}' created successfully as well as Site(s) '{1}' updated successully and the some site(s) - '{2}' needs no update in Cisco Catalyst Center""" - dnac_site.msg = msg.format(str(dnac_site.created_site_list), str(dnac_site.updated_site_list), str(dnac_site.update_not_neeeded_sites)) - else: - dnac_site.msg = """Site(s) '{0}' created successfully in Cisco Catalyst Center as well as Site(s) '{1}' updated successully in - Cisco Catalyst Center""".format(str(dnac_site.created_site_list), str(dnac_site.updated_site_list)) - elif dnac_site.created_site_list: - dnac_site.result['changed'] = True - if dnac_site.update_not_neeeded_sites: - dnac_site.msg = """Site(s) '{0}' created successfully and some site(s) '{1}' not needs any update in Cisco Catalyst - Center.""".format(str(dnac_site.created_site_list), str(dnac_site.update_not_neeeded_sites)) - else: - dnac_site.msg = "Site(s) '{0}' created successfully in Cisco Catalyst Center.".format(str(dnac_site.created_site_list)) - elif dnac_site.updated_site_list: - dnac_site.result['changed'] = True - if dnac_site.update_not_neeeded_sites: - dnac_site.msg = """Site(s) '{0}' updated successfully and some site(s) '{1}' not needs any update in Cisco Catalyst - Center.""".format(str(dnac_site.updated_site_list), str(dnac_site.update_not_neeeded_sites)) - else: - dnac_site.msg = "Site(s) '{0}' updated successfully in Cisco Catalyst Center.".format(str(dnac_site.updated_site_list)) - elif dnac_site.update_not_neeeded_sites: - dnac_site.result['changed'] = False - dnac_site.msg = "Site(s) '{0}' not needs any update in Cisco Catalyst Center.".format(str(dnac_site.update_not_neeeded_sites)) - elif dnac_site.deleted_site_list and dnac_site.site_absent_list: - dnac_site.result['changed'] = True - dnac_site.msg = """Given site(s) '{0}' deleted successfully from Cisco Catalyst Center and unable to deleted some site(s) '{1}' as they - are not found in Cisco Catalyst Center.""".format(str(dnac_site.deleted_site_list), str(dnac_site.site_absent_list)) - elif dnac_site.deleted_site_list: - dnac_site.result['changed'] = True - dnac_site.msg = "Given site(s) '{0}' deleted successfully from Cisco Catalyst Center".format(str(dnac_site.deleted_site_list)) - else: - dnac_site.result['changed'] = False - dnac_site.msg = "Unable to delete site(s) '{0}' as it's not found in Cisco Catalyst Center.".format(str(dnac_site.site_absent_list)) - - dnac_site.status = "success" - dnac_site.result['response'] = dnac_site.msg - dnac_site.result['msg'] = dnac_site.msg + # Invoke the API to check the status and log the output of each site on the console + dnac_site.update_site_messages().check_return_status() module.exit_json(**dnac_site.result) diff --git a/plugins/modules/site_workflow_manager.py b/plugins/modules/site_workflow_manager.py index ebcceb5d18..b822b52b91 100644 --- a/plugins/modules/site_workflow_manager.py +++ b/plugins/modules/site_workflow_manager.py @@ -1032,6 +1032,63 @@ def verify_diff_deleted(self, config): return self + def update_site_messages(self): + """ + Update site messages based on the status of created, updated, and deleted sites. + Args: + self (object): An instance of a class used for interacting with Cisco Catalyst Center. + Returns: + self (object): An instance of a class representing the status of the operation, including whether it was + successful or failed, any error messages encountered during operation. + Description: + This method updates the messages related to site creation, updating, and deletion in the Cisco Catalyst Center. + It evaluates the status of created sites, updated sites, and sites that are no longer needed for update to + determine the appropriate message to be set. The messages are then stored in the 'msg' attribute of the object. + """ + + if self.created_site_list and self.updated_site_list: + self.result['changed'] = True + if self.update_not_neeeded_sites: + msg = """Site(s) '{0}' created successfully as well as Site(s) '{1}' updated successully and the some site(s) + '{2}' needs no update in Cisco Catalyst Center""" + self.msg = msg.format(str(self.created_site_list), str(self.updated_site_list), str(self.update_not_neeeded_sites)) + else: + self.msg = """Site(s) '{0}' created successfully in Cisco Catalyst Center as well as Site(s) '{1}' updated successully in + Cisco Catalyst Center""".format(str(self.created_site_list), str(self.updated_site_list)) + elif self.created_site_list: + self.result['changed'] = True + if self.update_not_neeeded_sites: + self.msg = """Site(s) '{0}' created successfully and some site(s) '{1}' not needs any update in Cisco Catalyst + Center.""".format(str(self.created_site_list), str(self.update_not_neeeded_sites)) + else: + self.msg = "Site(s) '{0}' created successfully in Cisco Catalyst Center.".format(str(self.created_site_list)) + elif self.updated_site_list: + self.result['changed'] = True + if self.update_not_neeeded_sites: + self.msg = """Site(s) '{0}' updated successfully and some site(s) '{1}' not needs any update in Cisco Catalyst + Center.""".format(str(self.updated_site_list), str(self.update_not_neeeded_sites)) + else: + self.msg = "Site(s) '{0}' updated successfully in Cisco Catalyst Center.".format(str(self.updated_site_list)) + elif self.update_not_neeeded_sites: + self.result['changed'] = False + self.msg = "Site(s) '{0}' not needs any update in Cisco Catalyst Center.".format(str(self.update_not_neeeded_sites)) + elif self.deleted_site_list and self.site_absent_list: + self.result['changed'] = True + self.msg = """Given site(s) '{0}' deleted successfully from Cisco Catalyst Center and unable to deleted some site(s) '{1}' as they + are not found in Cisco Catalyst Center.""".format(str(self.deleted_site_list), str(self.site_absent_list)) + elif self.deleted_site_list: + self.result['changed'] = True + self.msg = "Given site(s) '{0}' deleted successfully from Cisco Catalyst Center".format(str(self.deleted_site_list)) + else: + self.result['changed'] = False + self.msg = "Unable to delete site(s) '{0}' as it's not found in Cisco Catalyst Center.".format(str(self.site_absent_list)) + + self.status = "success" + self.result['response'] = self.msg + self.result['msg'] = self.msg + + return self + def main(): """ main entry point for module execution @@ -1078,46 +1135,8 @@ def main(): if config_verify: ccc_site.verify_diff_state_apply[state](config).check_return_status() - if ccc_site.created_site_list and ccc_site.updated_site_list: - ccc_site.result['changed'] = True - if ccc_site.update_not_neeeded_sites: - msg = """Site(s) '{0}' created successfully as well as Site(s) '{1}' updated successully and the some site(s) - '{2}' needs no update in Cisco Catalyst Center""" - ccc_site.msg = msg.format(str(ccc_site.created_site_list), str(ccc_site.updated_site_list), str(ccc_site.update_not_neeeded_sites)) - else: - ccc_site.msg = """Site(s) '{0}' created successfully in Cisco Catalyst Center as well as Site(s) '{1}' updated successully in - Cisco Catalyst Center""".format(str(ccc_site.created_site_list), str(ccc_site.updated_site_list)) - elif ccc_site.created_site_list: - ccc_site.result['changed'] = True - if ccc_site.update_not_neeeded_sites: - ccc_site.msg = """Site(s) '{0}' created successfully and some site(s) '{1}' not needs any update in Cisco Catalyst - Center.""".format(str(ccc_site.created_site_list), str(ccc_site.update_not_neeeded_sites)) - else: - ccc_site.msg = "Site(s) '{0}' created successfully in Cisco Catalyst Center.".format(str(ccc_site.created_site_list)) - elif ccc_site.updated_site_list: - ccc_site.result['changed'] = True - if ccc_site.update_not_neeeded_sites: - ccc_site.msg = """Site(s) '{0}' updated successfully and some site(s) '{1}' not needs any update in Cisco Catalyst - Center.""".format(str(ccc_site.updated_site_list), str(ccc_site.update_not_neeeded_sites)) - else: - ccc_site.msg = "Site(s) '{0}' updated successfully in Cisco Catalyst Center.".format(str(ccc_site.updated_site_list)) - elif ccc_site.update_not_neeeded_sites: - ccc_site.result['changed'] = False - ccc_site.msg = "Site(s) '{0}' not needs any update in Cisco Catalyst Center.".format(str(ccc_site.update_not_neeeded_sites)) - elif ccc_site.deleted_site_list and ccc_site.site_absent_list: - ccc_site.result['changed'] = True - ccc_site.msg = """Given site(s) '{0}' deleted successfully from Cisco Catalyst Center and unable to deleted some site(s) '{1}' as they - are not found in Cisco Catalyst Center.""".format(str(ccc_site.deleted_site_list), str(ccc_site.site_absent_list)) - elif ccc_site.deleted_site_list: - ccc_site.result['changed'] = True - ccc_site.msg = "Given site(s) '{0}' deleted successfully from Cisco Catalyst Center".format(str(ccc_site.deleted_site_list)) - else: - ccc_site.result['changed'] = False - ccc_site.msg = "Unable to delete site(s) '{0}' as it's not found in Cisco Catalyst Center.".format(str(ccc_site.site_absent_list)) - - ccc_site.status = "success" - ccc_site.result['response'] = ccc_site.msg - ccc_site.result['msg'] = ccc_site.msg + # Invoke the API to check the status and log the output of each site on the console + ccc_site.update_site_messages().check_return_status() module.exit_json(**ccc_site.result) From 7038fae1c56af4da3467453803ebdcff4159bd24 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Fri, 3 May 2024 12:53:19 -0400 Subject: [PATCH 321/358] replaced fail_json with log in validate_params --- .../modules/network_compliance_workflow_manager.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 4b205fe9fc..9a4b02971c 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -420,12 +420,13 @@ def validate_run_compliance_paramters(self, mgmt_ip_instance_id_map, run_complia valid_categories = ["INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX", "NETWORK_SETTINGS"] if run_compliance_categories: + # Validate the categories provided if not all(category.upper() in valid_categories for category in run_compliance_categories): msg = "Invalid category provided. Valid categories are {0}.".format(valid_categories) self.log(msg, "ERROR") self.module.fail_json(msg) - if run_compliance is None or run_compliance: + if run_compliance: # run_compliance_params run_compliance_params["deviceUuids"] = list(mgmt_ip_instance_id_map.values()) run_compliance_params["triggerFull"] = False @@ -441,11 +442,12 @@ def validate_run_compliance_paramters(self, mgmt_ip_instance_id_map, run_complia compliance_types = list(set(compliance_types)) compliance_detail_params["complianceType"] = "', '".join(compliance_types) compliance_detail_params["complianceType"] = "'" + compliance_detail_params['complianceType'] + "'" + # Case when run_compliance_categories provided but run_compliance = False else: - msg = "No actions were requested. This network compliance module can perform the following tasks: Run Compliance Check or Sync Device Config." - self.log(msg, "ERROR") - self.module.fail_json(msg) - return self + msg = "Since run_compliance is set to {0}, even though run_compliance_categories are provided {1}, ".format( + run_compliance, run_compliance_categories) + msg += "Run Compliance Check will not be executed." + self.log(msg, "WARNING") if run_compliance and not run_compliance_categories: # run_compliance_params From ebe79cb4a4783423835b5ba43ea58ff2aeafb5ba Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Fri, 3 May 2024 13:00:17 -0400 Subject: [PATCH 322/358] replaced fail_json with log in validate_params --- plugins/modules/network_compliance_workflow_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 9a4b02971c..1766cd70d2 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -426,7 +426,7 @@ def validate_run_compliance_paramters(self, mgmt_ip_instance_id_map, run_complia self.log(msg, "ERROR") self.module.fail_json(msg) - if run_compliance: + if run_compliance: # run_compliance_params run_compliance_params["deviceUuids"] = list(mgmt_ip_instance_id_map.values()) run_compliance_params["triggerFull"] = False From a882549921052e21491d453303d7f46db6e251a4 Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Fri, 3 May 2024 13:28:42 -0400 Subject: [PATCH 323/358] changed if condition in validate_run_comp_params --- plugins/modules/network_compliance_workflow_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 1766cd70d2..911a71f439 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -77,7 +77,7 @@ requirements: - dnacentersdk >= 2.7.0 -- python >= 3.5 +- python >= 3.9 notes: - SDK Methods used are compliance.Compliance.run_compliance @@ -449,7 +449,7 @@ def validate_run_compliance_paramters(self, mgmt_ip_instance_id_map, run_complia msg += "Run Compliance Check will not be executed." self.log(msg, "WARNING") - if run_compliance and not run_compliance_categories: + elif run_compliance: # run_compliance_params run_compliance_params["deviceUuids"] = list(mgmt_ip_instance_id_map.values()) run_compliance_params["triggerFull"] = True From 1c101f24d0715fe6602cfc649e256b01045ee3bb Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Fri, 3 May 2024 13:57:37 -0400 Subject: [PATCH 324/358] modified dnacentersdk version --- plugins/modules/network_compliance_workflow_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 911a71f439..1f00036f28 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -76,7 +76,7 @@ default: False requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk == 2.7.0 - python >= 3.9 notes: - SDK Methods used are From 0468d51b4fe3445465374a972777b1703961788e Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Fri, 3 May 2024 14:16:35 -0400 Subject: [PATCH 325/358] added statement in doc for run_compliance --- plugins/modules/network_compliance_workflow_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 1f00036f28..b48b4aff76 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -57,7 +57,7 @@ run_compliance: description: Determines if a full compliance check should be triggered on the devices specified in the "ip_address_list" and/or "site_name". if it is True then compliance will be triggered for all categories. - If it is False then compliance will be not be triggered for all categories. + If it is False then compliance will be not be triggered even if run_compliance categories are provided. type: bool default: True run_compliance_categories: From 383e0a0c3f3ce189f53f5fe0b5ed226c69b08ddc Mon Sep 17 00:00:00 2001 From: Rugvedi Kapse Date: Fri, 3 May 2024 14:25:43 -0400 Subject: [PATCH 326/358] added statement in doc for run_compliance --- plugins/modules/network_compliance_workflow_manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index b48b4aff76..3860efe5c6 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -64,6 +64,7 @@ description: Specifying compliance categories allows you to trigger compliance checks only for the mentioned categories. Category can have one or more values from among the options "INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX", "NETWORK_SETTINGS". Category "INTENT" is mapped to compliance types "NETWORK_SETTINGS", "NETWORK_PROFILE", "WORKFLOW", "FABRIC", "APPLICATION_VISIBILITY". + If "run_compliance" is False then compliance will be not be triggered even if "run_compliance_categories" are provided. (e.g. ["INTENT", "RUNNING_CONFIG", "IMAGE", "PSIRT", "EOX", "NETWORK_SETTINGS"]) type: list elements: str From 04aacb19d1622a9a2732d5f411bd187db2090357 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Mon, 6 May 2024 10:30:47 +0530 Subject: [PATCH 327/358] Added new features and resolved the bugs for the network settings and template workflow manager modules --- plugins/module_utils/dnac.py | 5 +- .../network_settings_workflow_manager.py | 23 +- plugins/modules/template_workflow_manager.py | 222 ++++++------------ 3 files changed, 83 insertions(+), 167 deletions(-) diff --git a/plugins/module_utils/dnac.py b/plugins/module_utils/dnac.py index 1d4b804cd0..37a22c0f62 100644 --- a/plugins/module_utils/dnac.py +++ b/plugins/module_utils/dnac.py @@ -521,7 +521,10 @@ def is_path_exists(self, file_path): True/False (bool) - True if the file path exists, else False. """ - if not os.path.exists(file_path): + current_working_directory = os.getcwd() + final_file_path = os.path.join(current_working_directory, file_path) + self.log(str(final_file_path)) + if not os.path.exists(final_file_path): return False return True diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index 94a9b5b9a3..8735a28587 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -333,7 +333,7 @@ type: dict requirements: - dnacentersdk == 2.4.5 -- python >= 3.9 +- python >= 3.5 notes: - SDK Method used are network_settings.NetworkSettings.create_global_pool, @@ -1329,9 +1329,8 @@ def get_have_network(self, network_details): network = {} site_name = network_details.get("site_name") if site_name is None: - self.msg = "Mandatory Parameter 'site_name' missing" - self.status = "failed" - return self + site_name = "Global" + network_details.update({"site_name": site_name}) site_id = self.get_site_id(site_name) if site_id is None: @@ -1543,16 +1542,18 @@ def get_want_reserve_pool(self, reserve_pool): if pool_values.get("ipv4Prefix") is True: if pool_values.get("ipv4Subnet") is None and \ pool_values.get("ipv4TotalHost") is None: - self.msg = "missing parameter 'ipv4_subnet' or 'ipv4TotalHost' \ - while adding the ipv4 in reserve_pool_details '{0}' element".format(reserve_pool_index + 1) + self.msg = "missing parameter 'ipv4_subnet' or 'ipv4TotalHost' " + \ + "while adding the ipv4 in reserve_pool_details '{0}' element" \ + .format(reserve_pool_index + 1) self.status = "failed" return self if pool_values.get("ipv6Prefix") is True: if pool_values.get("ipv6Subnet") is None and \ pool_values.get("ipv6TotalHost") is None: - self.msg = "missing parameter 'ipv6_subnet' or 'ipv6TotalHost' \ - while adding the ipv6 in reserve_pool_details '{0}' element".format(reserve_pool_index + 1) + self.msg = "missing parameter 'ipv6_subnet' or 'ipv6TotalHost' " + \ + "while adding the ipv6 in reserve_pool_details '{0}' element" \ + .format(reserve_pool_index + 1) self.status = "failed" return self @@ -1804,8 +1805,7 @@ def get_want_network(self, network_management_details): }) else: if clientAndEndpoint_aaa.get("servers") == "ISE": - self.msg = "missing parameter ip_address in clientAndEndpoint_aaa, \ - server ISE is set" + self.msg = "missing parameter ip_address in clientAndEndpoint_aaa, server ISE is set" self.status = "failed" return self @@ -2310,8 +2310,7 @@ def verify_diff_merged(self, config): .format(config.get("network_management_details").get("site_name")), "INFO") self.result.get("response")[2].get("network").update({"Validation": "Success"}) - self.msg = "Successfully validated the Global Pool, Reserve Pool \ - and the Network Functions." + self.msg = "Successfully validated the Global Pool, Reserve Pool and the Network Functions." self.status = "success" return self diff --git a/plugins/modules/template_workflow_manager.py b/plugins/modules/template_workflow_manager.py index fbd91685ea..89abe2150f 100644 --- a/plugins/modules/template_workflow_manager.py +++ b/plugins/modules/template_workflow_manager.py @@ -287,9 +287,6 @@ type: str type: list elements: dict - create_time: - description: The creation time of the template refers to the initial development. - type: int custom_params_order: description: Specifies the sequence in which custom parameters or variables should be arranged within the template. type: bool @@ -322,21 +319,9 @@ - JINJA - VELOCITY type: str - last_update_time: - description: Indicates the most recent timestamp when the template was modified or revised. - type: int - latest_version_time: - description: Indicates when the most recent version of a template was released or updated. - type: int template_name: description: Name of template. This field is mandatory to create a new template. type: str - parent_template_id: - description: Refers to the unique identifier of a template from which another template derives. - type: str - project_id: - description: A unique identifier for the project, formatted as a UUID. - type: str project_name: description: Title of the project within which the template is categorized and managed. type: str @@ -537,24 +522,6 @@ type: dict type: list elements: dict - validation_errors: - description: Refer to issues or discrepancies identified during the validation process. - suboptions: - rollback_template_errors: - description: Validation or design conflicts errors of rollback template. - elements: dict - type: list - template_errors: - description: Refer to issues or discrepancies encountered during the processing of a template within a software application. - elements: dict - type: list - template_id: - description: A unique identifier for the template, represented as a UUID. - type: str - template_version: - description: The current version of validation process in the template. - type: str - type: dict version: description: The current version of template. type: str @@ -851,9 +818,6 @@ type: str type: list elements: dict - create_time: - description: The creation time of the template refers to the initial development. - type: int custom_params_order: description: Specifies the sequence in which custom parameters or variables should be arranged within the template. type: bool @@ -886,21 +850,9 @@ - JINJA - VELOCITY type: str - last_update_time: - description: Indicates the most recent timestamp when the template was modified or revised. - type: int - latest_version_time: - description: Indicates when the most recent version of a template was released or updated. - type: int template_name: description: Name of template. This field is mandatory to create a new template. type: str - parent_template_id: - description: Refers to the unique identifier of a template from which another template derives. - type: str - project_id: - description: A unique identifier for the project, formatted as a UUID. - type: str project_name: description: Title of the project within which the template is categorized and managed. type: str @@ -1101,24 +1053,6 @@ type: dict type: list elements: dict - validation_errors: - description: Refer to issues or discrepancies identified during the validation process. - suboptions: - rollback_template_errors: - description: Refer to errors or issues encountered during the process of reverting a template to a previous version or state. - elements: dict - type: list - template_errors: - description: Refer to issues or discrepancies encountered during the processing of a template within a software application. - elements: dict - type: list - template_id: - description: A unique identifier for the template, represented as a UUID. - type: str - template_version: - description: The current version of validation process in the template. - type: str - type: dict version: description: The current version of template. type: str @@ -1129,7 +1063,7 @@ requirements: - dnacentersdk == 2.4.5 -- python >= 3.9 +- python >= 3.5 notes: - SDK Method used are configuration_templates.ConfigurationTemplates.create_template, @@ -1169,7 +1103,6 @@ - configuration_templates: author: string composite: true - create_time: 0 custom_params_order: true description: string device_types: @@ -1179,11 +1112,7 @@ failure_policy: string id: string language: string - last_update_time: 0 - latest_version_time: 0 name: string - parent_template_id: string - project_id: string project_name: string project_description: string rollback_template_content: string @@ -1194,13 +1123,6 @@ - id: string name: string template_content: string - validation_errors: - rollback_template_errors: - - {} - template_errors: - - {} - template_id: string - template_version: string version: string - name: Export the projects. @@ -1415,7 +1337,6 @@ def validate_input(self): 'author': {'type': 'str'}, 'composite': {'type': 'bool'}, 'containing_templates': {'type': 'list'}, - 'create_time': {'type': 'int'}, 'custom_params_order': {'type': 'bool'}, 'template_description': {'type': 'str'}, 'device_types': { @@ -1428,11 +1349,7 @@ def validate_input(self): 'failure_policy': {'type': 'str'}, 'id': {'type': 'str'}, 'language': {'type': 'str'}, - 'last_update_time': {'type': 'int'}, - 'latest_version_time': {'type': 'int'}, 'name': {'type': 'str'}, - 'parent_template_id': {'type': 'str'}, - 'project_id': {'type': 'str'}, 'project_name': {'type': 'str'}, 'project_description': {'type': 'str'}, 'rollback_template_content': {'type': 'str'}, @@ -1443,7 +1360,6 @@ def validate_input(self): 'template_content': {'type': 'str'}, 'template_params': {'type': 'list'}, 'template_name': {'type': 'str'}, - 'validation_errors': {'type': 'dict'}, 'version': {'type': 'str'} }, 'export': { @@ -1472,7 +1388,6 @@ def validate_input(self): 'author': {'type': 'str'}, 'composite': {'type': 'bool'}, 'containing_templates': {'type': 'list'}, - 'create_time': {'type': 'int'}, 'custom_params_order': {'type': 'bool'}, 'template_description': {'type': 'str'}, 'device_types': { @@ -1485,11 +1400,7 @@ def validate_input(self): 'failure_policy': {'type': 'str'}, 'id': {'type': 'str'}, 'language': {'type': 'str'}, - 'last_update_time': {'type': 'int'}, - 'latest_version_time': {'type': 'int'}, 'name': {'type': 'str'}, - 'parent_template_id': {'type': 'str'}, - 'project_id': {'type': 'str'}, 'project_name': {'type': 'str'}, 'project_description': {'type': 'str'}, 'rollback_template_content': {'type': 'str'}, @@ -1500,7 +1411,6 @@ def validate_input(self): 'template_content': {'type': 'str'}, 'template_params': {'type': 'list'}, 'template_name': {'type': 'str'}, - 'validation_errors': {'type': 'dict'}, 'version': {'type': 'str'} } } @@ -1611,47 +1521,6 @@ def get_device_types(self, device_types): return deviceTypes - def get_validation_errors(self, validation_errors): - """ - Store template parameters from the playbook for template processing in Cisco Catalyst Center. - - Parameters: - validation_errors (dict) - Playbook details containing validation errors information. - - Returns: - validationErrors (dict) - Organized validation errors parameters. - """ - - if validation_errors is None: - return None - - validationErrors = {} - rollback_template_errors = validation_errors.get("rollback_template_errors") - if rollback_template_errors is not None: - validationErrors.update({ - "rollbackTemplateErrors": rollback_template_errors - }) - - template_errors = validation_errors.get("template_errors") - if template_errors is not None: - validationErrors.update({ - "templateErrors": template_errors - }) - - template_id = validation_errors.get("template_id") - if template_id is not None: - validationErrors.update({ - "templateId": template_id - }) - - template_version = validation_errors.get("template_version") - if template_version is not None: - validationErrors.update({ - "templateVersion": template_version - }) - - return validationErrors - def get_template_info(self, template_params): """ Store template params from the playbook for template processing in Cisco Catalyst Center. @@ -1771,7 +1640,7 @@ def get_template_info(self, template_params): return self.check_return_status() min_value = value.get("min_value") if min_value is not None: - _range[j].update({"maxValue": min_value}) + _range[j].update({"minValue": min_value}) else: self.msg = "min_value is mandatory for range under template_params" self.status = "failed" @@ -1800,13 +1669,37 @@ def get_template_info(self, template_params): return templateParams + def get_templates_details(self, name): + """ + Get the template details from the template name provided in the playbook. + + Parameters: + name (str) - Name of the template provided in the playbook. + + Returns: + result (dict) - Template details for the given template name. + """ + + result = None + items = self.dnac_apply['exec']( + family="configuration_templates", + function="get_templates_details", + op_modifies=True, + params={"name": name} + ) + if items: + result = items + + self.log("Received API response from 'get_templates_details': {0}".format(items), "DEBUG") + return result + def get_containing_templates(self, containing_templates): """ Store tags from the playbook for template processing in Cisco Catalyst Center. Check using check_return_status() Parameters: - containing_templates (dict) - Containing tempaltes details + containing_templates (dict) - Containing templates details containing Template information. Returns: @@ -1838,10 +1731,6 @@ def get_containing_templates(self, containing_templates): "deviceTypes": self.get_device_types(device_types) }) - id = item.get("id") - if id is not None: - containingTemplates[i].update({"id": id}) - name = item.get("name") if name is None: self.msg = "name is mandatory under containing templates" @@ -1850,6 +1739,17 @@ def get_containing_templates(self, containing_templates): containingTemplates[i].update({"name": name}) + template_details = self.get_templates_details(name) + template_details = template_details.get("response") + if not template_details: + self.msg = "No template with the template name '{0}' or it is not versioned".format(name) + self.status = "failed" + return self.check_return_status() + + id = template_details[0].get("id") + if id is not None: + containingTemplates[i].update({"id": id}) + language = item.get("language") if language is None: self.msg = "language is mandatory under containing templates" @@ -1912,17 +1812,12 @@ def get_template_params(self, params): "composite": params.get("composite"), "containingTemplates": self.get_containing_templates(params.get("containing_templates")), - "createTime": params.get("create_time"), "customParamsOrder": params.get("custom_params_order"), "description": params.get("template_description"), "deviceTypes": self.get_device_types(params.get("device_types")), "failurePolicy": params.get("failure_policy"), "id": params.get("id"), - "lastUpdateTime": params.get("last_update_time"), - "latestVersionTime": params.get("latest_version_time"), - "parentTemplateId": params.get("parent_template_id"), - "projectId": params.get("project_id"), "rollbackTemplateContent": params.get("rollback_template_content"), "rollbackTemplateParams": self.get_template_info(params.get("rollback_template_params")), @@ -1931,10 +1826,7 @@ def get_template_params(self, params): "templateContent": params.get("template_content"), "templateParams": self.get_template_info(params.get("template_params")), - "validationErrors": - self.get_validation_errors(params.get("validation_errors")), "version": params.get("version"), - "project_id": params.get("project_id") } language = params.get("language") if not language: @@ -2243,7 +2135,7 @@ def create_project_or_template(self, is_create_project=False): if task_details.get("isError"): self.log("Error occurred for '{0}' with taskid: {1}" .format(creation_value, task_id), "ERROR") - return creation_id, created + return task_id, created if validation_string not in task_details.get("progress"): self.log("'{0}' progress set to {1} for taskid: {2}" @@ -2298,18 +2190,13 @@ def requires_update(self): ("author", "author", ""), ("composite", "composite", False), ("containingTemplates", "containingTemplates", []), - ("createTime", "createTime", ""), ("customParamsOrder", "customParamsOrder", False), ("description", "description", ""), ("deviceTypes", "deviceTypes", []), ("failurePolicy", "failurePolicy", ""), ("id", "id", ""), ("language", "language", "VELOCITY"), - ("lastUpdateTime", "lastUpdateTime", ""), - ("latestVersionTime", "latestVersionTime", ""), ("name", "name", ""), - ("parentTemplateId", "parentTemplateId", ""), - ("projectId", "projectId", ""), ("projectName", "projectName", ""), ("rollbackTemplateContent", "rollbackTemplateContent", ""), ("rollbackTemplateParams", "rollbackTemplateParams", []), @@ -2318,7 +2205,6 @@ def requires_update(self): ("softwareVersion", "softwareVersion", ""), ("templateContent", "templateContent", ""), ("templateParams", "templateParams", []), - ("validationErrors", "validationErrors", {}), ("version", "version", ""), ] @@ -2522,6 +2408,15 @@ def update_configuration_templates(self, configuration_templates): self.msg = "Error while versioning the template" self.status = "failed" return self + else: + task_details = self.get_task_details(template_id) + self.log('Getting task details from task ID {0}: {1}'.format(template_id, task_details), "DEBUG") + if task_details.get("failureReason"): + self.msg = str(task_details.get("failureReason")) + else: + self.msg = str(task_details.get("progress")) + self.status = "failed" + return self def handle_export(self, export): """ @@ -2683,6 +2578,17 @@ def handle_import(self, _import): } self.log("Import template details from the playbook: {0}" .format(import_template), "DEBUG") + global_project_name = import_template.get("project_name") + for item in import_template.get("payload"): + template_project_name = item.get("projectName") + if template_project_name is not None and \ + global_project_name != template_project_name: + self.msg = "Template '{0}' under the the 'Import Template' should have project_name as {1}" \ + .format(item.get("name"), global_project_name) + self.log(str(self.msg), "ERROR") + self.status = "failed" + return self + if _import_template: response = self.dnac._exec( family="configuration_templates", @@ -2807,8 +2713,11 @@ def get_diff_deleted(self, config): if is_template_found: self.delete_project_or_template(config) else: + self.result['response'][0].get("configurationTemplate").update({ + "msg": "Template with template_name '{0}' already deleted".format(templateName) + }) self.msg = "Invalid template {0} under project".format(templateName) - self.status = "failed" + self.status = "success" return self else: self.log("Template name is empty, deleting the project '{0}' and " @@ -2850,6 +2759,11 @@ def verify_diff_merged(self, config): self.get_have_template(config, is_template_available) self.log("Current State (have): {0}".format(self.want.get("template_params")), "INFO") self.log("Desired State (want): {0}".format(self.have_template.get("template")), "INFO") + if not self.have_template.get("template"): + self.msg = "No template created with the name '{0}'".format(self.want.get("template_params").get("name")) + self.status = "failed" + return self + template_params = ["language", "name", "projectName", "softwareType", "softwareVariant", "templateContent"] for item in template_params: From fd27e0c060ce6f0290385e4c44986d88507a434a Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Mon, 6 May 2024 12:27:54 +0530 Subject: [PATCH 328/358] Addressed the review comments --- .../modules/network_settings_workflow_manager.py | 14 ++++++-------- plugins/modules/template_workflow_manager.py | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index 8735a28587..7b588e5d67 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -333,7 +333,7 @@ type: dict requirements: - dnacentersdk == 2.4.5 -- python >= 3.5 +- python >= 3.9 notes: - SDK Method used are network_settings.NetworkSettings.create_global_pool, @@ -1542,18 +1542,16 @@ def get_want_reserve_pool(self, reserve_pool): if pool_values.get("ipv4Prefix") is True: if pool_values.get("ipv4Subnet") is None and \ pool_values.get("ipv4TotalHost") is None: - self.msg = "missing parameter 'ipv4_subnet' or 'ipv4TotalHost' " + \ - "while adding the ipv4 in reserve_pool_details '{0}' element" \ - .format(reserve_pool_index + 1) + self.msg = "Failed to add IPv4 in reserve_pool_details '{0}'. ".format(reserve_pool_index + 1) + \ + "Required parameters 'ipv4_subnet' or 'ipv4_total_host' are missing." self.status = "failed" return self if pool_values.get("ipv6Prefix") is True: if pool_values.get("ipv6Subnet") is None and \ pool_values.get("ipv6TotalHost") is None: - self.msg = "missing parameter 'ipv6_subnet' or 'ipv6TotalHost' " + \ - "while adding the ipv6 in reserve_pool_details '{0}' element" \ - .format(reserve_pool_index + 1) + self.msg = "Failed to add IPv6 in reserve_pool_details '{0}'. ".format(reserve_pool_index + 1) + \ + "Required parameters 'ipv6_subnet' or 'ipv6_total_host' are missing." self.status = "failed" return self @@ -1805,7 +1803,7 @@ def get_want_network(self, network_management_details): }) else: if clientAndEndpoint_aaa.get("servers") == "ISE": - self.msg = "missing parameter ip_address in clientAndEndpoint_aaa, server ISE is set" + self.msg = "Failed to process client_and_endpoint_aaa due to missing 'ip_address' parameter. ISE server is configured." self.status = "failed" return self diff --git a/plugins/modules/template_workflow_manager.py b/plugins/modules/template_workflow_manager.py index 89abe2150f..b5aa0f1ee1 100644 --- a/plugins/modules/template_workflow_manager.py +++ b/plugins/modules/template_workflow_manager.py @@ -1063,7 +1063,7 @@ requirements: - dnacentersdk == 2.4.5 -- python >= 3.5 +- python >= 3.9 notes: - SDK Method used are configuration_templates.ConfigurationTemplates.create_template, From 2ef1ac5bd5a02990a90c4a895e0b34cd991e79c1 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Mon, 6 May 2024 12:46:03 +0530 Subject: [PATCH 329/358] Addressed the review comments --- plugins/modules/network_settings_workflow_manager.py | 6 +++--- plugins/modules/template_workflow_manager.py | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index 7b588e5d67..4474550c50 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -1813,7 +1813,7 @@ def get_want_network(self, network_management_details): clientAndEndpoint_aaa.get("network") }) else: - self.msg = "missing parameter network in clientAndEndpoint_aaa" + self.msg = "missing parameter network in client_and_endpoint_aaa" self.status = "failed" return self @@ -1823,7 +1823,7 @@ def get_want_network(self, network_management_details): clientAndEndpoint_aaa.get("protocol") }) else: - self.msg = "missing parameter protocol in clientAndEndpoint_aaa" + self.msg = "missing parameter protocol in client_and_endpoint_aaa" self.status = "failed" return self @@ -1833,7 +1833,7 @@ def get_want_network(self, network_management_details): clientAndEndpoint_aaa.get("servers") }) else: - self.msg = "missing parameter servers in clientAndEndpoint_aaa" + self.msg = "missing parameter servers in client_and_endpoint_aaa" self.status = "failed" return self diff --git a/plugins/modules/template_workflow_manager.py b/plugins/modules/template_workflow_manager.py index b5aa0f1ee1..491d7d321b 100644 --- a/plugins/modules/template_workflow_manager.py +++ b/plugins/modules/template_workflow_manager.py @@ -1739,8 +1739,7 @@ def get_containing_templates(self, containing_templates): containingTemplates[i].update({"name": name}) - template_details = self.get_templates_details(name) - template_details = template_details.get("response") + template_details = self.get_templates_details(name).get("response") if not template_details: self.msg = "No template with the template name '{0}' or it is not versioned".format(name) self.status = "failed" From 60953a1c9e123ac80ecbc4c6dbb35869271a0d50 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Mon, 6 May 2024 13:20:01 +0530 Subject: [PATCH 330/358] Addressed the review comments --- plugins/modules/network_settings_workflow_manager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index 4474550c50..eb1effbec3 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -1813,7 +1813,7 @@ def get_want_network(self, network_management_details): clientAndEndpoint_aaa.get("network") }) else: - self.msg = "missing parameter network in client_and_endpoint_aaa" + self.msg = "Failed to process client_and_endpoint_aaa due to missing parameter 'network' in the playbook." self.status = "failed" return self @@ -1823,7 +1823,7 @@ def get_want_network(self, network_management_details): clientAndEndpoint_aaa.get("protocol") }) else: - self.msg = "missing parameter protocol in client_and_endpoint_aaa" + self.msg = "Failed to process client_and_endpoint_aaa due to missing parameter 'protocol' in the playbook." self.status = "failed" return self @@ -1833,7 +1833,7 @@ def get_want_network(self, network_management_details): clientAndEndpoint_aaa.get("servers") }) else: - self.msg = "missing parameter servers in client_and_endpoint_aaa" + self.msg = "Failed to process client_and_endpoint_aaa due to missing parameter 'servers' in the playbook." self.status = "failed" return self From 982c09e723c784a9e83922f88a5e153b5cdd5bfe Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Tue, 7 May 2024 11:47:24 +0530 Subject: [PATCH 331/358] Update the cli_transport type in documentaion to ssh/telnet --- plugins/modules/inventory_intent.py | 2 +- plugins/modules/inventory_workflow_manager.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index ce6f0c2e2a..f1a37edd2a 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -57,7 +57,7 @@ default: "NETWORK_DEVICE" cli_transport: description: The essential prerequisite for adding Network devices is the specification of the transport - protocol (either SSH or Telnet) used by the device. + protocol (either ssh or telnet) used by the device. type: str compute_device: description: Indicates whether a device is a compute device. diff --git a/plugins/modules/inventory_workflow_manager.py b/plugins/modules/inventory_workflow_manager.py index b1bbc8b067..121212fc2d 100644 --- a/plugins/modules/inventory_workflow_manager.py +++ b/plugins/modules/inventory_workflow_manager.py @@ -57,7 +57,7 @@ default: "NETWORK_DEVICE" cli_transport: description: The essential prerequisite for adding Network devices is the specification of the transport - protocol (either SSH or Telnet) used by the device. + protocol (either ssh or telnet) used by the device. type: str compute_device: description: Indicates whether a device is a compute device. From 144282e71ac092ca15c01c89ae93d62ab75e2b8d Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Tue, 7 May 2024 14:48:18 +0530 Subject: [PATCH 332/358] Addressed the review comments and added a log message for checking the existence of the file path --- ...se_radius_integration_workflow_manager.yml | 13 +- plugins/module_utils/dnac.py | 1 + ...ise_radius_integration_workflow_manager.py | 210 +++++++++--------- 3 files changed, 114 insertions(+), 110 deletions(-) diff --git a/playbooks/ise_radius_integration_workflow_manager.yml b/playbooks/ise_radius_integration_workflow_manager.yml index eba36a3c59..28dd61696f 100644 --- a/playbooks/ise_radius_integration_workflow_manager.yml +++ b/playbooks/ise_radius_integration_workflow_manager.yml @@ -25,8 +25,8 @@ shared_secret: cisco protocol: RADIUS_TACACS # [TACACS, RADIUS, RADIUS_TACACS] encryption_scheme: KEYWRAP # KEYWRAP or RADSEC - message_key: dnacisesolutions1234 # For KEYWRAP, must be 20 char long encryption_key: dnacsolutions123 # For KEYWRAP, must be 16 char long + message_authenticator_code_key: dnacisesolutions1234 # For KEYWRAP, must be 20 char long authentication_port: 1800 accounting_port: 1700 port: 40 # For TACACS @@ -73,8 +73,8 @@ shared_secret: cisco protocol: RADIUS_TACACS # [TACACS, RADIUS, RADIUS_TACACS] encryption_scheme: KEYWRAP # KEYWRAP or RADSEC - message_key: dnacisesolutions1234 # For KEYWRAP, must be 20 char long encryption_key: dnacsolutions123 # For KEYWRAP, must be 16 char long + message_authenticator_code_key: dnacisesolutions1234 # For KEYWRAP, must be 20 char long authentication_port: 1800 accounting_port: 1700 port: 40 # For TACACS @@ -85,16 +85,11 @@ use_dnac_cert_for_pxgrid: False cisco_ise_dtos: # use this for creating the Cisco ISE Server - user_name: admin - password: abcdefgh + password: abcd fqdn: abc.cisco.com ip_address: 10.195.243.59 - subscriber_name: abc + subscriber_name: abcde description: CISCO ISE - # ssh_key: - # external_cisco_ise_ip_addr_dtos: - # - external_cisco_ise_ip_addresses: - # - external_ip_address: - # ise_type: trusted_server: True - name: Delete an ISE Server. diff --git a/plugins/module_utils/dnac.py b/plugins/module_utils/dnac.py index 37a22c0f62..2ec0d2ce0a 100644 --- a/plugins/module_utils/dnac.py +++ b/plugins/module_utils/dnac.py @@ -525,6 +525,7 @@ def is_path_exists(self, file_path): final_file_path = os.path.join(current_working_directory, file_path) self.log(str(final_file_path)) if not os.path.exists(final_file_path): + self.log("The specified path '{0}' is not valid. Please provide a valid path.".format(final_file_path), "ERROR") return False return True diff --git a/plugins/modules/ise_radius_integration_workflow_manager.py b/plugins/modules/ise_radius_integration_workflow_manager.py index 3bbe5c31f2..20e8527635 100644 --- a/plugins/modules/ise_radius_integration_workflow_manager.py +++ b/plugins/modules/ise_radius_integration_workflow_manager.py @@ -7,7 +7,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -__author__ = ['Muthu Rakesh, Madhan Sankaranarayanan'] +__author__ = ["Muthu Rakesh, Madhan Sankaranarayanan"] DOCUMENTATION = r""" --- @@ -31,7 +31,7 @@ state: description: The state of Cisco Catalyst Center after module completion. type: str - choices: [ merged, deleted ] + choices: [ "merged", "deleted" ] default: merged config: description: @@ -50,16 +50,16 @@ - ISE for Cisco ISE servers. - AAA for Non-Cisco ISE servers. type: str - choices: [ AAA, ISE ] + choices: [ "AAA", "ISE" ] default: AAA server_ip_address: - description: Ip Address of the Authentication and Policy Server. + description: IP Address of the Authentication and Policy Server. type: str required: True shared_secret: description: - Shared secret between devices and authentication and policy server. - - Shared secret key length should be from 4 to 10. + - Shared secret must have 4 to 100 characters with no spaces or the following characters - ["<", "?"]. - Shared secret is a Read-Only parameter. type: str protocol: @@ -68,11 +68,12 @@ - RADIUS provides centralized services (AAA) for users in remote access scenarios. - TACACS focuses on access control and administrative authentication for network devices. type: str - choices: [ TACACS, RADIUS, RADIUS_TACACS] - default: TACACS + choices: [ "TACACS", "RADIUS", "RADIUS_TACACS" ] + default: RADIUS encryption_scheme: description: - Type of encryption scheme for additional security. + - If encryption scheme is given, then message authenticator code and encryption keys need to be required. - Updation of encryption scheme is not possible. - > KEYWRAP is used for securely wrapping and unwrapping encryption keys, @@ -82,16 +83,7 @@ between RADIUS clients and servers over TLS/SSL. Enhances enhancing the confidentiality and integrity of authentication and accounting data exchange. type: str - choices: [KEYWRAP, RADSEC] - message_key: - description: - - Message key used to encrypt shared secret. - - Updation of message key is not possible. - - Required when encryption_scheme is provided. - - > - When ASCII format is selected, Message Authentication Code Key may contain - alphanumeric and special characters. Key must be 20 char long. - type: str + choices: [ "KEYWRAP", "RADSEC" ] encryption_key: description: - Encryption key used to encrypt shared secret. @@ -101,6 +93,15 @@ When ASCII format is selected, Encryption Key may contain alphanumeric and special characters. Key must be 16 char long. type: str + message_authenticator_code_key: + description: + - Message key used to encrypt shared secret. + - Updation of message key is not possible. + - Required when encryption_scheme is provided. + - > + When ASCII format is selected, Message Authentication Code Key may contain + alphanumeric and special characters. Key must be 20 char long. + type: str authentication_port: description: - Authentication port of RADIUS server. @@ -168,6 +169,7 @@ password: description: - Password of the Cisco ISE server. + - Password must have 4 to 127 characters with no spaces or the following characters - "<". - Required for passing the cisco_ise_dtos. type: str fqdn: @@ -192,17 +194,17 @@ description: SSH key of the Cisco ISE server. type: str external_cisco_ise_ip_addr_dtos: - description: External Cisco ISE Ip address data transfer objects for future use. + description: External Cisco ISE IP address data transfer objects for future use. type: list elements: dict suboptions: external_cisco_ise_ip_addresses: - description: External Cisco ISE Ip addresses. + description: External Cisco ISE IP addresses. type: list elements: dict suboptions: external_ip_address: - description: External Cisco ISE Ip address. + description: External Cisco ISE IP address. type: str ise_type: description: Type of the Authentication and Policy Server. @@ -213,8 +215,8 @@ - Serves as a validation of its authenticity and reliability in secure connections. type: bool requirements: -- dnacentersdk == 2.7.0 -- python >= 3.5 +- dnacentersdk == 2.6.0 +- python >= 3.9 notes: - SDK Method used are system_settings.SystemSettings.add_authentication_and_policy_server_access_configuration, @@ -246,19 +248,19 @@ config_verify: True config: - authentication_policy_server: - server_type: string - server_ip_address: string - shared_secret: string - protocol: string - encryption_scheme: string - message_key: string - encryption_key: string - authentication_port: string - accounting_port: string - port: string - retries: string - timeout: string - role: string + server_type: AAA + server_ip_address: 10.0.0.1 + shared_secret: 12345 + protocol: RADIUS_TACACS + encryption_scheme: KEYWRAP + encryption_key: 1234567890123456 + message_authenticator_code_key: asdfghjklasdfghjklas + authentication_port: 1812 + accounting_port: 1813 + port: 49 + retries: 3 + timeout: 4 + role: secondary - name: Create an Cisco ISE server. cisco.dnac.ise_radius_integration_workflow_manager: @@ -275,28 +277,28 @@ config_verify: True config: - authentication_policy_server: - server_type: string - server_ip_address: string - shared_secret: string - protocol: string - encryption_scheme: string - message_key: string - encryption_key: string - authentication_port: string - accounting_port: string - port: string - retries: string - timeout: string - role: string + server_type: ISE + server_ip_address: 10.0.0.2 + shared_secret: 12345 + protocol: RADIUS_TACACS + encryption_scheme: KEYWRAP + encryption_key: 1234567890123456 + message_authenticator_code_key: asdfghjklasdfghjklas + authentication_port: 1812 + accounting_port: 1813 + port: 49 + retries: 3 + timeout: 4 + role: primary use_dnac_cert_for_pxgrid: False pxgrid_enabled: True cisco_ise_dtos: - - user_name: string - password: string - fqdn: string - ip_address: string - subscriber_name: string - description: string + - user_name: Cisco ISE + password: 12345 + fqdn: abs.cisco.com + ip_address: 10.0.0.2 + subscriber_name: px-1234 + description: Cisco ISE - name: Update an AAA server. cisco.dnac.ise_radius_integration_workflow_manager: @@ -313,15 +315,15 @@ config_verify: True config: - authentication_policy_server: - server_type: string - server_ip_address: string - protocol: string - authentication_port: string - accounting_port: string - port: string - retries: string - timeout: string - role: string + server_type: AAA + server_ip_address: 10.0.0.1 + protocol: RADIUS_TACACS + authentication_port: 1812 + accounting_port: 1813 + port: 49 + retries: 3 + timeout: 5 + role: secondary - name: Update an Cisco ISE server. cisco.dnac.ise_radius_integration_workflow_manager: @@ -338,24 +340,24 @@ config_verify: True config: - authentication_policy_server: - server_type: string - server_ip_address: string - protocol: string - authentication_port: string - accounting_port: string - port: string - retries: string - timeout: string - role: string + server_type: ISE + server_ip_address: 10.0.0.2 + protocol: RADIUS_TACACS + authentication_port: 1812 + accounting_port: 1813 + port: 49 + retries: 3 + timeout: 5 + role: primary use_dnac_cert_for_pxgrid: False pxgrid_enabled: True cisco_ise_dtos: - - user_name: string - password: string - fqdn: string - ip_address: string - subscriber_name: string - description: string + - user_name: Cisco ISE + password: 12345 + fqdn: abs.cisco.com + ip_address: 10.0.0.2 + subscriber_name: px-1234 + description: Cisco ISE - name: Delete an Authentication and Policy server. cisco.dnac.ise_radius_integration_workflow_manager: @@ -372,7 +374,7 @@ config_verify: True config: - authentication_policy_server: - server_ip_address: string + server_ip_address: 10.0.0.1 """ RETURN = r""" @@ -468,7 +470,7 @@ def validate_input(self): "shared_secret": {"type": 'string'}, "protocol": {"type": 'string', "choices": ["TACACS", "RADIUS", "RADIUS_TACACS"]}, "encryption_scheme": {"type": 'string'}, - "message_key": {"type": 'string'}, + "message_authenticator_code_key": {"type": 'string'}, "encryption_key": {"type": 'string'}, "authentication_port": {"type": 'string'}, "accounting_port": {"type": 'string'}, @@ -666,6 +668,7 @@ def auth_server_exists(self, ipAddress): if not auth_server_details: self.log("Global pool {0} does not exist".format(ipAddress), "INFO") return AuthServer + AuthServer.update({"exists": True}) AuthServer.update({"id": auth_server_details.get("instanceUuid")}) AuthServer["details"] = self.get_auth_server_params(auth_server_details) @@ -699,13 +702,13 @@ def get_have_authentication_policy_server(self, config): self.status = "failed" return self - ipAddress = authentication_policy_server.get("server_ip_address") - if ipAddress is None: + ip_address = authentication_policy_server.get("server_ip_address") + if ip_address is None: self.msg = "Mandatory Parameter server_ip_address required" self.status = "failed" return self - AuthServer = self.auth_server_exists(ipAddress) + AuthServer = self.auth_server_exists(ip_address) self.log("Authentication and Policy Server exists: {0}" .format(AuthServer.get("exists")), "DEBUG") self.log("Authentication and Policy Server details: {0}" @@ -756,7 +759,6 @@ def get_want_authentication_policy_server(self, auth_policy_server): auth_server = {} trusted_server = False - auth_server_exists = self.have.get("authenticationPolicyServer").get("exists") server_type = auth_policy_server.get("server_type") if server_type not in ["ISE", "AAA", None]: self.msg = "server_type should either be ISE or AAA but not {0}.".format(server_type) @@ -770,17 +772,23 @@ def get_want_authentication_policy_server(self, auth_policy_server): auth_server.update({"ipAddress": auth_policy_server.get("server_ip_address")}) + auth_server_exists = self.have.get("authenticationPolicyServer").get("exists") shared_secret = auth_policy_server.get("shared_secret") if not (shared_secret or auth_server_exists): self.msg = "shared_secret is mandatory parameter" self.status = "failed" return self - if not (4 <= len(shared_secret) <= 10) or shared_secret.isspace(): + if not (4 <= len(shared_secret) <= 100) or shared_secret.isspace(): self.msg = "shared_secret should character should be between 4 to 100." self.status = "failed" return self + if "?" in shared_secret or "<" in shared_secret: + self.msg = "shared_secret should character should not contain '?' or '<'." + self.status = "failed" + return self + auth_server.update({"sharedSecret": shared_secret}) protocol = auth_policy_server.get("protocol") @@ -806,14 +814,14 @@ def get_want_authentication_policy_server(self, auth_policy_server): auth_server.update({"encryptionScheme": encryption_scheme}) if encryption_scheme == "KEYWRAP": - message_key = str(auth_policy_server.get("message_key")) + message_key = str(auth_policy_server.get("message_authenticator_code_key")) if not message_key: - self.msg = "message_key should not be empty if encryption_scheme is 'KEYWRAP'." + self.msg = "message_authenticator_code_key should not be empty if encryption_scheme is 'KEYWRAP'." self.status = "failed" return self if len(message_key) != 20: - self.msg = "message_key should be exactly 20 character." + self.msg = "message_authenticator_code_key should be exactly 20 character." self.status = "failed" return self @@ -826,7 +834,7 @@ def get_want_authentication_policy_server(self, auth_policy_server): return self if len(encryption_key) != 16: - self.msg = "encryption_key should be exactly 16 characters." + self.msg = "encryption_key must be 16 char long. encryption_key may contain alphanumeric and special characters." self.status = "failed" return self @@ -899,18 +907,6 @@ def get_want_authentication_policy_server(self, auth_policy_server): auth_server.update({"role": "secondary"}) if auth_server.get("isIseEnabled"): - pxgrid_enabled = auth_policy_server.get("pxgrid_enabled") - if pxgrid_enabled: - auth_server.update({"pxgridEnabled": pxgrid_enabled}) - else: - auth_server.update({"pxgridEnabled": True}) - - use_dnac_cert_for_pxgrid = auth_policy_server.get("use_dnac_cert_for_pxgrid") - if use_dnac_cert_for_pxgrid: - auth_server.update({"useDnacCertForPxgrid": use_dnac_cert_for_pxgrid}) - else: - auth_server.update({"useDnacCertForPxgrid": False}) - cisco_ise_dtos = auth_policy_server.get("cisco_ise_dtos") if not cisco_ise_dtos: self.msg = "Mandatory parameter cisco_ise_dtos " + \ @@ -989,6 +985,18 @@ def get_want_authentication_policy_server(self, auth_policy_server): position_ise_creds += 1 + pxgrid_enabled = auth_policy_server.get("pxgrid_enabled") + if pxgrid_enabled: + auth_server.update({"pxgridEnabled": pxgrid_enabled}) + else: + auth_server.update({"pxgridEnabled": True}) + + use_dnac_cert_for_pxgrid = auth_policy_server.get("use_dnac_cert_for_pxgrid") + if use_dnac_cert_for_pxgrid: + auth_server.update({"useDnacCertForPxgrid": use_dnac_cert_for_pxgrid}) + else: + auth_server.update({"useDnacCertForPxgrid": False}) + external_cisco_ise_ip_addr_dtos = auth_policy_server \ .get("external_cisco_ise_ip_addr_dtos") if external_cisco_ise_ip_addr_dtos: From 41d2b49078b012b4bc27ca9c7358ffb41a00ffd2 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Tue, 7 May 2024 15:07:40 +0530 Subject: [PATCH 333/358] Changed the dnacentersdk version '==' to '>=' --- .../ise_radius_integration_workflow_manager.py | 2 +- plugins/modules/network_settings_workflow_manager.py | 12 +++++++----- plugins/modules/template_workflow_manager.py | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/plugins/modules/ise_radius_integration_workflow_manager.py b/plugins/modules/ise_radius_integration_workflow_manager.py index 20e8527635..d79fced5b3 100644 --- a/plugins/modules/ise_radius_integration_workflow_manager.py +++ b/plugins/modules/ise_radius_integration_workflow_manager.py @@ -215,7 +215,7 @@ - Serves as a validation of its authenticity and reliability in secure connections. type: bool requirements: -- dnacentersdk == 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/network_settings_workflow_manager.py b/plugins/modules/network_settings_workflow_manager.py index eb1effbec3..7580660247 100644 --- a/plugins/modules/network_settings_workflow_manager.py +++ b/plugins/modules/network_settings_workflow_manager.py @@ -332,7 +332,7 @@ type: list type: dict requirements: -- dnacentersdk == 2.4.5 +- dnacentersdk >= 2.4.5 - python >= 3.9 notes: - SDK Method used are @@ -1521,8 +1521,6 @@ def get_want_reserve_pool(self, reserve_pool): "ipv4DhcpServers": item.get("ipv4_dhcp_servers"), "ipv4DnsServers": item.get("ipv4_dns_servers"), "ipv4Subnet": item.get("ipv4_subnet"), - "ipv6GlobalPool": self.get_global_pool_cidr(item.get("ipv6_global_pool"), - item.get("ipv6_global_pool_name")), "ipv6Prefix": item.get("ipv6_prefix"), "ipv6PrefixLength": item.get("ipv6_prefix_length"), "ipv6GateWay": item.get("ipv6_gateway"), @@ -1533,6 +1531,11 @@ def get_want_reserve_pool(self, reserve_pool): "ipv6TotalHost": item.get("ipv6_total_host") } # Check for missing mandatory parameters in the playbook + if pool_values.get("ipv6AddressSpace") is True: + pool_values.update({ + "ipv6GlobalPool": self.get_global_pool_cidr(item.get("ipv6_global_pool"), + item.get("ipv6_global_pool_name"))}) + if not pool_values.get("name"): self.msg = "Missing mandatory parameter 'name' in reserve_pool_details '{0}' element" \ .format(reserve_pool_index + 1) @@ -1591,8 +1594,7 @@ def get_want_reserve_pool(self, reserve_pool): del pool_values['ipv6Prefix'] if not pool_values.get("ipv6AddressSpace"): - keys_to_check = ['ipv6GlobalPool', 'ipv6PrefixLength', - 'ipv6GateWay', 'ipv6DhcpServers', + keys_to_check = ['ipv6PrefixLength', 'ipv6GateWay', 'ipv6DhcpServers', 'ipv6DnsServers', 'ipv6TotalHost'] for key in keys_to_check: if pool_values.get(key) is None: diff --git a/plugins/modules/template_workflow_manager.py b/plugins/modules/template_workflow_manager.py index 491d7d321b..9b7ec45908 100644 --- a/plugins/modules/template_workflow_manager.py +++ b/plugins/modules/template_workflow_manager.py @@ -1062,7 +1062,7 @@ type: str requirements: -- dnacentersdk == 2.4.5 +- dnacentersdk >= 2.4.5 - python >= 3.9 notes: - SDK Method used are From 5c9e9125233b213e52c8b1f8a020bb9a1c33be10 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Tue, 7 May 2024 15:59:37 +0530 Subject: [PATCH 334/358] Addressed the review comments --- .../ise_radius_integration_workflow_manager.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/modules/ise_radius_integration_workflow_manager.py b/plugins/modules/ise_radius_integration_workflow_manager.py index d79fced5b3..8b592a48ad 100644 --- a/plugins/modules/ise_radius_integration_workflow_manager.py +++ b/plugins/modules/ise_radius_integration_workflow_manager.py @@ -99,8 +99,8 @@ - Updation of message key is not possible. - Required when encryption_scheme is provided. - > - When ASCII format is selected, Message Authentication Code Key may contain - alphanumeric and special characters. Key must be 20 char long. + Message Authentication Code Key may contain alphanumeric and special characters. + Key must be 20 char long. type: str authentication_port: description: @@ -780,12 +780,12 @@ def get_want_authentication_policy_server(self, auth_policy_server): return self if not (4 <= len(shared_secret) <= 100) or shared_secret.isspace(): - self.msg = "shared_secret should character should be between 4 to 100." + self.msg = "The 'shared_secret' should contain between 4 and 100 characters." self.status = "failed" return self if "?" in shared_secret or "<" in shared_secret: - self.msg = "shared_secret should character should not contain '?' or '<'." + self.msg = "The 'shared_secret' should not contain '?' or '<' characters." self.status = "failed" return self @@ -816,12 +816,12 @@ def get_want_authentication_policy_server(self, auth_policy_server): if encryption_scheme == "KEYWRAP": message_key = str(auth_policy_server.get("message_authenticator_code_key")) if not message_key: - self.msg = "message_authenticator_code_key should not be empty if encryption_scheme is 'KEYWRAP'." + self.msg = "The 'message_authenticator_code_key' should not be empty if the encryption_scheme is 'KEYWRAP'." self.status = "failed" return self if len(message_key) != 20: - self.msg = "message_authenticator_code_key should be exactly 20 character." + self.msg = "The 'message_authenticator_code_key' should be exactly 20 characters." self.status = "failed" return self @@ -834,7 +834,7 @@ def get_want_authentication_policy_server(self, auth_policy_server): return self if len(encryption_key) != 16: - self.msg = "encryption_key must be 16 char long. encryption_key may contain alphanumeric and special characters." + self.msg = "The 'encryption_key' must be 16 characters long. It may contain alphanumeric and special characters." self.status = "failed" return self From a30b7d7927c80e3963c5f312a56976d511b577da Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Tue, 7 May 2024 16:51:51 +0530 Subject: [PATCH 335/358] Removed the unused failure_params parameter --- plugins/modules/template_workflow_manager.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/plugins/modules/template_workflow_manager.py b/plugins/modules/template_workflow_manager.py index 9b7ec45908..c9de7e4c60 100644 --- a/plugins/modules/template_workflow_manager.py +++ b/plugins/modules/template_workflow_manager.py @@ -307,9 +307,6 @@ product_type: description: Describes the exact type of the device. type: str - failure_policy: - description: Define failure policy if template provisioning fails. - type: str id: description: A unique identifier, represented as a UUID. type: str @@ -838,9 +835,6 @@ product_type: description: Describes the exact type of the device. type: str - failure_policy: - description: Define failure policy if template provisioning fails. - type: str id: description: A unique identifier, represented as a UUID. type: str @@ -1109,7 +1103,6 @@ - product_family: string product_series: string product_type: string - failure_policy: string id: string language: string name: string @@ -1346,7 +1339,6 @@ def validate_input(self): 'product_series': {'type': 'str'}, 'product_type': {'type': 'str'}, }, - 'failure_policy': {'type': 'str'}, 'id': {'type': 'str'}, 'language': {'type': 'str'}, 'name': {'type': 'str'}, @@ -1397,7 +1389,6 @@ def validate_input(self): 'product_series': {'type': 'str'}, 'product_type': {'type': 'str'}, }, - 'failure_policy': {'type': 'str'}, 'id': {'type': 'str'}, 'language': {'type': 'str'}, 'name': {'type': 'str'}, @@ -1815,7 +1806,6 @@ def get_template_params(self, params): "description": params.get("template_description"), "deviceTypes": self.get_device_types(params.get("device_types")), - "failurePolicy": params.get("failure_policy"), "id": params.get("id"), "rollbackTemplateContent": params.get("rollback_template_content"), "rollbackTemplateParams": @@ -2192,7 +2182,6 @@ def requires_update(self): ("customParamsOrder", "customParamsOrder", False), ("description", "description", ""), ("deviceTypes", "deviceTypes", []), - ("failurePolicy", "failurePolicy", ""), ("id", "id", ""), ("language", "language", "VELOCITY"), ("name", "name", ""), From db6a72bb86b036457bd827fda373d2f61361b732 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 8 May 2024 12:12:34 +0530 Subject: [PATCH 336/358] Prompts an error when the site_name is invalid under assign_credentials_to_site --- plugins/modules/device_credential_workflow_manager.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/modules/device_credential_workflow_manager.py b/plugins/modules/device_credential_workflow_manager.py index 74b47d9878..2580b57357 100644 --- a/plugins/modules/device_credential_workflow_manager.py +++ b/plugins/modules/device_credential_workflow_manager.py @@ -1954,17 +1954,19 @@ def get_want_assign_credentials(self, AssignCredentials): } site_name = AssignCredentials.get("site_name") if not site_name: - self.msg = "site_name is required for AssignCredentials" + self.msg = "The 'site_name' is required for 'assign_credentials_to_site'" self.status = "failed" return self + site_id = [] for site_name in site_name: siteId = self.get_site_id(site_name) - if not site_name: - self.msg = "site_name is invalid in AssignCredentials" + if not site_id: + self.msg = "site_name '{0}' is invalid in 'assign_credentials_to_site'".format(site_name) self.status = "failed" return self site_id.append(siteId) + want.update({"site_id": site_id}) global_credentials = self.get_global_credentials_params() cli_credential = AssignCredentials.get("cli_credential") @@ -2471,7 +2473,6 @@ def verify_diff_merged(self, config): self """ - self.log(str("Entered the verify function."), "DEBUG") self.get_have(config) self.get_want(config) self.log("Current State (have): {0}".format(self.have), "INFO") From bbb2e260be3e2a4bac0a69d4dfb1737bda95a628 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 8 May 2024 12:29:44 +0530 Subject: [PATCH 337/358] Addressed the review comments --- plugins/modules/device_credential_workflow_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/device_credential_workflow_manager.py b/plugins/modules/device_credential_workflow_manager.py index 2580b57357..48ec91efdd 100644 --- a/plugins/modules/device_credential_workflow_manager.py +++ b/plugins/modules/device_credential_workflow_manager.py @@ -1954,7 +1954,7 @@ def get_want_assign_credentials(self, AssignCredentials): } site_name = AssignCredentials.get("site_name") if not site_name: - self.msg = "The 'site_name' is required for 'assign_credentials_to_site'" + self.msg = "The 'site_name' is required parameter for 'assign_credentials_to_site'" self.status = "failed" return self @@ -1962,7 +1962,7 @@ def get_want_assign_credentials(self, AssignCredentials): for site_name in site_name: siteId = self.get_site_id(site_name) if not site_id: - self.msg = "site_name '{0}' is invalid in 'assign_credentials_to_site'".format(site_name) + self.msg = "The site_name '{0}' is invalid in 'assign_credentials_to_site'".format(site_name) self.status = "failed" return self site_id.append(siteId) From 1805b9833d0ded6ee19ce5c2730585e207535644 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 8 May 2024 15:50:49 +0530 Subject: [PATCH 338/358] Verified the config of containingTemplates under configuration_templates --- plugins/modules/template_workflow_manager.py | 26 +++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/plugins/modules/template_workflow_manager.py b/plugins/modules/template_workflow_manager.py index c9de7e4c60..b96435c150 100644 --- a/plugins/modules/template_workflow_manager.py +++ b/plugins/modules/template_workflow_manager.py @@ -2745,8 +2745,8 @@ def verify_diff_merged(self, config): return self self.get_have_template(config, is_template_available) - self.log("Current State (have): {0}".format(self.want.get("template_params")), "INFO") - self.log("Desired State (want): {0}".format(self.have_template.get("template")), "INFO") + self.log("Desired State (have): {0}".format(self.want.get("template_params")), "INFO") + self.log("Current State (want): {0}".format(self.have_template.get("template")), "INFO") if not self.have_template.get("template"): self.msg = "No template created with the name '{0}'".format(self.want.get("template_params").get("name")) self.status = "failed" @@ -2754,11 +2754,29 @@ def verify_diff_merged(self, config): template_params = ["language", "name", "projectName", "softwareType", "softwareVariant", "templateContent"] + error_msg = "Configuration Template config is not applied to the Cisco Catalyst Center." + have_template = self.have_template.get("template") + want_template = self.want.get("template_params") for item in template_params: - if self.have_template.get("template").get(item) != self.want.get("template_params").get(item): - self.msg = "Configuration Template config is not applied to the Cisco Catalyst Center." + if have_template.get(item) != want_template.get(item): + self.msg = error_msg self.status = "failed" return self + + want_template_containing_template = want_template.get("containingTemplates") + for item in want_template_containing_template: + name = item.get("name") + response = get_dict_result(have_template.get("containingTemplates"), "name", name) + if response is None: + self.msg = error_msg + self.status = "failed" + return self + for value in item: + if item.get(value) != response.get(value): + self.msg = error_msg + self.failed = "failed" + return self + self.log("Successfully validated the Template in the Catalyst Center.", "INFO") self.result['response'][0].get("configurationTemplate").get("response").update({"Validation": "Success"}) From 994c71da81574e9e7acf17841e32fd3416ce3331 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Thu, 9 May 2024 12:02:19 +0530 Subject: [PATCH 339/358] Addressed the review comments --- plugins/modules/template_workflow_manager.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/modules/template_workflow_manager.py b/plugins/modules/template_workflow_manager.py index b96435c150..830d4c6302 100644 --- a/plugins/modules/template_workflow_manager.py +++ b/plugins/modules/template_workflow_manager.py @@ -2754,12 +2754,12 @@ def verify_diff_merged(self, config): template_params = ["language", "name", "projectName", "softwareType", "softwareVariant", "templateContent"] - error_msg = "Configuration Template config is not applied to the Cisco Catalyst Center." have_template = self.have_template.get("template") want_template = self.want.get("template_params") for item in template_params: if have_template.get(item) != want_template.get(item): - self.msg = error_msg + self.msg = "Configuration Template config '{0}' is not applied to the Cisco Catalyst Center." \ + .format(item) self.status = "failed" return self @@ -2768,13 +2768,15 @@ def verify_diff_merged(self, config): name = item.get("name") response = get_dict_result(have_template.get("containingTemplates"), "name", name) if response is None: - self.msg = error_msg + self.msg = "Configuration Template config with template_name '{0}' under ".format(name) + \ + "'containing_templates' is not available in the Cisco Catalyst Center." self.status = "failed" return self for value in item: if item.get(value) != response.get(value): - self.msg = error_msg - self.failed = "failed" + self.msg = "Configuration Template config with template_name " + \ + "{0}'s '{1}' is not applied to the Cisco Catalyst Center.".format(name, value) + self.status = "failed" return self self.log("Successfully validated the Template in the Catalyst Center.", "INFO") From 137cb33749c0b1d3032ef21fa1d8dd758b4fa1e7 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Thu, 9 May 2024 12:58:16 +0530 Subject: [PATCH 340/358] Addressed the review comments --- plugins/modules/template_workflow_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/template_workflow_manager.py b/plugins/modules/template_workflow_manager.py index 830d4c6302..c3141559d7 100644 --- a/plugins/modules/template_workflow_manager.py +++ b/plugins/modules/template_workflow_manager.py @@ -2758,8 +2758,8 @@ def verify_diff_merged(self, config): want_template = self.want.get("template_params") for item in template_params: if have_template.get(item) != want_template.get(item): - self.msg = "Configuration Template config '{0}' is not applied to the Cisco Catalyst Center." \ - .format(item) + self.msg = "Configuration Template config with template_name {0}'s '{1}' is not applied to the Cisco Catalyst Center." \ + .format(want_template.get("name"), item) self.status = "failed" return self From 501feb52d1e7bf8988d4a4d4413391900d293584 Mon Sep 17 00:00:00 2001 From: Madhan Date: Thu, 9 May 2024 16:33:06 +0530 Subject: [PATCH 341/358] Adding workflow manager modules for IAC 2.0 --- changelogs/changelog.yaml | 15 ++++++++++++++- galaxy.yml | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 81e4f43487..60b9d4f89d 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -865,4 +865,17 @@ releases: minor_changes: - Adding support to importing a template using JSON file - Changes in discovery workflow manager modules relating to different states of the discovery job - - Changes in inventory and swim workflow manager modules. + 6.14.0: + release_date: "2024-05-09" + changes: + release_summary: Addition of Workflow Manager modules support for device configuration backups, events and notifications, ISE and RADIUS server integrations, and network compliance. + minor_changes: + - device_configs_backup_workflow_manager - New workflow manager module for device configuration backup functions. + - events_and_notifications_workflow_manager - New workflow manager for configuring various types of destinations(Webhook, Email, Syslog, SNMP, ITSM) to deliver event notifications. + - ise_radius_integration_workflow_manager - New workflow manager for Authentication and Policy Servers(ISE/AAA). + - network_compliance_workflow_manager - New workflow manager for Network Compliance module for managing network compliance tasks on reachable device(s). + - device_credential_workflow_manager - Updated the log messages. + - inventory_workflow_manager - Updated changes related to provisioning devices. + - provision_workflow_manager - Updated changes related to handle errors. + - site_workflow_manager - Updated changes in Site updation. + - network_settings_workflow_manager - Added attributes 'ipv4_global_pool_name' diff --git a/galaxy.yml b/galaxy.yml index 9858ed672f..e07c825ab1 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dnac -version: 6.13.3 +version: 6.14.0 readme: README.md authors: - Rafael Campos From 871c3de3e5710d7e5245f48e6cdf05364ad6a181 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Thu, 9 May 2024 16:40:21 +0530 Subject: [PATCH 342/358] Fixed the issue with passing more than one element in containingTemplates --- plugins/modules/template_workflow_manager.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/modules/template_workflow_manager.py b/plugins/modules/template_workflow_manager.py index c3141559d7..faa10573bd 100644 --- a/plugins/modules/template_workflow_manager.py +++ b/plugins/modules/template_workflow_manager.py @@ -1782,6 +1782,8 @@ def get_containing_templates(self, containing_templates): if version is not None: containingTemplates[i].update({"version": version}) + i += 1 + return containingTemplates def get_template_params(self, params): From 0ebd4ea4e365eecb484ac32b208868f781d8af46 Mon Sep 17 00:00:00 2001 From: Madhan Date: Thu, 9 May 2024 16:40:34 +0530 Subject: [PATCH 343/358] changes in workflow manager modules --- plugins/modules/device_configs_backup_workflow_manager.py | 2 +- plugins/modules/events_and_notifications_workflow_manager.py | 2 +- plugins/modules/ise_radius_integration_workflow_manager.py | 2 +- plugins/modules/network_compliance_workflow_manager.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/modules/device_configs_backup_workflow_manager.py b/plugins/modules/device_configs_backup_workflow_manager.py index dbecf4a500..2658c09ce6 100644 --- a/plugins/modules/device_configs_backup_workflow_manager.py +++ b/plugins/modules/device_configs_backup_workflow_manager.py @@ -15,7 +15,7 @@ short_description: Resource module for device_configs_backup functions description: - Manage operation related to taking the backup of running config, static config and vlan.dat.bat -version_added: '6.13.0' +version_added: '6.14.0' extends_documentation_fragment: - cisco.dnac.workflow_manager_params author: Abinash Mishra (@abimishr) diff --git a/plugins/modules/events_and_notifications_workflow_manager.py b/plugins/modules/events_and_notifications_workflow_manager.py index de5d9e47b5..f600293a4f 100644 --- a/plugins/modules/events_and_notifications_workflow_manager.py +++ b/plugins/modules/events_and_notifications_workflow_manager.py @@ -22,7 +22,7 @@ - Configuring/Updating the ITSM Integration Settings in Cisco Catalyst Center. - Deletes the ITSM Integration Settings from Cisco Catalyst Center. - Create/Update Notification using the above destination in Cisco Catalyst Center. - +version_added: '6.14.0' extends_documentation_fragment: - cisco.dnac.workflow_manager_params author: Abhishek Maheshwari (@abmahesh) diff --git a/plugins/modules/ise_radius_integration_workflow_manager.py b/plugins/modules/ise_radius_integration_workflow_manager.py index 8b592a48ad..b7cccfdcfb 100644 --- a/plugins/modules/ise_radius_integration_workflow_manager.py +++ b/plugins/modules/ise_radius_integration_workflow_manager.py @@ -18,7 +18,7 @@ - API to create Authentication and Policy Server Access Configuration. - API to update Authentication and Policy Server Access Configuration. - API to delete Authentication and Policy Server Access Configuration. -version_added: '6.13.0' +version_added: '6.14.0' extends_documentation_fragment: - cisco.dnac.workflow_manager_params author: Muthu Rakesh (@MUTHU-RAKESH-27) diff --git a/plugins/modules/network_compliance_workflow_manager.py b/plugins/modules/network_compliance_workflow_manager.py index 3860efe5c6..d0b716d5c1 100644 --- a/plugins/modules/network_compliance_workflow_manager.py +++ b/plugins/modules/network_compliance_workflow_manager.py @@ -17,7 +17,7 @@ - Perform compliance checks or sync configurations on reachable devices using IP Address(s) or Site. - API to perform full compliance checks or specific category checks on reachable device(s). - API to sync device configuration on device(s). -version_added: "6.13.0" +version_added: "6.14.0" extends_documentation_fragment: - cisco.dnac.workflow_manager_params author: Rugvedi Kapse (@rukapse) From 9504176a53dc968eca04958f5a27f513cf5626e1 Mon Sep 17 00:00:00 2001 From: Madhan Date: Thu, 9 May 2024 16:48:37 +0530 Subject: [PATCH 344/358] Correcting the format --- changelogs/changelog.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 60b9d4f89d..34cfd881e9 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -865,7 +865,7 @@ releases: minor_changes: - Adding support to importing a template using JSON file - Changes in discovery workflow manager modules relating to different states of the discovery job - 6.14.0: + 6.14.0: release_date: "2024-05-09" changes: release_summary: Addition of Workflow Manager modules support for device configuration backups, events and notifications, ISE and RADIUS server integrations, and network compliance. @@ -878,4 +878,5 @@ releases: - inventory_workflow_manager - Updated changes related to provisioning devices. - provision_workflow_manager - Updated changes related to handle errors. - site_workflow_manager - Updated changes in Site updation. - - network_settings_workflow_manager - Added attributes 'ipv4_global_pool_name' + - network_settings_workflow_manager - Added attributes 'ipv4_global_pool_name'. + - template_workflow_manager - Removed attributes 'create_time', 'failure_policy', 'last_update_time', 'latest_version_time', 'parent_template_id', 'project_id', 'validation_errors'. From 059d84430df6a38f0091ac409a38c218dd99a297 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Thu, 9 May 2024 17:00:00 +0530 Subject: [PATCH 345/358] Addressed the review comments --- plugins/modules/template_workflow_manager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/modules/template_workflow_manager.py b/plugins/modules/template_workflow_manager.py index faa10573bd..c13263e8f3 100644 --- a/plugins/modules/template_workflow_manager.py +++ b/plugins/modules/template_workflow_manager.py @@ -1755,13 +1755,13 @@ def get_containing_templates(self, containing_templates): containingTemplates[i].update({"language": language}) project_name = item.get("project_name") - if project_name is not None: - containingTemplates[i].update({"projectName": project_name}) - else: + if project_name is None: self.msg = "project_name is mandatory under containing templates" self.status = "failed" return self.check_return_status() + containingTemplates[i].update({"projectName": project_name}) + rollback_template_params = item.get("rollback_template_params") if rollback_template_params is not None: containingTemplates[i].update({ From db3f5575f798daddcb4305d628e58d6c2ce8d8a0 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Fri, 10 May 2024 10:59:18 +0530 Subject: [PATCH 346/358] Removed the unused variables which shows no effect on the GUI --- plugins/modules/template_workflow_manager.py | 359 ------------------- 1 file changed, 359 deletions(-) diff --git a/plugins/modules/template_workflow_manager.py b/plugins/modules/template_workflow_manager.py index c13263e8f3..4a123ed2b3 100644 --- a/plugins/modules/template_workflow_manager.py +++ b/plugins/modules/template_workflow_manager.py @@ -100,90 +100,6 @@ project_description: description: Narrative that elaborates on the purpose and scope of the project. type: str - rollback_template_params: - description: A list of dictionaries defining parameters necessary for the rollback functionality of a template. - type: list - elements: dict - suboptions: - binding: - description: Associates the parameter with its source. - type: str - custom_order: - description: Specifies a user-defined ordering for the parameter. - type: int - data_type: - description: Identifies the data type of the parameter (e.g., string, integer, boolean). - type: str - default_value: - description: Establishes a default value for the parameter, used if no other value is provided. - type: str - description: - description: Provides a descriptive explanation of the parameter's purpose. - type: str - display_name: - description: The name of the parameter as displayed to users. - type: str - group: - description: Categorizes the parameter into a named group for organizational purposes. - type: str - id: - description: A unique identifier for the parameter, formatted as a UUID. - type: str - instruction_text: - description: Gives guidance or instructions regarding the parameter's use. - type: str - key: - description: A unique key that identifies the parameter within the template. - type: str - not_param: - description: Indicates whether the entry is not to be treated as a parameter. - type: bool - order: - description: Determines the sequence in which the parameter appears relative to others. - type: int - param_array: - description: Specifies if the parameter should be treated as an array. - type: bool - parameter_name: - description: The name of the parameter. - type: str - provider: - description: Denotes the provider associated with the parameter. - type: str - range: - description: Defines the permissible range for the parameter's value. - type: list - elements: dict - suboptions: - id: - description: Unique identifier for the range, represented as a UUID. - type: str - max_value: - description: Specifies the maximum allowable value for the parameter. - type: int - min_value: - description: Specifies the minimum allowable value for the parameter. - type: int - required: - description: Dictates whether the parameter is mandatory for template operations. - type: bool - selection: - description: Contains options for parameter selection when a choice is available. - suboptions: - default_selected_values: - description: Lists the default values that are preselected. - elements: str - type: list - id: - description: A unique identifier for the selection entity, represented as a UUID. - type: str - selection_type: - description: Specifies the type of selection, such as 'SINGLE_SELECT' or 'MULTI_SELECT'. - type: str - selection_values: - description: A dictionary of available values for selection. - type: dict - type: dict tags: description: A list of dictionaries representing tags associated with the Configuration Template during creation. suboptions: @@ -325,93 +241,6 @@ project_description: description: Narrative that elaborates on the purpose and scope of the project. type: str - rollback_template_content: - description: Refers to the process of reverting the content of a template back to a previous version or state. - type: str - rollback_template_params: - description: A list of dictionaries defining parameters necessary for the rollback functionality of a template. - suboptions: - binding: - description: Associates the parameter with its source. - type: str - custom_order: - description: Specifies a user-defined ordering for the parameter. - type: int - data_type: - description: Identifies the data type of the parameter (e.g., string, integer, boolean). - type: str - default_value: - description: Establishes a default value for the parameter, used if no other value is provided. - type: str - description: - description: Provides a descriptive explanation of the parameter's purpose. - type: str - display_name: - description: The name of the parameter as displayed to users. - type: str - group: - description: Categorizes the parameter into a named group for organizational purposes. - type: str - id: - description: A unique identifier for the parameter, formatted as a UUID. - type: str - instruction_text: - description: Gives guidance or instructions regarding the parameter's use. - type: str - key: - description: A unique key that identifies the parameter within the template. - type: str - not_param: - description: Indicates whether the entry is not to be treated as a parameter. - type: bool - order: - description: Determines the sequence in which the parameter appears relative to others. - type: int - param_array: - description: Specifies if the parameter should be treated as an array. - type: bool - parameter_name: - description: The name of the parameter. - type: str - provider: - description: Denotes the provider associated with the parameter. - type: str - range: - description: Defines the permissible range for the parameter's value. - suboptions: - id: - description: Unique identifier for the range, represented as a UUID. - type: str - max_value: - description: Specifies the maximum allowable value for the parameter. - type: int - min_value: - description: Specifies the minimum allowable value for the parameter. - type: int - type: list - elements: dict - required: - description: Dictates whether the parameter is mandatory for template operations. - type: bool - selection: - description: Contains options for parameter selection when a choice is available. - suboptions: - default_selected_values: - description: Lists the default values that are preselected. - elements: str - type: list - id: - description: A unique identifier for the selection entity, represented as a UUID. - type: str - selection_type: - description: Specifies the type of selection, such as 'SINGLE_SELECT' or 'MULTI_SELECT'. - type: str - selection_values: - description: A dictionary of available values for selection. - type: dict - type: dict - type: list - elements: dict software_type: description: Applicable device software type. This field is mandatory to create a new template. type: str @@ -628,90 +457,6 @@ project_name: description: Title of the project within which the template is categorized and managed. type: str - rollback_template_params: - description: A list of dictionaries defining parameters necessary for the rollback functionality of a template. - type: list - elements: dict - suboptions: - binding: - description: Associates the parameter with its source. - type: str - custom_order: - description: Specifies a user-defined ordering for the parameter. - type: int - data_type: - description: Identifies the data type of the parameter (e.g., string, integer, boolean). - type: str - default_value: - description: Establishes a default value for the parameter, used if no other value is provided. - type: str - description: - description: Provides a descriptive explanation of the parameter's purpose. - type: str - display_name: - description: The name of the parameter as displayed to users. - type: str - group: - description: Categorizes the parameter into a named group for organizational purposes. - type: str - id: - description: A unique identifier for the parameter, formatted as a UUID. - type: str - instruction_text: - description: Gives guidance or instructions regarding the parameter's use. - type: str - key: - description: A unique key that identifies the parameter within the template. - type: str - not_param: - description: Indicates whether the entry is not to be treated as a parameter. - type: bool - order: - description: Determines the sequence in which the parameter appears relative to others. - type: int - param_array: - description: Specifies if the parameter should be treated as an array. - type: bool - parameter_name: - description: The name of the parameter. - type: str - provider: - description: Denotes the provider associated with the parameter. - type: str - range: - description: Defines the permissible range for the parameter's value. - type: list - elements: dict - suboptions: - id: - description: Unique identifier for the range, represented as a UUID. - type: str - max_value: - description: Specifies the maximum allowable value for the parameter. - type: int - min_value: - description: Specifies the minimum allowable value for the parameter. - type: int - required: - description: Dictates whether the parameter is mandatory for template operations. - type: bool - selection: - description: Contains options for parameter selection when a choice is available. - suboptions: - default_selected_values: - description: Lists the default values that are preselected. - elements: str - type: list - id: - description: A unique identifier for the selection entity, represented as a UUID. - type: str - selection_type: - description: Specifies the type of selection, such as 'SINGLE_SELECT' or 'MULTI_SELECT'. - type: str - selection_values: - description: A dictionary of available values for selection. - type: dict - type: dict tags: description: A list of dictionaries representing tags associated with the Configuration Template during creation. suboptions: @@ -853,93 +598,6 @@ project_description: description: Narrative that elaborates on the purpose and scope of the project. type: str - rollback_template_content: - description: Refers to the process of reverting the content of a template back to a previous version or state. - type: str - rollback_template_params: - description: A list of dictionaries defining parameters necessary for the rollback functionality of a template. - suboptions: - binding: - description: Associates the parameter with its source. - type: str - custom_order: - description: Specifies a user-defined ordering for the parameter. - type: int - data_type: - description: Identifies the data type of the parameter (e.g., string, integer, boolean). - type: str - default_value: - description: Establishes a default value for the parameter, used if no other value is provided. - type: str - description: - description: Provides a descriptive explanation of the parameter's purpose. - type: str - display_name: - description: The name of the parameter as displayed to users. - type: str - group: - description: Categorizes the parameter into a named group for organizational purposes. - type: str - id: - description: A unique identifier for the parameter, formatted as a UUID. - type: str - instruction_text: - description: Gives guidance or instructions regarding the parameter's use. - type: str - key: - description: A unique key that identifies the parameter within the template. - type: str - not_param: - description: Indicates whether the entry is not to be treated as a parameter. - type: bool - order: - description: Determines the sequence in which the parameter appears relative to others. - type: int - param_array: - description: Specifies if the parameter should be treated as an array. - type: bool - parameter_name: - description: The name of the parameter. - type: str - provider: - description: Denotes the provider associated with the parameter. - type: str - range: - description: Defines the permissible range for the parameter's value. - suboptions: - id: - description: Unique identifier for the range, represented as a UUID. - type: str - max_value: - description: Specifies the maximum allowable value for the parameter. - type: int - min_value: - description: Specifies the minimum allowable value for the parameter. - type: int - type: list - elements: dict - required: - description: Dictates whether the parameter is mandatory for template operations. - type: bool - selection: - description: Contains options for parameter selection when a choice is available. - suboptions: - default_selected_values: - description: Lists the default values that are preselected. - elements: str - type: list - id: - description: A unique identifier for the selection entity, represented as a UUID. - type: str - selection_type: - description: Specifies the type of selection, such as 'SINGLE_SELECT' or 'MULTI_SELECT'. - type: str - selection_values: - description: A dictionary of available values for selection. - type: dict - type: dict - type: list - elements: dict software_type: description: Applicable device software type. This field is mandatory to create a new template. type: str @@ -1108,7 +766,6 @@ name: string project_name: string project_description: string - rollback_template_content: string software_type: string software_variant: string software_version: string @@ -1344,8 +1001,6 @@ def validate_input(self): 'name': {'type': 'str'}, 'project_name': {'type': 'str'}, 'project_description': {'type': 'str'}, - 'rollback_template_content': {'type': 'str'}, - 'rollback_template_params': {'type': 'list'}, 'software_type': {'type': 'str'}, 'software_variant': {'type': 'str'}, 'software_version': {'type': 'str'}, @@ -1394,8 +1049,6 @@ def validate_input(self): 'name': {'type': 'str'}, 'project_name': {'type': 'str'}, 'project_description': {'type': 'str'}, - 'rollback_template_content': {'type': 'str'}, - 'rollback_template_params': {'type': 'list'}, 'software_type': {'type': 'str'}, 'software_variant': {'type': 'str'}, 'software_version': {'type': 'str'}, @@ -1761,13 +1414,6 @@ def get_containing_templates(self, containing_templates): return self.check_return_status() containingTemplates[i].update({"projectName": project_name}) - - rollback_template_params = item.get("rollback_template_params") - if rollback_template_params is not None: - containingTemplates[i].update({ - "rollbackTemplateParams": self.get_template_info(rollback_template_params) - }) - template_content = item.get("template_content") if template_content is not None: containingTemplates[i].update({"templateContent": template_content}) @@ -1809,9 +1455,6 @@ def get_template_params(self, params): "deviceTypes": self.get_device_types(params.get("device_types")), "id": params.get("id"), - "rollbackTemplateContent": params.get("rollback_template_content"), - "rollbackTemplateParams": - self.get_template_info(params.get("rollback_template_params")), "softwareVariant": params.get("software_variant"), "softwareVersion": params.get("software_version"), "templateContent": params.get("template_content"), @@ -2188,8 +1831,6 @@ def requires_update(self): ("language", "language", "VELOCITY"), ("name", "name", ""), ("projectName", "projectName", ""), - ("rollbackTemplateContent", "rollbackTemplateContent", ""), - ("rollbackTemplateParams", "rollbackTemplateParams", []), ("softwareType", "softwareType", ""), ("softwareVariant", "softwareVariant", ""), ("softwareVersion", "softwareVersion", ""), From 0cac68ebb27711e40b5d5e868546c9120298dfa4 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Fri, 10 May 2024 11:18:50 +0530 Subject: [PATCH 347/358] Added the removed variables in the changelogs.yaml --- changelogs/changelog.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 34cfd881e9..ea7583d49b 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -880,3 +880,4 @@ releases: - site_workflow_manager - Updated changes in Site updation. - network_settings_workflow_manager - Added attributes 'ipv4_global_pool_name'. - template_workflow_manager - Removed attributes 'create_time', 'failure_policy', 'last_update_time', 'latest_version_time', 'parent_template_id', 'project_id', 'validation_errors'. + - template_workflow_manager - Removed attributes 'rollback_template_params', 'rollback_template_content'. \ No newline at end of file From c3521a120b752b1d6ba33ad4158484fa3aae5964 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Fri, 10 May 2024 11:27:06 +0530 Subject: [PATCH 348/358] Addressed the review comments --- changelogs/changelog.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index ea7583d49b..e033891697 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -879,5 +879,4 @@ releases: - provision_workflow_manager - Updated changes related to handle errors. - site_workflow_manager - Updated changes in Site updation. - network_settings_workflow_manager - Added attributes 'ipv4_global_pool_name'. - - template_workflow_manager - Removed attributes 'create_time', 'failure_policy', 'last_update_time', 'latest_version_time', 'parent_template_id', 'project_id', 'validation_errors'. - - template_workflow_manager - Removed attributes 'rollback_template_params', 'rollback_template_content'. \ No newline at end of file + - template_workflow_manager - Removed attributes 'create_time', 'failure_policy', 'last_update_time', 'latest_version_time', 'parent_template_id', 'project_id', 'validation_errors', 'rollback_template_params' and 'rollback_template_content'. \ No newline at end of file From 8d00176f266b21720a56a6b4f3a8979d0e81f682 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Fri, 10 May 2024 16:33:07 +0530 Subject: [PATCH 349/358] Fix the issue of validating Server_address of Syslog destination, update description, port validation in syslog, webhook headers update --- ...ents_and_notifications_workflow_manager.py | 96 ++++++++----------- 1 file changed, 39 insertions(+), 57 deletions(-) diff --git a/plugins/modules/events_and_notifications_workflow_manager.py b/plugins/modules/events_and_notifications_workflow_manager.py index de5d9e47b5..0ca498bbbc 100644 --- a/plugins/modules/events_and_notifications_workflow_manager.py +++ b/plugins/modules/events_and_notifications_workflow_manager.py @@ -184,7 +184,7 @@ type: str required: True server_address: - description: Port number that the syslog server listens on, which must fall within the range of 1 to 65535. + description: Hostname or IP address of the Syslog server. type: str required: True protocol: @@ -301,6 +301,8 @@ - python >= 3.5 notes: + - Configuring webhook destination with headers start supporting from dnacentersdk 2.9.1 onwards as we are aligned with CatC Release 2.3.7.5. + - Configuring Syslog destination start supporting from dnacentersdk 2.9.x onwards as we are aligned with CatC Release 2.3.7.5. - SDK Method used are events.Events.get_syslog_destination, events.Events.create_syslog_destination, @@ -602,8 +604,7 @@ def validate_input(self): 'method': {'type': 'str', 'default': 'POST'}, 'trust_cert': {'type': 'bool', 'default': False}, 'headers': { - 'type': 'list', - 'elements': 'dict', + 'type': 'dict', 'name': {'type': 'str'}, 'value': {'type': 'str'}, 'default_value': {'type': 'str'}, @@ -896,6 +897,12 @@ def add_syslog_destination(self, syslog_details): server_address = syslog_details.get('server_address') protocol = syslog_details.get('protocol') + if not self.is_valid_ipv4(server_address): + self.status = "failed" + self.msg = "Invalid server adderess '{0}' given in the playbook for configuring syslog destination".format(server_address) + self.log(self.msg, "ERROR") + return self + if not protocol: self.status = "failed" self.msg = "Protocol is needed while configuring the syslog destionation with name '{0}' in Cisco Catalyst Center".format(name) @@ -987,6 +994,13 @@ def update_syslog_destination(self, syslog_details, syslog_details_in_ccc): self.log(self.msg, "ERROR") return self + server_address = update_syslog_params.get('host') + if not self.is_valid_ipv4(server_address): + self.status = "failed" + self.msg = "Invalid server adderess '{0}' given in the playbook for updating syslog destination".format(server_address) + self.log(self.msg, "ERROR") + return self + response = self.dnac._exec( family="event_management", function='update_syslog_destination', @@ -1073,6 +1087,13 @@ def collect_snmp_playbook_params(self, snmp_details): 'port': snmp_details.get('port'), 'snmpVersion': snmp_details.get('snmp_version') } + server_address = snmp_details.get('server_address') + + if server_address and not self.is_valid_ipv4(server_address): + self.status = "failed" + self.msg = "Invalid server adderess '{0}' given in the playbook for configuring SNMP destination".format(server_address) + self.log(self.msg, "ERROR") + return self if playbook_params.get('snmpVersion') == "V2C": playbook_params['community'] = snmp_details.get('community') @@ -1369,16 +1390,8 @@ def collect_webhook_playbook_params(self, webhook_details): } if webhook_details.get('headers'): - headers_list = webhook_details['headers'] - playbook_params['headers'] = [] - for headers in headers_list: - temp_dict = { - 'name': headers.get('name'), - 'value': headers.get('value'), - 'defaultValue': headers.get('default_value'), - 'encrypt': headers.get('encrypt') - } - playbook_params['headers'].append(temp_dict) + custom_header = webhook_details['headers'] + playbook_params['customHeaders'] = custom_header return playbook_params @@ -1400,6 +1413,7 @@ def add_webhook_destination(self, webhook_params): """ try: + self.log("Requested payload for creating webhook destination - {0}".format(str(webhook_params)), "INFO") response = self.dnac._exec( family="event_management", function='create_webhook_destination', @@ -1460,35 +1474,6 @@ def webhook_dest_needs_update(self, webhook_params, webhook_dest_detail_in_ccc): return update_needed - def remove_duplicates(self, headers_in_ccc): - """ - Remove duplicate headers from a list of header dictionaries. - Args: - self (object): An instance of a class used for interacting with Cisco Catalyst Center. - headers_in_ccc (list): A list of dictionaries representing headers. - Returns: - list: A list of dictionaries with duplicate headers removed. - Description: - This function takes a list of header dictionaries (`headers_in_ccc`) as input and removes duplicate headers from it. - It iterates through each dictionary in the list and converts it to a tuple of its items. This tuple representation - is used to check if a similar tuple has been seen before. If not, the dictionary is added to the list of unique_dicts. - Finally, it returns the list of dictionaries with duplicate headers removed. - """ - - seen_set = set() - unique_dicts = [] - - for header_dict in headers_in_ccc: - # Convert the dictionary to a tuple of its items - dict_tuple = tuple(sorted(header_dict.items())) - - # Check if the tuple representation of the dictionary has been seen before - if dict_tuple not in seen_set: - seen_set.add(dict_tuple) - unique_dicts.append(header_dict) - - return unique_dicts - def update_webhook_destination(self, webhook_params, webhook_dest_detail_in_ccc): """ Update a webhook destination in Cisco Catalyst Center with the provided details. @@ -1515,22 +1500,13 @@ def update_webhook_destination(self, webhook_params, webhook_dest_detail_in_ccc) update_webhook_params['method'] = webhook_params.get('method') or webhook_dest_detail_in_ccc.get('method') update_webhook_params['trustCert'] = webhook_params.get('trustCert') or webhook_dest_detail_in_ccc.get('trustCert') update_webhook_params['isProxyRoute'] = webhook_params.get('isProxyRoute') or webhook_dest_detail_in_ccc.get('isProxyRoute') - playbook_headers = webhook_params.get('headers') - headers_in_ccc = webhook_dest_detail_in_ccc.get('headers') - - final_headers_list = [] - if playbook_headers: - if headers_in_ccc: - headers_in_ccc.extend(playbook_headers) - final_headers_list = self.remove_duplicates(headers_in_ccc) - else: - final_headers_list.extend(playbook_headers) + update_webhook_params['headers'] = webhook_params.get('headers') - if not final_headers_list: - final_headers_list = None + if not update_webhook_params['headers'] and webhook_dest_detail_in_ccc.get('headers'): + update_webhook_params['headers'] = webhook_dest_detail_in_ccc.get('headers')[0] - update_webhook_params['headers'] = final_headers_list update_webhook_params['webhookId'] = webhook_dest_detail_in_ccc.get('webhookId') + name = update_webhook_params.get('name') response = self.dnac._exec( family="event_management", @@ -1539,7 +1515,6 @@ def update_webhook_destination(self, webhook_params, webhook_dest_detail_in_ccc) params=update_webhook_params ) self.log("Received API response from 'update_webhook_destination': {0}".format(str(response)), "DEBUG") - name = update_webhook_params.get('name') status = response.get('apiStatus') if status == 'SUCCESS': @@ -2304,7 +2279,14 @@ def get_diff_merged(self, config): self.log(self.msg, "ERROR") return self - if not port.isdigit() or (isinstance(port, int) and port not in range(1, 65536)): + if isinstance(port, str): + if not port.isdigit() or (int(port) not in range(1, 65536)): + self.status = "failed" + self.msg = "Invalid Syslog destination port '{0}' given in playbook. Select port from the number range(1, 65535)".format(port) + self.log(self.msg, "ERROR") + return self + + if isinstance(port, int) and (int(port) not in range(1, 65536)): self.status = "failed" self.msg = "Invalid Syslog destination port '{0}' given in playbook. Select port from the number range(1, 65535)".format(port) self.log(self.msg, "ERROR") From 0f235c500eaebf9fb90f9ac693cb0f94a2cf9105 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Fri, 10 May 2024 17:55:07 +0530 Subject: [PATCH 350/358] updated review comments --- .../events_and_notifications_workflow_manager.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/modules/events_and_notifications_workflow_manager.py b/plugins/modules/events_and_notifications_workflow_manager.py index 0ca498bbbc..7d64e4b9c9 100644 --- a/plugins/modules/events_and_notifications_workflow_manager.py +++ b/plugins/modules/events_and_notifications_workflow_manager.py @@ -301,8 +301,10 @@ - python >= 3.5 notes: - - Configuring webhook destination with headers start supporting from dnacentersdk 2.9.1 onwards as we are aligned with CatC Release 2.3.7.5. - - Configuring Syslog destination start supporting from dnacentersdk 2.9.x onwards as we are aligned with CatC Release 2.3.7.5. + - Configuring the webhook destination with headers now supports starting from dnacentersdk version 2.9.1 onwards. This enhancement is in + alignment with Catalyst Center Release 2.3.7.5. + - Configuring the SNMP destination now supports starting from dnacentersdk version 2.9.1 onwards. This enhancement is in + alignment with Catalyst Center Release 2.3.7.5. - SDK Method used are events.Events.get_syslog_destination, events.Events.create_syslog_destination, @@ -2282,13 +2284,14 @@ def get_diff_merged(self, config): if isinstance(port, str): if not port.isdigit() or (int(port) not in range(1, 65536)): self.status = "failed" - self.msg = "Invalid Syslog destination port '{0}' given in playbook. Select port from the number range(1, 65535)".format(port) + self.msg = """Invalid Syslog destination port '{0}' given in playbook. Please choose a port within the range of + numbers (1, 65535)""".format(port) self.log(self.msg, "ERROR") return self if isinstance(port, int) and (int(port) not in range(1, 65536)): self.status = "failed" - self.msg = "Invalid Syslog destination port '{0}' given in playbook. Select port from the number range(1, 65535)".format(port) + self.msg = "Invalid Syslog destination port '{0}' given in playbook. Please choose a port within the range of numbers (1, 65535)".format(port) self.log(self.msg, "ERROR") return self From 930e54f0442fa89de0641bf5fc65e408fda99f73 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Mon, 13 May 2024 12:21:52 +0530 Subject: [PATCH 351/358] Fixed the issue of valdiating snmp server address, validating url in ITSM, fixed secondary smtp server while configuring email destination with proper log message for attached port number with smtp type --- ...ents_and_notifications_workflow_manager.py | 97 ++++++++++++------- 1 file changed, 63 insertions(+), 34 deletions(-) diff --git a/plugins/modules/events_and_notifications_workflow_manager.py b/plugins/modules/events_and_notifications_workflow_manager.py index 7d64e4b9c9..6a27300b5c 100644 --- a/plugins/modules/events_and_notifications_workflow_manager.py +++ b/plugins/modules/events_and_notifications_workflow_manager.py @@ -619,16 +619,16 @@ def validate_input(self): 'primary_smtp_config': { 'type': 'dict', 'server_address': {'type': 'str'}, - 'port': {'type': 'str', 'default': '25'}, 'smtp_type': {'type': 'str', 'default': 'DEFAULT'}, + 'port': {'type': 'str', 'default': '25'}, 'username': {'type': 'str'}, 'password': {'type': 'str'}, }, 'secondary_smtp_config': { 'type': 'dict', 'server_address': {'type': 'str'}, - 'port': {'type': 'str'}, 'smtp_type': {'type': 'str'}, + 'port': {'type': 'str'}, 'username': {'type': 'str'}, 'password': {'type': 'str'}, }, @@ -951,8 +951,9 @@ def add_syslog_destination(self, syslog_details): except Exception as e: failure_msg = "Unable to Add syslog destination with name '{0}' in Cisco Catalyst Center".format(name) - self.log(failure_msg, "ERROR") - self.result['response'] = failure_msg + self.msg = failure_msg + self.log(self.msg, "ERROR") + self.result['response'] = self.msg except Exception as e: self.status = "failed" @@ -1026,8 +1027,9 @@ def update_syslog_destination(self, syslog_details, syslog_details_in_ccc): except Exception as e: failure_msg = "Unable to update syslog destination with name '{0}' in Cisco Catalyst Center".format(name) - self.log(failure_msg, "ERROR") - self.result['response'] = failure_msg + self.msg = failure_msg + self.log(self.msg, "ERROR") + self.result['response'] = self.msg except Exception as e: self.status = "failed" @@ -1095,7 +1097,7 @@ def collect_snmp_playbook_params(self, snmp_details): self.status = "failed" self.msg = "Invalid server adderess '{0}' given in the playbook for configuring SNMP destination".format(server_address) self.log(self.msg, "ERROR") - return self + self.check_return_status() if playbook_params.get('snmpVersion') == "V2C": playbook_params['community'] = snmp_details.get('community') @@ -1205,8 +1207,9 @@ def add_snmp_destination(self, snmp_params): else: failure_msg = "Unable to Add SNMP destination with name '{0}' in Cisco Catalyst Center".format(snmp_params.get('name')) - self.log(failure_msg, "ERROR") - self.result['response'] = failure_msg + self.msg = failure_msg + self.log(self.msg, "ERROR") + self.result['response'] = self.msg return self @@ -1326,8 +1329,9 @@ def update_snmp_destination(self, snmp_params, snmp_dest_detail_in_ccc): else: failure_msg = "Unable to update SNMP destination with name '{0}' in Cisco Catalyst Center".format(update_snmp_params.get('name')) - self.log(failure_msg, "ERROR") - self.result['response'] = failure_msg + self.msg = failure_msg + self.log(self.msg, "ERROR") + self.result['response'] = self.msg except Exception as e: self.status = "failed" @@ -1440,8 +1444,9 @@ def add_webhook_destination(self, webhook_params): else: failure_msg = "Unable to Add Webhook destination with name '{0}' in Cisco Catalyst Center".format(webhook_params.get('name')) - self.log(failure_msg, "ERROR") - self.result['response'] = failure_msg + self.msg = failure_msg + self.log(self.msg, "ERROR") + self.result['response'] = self.msg except Exception as e: self.status = "failed" @@ -1535,8 +1540,9 @@ def update_webhook_destination(self, webhook_params, webhook_dest_detail_in_ccc) else: failure_msg = "Unable to update rest webhook destination with name '{0}' in Cisco Catalyst Center".format(name) - self.log(failure_msg, "ERROR") - self.result['response'] = failure_msg + self.msg = failure_msg + self.log(self.msg, "ERROR") + self.result['response'] = self.msg except Exception as e: self.status = "failed" @@ -1611,7 +1617,7 @@ def collect_email_playbook_params(self, email_details): playbook_params['primarySMTPConfig']['userName'] = primary_smtp_details.get('username', '') playbook_params['primarySMTPConfig']['password'] = primary_smtp_details.get('password', '') - if email_details.get('seconday_smtp_config'): + if email_details.get('secondary_smtp_config'): secondary_smtp_details = email_details.get('secondary_smtp_config') playbook_params['secondarySMTPConfig'] = {} playbook_params['secondarySMTPConfig']['hostName'] = secondary_smtp_details.get('server_address') @@ -1679,8 +1685,9 @@ def add_email_destination(self, email_params): else: failure_msg = "Unable to Add Email destination in Cisco Catalyst Center." - self.log(failure_msg, "ERROR") - self.result['response'] = failure_msg + self.msg = failure_msg + self.log(self.msg, "ERROR") + self.result['response'] = self.msg except Exception as e: self.status = "failed" @@ -1708,12 +1715,18 @@ def email_dest_needs_update(self, email_params, email_dest_detail_in_ccc): update_needed = False for key, value in email_params.items(): + + if not email_dest_detail_in_ccc.get(key): + update_needed = True + return update_needed + if isinstance(value, dict): self.email_dest_needs_update(value, email_dest_detail_in_ccc[key]) - elif email_dest_detail_in_ccc[key] == value or value == "": + elif email_dest_detail_in_ccc.get(key) == value or value == "": continue else: update_needed = True + return update_needed return update_needed @@ -1773,15 +1786,16 @@ def update_email_destination(self, email_details, email_dest_detail_in_ccc): return self self.status = "failed" - error_messages = response.get('errorMessage') + error_messages = status_response.get('errorMessage') if error_messages: failure_msg = error_messages.get('errors') else: failure_msg = "Unable to update Email destination in Cisco Catalyst Center." - self.log(failure_msg, "ERROR") - self.result['response'] = failure_msg + self.msg = failure_msg + self.log(self.msg, "ERROR") + self.result['response'] = self.msg except Exception as e: self.status = "failed" @@ -1958,8 +1972,9 @@ def create_itsm_integration_setting(self, itsm_params): if not failure_msg: failure_msg = "Unable to create ITSM Integration Settings with name '{0}' in Cisco Catalyst Center".format(instance_name) - self.log(failure_msg, "ERROR") - self.result['response'] = failure_msg + self.msg = failure_msg + self.log(self.msg, "ERROR") + self.result['response'] = self.msg except Exception as e: self.status = "failed" @@ -2095,8 +2110,9 @@ def update_itsm_integration_setting(self, itsm_params, itsm_in_ccc): if not failure_msg: failure_msg = "Unable to update ITSM Integration Settings with name '{0}' in Cisco Catalyst Center".format(update_itsm_params.get('name')) - self.log(failure_msg, "ERROR") - self.result['response'] = failure_msg + self.msg = failure_msg + self.log(self.msg, "ERROR") + self.result['response'] = self.msg except Exception as e: self.status = "failed" @@ -2316,20 +2332,21 @@ def get_diff_merged(self, config): if config.get('snmp_destination'): snmp_details = self.want.get('snmp_details') destination_name = snmp_details.get('name') + if not destination_name: self.status = "failed" self.msg = "Name is required parameter for adding/updating SNMP destination for creating/updating the event." self.log(self.msg, "ERROR") return self - is_destination_exist = False + for snmp_dict in self.have.get('snmp_destinations'): if snmp_dict['name'] == destination_name: snmp_dest_detail_in_ccc = snmp_dict is_destination_exist = True break - snmp_params = self.collect_snmp_playbook_params(snmp_details) + if snmp_params.get('port'): try: port = int(snmp_params.get('port')) @@ -2390,17 +2407,22 @@ def get_diff_merged(self, config): # Need to Add snmp destination in Cisco Catalyst Center with given playbook params invalid_itsm_params = [] invalid_itsm_params = self.check_required_itsm_param(itsm_params, invalid_itsm_params) + connection_setting = itsm_params.get('data').get('ConnectionSettings') - # Check whether the url is valid or not - url = itsm_params.get('data').get('ConnectionSettings').get('Url') - regex_pattern = r'https://\S+' - - if not re.match(regex_pattern, url): + if not connection_setting: + invalid_itsm_params.extends(["url", "username", "password"]) self.status = "failed" - self.msg = "Given url '{0}' is invalid url for ITSM Intergartion setting. It must starts with 'https://'".format(url) + self.msg = """Required parameter '{0}' for configuring ITSM Intergartion setting in Cisco Catalyst + Center is missing.""".format(str(invalid_itsm_params)) self.log(self.msg, "ERROR") + self.result['response'] = self.msg return self + # Check whether the url exist or not and if exists is it valid + url = connection_setting.get('Url') + if not url and "Url" not in invalid_itsm_params: + invalid_itsm_params.append("URL") + if invalid_itsm_params: self.status = "failed" self.msg = """Required parameter '{0}' for configuring ITSM Intergartion setting in Cisco Catalyst @@ -2409,6 +2431,13 @@ def get_diff_merged(self, config): self.result['response'] = self.msg return self + regex_pattern = r'https://\S+' + if not re.match(regex_pattern, url): + self.status = "failed" + self.msg = "Given url '{0}' is invalid url for ITSM Intergartion setting. It must starts with 'https://'".format(url) + self.log(self.msg, "ERROR") + return self + self.log("Required parameter validated successfully for configuring ITSM Intergartion setting in Cisco Catalyst Center.", "INFO") self.create_itsm_integration_setting(itsm_params).check_return_status() else: From 845da185cc0d5f31cfa6946602fddf5995c7e5e9 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Mon, 13 May 2024 15:52:42 +0530 Subject: [PATCH 352/358] address review comments --- ...vents_and_notifications_workflow_manager.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/plugins/modules/events_and_notifications_workflow_manager.py b/plugins/modules/events_and_notifications_workflow_manager.py index 6a27300b5c..332c814fcb 100644 --- a/plugins/modules/events_and_notifications_workflow_manager.py +++ b/plugins/modules/events_and_notifications_workflow_manager.py @@ -569,6 +569,7 @@ validate_list_of_dicts, ) import re +import time class Events(DnacBase): @@ -1715,18 +1716,18 @@ def email_dest_needs_update(self, email_params, email_dest_detail_in_ccc): update_needed = False for key, value in email_params.items(): - if not email_dest_detail_in_ccc.get(key): update_needed = True - return update_needed + break if isinstance(value, dict): - self.email_dest_needs_update(value, email_dest_detail_in_ccc[key]) - elif email_dest_detail_in_ccc.get(key) == value or value == "": - continue - else: + # Recursive call should impact the update_needed flag + update_needed = self.email_dest_needs_update(value, email_dest_detail_in_ccc[key]) + if update_needed: + break + elif email_dest_detail_in_ccc.get(key) != value and value != "": update_needed = True - return update_needed + break return update_needed @@ -1765,6 +1766,7 @@ def update_email_destination(self, email_details, email_dest_detail_in_ccc): params=update_email_params ) self.log("Received API response from 'update_email_destination': {0}".format(str(response)), "DEBUG") + time.sleep(2) status = response.get('statusUri') status_execution_id = status.split("/")[-1] @@ -2076,7 +2078,7 @@ def update_itsm_integration_setting(self, itsm_params, itsm_in_ccc): if not re.match(regex_pattern, url): self.status = "failed" - self.msg = "Given url '{0}' is invalid url for ITSM Intergartion setting. It must starts with 'https://'".format(url) + self.msg = "Given url '{0}' is invalid url for ITSM Intergartion setting. It must start with 'https://'".format(url) self.log(self.msg, "ERROR") return self From 34d59ea3e145b9e24f7f08b452b1ec2ee6aecd6f Mon Sep 17 00:00:00 2001 From: jose ocampo Date: Thu, 30 May 2024 14:16:55 -0600 Subject: [PATCH 353/358] update 2.3.7.6 version --- README.md | 8 ++++---- changelogs/changelog.yaml | 2 +- playbooks/credentials.template | 2 +- plugins/action/site_assign_device.py | 2 +- plugins/doc_fragments/module.py | 2 +- plugins/doc_fragments/module_info.py | 2 +- plugins/plugin_utils/dnac.py | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4d2835f33d..599503c6ca 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The dnacenter-ansible project provides an Ansible collection for managing and automating your Cisco DNA Center environment. It consists of a set of modules and roles for performing tasks related to DNA Center. -This collection has been tested and supports Cisco DNA Center 2.3.5.3. +This collection has been tested and supports Cisco DNA Center 2.3.7.6. *Note: This collection is not compatible with versions of Ansible before v2.8.* @@ -15,11 +15,11 @@ The following table shows the supported versions. | Cisco DNA Center version | Ansible "cisco.dnac" version | Python "dnacentersdk" version | |--------------------------|------------------------------|-------------------------------| -| 2.1.1 | 3.0.0 | 2.2.5 | | 2.2.2.3 | 3.3.1 | 2.3.3 | | 2.2.3.3 | 6.4.0 | 2.4.11 | | 2.3.3.0 | 6.6.4 | 2.5.5 | | 2.3.5.3 | ^6.13.0 | ^2.6.0 | +| 2.3.7.6 | ^6.14.0 | ^2.7.0 | If your Ansible collection is older please consider updating it first. @@ -76,7 +76,7 @@ export DNAC_HOST= export DNAC_PORT=443 # optional, defaults to 443 export DNAC_USERNAME= export DNAC_PASSWORD= -export DNAC_VERSION=2.3.5.3 # optional, defaults to 2.3.5.3. See the Compatibility matrix +export DNAC_VERSION=2.3.7.6 # optional, defaults to 2.3.7.6. See the Compatibility matrix export DNAC_VERIFY=False # optional, defaults to True export DNAC_DEBUG=False # optional, defaults to False ``` @@ -114,7 +114,7 @@ dnac_host: dnac_port: 443 # optional, defaults to 443 dnac_username: dnac_password: -dnac_version: 2.3.5.3 # optional, defaults to 2.3.5.3. See the Compatibility matrix +dnac_version: 2.3.7.6 # optional, defaults to 2.3.7.6. See the Compatibility matrix dnac_verify: False # optional, defaults to True dnac_debug: False # optional, defaults to False ``` diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index bc40e8d7bf..02d1d825df 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -869,7 +869,7 @@ releases: 6.14.0 release_date: "2024-04-25" changes: - release_summary: New Dna Center API version 2.3.7.5. + release_summary: New Dna Center API version 2.3.7.6. minor_changes: - application_policy_application_set_count_info - new module - application_policy_application_set_info - new module diff --git a/playbooks/credentials.template b/playbooks/credentials.template index 5270c08164..4e2878d254 100644 --- a/playbooks/credentials.template +++ b/playbooks/credentials.template @@ -3,7 +3,7 @@ dnac_host: dnac_port: 443 dnac_username: dnac_password: -dnac_version: 2.3.5.3 +dnac_version: 2.3.7.6 dnac_verify: False dnac_debug: False dnac_log_level: [CRITICAL, ERROR, WARNING, INFO, DEBUG] diff --git a/plugins/action/site_assign_device.py b/plugins/action/site_assign_device.py index dec7df437c..d905f21e7d 100644 --- a/plugins/action/site_assign_device.py +++ b/plugins/action/site_assign_device.py @@ -78,7 +78,7 @@ def run(self, tmp=None, task_vars=None): Display().warning("This module is currently unmaintained " "and will be removed in future releases." "New module is assign_device_to_site " - "for 2.3.5.3 or higher") + "for 2.3.7.6 or higher") dnac = DNACSDK(params=self._task.args) diff --git a/plugins/doc_fragments/module.py b/plugins/doc_fragments/module.py index 6c92fb75fc..01286a6227 100644 --- a/plugins/doc_fragments/module.py +++ b/plugins/doc_fragments/module.py @@ -43,7 +43,7 @@ class ModuleDocFragment(object): description: - Informs the SDK which version of Cisco DNA Center to use. type: str - default: 2.3.5.3 + default: 2.3.7.6 dnac_debug: description: - Flag for Cisco DNA Center SDK to enable debugging. diff --git a/plugins/doc_fragments/module_info.py b/plugins/doc_fragments/module_info.py index 7ac68f449e..507ef06082 100644 --- a/plugins/doc_fragments/module_info.py +++ b/plugins/doc_fragments/module_info.py @@ -43,7 +43,7 @@ class ModuleDocFragment(object): description: - Informs the SDK which version of Cisco DNA Center to use. type: str - default: 2.3.5.3 + default: 2.3.7.6 dnac_debug: description: - Flag for Cisco DNA Center SDK to enable debugging. diff --git a/plugins/plugin_utils/dnac.py b/plugins/plugin_utils/dnac.py index 7448c4c508..514106e2f1 100644 --- a/plugins/plugin_utils/dnac.py +++ b/plugins/plugin_utils/dnac.py @@ -140,7 +140,7 @@ def dnac_argument_spec(): dnac_username=dict(type="str", fallback=(env_fallback, ['DNAC_USERNAME']), default="admin", aliases=["user"]), dnac_password=dict(type="str", fallback=(env_fallback, ['DNAC_PASSWORD']), no_log=True), dnac_verify=dict(type="bool", fallback=(env_fallback, ['DNAC_VERIFY']), default=True), - dnac_version=dict(type="str", fallback=(env_fallback, ['DNAC_VERSION']), default="2.3.5.3"), + dnac_version=dict(type="str", fallback=(env_fallback, ['DNAC_VERSION']), default="2.3.7.6"), dnac_debug=dict(type="bool", fallback=(env_fallback, ['DNAC_DEBUG']), default=False), validate_response_schema=dict(type="bool", fallback=(env_fallback, ['VALIDATE_RESPONSE_SCHEMA']), default=True), ) From d2b7d0728ad50abc538ec58f54165bbfa936f874 Mon Sep 17 00:00:00 2001 From: jose ocampo Date: Fri, 31 May 2024 08:28:13 -0600 Subject: [PATCH 354/358] update 2.3.7.6 version --- Pipfile | 2 +- README.md | 6 +++--- plugins/modules/device_credential_intent.py | 2 +- plugins/modules/device_credential_workflow_manager.py | 2 +- .../modules/disasterrecovery_system_operationstatus_info.py | 2 +- plugins/modules/disasterrecovery_system_status_info.py | 2 +- plugins/modules/endpoint_analytics_profiling_rules.py | 2 +- plugins/modules/endpoint_analytics_profiling_rules_info.py | 2 +- plugins/modules/inventory_intent.py | 2 +- plugins/modules/inventory_workflow_manager.py | 2 +- plugins/modules/network_device_with_snmp_v3_des_info.py | 2 +- plugins/modules/network_update.py | 2 +- plugins/modules/network_v2.py | 2 +- plugins/modules/network_v2_info.py | 2 +- plugins/modules/nfv_profile.py | 2 +- plugins/modules/nfv_profile_info.py | 2 +- plugins/modules/nfv_provision.py | 2 +- plugins/modules/nfv_provision_detail_info.py | 2 +- plugins/modules/nfv_provision_details.py | 2 +- plugins/modules/profiling_rules_count_info.py | 2 +- plugins/modules/profiling_rules_in_bulk_create.py | 2 +- plugins/modules/sda_count_info.py | 2 +- plugins/modules/sda_fabric.py | 2 +- plugins/modules/sda_fabric_info.py | 2 +- plugins/modules/site_assign_device.py | 2 +- plugins/modules/site_design_floormap.py | 2 +- plugins/modules/site_design_floormap_info.py | 2 +- plugins/modules/syslog_config_create.py | 2 +- plugins/modules/syslog_config_update.py | 2 +- plugins/modules/threat_detail.py | 2 +- plugins/modules/threat_detail_count.py | 2 +- plugins/modules/threat_summary.py | 2 +- requirements.txt | 2 +- 33 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Pipfile b/Pipfile index b53ecf4600..fbe2bde8da 100644 --- a/Pipfile +++ b/Pipfile @@ -4,7 +4,7 @@ verify_ssl = true name = "pypi" [packages] -dnacentersdk = ">=2.6.0" +dnacentersdk = ">=2.7.0" [dev-packages] diff --git a/README.md b/README.md index 599503c6ca..7b988ff817 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ The following table shows the supported versions. | 2.2.2.3 | 3.3.1 | 2.3.3 | | 2.2.3.3 | 6.4.0 | 2.4.11 | | 2.3.3.0 | 6.6.4 | 2.5.5 | -| 2.3.5.3 | ^6.13.0 | ^2.6.0 | -| 2.3.7.6 | ^6.14.0 | ^2.7.0 | +| 2.3.5.3 | 6.13.3 | 2.6.11 | +| 2.3.7.6 | ^6.14.0 | ^2.7.0 | If your Ansible collection is older please consider updating it first. @@ -45,7 +45,7 @@ ansible-galaxy collection install cisco.dnac:3.3.1 ## Requirements - Ansible >= 2.15 -- [Python DNA Center SDK](https://github.com/cisco-en-programmability/dnacentersdk) v2.6.0 or newer +- [Python DNA Center SDK](https://github.com/cisco-en-programmability/dnacentersdk) v2.7.0 or newer - Python >= 3.9, as the DNA Center SDK doesn't support Python version 2.x ## Install diff --git a/plugins/modules/device_credential_intent.py b/plugins/modules/device_credential_intent.py index 3b887aa8d2..b03039ac7a 100644 --- a/plugins/modules/device_credential_intent.py +++ b/plugins/modules/device_credential_intent.py @@ -298,7 +298,7 @@ description: snmp_v3 Credential Id. Use Description or Id. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Discovery CreateGlobalCredentialsV2 diff --git a/plugins/modules/device_credential_workflow_manager.py b/plugins/modules/device_credential_workflow_manager.py index a6d188de40..b8ea0cc844 100644 --- a/plugins/modules/device_credential_workflow_manager.py +++ b/plugins/modules/device_credential_workflow_manager.py @@ -298,7 +298,7 @@ description: snmp_v3 Credential Id. Use Description or Id. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco Catalyst Center documentation for Discovery CreateGlobalCredentialsV2 diff --git a/plugins/modules/disasterrecovery_system_operationstatus_info.py b/plugins/modules/disasterrecovery_system_operationstatus_info.py index 1c6621afee..aca22ff589 100644 --- a/plugins/modules/disasterrecovery_system_operationstatus_info.py +++ b/plugins/modules/disasterrecovery_system_operationstatus_info.py @@ -20,7 +20,7 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/disasterrecovery_system_status_info.py b/plugins/modules/disasterrecovery_system_status_info.py index f1c3c318cf..e526e38f9c 100644 --- a/plugins/modules/disasterrecovery_system_status_info.py +++ b/plugins/modules/disasterrecovery_system_status_info.py @@ -20,7 +20,7 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/endpoint_analytics_profiling_rules.py b/plugins/modules/endpoint_analytics_profiling_rules.py index 43633824b2..7a5eda27ff 100644 --- a/plugins/modules/endpoint_analytics_profiling_rules.py +++ b/plugins/modules/endpoint_analytics_profiling_rules.py @@ -114,7 +114,7 @@ elements: str type: list requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/endpoint_analytics_profiling_rules_info.py b/plugins/modules/endpoint_analytics_profiling_rules_info.py index 1e3ca88c2a..f410255e52 100644 --- a/plugins/modules/endpoint_analytics_profiling_rules_info.py +++ b/plugins/modules/endpoint_analytics_profiling_rules_info.py @@ -60,7 +60,7 @@ - RuleId path parameter. Unique rule identifier. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index af25724868..21a2ecb6fc 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -307,7 +307,7 @@ version_added: 6.12.0 requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco Catalyst Center documentation for Devices AddDevice2 diff --git a/plugins/modules/inventory_workflow_manager.py b/plugins/modules/inventory_workflow_manager.py index 17f63f475b..1ee200c8e4 100644 --- a/plugins/modules/inventory_workflow_manager.py +++ b/plugins/modules/inventory_workflow_manager.py @@ -307,7 +307,7 @@ version_added: 6.12.0 requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco Catalyst Center documentation for Devices AddDevice2 diff --git a/plugins/modules/network_device_with_snmp_v3_des_info.py b/plugins/modules/network_device_with_snmp_v3_des_info.py index b3b6a55d68..f2b8cf2291 100644 --- a/plugins/modules/network_device_with_snmp_v3_des_info.py +++ b/plugins/modules/network_device_with_snmp_v3_des_info.py @@ -42,7 +42,7 @@ - Order query parameter. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Devices ReturnsDevicesAddedToCiscoDNACenterWithSnmpV3DES diff --git a/plugins/modules/network_update.py b/plugins/modules/network_update.py index 42b2eec0fd..72aa9ca8e9 100644 --- a/plugins/modules/network_update.py +++ b/plugins/modules/network_update.py @@ -131,7 +131,7 @@ is associated with the site. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Network Settings UpdateNetwork diff --git a/plugins/modules/network_v2.py b/plugins/modules/network_v2.py index faa1b85c9b..d072ac3b36 100644 --- a/plugins/modules/network_v2.py +++ b/plugins/modules/network_v2.py @@ -134,7 +134,7 @@ the network settings. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Network Settings CreateNetworkV2 diff --git a/plugins/modules/network_v2_info.py b/plugins/modules/network_v2_info.py index 096b27bbda..03f53b4255 100644 --- a/plugins/modules/network_v2_info.py +++ b/plugins/modules/network_v2_info.py @@ -24,7 +24,7 @@ - SiteId query parameter. Site Id to get the network settings associated with the site. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Network Settings GetNetworkV2 diff --git a/plugins/modules/nfv_profile.py b/plugins/modules/nfv_profile.py index 37ce591019..ca906313b7 100644 --- a/plugins/modules/nfv_profile.py +++ b/plugins/modules/nfv_profile.py @@ -147,7 +147,7 @@ description: Name of the profile to create NFV profile. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Site Design CreateNFVProfile diff --git a/plugins/modules/nfv_profile_info.py b/plugins/modules/nfv_profile_info.py index 7deb4f7bea..ca3937bafe 100644 --- a/plugins/modules/nfv_profile_info.py +++ b/plugins/modules/nfv_profile_info.py @@ -36,7 +36,7 @@ - Name query parameter. Name of network profile to be retrieved. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Site Design GetNFVProfile diff --git a/plugins/modules/nfv_provision.py b/plugins/modules/nfv_provision.py index e242de7f57..3cf14f8910 100644 --- a/plugins/modules/nfv_provision.py +++ b/plugins/modules/nfv_provision.py @@ -375,7 +375,7 @@ type: str type: list requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Site Design ProvisionNFV diff --git a/plugins/modules/nfv_provision_detail_info.py b/plugins/modules/nfv_provision_detail_info.py index 2a0f85a5a5..31c47f9ed5 100644 --- a/plugins/modules/nfv_provision_detail_info.py +++ b/plugins/modules/nfv_provision_detail_info.py @@ -24,7 +24,7 @@ - DeviceIp query parameter. Device to which the provisioning detail has to be retrieved. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Site Design GetDeviceDetailsByIP diff --git a/plugins/modules/nfv_provision_details.py b/plugins/modules/nfv_provision_details.py index af9792e72d..84d81501c4 100644 --- a/plugins/modules/nfv_provision_details.py +++ b/plugins/modules/nfv_provision_details.py @@ -23,7 +23,7 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Site Design NFVProvisioningDetail diff --git a/plugins/modules/profiling_rules_count_info.py b/plugins/modules/profiling_rules_count_info.py index 461adba262..be066e2b8d 100644 --- a/plugins/modules/profiling_rules_count_info.py +++ b/plugins/modules/profiling_rules_count_info.py @@ -29,7 +29,7 @@ - IncludeDeleted query parameter. Flag to indicate whether deleted rules should be part of the records fetched. type: bool requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/profiling_rules_in_bulk_create.py b/plugins/modules/profiling_rules_in_bulk_create.py index ec2bfc306a..bff3abee05 100644 --- a/plugins/modules/profiling_rules_in_bulk_create.py +++ b/plugins/modules/profiling_rules_in_bulk_create.py @@ -121,7 +121,7 @@ type: list type: list requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/sda_count_info.py b/plugins/modules/sda_count_info.py index d942591c12..458526990b 100644 --- a/plugins/modules/sda_count_info.py +++ b/plugins/modules/sda_count_info.py @@ -20,7 +20,7 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/sda_fabric.py b/plugins/modules/sda_fabric.py index f068b0e1e4..59ff8c7cbb 100644 --- a/plugins/modules/sda_fabric.py +++ b/plugins/modules/sda_fabric.py @@ -21,7 +21,7 @@ description: FabricName query parameter. Fabric Name. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/sda_fabric_info.py b/plugins/modules/sda_fabric_info.py index c44290025c..93858f89ea 100644 --- a/plugins/modules/sda_fabric_info.py +++ b/plugins/modules/sda_fabric_info.py @@ -24,7 +24,7 @@ - FabricName query parameter. Fabric Name. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/site_assign_device.py b/plugins/modules/site_assign_device.py index 1c080cba4d..520cf7c8fd 100644 --- a/plugins/modules/site_assign_device.py +++ b/plugins/modules/site_assign_device.py @@ -28,7 +28,7 @@ description: SiteId path parameter. Site id to which site the device to assign. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/site_design_floormap.py b/plugins/modules/site_design_floormap.py index 0948930f3a..f967b93eaf 100644 --- a/plugins/modules/site_design_floormap.py +++ b/plugins/modules/site_design_floormap.py @@ -24,7 +24,7 @@ description: Site Design Floormap's payload type: dict requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/site_design_floormap_info.py b/plugins/modules/site_design_floormap_info.py index c427e42bb0..e07d5b1d67 100644 --- a/plugins/modules/site_design_floormap_info.py +++ b/plugins/modules/site_design_floormap_info.py @@ -26,7 +26,7 @@ - FloorId path parameter. Group Id of the specified floormap. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/syslog_config_create.py b/plugins/modules/syslog_config_create.py index c4804a3b31..a0f8fd8d1e 100644 --- a/plugins/modules/syslog_config_create.py +++ b/plugins/modules/syslog_config_create.py @@ -35,7 +35,7 @@ description: Protocol. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Event Management CreateSyslogDestination diff --git a/plugins/modules/syslog_config_update.py b/plugins/modules/syslog_config_update.py index 653555ac9f..3c6b6584e0 100644 --- a/plugins/modules/syslog_config_update.py +++ b/plugins/modules/syslog_config_update.py @@ -35,7 +35,7 @@ description: Protocol. type: str requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Event Management UpdateSyslogDestination diff --git a/plugins/modules/threat_detail.py b/plugins/modules/threat_detail.py index 0bcfac62c2..a96372d91d 100644 --- a/plugins/modules/threat_detail.py +++ b/plugins/modules/threat_detail.py @@ -44,7 +44,7 @@ elements: str type: list requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/threat_detail_count.py b/plugins/modules/threat_detail_count.py index 7a21cd1ade..36e5c1ca3f 100644 --- a/plugins/modules/threat_detail_count.py +++ b/plugins/modules/threat_detail_count.py @@ -44,7 +44,7 @@ elements: str type: list requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/threat_summary.py b/plugins/modules/threat_summary.py index 635b0c43c0..7db0d32f01 100644 --- a/plugins/modules/threat_summary.py +++ b/plugins/modules/threat_summary.py @@ -35,7 +35,7 @@ elements: str type: list requirements: -- dnacentersdk >= 2.6.0 +- dnacentersdk >= 2.7.0 - python >= 3.9 notes: - SDK Method used are diff --git a/requirements.txt b/requirements.txt index fe7a7694cd..398b994a11 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -dnacentersdk >= 2.6.0 \ No newline at end of file +dnacentersdk >= 2.7.0 \ No newline at end of file From 67a57ff741461e40d27827b2787f4c28aa99880e Mon Sep 17 00:00:00 2001 From: bvargasre Date: Fri, 31 May 2024 16:45:31 -0600 Subject: [PATCH 355/358] chore: Update dnacentersdk requirement to 2.7.1 --- README.md | 2 +- changelogs/changelog.yaml | 2 +- plugins/modules/device_credential_intent.py | 2 +- plugins/modules/device_credential_workflow_manager.py | 2 +- plugins/modules/disasterrecovery_system_operationstatus_info.py | 2 +- plugins/modules/disasterrecovery_system_status_info.py | 2 +- plugins/modules/endpoint_analytics_profiling_rules.py | 2 +- plugins/modules/endpoint_analytics_profiling_rules_info.py | 2 +- plugins/modules/inventory_intent.py | 2 +- plugins/modules/inventory_workflow_manager.py | 2 +- plugins/modules/ise_radius_integration_workflow_manager.py | 2 +- plugins/modules/network_device_with_snmp_v3_des_info.py | 2 +- plugins/modules/network_update.py | 2 +- plugins/modules/network_v2.py | 2 +- plugins/modules/network_v2_info.py | 2 +- plugins/modules/nfv_profile.py | 2 +- plugins/modules/nfv_profile_info.py | 2 +- plugins/modules/nfv_provision.py | 2 +- plugins/modules/nfv_provision_detail_info.py | 2 +- plugins/modules/nfv_provision_details.py | 2 +- plugins/modules/profiling_rules_count_info.py | 2 +- plugins/modules/profiling_rules_in_bulk_create.py | 2 +- plugins/modules/sda_count_info.py | 2 +- plugins/modules/sda_fabric.py | 2 +- plugins/modules/sda_fabric_info.py | 2 +- plugins/modules/site_assign_device.py | 2 +- plugins/modules/site_design_floormap.py | 2 +- plugins/modules/site_design_floormap_info.py | 2 +- plugins/modules/syslog_config_create.py | 2 +- plugins/modules/syslog_config_update.py | 2 +- plugins/modules/threat_detail.py | 2 +- plugins/modules/threat_detail_count.py | 2 +- plugins/modules/threat_summary.py | 2 +- requirements.txt | 2 +- 34 files changed, 34 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 7b988ff817..7909c6776b 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ The following table shows the supported versions. | 2.2.3.3 | 6.4.0 | 2.4.11 | | 2.3.3.0 | 6.6.4 | 2.5.5 | | 2.3.5.3 | 6.13.3 | 2.6.11 | -| 2.3.7.6 | ^6.14.0 | ^2.7.0 | +| 2.3.7.6 | ^6.14.0 | ^2.7.1 | If your Ansible collection is older please consider updating it first. diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 47e4550958..e1ce85f173 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -866,7 +866,7 @@ releases: - Adding support to importing a template using JSON file - Changes in discovery workflow manager modules relating to different states of the discovery job 6.14.0: - release_date: "2024-05-09" + release_date: "2024-05-31" changes: release_summary: New Dna Center API version 2.3.7.6, and addition of Workflow Manager modules support for device configuration backups, events and notifications, ISE and RADIUS server integrations, and network compliance. minor_changes: diff --git a/plugins/modules/device_credential_intent.py b/plugins/modules/device_credential_intent.py index b03039ac7a..0bd15f1fad 100644 --- a/plugins/modules/device_credential_intent.py +++ b/plugins/modules/device_credential_intent.py @@ -298,7 +298,7 @@ description: snmp_v3 Credential Id. Use Description or Id. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Discovery CreateGlobalCredentialsV2 diff --git a/plugins/modules/device_credential_workflow_manager.py b/plugins/modules/device_credential_workflow_manager.py index fa72e7fac1..c7b8e8921e 100644 --- a/plugins/modules/device_credential_workflow_manager.py +++ b/plugins/modules/device_credential_workflow_manager.py @@ -298,7 +298,7 @@ description: snmp_v3 Credential Id. Use Description or Id. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco Catalyst Center documentation for Discovery CreateGlobalCredentialsV2 diff --git a/plugins/modules/disasterrecovery_system_operationstatus_info.py b/plugins/modules/disasterrecovery_system_operationstatus_info.py index aca22ff589..3f821aeefc 100644 --- a/plugins/modules/disasterrecovery_system_operationstatus_info.py +++ b/plugins/modules/disasterrecovery_system_operationstatus_info.py @@ -20,7 +20,7 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/disasterrecovery_system_status_info.py b/plugins/modules/disasterrecovery_system_status_info.py index e526e38f9c..2c3d3bb9d1 100644 --- a/plugins/modules/disasterrecovery_system_status_info.py +++ b/plugins/modules/disasterrecovery_system_status_info.py @@ -20,7 +20,7 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/endpoint_analytics_profiling_rules.py b/plugins/modules/endpoint_analytics_profiling_rules.py index 7a5eda27ff..bbe87bf9b6 100644 --- a/plugins/modules/endpoint_analytics_profiling_rules.py +++ b/plugins/modules/endpoint_analytics_profiling_rules.py @@ -114,7 +114,7 @@ elements: str type: list requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/endpoint_analytics_profiling_rules_info.py b/plugins/modules/endpoint_analytics_profiling_rules_info.py index f410255e52..45bf1bf517 100644 --- a/plugins/modules/endpoint_analytics_profiling_rules_info.py +++ b/plugins/modules/endpoint_analytics_profiling_rules_info.py @@ -60,7 +60,7 @@ - RuleId path parameter. Unique rule identifier. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index 69f196b9e9..cada74a18b 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -307,7 +307,7 @@ version_added: 6.12.0 requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco Catalyst Center documentation for Devices AddDevice2 diff --git a/plugins/modules/inventory_workflow_manager.py b/plugins/modules/inventory_workflow_manager.py index 8d990a3380..9af856ba64 100644 --- a/plugins/modules/inventory_workflow_manager.py +++ b/plugins/modules/inventory_workflow_manager.py @@ -307,7 +307,7 @@ version_added: 6.12.0 requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco Catalyst Center documentation for Devices AddDevice2 diff --git a/plugins/modules/ise_radius_integration_workflow_manager.py b/plugins/modules/ise_radius_integration_workflow_manager.py index b7cccfdcfb..c5a62715a5 100644 --- a/plugins/modules/ise_radius_integration_workflow_manager.py +++ b/plugins/modules/ise_radius_integration_workflow_manager.py @@ -215,7 +215,7 @@ - Serves as a validation of its authenticity and reliability in secure connections. type: bool requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/network_device_with_snmp_v3_des_info.py b/plugins/modules/network_device_with_snmp_v3_des_info.py index f2b8cf2291..81abfc8127 100644 --- a/plugins/modules/network_device_with_snmp_v3_des_info.py +++ b/plugins/modules/network_device_with_snmp_v3_des_info.py @@ -42,7 +42,7 @@ - Order query parameter. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Devices ReturnsDevicesAddedToCiscoDNACenterWithSnmpV3DES diff --git a/plugins/modules/network_update.py b/plugins/modules/network_update.py index 72aa9ca8e9..65e6265006 100644 --- a/plugins/modules/network_update.py +++ b/plugins/modules/network_update.py @@ -131,7 +131,7 @@ is associated with the site. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Network Settings UpdateNetwork diff --git a/plugins/modules/network_v2.py b/plugins/modules/network_v2.py index d072ac3b36..0bbe2869a1 100644 --- a/plugins/modules/network_v2.py +++ b/plugins/modules/network_v2.py @@ -134,7 +134,7 @@ the network settings. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Network Settings CreateNetworkV2 diff --git a/plugins/modules/network_v2_info.py b/plugins/modules/network_v2_info.py index 03f53b4255..715d1f6de1 100644 --- a/plugins/modules/network_v2_info.py +++ b/plugins/modules/network_v2_info.py @@ -24,7 +24,7 @@ - SiteId query parameter. Site Id to get the network settings associated with the site. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Network Settings GetNetworkV2 diff --git a/plugins/modules/nfv_profile.py b/plugins/modules/nfv_profile.py index ca906313b7..42809830ca 100644 --- a/plugins/modules/nfv_profile.py +++ b/plugins/modules/nfv_profile.py @@ -147,7 +147,7 @@ description: Name of the profile to create NFV profile. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Site Design CreateNFVProfile diff --git a/plugins/modules/nfv_profile_info.py b/plugins/modules/nfv_profile_info.py index ca3937bafe..2a48807428 100644 --- a/plugins/modules/nfv_profile_info.py +++ b/plugins/modules/nfv_profile_info.py @@ -36,7 +36,7 @@ - Name query parameter. Name of network profile to be retrieved. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Site Design GetNFVProfile diff --git a/plugins/modules/nfv_provision.py b/plugins/modules/nfv_provision.py index 3cf14f8910..7c913e63b0 100644 --- a/plugins/modules/nfv_provision.py +++ b/plugins/modules/nfv_provision.py @@ -375,7 +375,7 @@ type: str type: list requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Site Design ProvisionNFV diff --git a/plugins/modules/nfv_provision_detail_info.py b/plugins/modules/nfv_provision_detail_info.py index 31c47f9ed5..65b9281db4 100644 --- a/plugins/modules/nfv_provision_detail_info.py +++ b/plugins/modules/nfv_provision_detail_info.py @@ -24,7 +24,7 @@ - DeviceIp query parameter. Device to which the provisioning detail has to be retrieved. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Site Design GetDeviceDetailsByIP diff --git a/plugins/modules/nfv_provision_details.py b/plugins/modules/nfv_provision_details.py index 84d81501c4..552fa12b34 100644 --- a/plugins/modules/nfv_provision_details.py +++ b/plugins/modules/nfv_provision_details.py @@ -23,7 +23,7 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Site Design NFVProvisioningDetail diff --git a/plugins/modules/profiling_rules_count_info.py b/plugins/modules/profiling_rules_count_info.py index be066e2b8d..a7c9f8dca4 100644 --- a/plugins/modules/profiling_rules_count_info.py +++ b/plugins/modules/profiling_rules_count_info.py @@ -29,7 +29,7 @@ - IncludeDeleted query parameter. Flag to indicate whether deleted rules should be part of the records fetched. type: bool requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/profiling_rules_in_bulk_create.py b/plugins/modules/profiling_rules_in_bulk_create.py index bff3abee05..5819da497d 100644 --- a/plugins/modules/profiling_rules_in_bulk_create.py +++ b/plugins/modules/profiling_rules_in_bulk_create.py @@ -121,7 +121,7 @@ type: list type: list requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/sda_count_info.py b/plugins/modules/sda_count_info.py index 458526990b..a8a2ce8afb 100644 --- a/plugins/modules/sda_count_info.py +++ b/plugins/modules/sda_count_info.py @@ -20,7 +20,7 @@ description: Additional headers. type: dict requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/sda_fabric.py b/plugins/modules/sda_fabric.py index 59ff8c7cbb..9ab5c6c06d 100644 --- a/plugins/modules/sda_fabric.py +++ b/plugins/modules/sda_fabric.py @@ -21,7 +21,7 @@ description: FabricName query parameter. Fabric Name. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/sda_fabric_info.py b/plugins/modules/sda_fabric_info.py index 93858f89ea..99d7e11271 100644 --- a/plugins/modules/sda_fabric_info.py +++ b/plugins/modules/sda_fabric_info.py @@ -24,7 +24,7 @@ - FabricName query parameter. Fabric Name. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/site_assign_device.py b/plugins/modules/site_assign_device.py index 520cf7c8fd..3b7bb354e3 100644 --- a/plugins/modules/site_assign_device.py +++ b/plugins/modules/site_assign_device.py @@ -28,7 +28,7 @@ description: SiteId path parameter. Site id to which site the device to assign. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/site_design_floormap.py b/plugins/modules/site_design_floormap.py index f967b93eaf..3405dfe6e5 100644 --- a/plugins/modules/site_design_floormap.py +++ b/plugins/modules/site_design_floormap.py @@ -24,7 +24,7 @@ description: Site Design Floormap's payload type: dict requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/site_design_floormap_info.py b/plugins/modules/site_design_floormap_info.py index e07d5b1d67..5606039021 100644 --- a/plugins/modules/site_design_floormap_info.py +++ b/plugins/modules/site_design_floormap_info.py @@ -26,7 +26,7 @@ - FloorId path parameter. Group Id of the specified floormap. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/syslog_config_create.py b/plugins/modules/syslog_config_create.py index a0f8fd8d1e..57c525fd60 100644 --- a/plugins/modules/syslog_config_create.py +++ b/plugins/modules/syslog_config_create.py @@ -35,7 +35,7 @@ description: Protocol. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Event Management CreateSyslogDestination diff --git a/plugins/modules/syslog_config_update.py b/plugins/modules/syslog_config_update.py index 3c6b6584e0..6eeae91a0e 100644 --- a/plugins/modules/syslog_config_update.py +++ b/plugins/modules/syslog_config_update.py @@ -35,7 +35,7 @@ description: Protocol. type: str requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 seealso: - name: Cisco DNA Center documentation for Event Management UpdateSyslogDestination diff --git a/plugins/modules/threat_detail.py b/plugins/modules/threat_detail.py index a96372d91d..a7cd309ce2 100644 --- a/plugins/modules/threat_detail.py +++ b/plugins/modules/threat_detail.py @@ -44,7 +44,7 @@ elements: str type: list requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/threat_detail_count.py b/plugins/modules/threat_detail_count.py index 36e5c1ca3f..4b63e29b73 100644 --- a/plugins/modules/threat_detail_count.py +++ b/plugins/modules/threat_detail_count.py @@ -44,7 +44,7 @@ elements: str type: list requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/plugins/modules/threat_summary.py b/plugins/modules/threat_summary.py index 7db0d32f01..a8c1d7a4b0 100644 --- a/plugins/modules/threat_summary.py +++ b/plugins/modules/threat_summary.py @@ -35,7 +35,7 @@ elements: str type: list requirements: -- dnacentersdk >= 2.7.0 +- dnacentersdk >= 2.7.1 - python >= 3.9 notes: - SDK Method used are diff --git a/requirements.txt b/requirements.txt index 398b994a11..cf40b8f59f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -dnacentersdk >= 2.7.0 \ No newline at end of file +dnacentersdk >= 2.7.1 \ No newline at end of file From 72d7ed4b62fdcaf5b1cdfff4cf48b09e9f8cdb99 Mon Sep 17 00:00:00 2001 From: bvargasre Date: Fri, 31 May 2024 18:18:38 -0600 Subject: [PATCH 356/358] Remove trailing whitespace --- .../network_devices_interfaces_query.py | 92 ------------------- plugins/action/sda_virtual_network_ip_pool.py | 1 - .../modules/authentication_policy_servers.py | 6 +- .../modules/configuration_template_info.py | 4 +- .../modules/device_replacement_count_info.py | 2 +- plugins/modules/device_replacement_info.py | 2 +- plugins/modules/discovery_summary_info.py | 12 +-- plugins/modules/network_device_count_info.py | 8 +- ...twork_device_functional_capability_info.py | 2 +- plugins/modules/network_device_info.py | 6 +- .../network_device_module_count_info.py | 4 +- plugins/modules/network_device_module_info.py | 4 +- .../network_devices_interfaces_query.py | 35 ------- plugins/modules/pnp_device_count_info.py | 20 ++-- plugins/modules/pnp_device_history_info.py | 2 +- plugins/modules/pnp_device_info.py | 22 ++--- plugins/modules/pnp_workflow_count_info.py | 2 +- plugins/modules/pnp_workflow_info.py | 6 +- plugins/modules/templates_details_info.py | 2 +- 19 files changed, 52 insertions(+), 180 deletions(-) delete mode 100644 plugins/action/network_devices_interfaces_query.py delete mode 100644 plugins/modules/network_devices_interfaces_query.py diff --git a/plugins/action/network_devices_interfaces_query.py b/plugins/action/network_devices_interfaces_query.py deleted file mode 100644 index d5e2d49012..0000000000 --- a/plugins/action/network_devices_interfaces_query.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright (c) 2021, Cisco Systems -# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type -from ansible.plugins.action import ActionBase -try: - from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( - AnsibleArgSpecValidator, - ) -except ImportError: - ANSIBLE_UTILS_IS_INSTALLED = False -else: - ANSIBLE_UTILS_IS_INSTALLED = True -from ansible.errors import AnsibleActionFail -from ansible_collections.cisco.dnac.plugins.plugin_utils.dnac import ( - DNACSDK, - dnac_argument_spec, -) - -# Get common arguements specification -argument_spec = dnac_argument_spec() -# Add arguments specific for this module -argument_spec.update(dict( - startTime=dict(type="int"), - endTime=dict(type="int"), - query=dict(type="dict"), - deviceId=dict(type="str"), -)) - -required_if = [] -required_one_of = [] -mutually_exclusive = [] -required_together = [] - - -class ActionModule(ActionBase): - def __init__(self, *args, **kwargs): - if not ANSIBLE_UTILS_IS_INSTALLED: - raise AnsibleActionFail("ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") - super(ActionModule, self).__init__(*args, **kwargs) - self._supports_async = False - self._supports_check_mode = False - self._result = None - - # Checks the supplied parameters against the argument spec for this module - def _check_argspec(self): - aav = AnsibleArgSpecValidator( - data=self._task.args, - schema=dict(argument_spec=argument_spec), - schema_format="argspec", - schema_conditionals=dict( - required_if=required_if, - required_one_of=required_one_of, - mutually_exclusive=mutually_exclusive, - required_together=required_together, - ), - name=self._task.action, - ) - valid, errors, self._task.args = aav.validate() - if not valid: - raise AnsibleActionFail(errors) - - def get_object(self, params): - new_object = dict( - startTime=params.get("startTime"), - endTime=params.get("endTime"), - query=params.get("query"), - device_id=params.get("deviceId"), - ) - return new_object - - def run(self, tmp=None, task_vars=None): - self._task.diff = False - self._result = super(ActionModule, self).run(tmp, task_vars) - self._result["changed"] = False - self._check_argspec() - - dnac = DNACSDK(params=self._task.args) - - response = dnac.exec( - family="devices", - # No function - # Metadata: {'type': 'c', 'look_by': '', 'urls': ['/dna/intent/api/v2/networkDevices/{deviceId}/interfaces/query'], 'tag': 'Devices', 'version_added': '6.14.0', 'get_all': 'get_device_interface_stats_info', 'operation_id_list': ['get:GetDeviceInterfaceStatsInfo'], 'description': 'get:This API returns the Interface Stats for the given Device Id. Please refer to the Feature tab for the Request Body usage and the API filtering support.\n', 'method_url': 'get:post /dna/intent/api/v2/networkDevices/{deviceId}/interfaces/query,\n'} - params=self.get_object(self._task.args), - ) - self._result.update(dict(dnac_response=response)) - self._result.update(dnac.exit_json()) - return self._result diff --git a/plugins/action/sda_virtual_network_ip_pool.py b/plugins/action/sda_virtual_network_ip_pool.py index 69bb4561d8..e4563fe89e 100644 --- a/plugins/action/sda_virtual_network_ip_pool.py +++ b/plugins/action/sda_virtual_network_ip_pool.py @@ -78,7 +78,6 @@ def __init__(self, params, dnac): isCommonPool=params.get("isCommonPool"), isBridgeModeVm=params.get("isBridgeModeVm"), poolType=params.get("poolType"), - site_name_hierarchy=params.get("siteNameHierarchy"), virtual_network_name=params.get("virtualNetworkName"), ip_pool_name=params.get("ipPoolName"), ) diff --git a/plugins/modules/authentication_policy_servers.py b/plugins/modules/authentication_policy_servers.py index a3d56e6180..2b1337b6fb 100644 --- a/plugins/modules/authentication_policy_servers.py +++ b/plugins/modules/authentication_policy_servers.py @@ -12,13 +12,13 @@ - Manage operations create, update and delete of the resource Authentication Policy Servers. - > API to add AAA/ISE server access configuration. Protocol can be configured as either RADIUS OR TACACS OR - RADIUS_TACACS. If configuring Cisco ISE server, after configuration, use ‘Cisco ISE Server Integration Status' + RADIUS_TACACS. If configuring Cisco ISE server, after configuration, use 'Cisco ISE Server Integration Status' Intent API to check the integration status. Based on integration status, if require use 'Accept Cisco ISE Server Certificate for Cisco ISE Server Integration' Intent API to accept the Cisco ISE certificate for Cisco ISE server - integration, then use again ‘Cisco ISE Server Integration Status' Intent API to check the integration status. + integration, then use again 'Cisco ISE Server Integration Status' Intent API to check the integration status. - API to delete AAA/ISE server access configuration. - > - API to edit AAA/ISE server access configuration. After edit, use ‘Cisco ISE Server Integration Status' Intent API + API to edit AAA/ISE server access configuration. After edit, use 'Cisco ISE Server Integration Status' Intent API to check the integration status. version_added: '3.1.0' extends_documentation_fragment: diff --git a/plugins/modules/configuration_template_info.py b/plugins/modules/configuration_template_info.py index dc472bf0cf..b03b4cfaaa 100644 --- a/plugins/modules/configuration_template_info.py +++ b/plugins/modules/configuration_template_info.py @@ -51,12 +51,12 @@ type: bool tags: description: - - Tags query parameter. Filter template(s) based on tags. + - Tags query parameter. Filter template(s) based on tags. elements: str type: list projectNames: description: - - ProjectNames query parameter. Filter template(s) based on project names. + - ProjectNames query parameter. Filter template(s) based on project names. elements: str type: list unCommitted: diff --git a/plugins/modules/device_replacement_count_info.py b/plugins/modules/device_replacement_count_info.py index 98c7f9257a..313326f070 100644 --- a/plugins/modules/device_replacement_count_info.py +++ b/plugins/modules/device_replacement_count_info.py @@ -23,7 +23,7 @@ description: - > ReplacementStatus query parameter. Device Replacement status listREADY-FOR-REPLACEMENT, REPLACEMENT-IN- - PROGRESS, REPLACEMENT-SCHEDULED, REPLACED, ERROR. + PROGRESS, REPLACEMENT-SCHEDULED, REPLACED, ERROR. elements: str type: list requirements: diff --git a/plugins/modules/device_replacement_info.py b/plugins/modules/device_replacement_info.py index 49bdb7f7b5..592aa958d7 100644 --- a/plugins/modules/device_replacement_info.py +++ b/plugins/modules/device_replacement_info.py @@ -46,7 +46,7 @@ description: - > ReplacementStatus query parameter. Device Replacement status READY-FOR-REPLACEMENT, REPLACEMENT-IN-PROGRESS, - REPLACEMENT-SCHEDULED, REPLACED, ERROR, NETWORK_READINESS_REQUESTED, NETWORK_READINESS_FAILED. + REPLACEMENT-SCHEDULED, REPLACED, ERROR, NETWORK_READINESS_REQUESTED, NETWORK_READINESS_FAILED. elements: str type: list family: diff --git a/plugins/modules/discovery_summary_info.py b/plugins/modules/discovery_summary_info.py index 38bc3f1809..e920fffb92 100644 --- a/plugins/modules/discovery_summary_info.py +++ b/plugins/modules/discovery_summary_info.py @@ -41,42 +41,42 @@ type: str ipAddress: description: - - IpAddress query parameter. IP Address of the device. + - IpAddress query parameter. IP Address of the device. elements: str type: list pingStatus: description: - > PingStatus query parameter. Ping status for the IP during the job run. Available values are 'SUCCESS', - 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. + 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. elements: str type: list snmpStatus: description: - > SnmpStatus query parameter. SNMP status for the IP during the job run. Available values are 'SUCCESS', - 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. + 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. elements: str type: list cliStatus: description: - > CliStatus query parameter. CLI status for the IP during the job run. Available values are 'SUCCESS', - 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. + 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. elements: str type: list netconfStatus: description: - > NetconfStatus query parameter. NETCONF status for the IP during the job run. Available values are 'SUCCESS', - 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. + 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. elements: str type: list httpStatus: description: - > HttpStatus query parameter. HTTP staus for the IP during the job run. Available values are 'SUCCESS', - 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. + 'FAILURE', 'NOT-PROVIDED' and 'NOT-VALIDATED'. elements: str type: list requirements: diff --git a/plugins/modules/network_device_count_info.py b/plugins/modules/network_device_count_info.py index eca9dcaf8e..e7bdab9c9a 100644 --- a/plugins/modules/network_device_count_info.py +++ b/plugins/modules/network_device_count_info.py @@ -29,22 +29,22 @@ type: str hostname: description: - - Hostname query parameter. + - Hostname query parameter. elements: str type: list managementIpAddress: description: - - ManagementIpAddress query parameter. + - ManagementIpAddress query parameter. elements: str type: list macAddress: description: - - MacAddress query parameter. + - MacAddress query parameter. elements: str type: list locationName: description: - - LocationName query parameter. + - LocationName query parameter. elements: str type: list requirements: diff --git a/plugins/modules/network_device_functional_capability_info.py b/plugins/modules/network_device_functional_capability_info.py index 213f6a32e6..f8b1cb7323 100644 --- a/plugins/modules/network_device_functional_capability_info.py +++ b/plugins/modules/network_device_functional_capability_info.py @@ -29,7 +29,7 @@ type: str functionName: description: - - FunctionName query parameter. + - FunctionName query parameter. elements: str type: list id: diff --git a/plugins/modules/network_device_info.py b/plugins/modules/network_device_info.py index 3bbbb1f9ce..ec67bf1676 100644 --- a/plugins/modules/network_device_info.py +++ b/plugins/modules/network_device_info.py @@ -113,17 +113,17 @@ type: list reachabilityStatus: description: - - ReachabilityStatus query parameter. + - ReachabilityStatus query parameter. elements: str type: list upTime: description: - - UpTime query parameter. + - UpTime query parameter. elements: str type: list associatedWlcIp: description: - - AssociatedWlcIp query parameter. + - AssociatedWlcIp query parameter. elements: str type: list license_name: diff --git a/plugins/modules/network_device_module_count_info.py b/plugins/modules/network_device_module_count_info.py index a02c59f21d..8a7400622d 100644 --- a/plugins/modules/network_device_module_count_info.py +++ b/plugins/modules/network_device_module_count_info.py @@ -25,7 +25,7 @@ type: str nameList: description: - - NameList query parameter. + - NameList query parameter. elements: str type: list vendorEquipmentTypeList: @@ -40,7 +40,7 @@ type: list operationalStateCodeList: description: - - OperationalStateCodeList query parameter. + - OperationalStateCodeList query parameter. elements: str type: list requirements: diff --git a/plugins/modules/network_device_module_info.py b/plugins/modules/network_device_module_info.py index 33e6f4e0f6..05ae77d724 100644 --- a/plugins/modules/network_device_module_info.py +++ b/plugins/modules/network_device_module_info.py @@ -35,7 +35,7 @@ type: int nameList: description: - - NameList query parameter. + - NameList query parameter. elements: str type: list vendorEquipmentTypeList: @@ -50,7 +50,7 @@ type: list operationalStateCodeList: description: - - OperationalStateCodeList query parameter. + - OperationalStateCodeList query parameter. elements: str type: list id: diff --git a/plugins/modules/network_devices_interfaces_query.py b/plugins/modules/network_devices_interfaces_query.py deleted file mode 100644 index be92d6315f..0000000000 --- a/plugins/modules/network_devices_interfaces_query.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright (c) 2021, Cisco Systems -# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) - -DOCUMENTATION = r""" ---- -module: networkDevices_interfaces_query -short_description: Resource module for Networkdevices Interfaces Query -description: -- Manage operation create of the resource Networkdevices Interfaces Query. -version_added: '6.14.0' -extends_documentation_fragment: - - cisco.dnac.module -author: Rafael Campos (@racampos) -options: {} -requirements: -- dnacentersdk >= 2.4.9 -- python >= 3.5 -notes: - - Paths used are - -""" - -EXAMPLES = r""" -""" -RETURN = r""" -dnac_response: - description: A dictionary or list with the response returned by the Cisco DNAC Python SDK - returned: always - type: dict - sample: > - {} -""" diff --git a/plugins/modules/pnp_device_count_info.py b/plugins/modules/pnp_device_count_info.py index 562196fe08..b670f9e439 100644 --- a/plugins/modules/pnp_device_count_info.py +++ b/plugins/modules/pnp_device_count_info.py @@ -21,52 +21,52 @@ type: dict serialNumber: description: - - SerialNumber query parameter. Device Serial Number. + - SerialNumber query parameter. Device Serial Number. elements: str type: list state_: description: - - State query parameter. Device State. + - State query parameter. Device State. elements: str type: list onbState: description: - - OnbState query parameter. Device Onboarding State. + - OnbState query parameter. Device Onboarding State. elements: str type: list name: description: - - Name query parameter. Device Name. + - Name query parameter. Device Name. elements: str type: list pid: description: - - Pid query parameter. Device ProductId. + - Pid query parameter. Device ProductId. elements: str type: list source: description: - - Source query parameter. Device Source. + - Source query parameter. Device Source. elements: str type: list workflowId: description: - - WorkflowId query parameter. Device Workflow Id. + - WorkflowId query parameter. Device Workflow Id. elements: str type: list workflowName: description: - - WorkflowName query parameter. Device Workflow Name. + - WorkflowName query parameter. Device Workflow Name. elements: str type: list smartAccountId: description: - - SmartAccountId query parameter. Device Smart Account. + - SmartAccountId query parameter. Device Smart Account. elements: str type: list virtualAccountId: description: - - VirtualAccountId query parameter. Device Virtual Account. + - VirtualAccountId query parameter. Device Virtual Account. elements: str type: list lastContact: diff --git a/plugins/modules/pnp_device_history_info.py b/plugins/modules/pnp_device_history_info.py index 44bad616ce..0b7c697d10 100644 --- a/plugins/modules/pnp_device_history_info.py +++ b/plugins/modules/pnp_device_history_info.py @@ -25,7 +25,7 @@ type: str sort: description: - - Sort query parameter. Comma seperated list of fields to sort on. + - Sort query parameter. Comma seperated list of fields to sort on. elements: str type: list sortOrder: diff --git a/plugins/modules/pnp_device_info.py b/plugins/modules/pnp_device_info.py index 6811c1c857..2899b2d637 100644 --- a/plugins/modules/pnp_device_info.py +++ b/plugins/modules/pnp_device_info.py @@ -33,7 +33,7 @@ type: int sort: description: - - Sort query parameter. Comma seperated list of fields to sort on. + - Sort query parameter. Comma seperated list of fields to sort on. elements: str type: list sortOrder: @@ -42,52 +42,52 @@ type: str serialNumber: description: - - SerialNumber query parameter. Device Serial Number. + - SerialNumber query parameter. Device Serial Number. elements: str type: list state_: description: - - State query parameter. Device State. + - State query parameter. Device State. elements: str type: list onbState: description: - - OnbState query parameter. Device Onboarding State. + - OnbState query parameter. Device Onboarding State. elements: str type: list name: description: - - Name query parameter. Device Name. + - Name query parameter. Device Name. elements: str type: list pid: description: - - Pid query parameter. Device ProductId. + - Pid query parameter. Device ProductId. elements: str type: list source: description: - - Source query parameter. Device Source. + - Source query parameter. Device Source. elements: str type: list workflowId: description: - - WorkflowId query parameter. Device Workflow Id. + - WorkflowId query parameter. Device Workflow Id. elements: str type: list workflowName: description: - - WorkflowName query parameter. Device Workflow Name. + - WorkflowName query parameter. Device Workflow Name. elements: str type: list smartAccountId: description: - - SmartAccountId query parameter. Device Smart Account. + - SmartAccountId query parameter. Device Smart Account. elements: str type: list virtualAccountId: description: - - VirtualAccountId query parameter. Device Virtual Account. + - VirtualAccountId query parameter. Device Virtual Account. elements: str type: list lastContact: diff --git a/plugins/modules/pnp_workflow_count_info.py b/plugins/modules/pnp_workflow_count_info.py index ae4630b978..65a86c79ab 100644 --- a/plugins/modules/pnp_workflow_count_info.py +++ b/plugins/modules/pnp_workflow_count_info.py @@ -21,7 +21,7 @@ type: dict name: description: - - Name query parameter. Workflow Name. + - Name query parameter. Workflow Name. elements: str type: list requirements: diff --git a/plugins/modules/pnp_workflow_info.py b/plugins/modules/pnp_workflow_info.py index 0de9b85ab2..6ad13d548f 100644 --- a/plugins/modules/pnp_workflow_info.py +++ b/plugins/modules/pnp_workflow_info.py @@ -33,7 +33,7 @@ type: int sort: description: - - Sort query parameter. Comma seperated lost of fields to sort on. + - Sort query parameter. Comma seperated lost of fields to sort on. elements: str type: list sortOrder: @@ -42,12 +42,12 @@ type: str type: description: - - Type query parameter. Workflow Type. + - Type query parameter. Workflow Type. elements: str type: list name: description: - - Name query parameter. Workflow Name. + - Name query parameter. Workflow Name. elements: str type: list id: diff --git a/plugins/modules/templates_details_info.py b/plugins/modules/templates_details_info.py index 9178b21e9d..af205545c9 100644 --- a/plugins/modules/templates_details_info.py +++ b/plugins/modules/templates_details_info.py @@ -61,7 +61,7 @@ type: bool tags: description: - - Tags query parameter. Filter template(s) based on tags. + - Tags query parameter. Filter template(s) based on tags. elements: str type: list unCommitted: From edd7f05284c682d87bb264c5f8f1be5a0803ef07 Mon Sep 17 00:00:00 2001 From: bvargasre Date: Fri, 31 May 2024 19:02:16 -0600 Subject: [PATCH 357/358] chore: Remove inconsistent parameters import and fix some module's name --- ...business_sda_hostonboarding_ssid_ippool.py | 5 +- plugins/action/event_snmp_config.py | 1 - plugins/action/event_snmp_config_info.py | 18 +++- plugins/action/path_trace.py | 1 - plugins/action/pnp_global_settings.py | 4 - plugins/action/sda_anycast_gateways.py | 4 - plugins/action/sda_authentication_profiles.py | 1 - plugins/action/sda_extranet_policies.py | 4 - .../sda_fabric_authentication_profile.py | 2 - plugins/action/sda_fabric_border_device.py | 2 - .../action/sda_fabric_control_plane_device.py | 1 - plugins/action/sda_fabric_devices.py | 1 - .../sda_fabric_devices_layer2_handoffs.py | 5 -- ...ric_devices_layer2_handoffs_ip_transits.py | 4 - ...ic_devices_layer2_handoffs_sda_transits.py | 2 - plugins/action/sda_fabric_edge_device.py | 1 - plugins/action/sda_fabric_site.py | 1 - plugins/action/sda_fabric_sites.py | 4 - plugins/action/sda_fabric_zones.py | 4 - plugins/action/sda_multicast.py | 1 - .../sda_port_assignment_for_access_point.py | 1 - .../sda_port_assignment_for_user_device.py | 1 - plugins/action/sda_port_assignments.py | 4 - plugins/action/sda_provision_device.py | 1 - plugins/action/sda_provision_devices.py | 4 - plugins/action/sda_virtual_network_ip_pool.py | 1 - plugins/action/sda_virtual_network_v2.py | 1 - plugins/action/wireless_profile.py | 3 +- plugins/modules/event_snmp_config_info.py | 84 +++++++++++++++++-- .../modules/lan_automation_update_device.py | 2 +- .../modules/network_device_config__info.py | 6 +- .../network_device_custom_prompt_info.py | 4 +- plugins/modules/sda_anycast_gateways.py | 4 +- .../sda_anycast_gateways_count_info.py | 4 +- plugins/modules/sda_anycast_gateways_info.py | 4 +- .../modules/sda_authentication_profiles.py | 4 +- .../sda_authentication_profiles_info.py | 4 +- plugins/modules/sda_extranet_policies.py | 8 +- .../sda_extranet_policies_count_info.py | 4 +- plugins/modules/sda_extranet_policies_info.py | 4 +- plugins/modules/sda_fabric_devices.py | 10 +-- .../modules/sda_fabric_devices_count_info.py | 4 +- plugins/modules/sda_fabric_devices_info.py | 4 +- .../sda_fabric_devices_layer2_handoffs.py | 8 +- ...bric_devices_layer2_handoffs_count_info.py | 4 +- ...sda_fabric_devices_layer2_handoffs_info.py | 4 +- ...ric_devices_layer2_handoffs_ip_transits.py | 10 +-- ..._layer2_handoffs_ip_transits_count_info.py | 4 +- ...evices_layer2_handoffs_ip_transits_info.py | 4 +- ...ic_devices_layer2_handoffs_sda_transits.py | 8 +- ...layer2_handoffs_sda_transits_count_info.py | 4 +- ...vices_layer2_handoffs_sda_transits_info.py | 4 +- plugins/modules/sda_fabric_sites.py | 8 +- .../modules/sda_fabric_sites_count_info.py | 4 +- plugins/modules/sda_fabric_sites_info.py | 4 +- plugins/modules/sda_fabric_zones.py | 8 +- .../modules/sda_fabric_zones_count_info.py | 4 +- plugins/modules/sda_fabric_zones_info.py | 4 +- plugins/modules/sda_port_assignments.py | 10 +-- .../sda_port_assignments_count_info.py | 4 +- plugins/modules/sda_port_assignments_info.py | 4 +- plugins/modules/sda_provision_devices.py | 10 +-- .../sda_provision_devices_count_info.py | 4 +- plugins/modules/sda_provision_devices_info.py | 4 +- 64 files changed, 189 insertions(+), 161 deletions(-) diff --git a/plugins/action/business_sda_hostonboarding_ssid_ippool.py b/plugins/action/business_sda_hostonboarding_ssid_ippool.py index 9eceec3cf3..0a9652a759 100644 --- a/plugins/action/business_sda_hostonboarding_ssid_ippool.py +++ b/plugins/action/business_sda_hostonboarding_ssid_ippool.py @@ -22,9 +22,6 @@ dnac_compare_equality, get_dict_result, ) -from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, -) # Get common arguments specification argument_spec = dnac_argument_spec() @@ -35,6 +32,7 @@ scalableGroupName=dict(type="str"), ssidNames=dict(type="list"), siteNameHierarchy=dict(type="str"), + headers=dict(type="dict"), )) required_if = [ @@ -54,6 +52,7 @@ def __init__(self, params, dnac): scalableGroupName=params.get("scalableGroupName"), ssidNames=params.get("ssidNames"), siteNameHierarchy=params.get("siteNameHierarchy"), + headers=params.get("headers"), ) def get_all_params(self, name=None, id=None): diff --git a/plugins/action/event_snmp_config.py b/plugins/action/event_snmp_config.py index d2d3593b18..8c0683ce8e 100644 --- a/plugins/action/event_snmp_config.py +++ b/plugins/action/event_snmp_config.py @@ -20,7 +20,6 @@ DNACSDK, dnac_argument_spec, dnac_compare_equality, - get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( InconsistentParameters, diff --git a/plugins/action/event_snmp_config_info.py b/plugins/action/event_snmp_config_info.py index cbd01f851f..1bc024081f 100644 --- a/plugins/action/event_snmp_config_info.py +++ b/plugins/action/event_snmp_config_info.py @@ -25,6 +25,11 @@ argument_spec = dnac_argument_spec() # Add arguments specific for this module argument_spec.update(dict( + configId=dict(type="str"), + offset=dict(type="int"), + limit=dict(type="int"), + sortBy=dict(type="str"), + order=dict(type="str"), headers=dict(type="dict"), )) @@ -63,6 +68,11 @@ def _check_argspec(self): def get_object(self, params): new_object = dict( + config_id=params.get("configId"), + offset=params.get("offset"), + limit=params.get("limit"), + sort_by=params.get("sortBy"), + order=params.get("order"), headers=params.get("headers"), ) return new_object @@ -77,9 +87,11 @@ def run(self, tmp=None, task_vars=None): dnac = DNACSDK(params=self._task.args) - # NOTE: Does not have a get all method or it is in another action - response = None - dnac.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + response = dnac.exec( + family="event_management", + function='get_snmp_destination', + params=self.get_object(self._task.args), + ) self._result.update(dict(dnac_response=response)) self._result.update(dnac.exit_json()) return self._result diff --git a/plugins/action/path_trace.py b/plugins/action/path_trace.py index ce5793b1fa..d494172555 100644 --- a/plugins/action/path_trace.py +++ b/plugins/action/path_trace.py @@ -20,7 +20,6 @@ DNACSDK, dnac_argument_spec, dnac_compare_equality, - get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( InconsistentParameters, diff --git a/plugins/action/pnp_global_settings.py b/plugins/action/pnp_global_settings.py index 7cd5247223..681e25e204 100644 --- a/plugins/action/pnp_global_settings.py +++ b/plugins/action/pnp_global_settings.py @@ -20,10 +20,6 @@ DNACSDK, dnac_argument_spec, dnac_compare_equality, - get_dict_result, -) -from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, ) # Get common arguments specification diff --git a/plugins/action/sda_anycast_gateways.py b/plugins/action/sda_anycast_gateways.py index 15cdd3d3d2..0fe26ddfb3 100644 --- a/plugins/action/sda_anycast_gateways.py +++ b/plugins/action/sda_anycast_gateways.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) @@ -37,10 +36,7 @@ )) required_if = [ - ("state", "present", ["id"], True), ("state", "present", ["payload"], True), - ("state", "absent", ["id"], True), - ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] diff --git a/plugins/action/sda_authentication_profiles.py b/plugins/action/sda_authentication_profiles.py index 73a6176686..fde4c48cc1 100644 --- a/plugins/action/sda_authentication_profiles.py +++ b/plugins/action/sda_authentication_profiles.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_extranet_policies.py b/plugins/action/sda_extranet_policies.py index e83a322570..265d7c34b0 100644 --- a/plugins/action/sda_extranet_policies.py +++ b/plugins/action/sda_extranet_policies.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) @@ -37,10 +36,7 @@ )) required_if = [ - ("state", "present", ["id"], True), ("state", "present", ["payload"], True), - ("state", "absent", ["id"], True), - ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] diff --git a/plugins/action/sda_fabric_authentication_profile.py b/plugins/action/sda_fabric_authentication_profile.py index f367da227a..d546eed18d 100644 --- a/plugins/action/sda_fabric_authentication_profile.py +++ b/plugins/action/sda_fabric_authentication_profile.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) @@ -38,7 +37,6 @@ required_if = [ ("state", "present", ["payload"], True), - ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] diff --git a/plugins/action/sda_fabric_border_device.py b/plugins/action/sda_fabric_border_device.py index 31cf6e9160..1088414d9d 100644 --- a/plugins/action/sda_fabric_border_device.py +++ b/plugins/action/sda_fabric_border_device.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) @@ -38,7 +37,6 @@ required_if = [ ("state", "present", ["payload"], True), - ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] diff --git a/plugins/action/sda_fabric_control_plane_device.py b/plugins/action/sda_fabric_control_plane_device.py index 1bb2fd0716..c2df756d5a 100644 --- a/plugins/action/sda_fabric_control_plane_device.py +++ b/plugins/action/sda_fabric_control_plane_device.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_fabric_devices.py b/plugins/action/sda_fabric_devices.py index 810ebca76f..e1dfa3e566 100644 --- a/plugins/action/sda_fabric_devices.py +++ b/plugins/action/sda_fabric_devices.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs.py b/plugins/action/sda_fabric_devices_layer2_handoffs.py index 284e0c4606..3a018c352e 100644 --- a/plugins/action/sda_fabric_devices_layer2_handoffs.py +++ b/plugins/action/sda_fabric_devices_layer2_handoffs.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) @@ -39,16 +38,12 @@ )) required_if = [ - ("state", "present", ["id"], True), ("state", "present", ["payload"], True), - ("state", "absent", ["id"], True), - ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] required_together = [] - class SdaFabricDevicesLayer2Handoffs(object): def __init__(self, params, dnac): self.dnac = dnac diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits.py b/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits.py index 67469c79fc..7135b248e3 100644 --- a/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits.py +++ b/plugins/action/sda_fabric_devices_layer2_handoffs_ip_transits.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) @@ -39,10 +38,7 @@ )) required_if = [ - ("state", "present", ["id"], True), ("state", "present", ["payload"], True), - ("state", "absent", ["id"], True), - ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits.py b/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits.py index 46c1f73fcc..5353e6183f 100644 --- a/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits.py +++ b/plugins/action/sda_fabric_devices_layer2_handoffs_sda_transits.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) @@ -39,7 +38,6 @@ required_if = [ ("state", "present", ["payload"], True), - ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] diff --git a/plugins/action/sda_fabric_edge_device.py b/plugins/action/sda_fabric_edge_device.py index d51e6f00b2..84bd9ed571 100644 --- a/plugins/action/sda_fabric_edge_device.py +++ b/plugins/action/sda_fabric_edge_device.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_fabric_site.py b/plugins/action/sda_fabric_site.py index 2b1be14c47..47af152760 100644 --- a/plugins/action/sda_fabric_site.py +++ b/plugins/action/sda_fabric_site.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_fabric_sites.py b/plugins/action/sda_fabric_sites.py index ce95fe893c..c9f4a4378b 100644 --- a/plugins/action/sda_fabric_sites.py +++ b/plugins/action/sda_fabric_sites.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) @@ -37,10 +36,7 @@ )) required_if = [ - ("state", "present", ["id"], True), ("state", "present", ["payload"], True), - ("state", "absent", ["id"], True), - ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] diff --git a/plugins/action/sda_fabric_zones.py b/plugins/action/sda_fabric_zones.py index 158a1edb52..f441b88900 100644 --- a/plugins/action/sda_fabric_zones.py +++ b/plugins/action/sda_fabric_zones.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) @@ -37,10 +36,7 @@ )) required_if = [ - ("state", "present", ["id"], True), ("state", "present", ["payload"], True), - ("state", "absent", ["id"], True), - ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] diff --git a/plugins/action/sda_multicast.py b/plugins/action/sda_multicast.py index 9a56d53a28..60c6b68abd 100644 --- a/plugins/action/sda_multicast.py +++ b/plugins/action/sda_multicast.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_port_assignment_for_access_point.py b/plugins/action/sda_port_assignment_for_access_point.py index 5ea494ed9a..0cdfd8bf5a 100644 --- a/plugins/action/sda_port_assignment_for_access_point.py +++ b/plugins/action/sda_port_assignment_for_access_point.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_port_assignment_for_user_device.py b/plugins/action/sda_port_assignment_for_user_device.py index 02c99ae152..3c2a0728a2 100644 --- a/plugins/action/sda_port_assignment_for_user_device.py +++ b/plugins/action/sda_port_assignment_for_user_device.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_port_assignments.py b/plugins/action/sda_port_assignments.py index baebcf2e13..2c2158103f 100644 --- a/plugins/action/sda_port_assignments.py +++ b/plugins/action/sda_port_assignments.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) @@ -42,10 +41,7 @@ )) required_if = [ - ("state", "present", ["id"], True), ("state", "present", ["payload"], True), - ("state", "absent", ["id"], True), - ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] diff --git a/plugins/action/sda_provision_device.py b/plugins/action/sda_provision_device.py index 53092c86a7..d9215cb0d0 100644 --- a/plugins/action/sda_provision_device.py +++ b/plugins/action/sda_provision_device.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_provision_devices.py b/plugins/action/sda_provision_devices.py index 85b8046064..836c8d928e 100644 --- a/plugins/action/sda_provision_devices.py +++ b/plugins/action/sda_provision_devices.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) @@ -39,10 +38,7 @@ )) required_if = [ - ("state", "present", ["id"], True), ("state", "present", ["payload"], True), - ("state", "absent", ["id"], True), - ("state", "absent", ["payload"], True), ] required_one_of = [] mutually_exclusive = [] diff --git a/plugins/action/sda_virtual_network_ip_pool.py b/plugins/action/sda_virtual_network_ip_pool.py index e4563fe89e..b5128268b2 100644 --- a/plugins/action/sda_virtual_network_ip_pool.py +++ b/plugins/action/sda_virtual_network_ip_pool.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/sda_virtual_network_v2.py b/plugins/action/sda_virtual_network_v2.py index 2410e2a326..45c66872d8 100644 --- a/plugins/action/sda_virtual_network_v2.py +++ b/plugins/action/sda_virtual_network_v2.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/action/wireless_profile.py b/plugins/action/wireless_profile.py index 9bdfadd9db..acf011b1ea 100644 --- a/plugins/action/wireless_profile.py +++ b/plugins/action/wireless_profile.py @@ -20,7 +20,6 @@ DNACSDK, dnac_argument_spec, dnac_compare_equality, - get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( InconsistentParameters, @@ -36,7 +35,7 @@ )) required_if = [ - ("state", "present", ["wirelessProfileName"], True), + ("state", "present", ["profileDetails"], True), ("state", "absent", ["wirelessProfileName"], True), ] required_one_of = [] diff --git a/plugins/modules/event_snmp_config_info.py b/plugins/modules/event_snmp_config_info.py index 0f4065ef90..b870816721 100644 --- a/plugins/modules/event_snmp_config_info.py +++ b/plugins/modules/event_snmp_config_info.py @@ -9,7 +9,9 @@ module: event_snmp_config_info short_description: Information module for Event Snmp Config description: -version_added: '3.1.0' +- Get all Event Snmp Config. +- Get SNMP Destination. +version_added: '6.7.0' extends_documentation_fragment: - cisco.dnac.module_info author: Rafael Campos (@racampos) @@ -17,21 +19,93 @@ headers: description: Additional headers. type: dict + configId: + description: + - ConfigId query parameter. List of SNMP configurations. + type: str + offset: + description: + - Offset query parameter. The number of SNMP configuration's to offset in the resultset whose default value 0. + type: int + limit: + description: + - Limit query parameter. The number of SNMP configuration's to limit in the resultset whose default value 10. + type: int + sortBy: + description: + - SortBy query parameter. SortBy field name. + type: str + order: + description: + - Order query parameter. + type: str requirements: -- dnacentersdk >= 2.4.9 -- python >= 3.5 +- dnacentersdk >= 2.6.0 +- python >= 3.9 +seealso: +- name: Cisco DNA Center documentation for Event Management GetSNMPDestination + description: Complete reference of the GetSNMPDestination API. + link: https://developer.cisco.com/docs/dna-center/#!get-snmp-destination notes: + - SDK Method used are + event_management.EventManagement.get_snmp_destination, + - Paths used are + get /dna/intent/api/v1/event/snmp-config, """ EXAMPLES = r""" +- name: Get all Event Snmp Config + cisco.dnac.event_snmp_config_info: + dnac_host: "{{dnac_host}}" + dnac_username: "{{dnac_username}}" + dnac_password: "{{dnac_password}}" + dnac_verify: "{{dnac_verify}}" + dnac_port: "{{dnac_port}}" + dnac_version: "{{dnac_version}}" + dnac_debug: "{{dnac_debug}}" + headers: "{{my_headers | from_json}}" + configId: string + offset: 0 + limit: 0 + sortBy: string + order: string + register: result + """ + RETURN = r""" dnac_response: description: A dictionary or list with the response returned by the Cisco DNAC Python SDK returned: always type: dict - sample: - - {} + sample: > + { + "errorMessage": { + "errors": [ + "string" + ] + }, + "apiStatus": "string", + "statusMessage": [ + { + "version": "string", + "tenantId": "string", + "configId": "string", + "name": "string", + "description": "string", + "ipAddress": "string", + "port": 0, + "snmpVersion": "string", + "community": "string", + "userName": "string", + "snmpMode": "string", + "snmpAuthType": "string", + "authPassword": "string", + "snmpPrivacyType": "string", + "privacyPassword": "string" + } + ] + } """ diff --git a/plugins/modules/lan_automation_update_device.py b/plugins/modules/lan_automation_update_device.py index 688e45b133..efcfcf90ec 100644 --- a/plugins/modules/lan_automation_update_device.py +++ b/plugins/modules/lan_automation_update_device.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: lan_automation_updateDevice +module: lan_automation_update_device short_description: Resource module for Lan Automation Updatedevice description: - Manage operation update of the resource Lan Automation Updatedevice. diff --git a/plugins/modules/network_device_config__info.py b/plugins/modules/network_device_config__info.py index ab41a0acac..fa2701582b 100644 --- a/plugins/modules/network_device_config__info.py +++ b/plugins/modules/network_device_config__info.py @@ -7,9 +7,9 @@ DOCUMENTATION = r""" --- module: network_device_config__info -short_description: Information module for Network Device Config +short_description: Information module for Network Device Config description: -- Get all Network Device Config . +- Get all Network Device Config. - > Returns the historical device configurations running configuration , startup configuration , vlan if applicable by specified criteria. @@ -67,7 +67,7 @@ """ EXAMPLES = r""" -- name: Get all Network Device Config +- name: Get all Network Device Config cisco.dnac.network_device_config__info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" diff --git a/plugins/modules/network_device_custom_prompt_info.py b/plugins/modules/network_device_custom_prompt_info.py index 06f247d00b..5228a1f00f 100644 --- a/plugins/modules/network_device_custom_prompt_info.py +++ b/plugins/modules/network_device_custom_prompt_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: network_device_custom_prompt_info_info +module: network_device_custom_prompt_info short_description: Information module for Network Device Custom Prompt Info description: - Get all Network Device Custom Prompt Info. @@ -37,7 +37,7 @@ EXAMPLES = r""" - name: Get all Network Device Custom Prompt Info - cisco.dnac.network_device_custom_prompt_info_info: + cisco.dnac.network_device_custom_prompt_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_anycast_gateways.py b/plugins/modules/sda_anycast_gateways.py index a53b86d0be..e8a5080221 100644 --- a/plugins/modules/sda_anycast_gateways.py +++ b/plugins/modules/sda_anycast_gateways.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_anycastGateways +module: sda_any_cast_gateways short_description: Resource module for Sda Anycastgateways description: - Manage operations create, update and delete of the resource Sda Anycastgateways. @@ -117,7 +117,7 @@ EXAMPLES = r""" - name: Update all - cisco.dnac.sda_anycastGateways: + cisco.dnac.sda_any_cast_gateways: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_anycast_gateways_count_info.py b/plugins/modules/sda_anycast_gateways_count_info.py index 76b979741f..e9bf1cf195 100644 --- a/plugins/modules/sda_anycast_gateways_count_info.py +++ b/plugins/modules/sda_anycast_gateways_count_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_anycastGateways_count_info +module: sda_anycast_gateways_count_info short_description: Information module for Sda Anycastgateways Count description: - Get all Sda Anycastgateways Count. @@ -57,7 +57,7 @@ EXAMPLES = r""" - name: Get all Sda Anycastgateways Count - cisco.dnac.sda_anycastGateways_count_info: + cisco.dnac.sda_anycast_gateways_count_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_anycast_gateways_info.py b/plugins/modules/sda_anycast_gateways_info.py index b37753e354..6a81154f59 100644 --- a/plugins/modules/sda_anycast_gateways_info.py +++ b/plugins/modules/sda_anycast_gateways_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_anycastGateways_info +module: sda_anycast_gateways_info short_description: Information module for Sda Anycastgateways description: - Get all Sda Anycastgateways. @@ -69,7 +69,7 @@ EXAMPLES = r""" - name: Get all Sda Anycastgateways - cisco.dnac.sda_anycastGateways_info: + cisco.dnac.sda_anycast_gateways_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_authentication_profiles.py b/plugins/modules/sda_authentication_profiles.py index c79e14ddee..ec31b797e5 100644 --- a/plugins/modules/sda_authentication_profiles.py +++ b/plugins/modules/sda_authentication_profiles.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_authenticationProfiles +module: sda_authentication_profiles short_description: Resource module for Sda Authenticationprofiles description: - Manage operation update of the resource Sda Authenticationprofiles. @@ -61,7 +61,7 @@ EXAMPLES = r""" - name: Update all - cisco.dnac.sda_authenticationProfiles: + cisco.dnac.sda_authentication_profiles: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_authentication_profiles_info.py b/plugins/modules/sda_authentication_profiles_info.py index bdacc510ae..27da6f55d8 100644 --- a/plugins/modules/sda_authentication_profiles_info.py +++ b/plugins/modules/sda_authentication_profiles_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_authenticationProfiles_info +module: sda_authentication_profiles_info short_description: Information module for Sda Authenticationprofiles description: - Get all Sda Authenticationprofiles. @@ -47,7 +47,7 @@ EXAMPLES = r""" - name: Get all Sda Authenticationprofiles - cisco.dnac.sda_authenticationProfiles_info: + cisco.dnac.sda_authentication_profiles_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_extranet_policies.py b/plugins/modules/sda_extranet_policies.py index 2f7eb409ad..8a4df37a30 100644 --- a/plugins/modules/sda_extranet_policies.py +++ b/plugins/modules/sda_extranet_policies.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_extranetPolicies +module: sda_extranet_policies short_description: Resource module for Sda Extranetpolicies description: - Manage operations create, update and delete of the resource Sda Extranetpolicies. @@ -75,7 +75,7 @@ EXAMPLES = r""" - name: Update all - cisco.dnac.sda_extranetPolicies: + cisco.dnac.sda_extranet_policies: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -94,7 +94,7 @@ - string - name: Create - cisco.dnac.sda_extranetPolicies: + cisco.dnac.sda_extranet_policies: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -112,7 +112,7 @@ - string - name: Delete by id - cisco.dnac.sda_extranetPolicies: + cisco.dnac.sda_extranet_policies: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_extranet_policies_count_info.py b/plugins/modules/sda_extranet_policies_count_info.py index c36637675f..37e163f95b 100644 --- a/plugins/modules/sda_extranet_policies_count_info.py +++ b/plugins/modules/sda_extranet_policies_count_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_extranetPolicies_count_info +module: sda_extranet_policies_count_info short_description: Information module for Sda Extranetpolicies Count description: - Get all Sda Extranetpolicies Count. @@ -37,7 +37,7 @@ EXAMPLES = r""" - name: Get all Sda Extranetpolicies Count - cisco.dnac.sda_extranetPolicies_count_info: + cisco.dnac.sda_extranet_policies_count_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_extranet_policies_info.py b/plugins/modules/sda_extranet_policies_info.py index af10423206..582ab76c63 100644 --- a/plugins/modules/sda_extranet_policies_info.py +++ b/plugins/modules/sda_extranet_policies_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_extranetPolicies_info +module: sda_extranet_policies_info short_description: Information module for Sda Extranetpolicies description: - Get all Sda Extranetpolicies. @@ -49,7 +49,7 @@ EXAMPLES = r""" - name: Get all Sda Extranetpolicies - cisco.dnac.sda_extranetPolicies_info: + cisco.dnac.sda_extranet_policies_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices.py b/plugins/modules/sda_fabric_devices.py index de78e18e40..2a886860d6 100644 --- a/plugins/modules/sda_fabric_devices.py +++ b/plugins/modules/sda_fabric_devices.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices +module: sda_fabric_devices short_description: Resource module for Sda Fabricdevices description: - Manage operations create, update and delete of the resource Sda Fabricdevices. @@ -122,7 +122,7 @@ EXAMPLES = r""" - name: Update all - cisco.dnac.sda_fabricDevices: + cisco.dnac.sda_fabric_devices: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -148,7 +148,7 @@ networkDeviceId: string - name: Delete all - cisco.dnac.sda_fabricDevices: + cisco.dnac.sda_fabric_devices: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -162,7 +162,7 @@ networkDeviceId: string - name: Create - cisco.dnac.sda_fabricDevices: + cisco.dnac.sda_fabric_devices: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -187,7 +187,7 @@ networkDeviceId: string - name: Delete by id - cisco.dnac.sda_fabricDevices: + cisco.dnac.sda_fabric_devices: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_count_info.py b/plugins/modules/sda_fabric_devices_count_info.py index 90cd980bb2..c3aba25bbb 100644 --- a/plugins/modules/sda_fabric_devices_count_info.py +++ b/plugins/modules/sda_fabric_devices_count_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices_count_info +module: sda_fabric_devices_count_info short_description: Information module for Sda Fabricdevices Count description: - Get all Sda Fabricdevices Count. @@ -49,7 +49,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricdevices Count - cisco.dnac.sda_fabricDevices_count_info: + cisco.dnac.sda_fabric_devices_count_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_info.py b/plugins/modules/sda_fabric_devices_info.py index dfa246004f..4c1ee703e0 100644 --- a/plugins/modules/sda_fabric_devices_info.py +++ b/plugins/modules/sda_fabric_devices_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices_info +module: sda_fabric_devices_info short_description: Information module for Sda Fabricdevices description: - Get all Sda Fabricdevices. @@ -57,7 +57,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricdevices - cisco.dnac.sda_fabricDevices_info: + cisco.dnac.sda_fabric_devices_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs.py b/plugins/modules/sda_fabric_devices_layer2_handoffs.py index 3499dd43e1..c968009933 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices_layer2Handoffs +module: sda_fabric_devices_layer2_handoffs short_description: Resource module for Sda Fabricdevices Layer2handoffs description: - Manage operations create, update and delete of the resource Sda Fabricdevices Layer2handoffs. @@ -76,7 +76,7 @@ EXAMPLES = r""" - name: Delete all - cisco.dnac.sda_fabricDevices_layer2Handoffs: + cisco.dnac.sda_fabric_devices_layer2_handoffs: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -89,7 +89,7 @@ networkDeviceId: string - name: Create - cisco.dnac.sda_fabricDevices_layer2Handoffs: + cisco.dnac.sda_fabric_devices_layer2_handoffs: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -106,7 +106,7 @@ networkDeviceId: string - name: Delete by id - cisco.dnac.sda_fabricDevices_layer2Handoffs: + cisco.dnac.sda_fabric_devices_layer2_handoffs: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_count_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_count_info.py index de3e733ecb..7af6f40eef 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs_count_info.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_count_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices_layer2Handoffs_count_info +module: sda_fabric_devices_layer2_handoffs_count_info short_description: Information module for Sda Fabricdevices Layer2handoffs Count description: - Get all Sda Fabricdevices Layer2handoffs Count. @@ -45,7 +45,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricdevices Layer2handoffs Count - cisco.dnac.sda_fabricDevices_layer2Handoffs_count_info: + cisco.dnac.sda_fabric_devices_layer2_handoffs_count_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_info.py index 1f05bc2ebd..e1d25bc30c 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs_info.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices_layer2Handoffs_info +module: sda_fabric_devices_layer2_handoffs_info short_description: Information module for Sda Fabricdevices Layer2handoffs description: - Get all Sda Fabricdevices Layer2handoffs. @@ -53,7 +53,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricdevices Layer2handoffs - cisco.dnac.sda_fabricDevices_layer2Handoffs_info: + cisco.dnac.sda_fabric_devices_layer2_handoffs_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits.py index 1a2dd38e7a..bc8a7f9e4f 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices_layer2Handoffs_ipTransits +module: sda_fabric_devices_layer2_handoffs_ip_transits short_description: Resource module for Sda Fabricdevices Layer2handoffs Iptransits description: - Manage operations create, update and delete of the resource Sda Fabricdevices Layer2handoffs Iptransits. @@ -119,7 +119,7 @@ EXAMPLES = r""" - name: Create - cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits: + cisco.dnac.sda_fabric_devices_layer2_handoffs_ip_transits: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -143,7 +143,7 @@ vlanId: 0 - name: Update all - cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits: + cisco.dnac.sda_fabric_devices_layer2_handoffs_ip_transits: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -168,7 +168,7 @@ vlanId: 0 - name: Delete all - cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits: + cisco.dnac.sda_fabric_devices_layer2_handoffs_ip_transits: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -181,7 +181,7 @@ networkDeviceId: string - name: Delete by id - cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits: + cisco.dnac.sda_fabric_devices_layer2_handoffs_ip_transits: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py index 2b2d4d2c27..92831f8f1b 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_count_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices_layer2Handoffs_ipTransits_count_info +module: sda_fabric_devices_layer2_handoffs_ip_transits_count_info short_description: Information module for Sda Fabricdevices Layer2handoffs Iptransits Count description: - Get all Sda Fabricdevices Layer2handoffs Iptransits Count. @@ -45,7 +45,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricdevices Layer2handoffs Iptransits Count - cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits_count_info: + cisco.dnac.sda_fabric_devices_layer2_handoffs_ip_transits_count_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_info.py index 495836cb7b..0adfdebe20 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_info.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_ip_transits_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices_layer2Handoffs_ipTransits_info +module: sda_fabric_devices_layer2_handoffs_ip_transits_info short_description: Information module for Sda Fabricdevices Layer2handoffs Iptransits description: - Get all Sda Fabricdevices Layer2handoffs Iptransits. @@ -53,7 +53,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricdevices Layer2handoffs Iptransits - cisco.dnac.sda_fabricDevices_layer2Handoffs_ipTransits_info: + cisco.dnac.sda_fabric_devices_layer2_handoffs_ip_transits_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py index fa7a8e5bb5..b0df228787 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices_layer2Handoffs_sdaTransits +module: sda_fabric_devices_layer2_handoffs__sda_transits short_description: Resource module for Sda Fabricdevices Layer2handoffs Sdatransits description: - Manage operations create, update and delete of the resource Sda Fabricdevices Layer2handoffs Sdatransits. @@ -90,7 +90,7 @@ EXAMPLES = r""" - name: Update all - cisco.dnac.sda_fabricDevices_layer2Handoffs_sdaTransits: + cisco.dnac.sda_fabric_devices_layer2_handoffs__sda_transits: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -109,7 +109,7 @@ transitNetworkId: string - name: Delete all - cisco.dnac.sda_fabricDevices_layer2Handoffs_sdaTransits: + cisco.dnac.sda_fabric_devices_layer2_handoffs__sda_transits: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -122,7 +122,7 @@ networkDeviceId: string - name: Create - cisco.dnac.sda_fabricDevices_layer2Handoffs_sdaTransits: + cisco.dnac.sda_fabric_devices_layer2_handoffs__sda_transits: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py index 224f078932..5cdca9e3b9 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices_layer2Handoffs_sdaTransits_count_info +module: sda_fabric_devices_layer2_handoffs__sda_transits_count_info short_description: Information module for Sda Fabricdevices Layer2handoffs Sdatransits Count description: - Get all Sda Fabricdevices Layer2handoffs Sdatransits Count. @@ -45,7 +45,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricdevices Layer2handoffs Sdatransits Count - cisco.dnac.sda_fabricDevices_layer2Handoffs_sdaTransits_count_info: + cisco.dnac.sda_fabric_devices_layer2_handoffs__sda_transits_count_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py index 1affe2f9c0..722f3e1d64 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricDevices_layer2Handoffs_sdaTransits_info +module: sda_fabric_devices_layer2_handoffs__sda_transits_info short_description: Information module for Sda Fabricdevices Layer2handoffs Sdatransits description: - Get all Sda Fabricdevices Layer2handoffs Sdatransits. @@ -53,7 +53,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricdevices Layer2handoffs Sdatransits - cisco.dnac.sda_fabricDevices_layer2Handoffs_sdaTransits_info: + cisco.dnac.sda_fabric_devices_layer2_handoffs__sda_transits_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_sites.py b/plugins/modules/sda_fabric_sites.py index 75676b0eff..2a20b982b2 100644 --- a/plugins/modules/sda_fabric_sites.py +++ b/plugins/modules/sda_fabric_sites.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricSites +module: sda_fabric_sites short_description: Resource module for Sda Fabricsites description: - Manage operations create, update and delete of the resource Sda Fabricsites. @@ -64,7 +64,7 @@ EXAMPLES = r""" - name: Create - cisco.dnac.sda_fabricSites: + cisco.dnac.sda_fabric_sites: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -79,7 +79,7 @@ siteId: string - name: Update all - cisco.dnac.sda_fabricSites: + cisco.dnac.sda_fabric_sites: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -95,7 +95,7 @@ siteId: string - name: Delete by id - cisco.dnac.sda_fabricSites: + cisco.dnac.sda_fabric_sites: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_sites_count_info.py b/plugins/modules/sda_fabric_sites_count_info.py index 17037a3fce..9bc70272ac 100644 --- a/plugins/modules/sda_fabric_sites_count_info.py +++ b/plugins/modules/sda_fabric_sites_count_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricSites_count_info +module: sda_fabric_sites_count_info short_description: Information module for Sda Fabricsites Count description: - Get all Sda Fabricsites Count. @@ -37,7 +37,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricsites Count - cisco.dnac.sda_fabricSites_count_info: + cisco.dnac.sda_fabric_sites_count_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_sites_info.py b/plugins/modules/sda_fabric_sites_info.py index cfc520572f..6e10d0198f 100644 --- a/plugins/modules/sda_fabric_sites_info.py +++ b/plugins/modules/sda_fabric_sites_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricSites_info +module: sda_fabric_sites_info short_description: Information module for Sda Fabricsites description: - Get all Sda Fabricsites. @@ -53,7 +53,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricsites - cisco.dnac.sda_fabricSites_info: + cisco.dnac.sda_fabric_sites_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_zones.py b/plugins/modules/sda_fabric_zones.py index b347e50a4d..2f5ca3bfcb 100644 --- a/plugins/modules/sda_fabric_zones.py +++ b/plugins/modules/sda_fabric_zones.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricZones +module: sda_fabric_zones short_description: Resource module for Sda Fabriczones description: - Manage operations create, update and delete of the resource Sda Fabriczones. @@ -63,7 +63,7 @@ EXAMPLES = r""" - name: Update all - cisco.dnac.sda_fabricZones: + cisco.dnac.sda_fabric_zones: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -78,7 +78,7 @@ siteId: string - name: Create - cisco.dnac.sda_fabricZones: + cisco.dnac.sda_fabric_zones: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -92,7 +92,7 @@ siteId: string - name: Delete by id - cisco.dnac.sda_fabricZones: + cisco.dnac.sda_fabric_zones: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_zones_count_info.py b/plugins/modules/sda_fabric_zones_count_info.py index 153f931bc5..b925a188de 100644 --- a/plugins/modules/sda_fabric_zones_count_info.py +++ b/plugins/modules/sda_fabric_zones_count_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricZones_count_info +module: sda_fabric_zones_count_info short_description: Information module for Sda Fabriczones Count description: - Get all Sda Fabriczones Count. @@ -37,7 +37,7 @@ EXAMPLES = r""" - name: Get all Sda Fabriczones Count - cisco.dnac.sda_fabricZones_count_info: + cisco.dnac.sda_fabric_zones_count_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_zones_info.py b/plugins/modules/sda_fabric_zones_info.py index 8825b8ef83..fed42f535a 100644 --- a/plugins/modules/sda_fabric_zones_info.py +++ b/plugins/modules/sda_fabric_zones_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabricZones_info +module: sda_fabric_zones_info short_description: Information module for Sda Fabriczones description: - Get all Sda Fabriczones. @@ -53,7 +53,7 @@ EXAMPLES = r""" - name: Get all Sda Fabriczones - cisco.dnac.sda_fabricZones_info: + cisco.dnac.sda_fabric_zones_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_port_assignments.py b/plugins/modules/sda_port_assignments.py index 0670e803ef..ccaded080d 100644 --- a/plugins/modules/sda_port_assignments.py +++ b/plugins/modules/sda_port_assignments.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_portAssignments +module: sda_port_assignments short_description: Resource module for Sda Portassignments description: - Manage operations create, update and delete of the resource Sda Portassignments. @@ -101,7 +101,7 @@ EXAMPLES = r""" - name: Create - cisco.dnac.sda_portAssignments: + cisco.dnac.sda_port_assignments: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -122,7 +122,7 @@ voiceVlanName: string - name: Update all - cisco.dnac.sda_portAssignments: + cisco.dnac.sda_port_assignments: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -144,7 +144,7 @@ voiceVlanName: string - name: Delete all - cisco.dnac.sda_portAssignments: + cisco.dnac.sda_port_assignments: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -160,7 +160,7 @@ voiceVlanName: string - name: Delete by id - cisco.dnac.sda_portAssignments: + cisco.dnac.sda_port_assignments: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_port_assignments_count_info.py b/plugins/modules/sda_port_assignments_count_info.py index 82e3b42c4f..6c81f99f6d 100644 --- a/plugins/modules/sda_port_assignments_count_info.py +++ b/plugins/modules/sda_port_assignments_count_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_portAssignments_count_info +module: sda_port_assignments_count_info short_description: Information module for Sda Portassignments Count description: - Get all Sda Portassignments Count. @@ -57,7 +57,7 @@ EXAMPLES = r""" - name: Get all Sda Portassignments Count - cisco.dnac.sda_portAssignments_count_info: + cisco.dnac.sda_port_assignments_count_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_port_assignments_info.py b/plugins/modules/sda_port_assignments_info.py index e6596a3e93..817d48f436 100644 --- a/plugins/modules/sda_port_assignments_info.py +++ b/plugins/modules/sda_port_assignments_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_portAssignments_info +module: sda_port_assignments_info short_description: Information module for Sda Portassignments description: - Get all Sda Portassignments. @@ -65,7 +65,7 @@ EXAMPLES = r""" - name: Get all Sda Portassignments - cisco.dnac.sda_portAssignments_info: + cisco.dnac.sda_port_assignments_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_provision_devices.py b/plugins/modules/sda_provision_devices.py index 493a7a04e5..69dff062ba 100644 --- a/plugins/modules/sda_provision_devices.py +++ b/plugins/modules/sda_provision_devices.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_provisionDevices +module: sda_provision_devices short_description: Resource module for Sda Provisiondevices description: - Manage operations create, update and delete of the resource Sda Provisiondevices. @@ -71,7 +71,7 @@ EXAMPLES = r""" - name: Delete all - cisco.dnac.sda_provisionDevices: + cisco.dnac.sda_provision_devices: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -84,7 +84,7 @@ siteId: string - name: Create - cisco.dnac.sda_provisionDevices: + cisco.dnac.sda_provision_devices: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -98,7 +98,7 @@ siteId: string - name: Update all - cisco.dnac.sda_provisionDevices: + cisco.dnac.sda_provision_devices: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -113,7 +113,7 @@ siteId: string - name: Delete by id - cisco.dnac.sda_provisionDevices: + cisco.dnac.sda_provision_devices: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_provision_devices_count_info.py b/plugins/modules/sda_provision_devices_count_info.py index 50ef2b8afe..b733a2ad75 100644 --- a/plugins/modules/sda_provision_devices_count_info.py +++ b/plugins/modules/sda_provision_devices_count_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_provisionDevices_count_info +module: sda_provision_devices_count_info short_description: Information module for Sda Provisiondevices Count description: - Get all Sda Provisiondevices Count. @@ -41,7 +41,7 @@ EXAMPLES = r""" - name: Get all Sda Provisiondevices Count - cisco.dnac.sda_provisionDevices_count_info: + cisco.dnac.sda_provision_devices_count_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_provision_devices_info.py b/plugins/modules/sda_provision_devices_info.py index 253ce600f8..464cf3ec1e 100644 --- a/plugins/modules/sda_provision_devices_info.py +++ b/plugins/modules/sda_provision_devices_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_provisionDevices_info +module: sda_provision_devices_info short_description: Information module for Sda Provisiondevices description: - Get all Sda Provisiondevices. @@ -57,7 +57,7 @@ EXAMPLES = r""" - name: Get all Sda Provisiondevices - cisco.dnac.sda_provisionDevices_info: + cisco.dnac.sda_provision_devices_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" From d771b44d8fbd8db5b3f95616b9e4843c922386ec Mon Sep 17 00:00:00 2001 From: bvargasre Date: Fri, 31 May 2024 19:15:57 -0600 Subject: [PATCH 358/358] Fix inconsistent parameters import and module names -pep8 -pylint -validate-modules --- plugins/action/sda_fabric_devices_layer2_handoffs.py | 1 + plugins/action/sda_virtual_network.py | 1 - plugins/modules/sda_anycast_gateways.py | 4 ++-- .../sda_fabric_devices_layer2_handoffs_sda_transits.py | 8 ++++---- ...ric_devices_layer2_handoffs_sda_transits_count_info.py | 4 ++-- ...da_fabric_devices_layer2_handoffs_sda_transits_info.py | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/action/sda_fabric_devices_layer2_handoffs.py b/plugins/action/sda_fabric_devices_layer2_handoffs.py index 3a018c352e..6655e5b6a2 100644 --- a/plugins/action/sda_fabric_devices_layer2_handoffs.py +++ b/plugins/action/sda_fabric_devices_layer2_handoffs.py @@ -44,6 +44,7 @@ mutually_exclusive = [] required_together = [] + class SdaFabricDevicesLayer2Handoffs(object): def __init__(self, params, dnac): self.dnac = dnac diff --git a/plugins/action/sda_virtual_network.py b/plugins/action/sda_virtual_network.py index a116f29949..5f8405abab 100644 --- a/plugins/action/sda_virtual_network.py +++ b/plugins/action/sda_virtual_network.py @@ -23,7 +23,6 @@ get_dict_result, ) from ansible_collections.cisco.dnac.plugins.plugin_utils.exceptions import ( - InconsistentParameters, AnsibleSDAException, ) diff --git a/plugins/modules/sda_anycast_gateways.py b/plugins/modules/sda_anycast_gateways.py index e8a5080221..70080060d4 100644 --- a/plugins/modules/sda_anycast_gateways.py +++ b/plugins/modules/sda_anycast_gateways.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_any_cast_gateways +module: sda_anycast_gateways short_description: Resource module for Sda Anycastgateways description: - Manage operations create, update and delete of the resource Sda Anycastgateways. @@ -117,7 +117,7 @@ EXAMPLES = r""" - name: Update all - cisco.dnac.sda_any_cast_gateways: + cisco.dnac.sda_anycast_gateways: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py index b0df228787..a0097961ed 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabric_devices_layer2_handoffs__sda_transits +module: sda_fabric_devices_layer2_handoffs_sda_transits short_description: Resource module for Sda Fabricdevices Layer2handoffs Sdatransits description: - Manage operations create, update and delete of the resource Sda Fabricdevices Layer2handoffs Sdatransits. @@ -90,7 +90,7 @@ EXAMPLES = r""" - name: Update all - cisco.dnac.sda_fabric_devices_layer2_handoffs__sda_transits: + cisco.dnac.sda_fabric_devices_layer2_handoffs_sda_transits: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -109,7 +109,7 @@ transitNetworkId: string - name: Delete all - cisco.dnac.sda_fabric_devices_layer2_handoffs__sda_transits: + cisco.dnac.sda_fabric_devices_layer2_handoffs_sda_transits: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" @@ -122,7 +122,7 @@ networkDeviceId: string - name: Create - cisco.dnac.sda_fabric_devices_layer2_handoffs__sda_transits: + cisco.dnac.sda_fabric_devices_layer2_handoffs_sda_transits: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py index 5cdca9e3b9..6b6d210249 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_count_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabric_devices_layer2_handoffs__sda_transits_count_info +module: sda_fabric_devices_layer2_handoffs_sda_transits_count_info short_description: Information module for Sda Fabricdevices Layer2handoffs Sdatransits Count description: - Get all Sda Fabricdevices Layer2handoffs Sdatransits Count. @@ -45,7 +45,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricdevices Layer2handoffs Sdatransits Count - cisco.dnac.sda_fabric_devices_layer2_handoffs__sda_transits_count_info: + cisco.dnac.sda_fabric_devices_layer2_handoffs_sda_transits_count_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}" diff --git a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py index 722f3e1d64..36b4249ff1 100644 --- a/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py +++ b/plugins/modules/sda_fabric_devices_layer2_handoffs_sda_transits_info.py @@ -6,7 +6,7 @@ DOCUMENTATION = r""" --- -module: sda_fabric_devices_layer2_handoffs__sda_transits_info +module: sda_fabric_devices_layer2_handoffs_sda_transits_info short_description: Information module for Sda Fabricdevices Layer2handoffs Sdatransits description: - Get all Sda Fabricdevices Layer2handoffs Sdatransits. @@ -53,7 +53,7 @@ EXAMPLES = r""" - name: Get all Sda Fabricdevices Layer2handoffs Sdatransits - cisco.dnac.sda_fabric_devices_layer2_handoffs__sda_transits_info: + cisco.dnac.sda_fabric_devices_layer2_handoffs_sda_transits_info: dnac_host: "{{dnac_host}}" dnac_username: "{{dnac_username}}" dnac_password: "{{dnac_password}}"