Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ansible_collections/juniper/device/.ansible-lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
profile: production

exclude_paths:
- changelogs/config.yaml
- tests/sanity
119 changes: 119 additions & 0 deletions ansible_collections/juniper/device/CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
=======================================
Juniper Device Collection Release Notes
=======================================

===========================
Changelog for Juniper Device Ansible Collection
===========================

Version 1.0.8 (2025-04-28)
---------------------------
Enhancements
------------
- Supported juniper.device.software: VMHost device software upgrade with version check to use the details of "show vmhost version" (#709).
- Supported ansible-test sanity unit test and pytest framework (#718).
- Supported ansible-test network-integration framework (#713).

Bugs Fixed
----------
- Fixed typo in juniper.device.config module with format: "json" (#711).

Version 1.0.7 (2024-12-19)
---------------------------
Enhancements
------------
- None.

Bugs Fixed
----------
- Fixed galaxy.yml "documentation" link (#692).
- Code formatting (trailing-whitespace removal, end-of-file-fixer, sort the import namespaces, Black validation) (#699, #701).
- Fixed version extraction from image filename for EX2300 firmware (#695).
- Fixed JSON response handling (#690, #703).
- Updated Dockerfile to include latest junos-eznc, jsnapy, and ansible modules (#707).
- Added DOCKER-EXAMPLES.md file.

Version 1.0.6 (2024-08-27)
---------------------------
Enhancements
------------
- Introduced `dest_dir` parameter to save the failed JSNAPy tests (#678).

Bugs Fixed
----------
- Fixed handling of ping failures when traffic-loss values are of type float (#672).
- Fixed `SyntaxWarning: invalid escape sequence '*'` emitted during ansible-playbook execution (#674).
- Fixed RPC exception handling when RPC is not supported on the platform while using persistent connection (#677).

Version 1.0.5 (2024-05-22)
---------------------------
Enhancements
------------
- Introduced new module `file_copy` to support SCP put and get options.

Bugs Fixed
----------
- Added timeout argument for configuration commit RPC (#607).
- Fixed ansible playbook coding style issues using ansible-lint tool (#623, #553).
- Support for relative paths for source configuration file added for PyEZ persistent connection (#580).
- Fixed exception handling for software install (#662).
- Fixed config module to perform all commit options (#660).

Version 1.0.4 (2024-04-30)
---------------------------
Enhancements
------------
- None.

Bugs Fixed
----------
- Added inventory template file to run ansible functional test cases for local and PyEZ persistent connection (#645).
- Updated command and config playbook-related test cases (#645).
- Fixed PyEZ connection rollback configuration issue (#645).
- Normalized value not passed correctly in PyEZ connection `rpc.ping()` API (#646).
- Fixed JSON encoder error "TypeError: Object of type function is not JSON serializable" (#647).
- Fixed persistent connection reboot exception handler for `ConnectionError` (#649).
- Module `snapy.py`: Added code for persistent PyEZ connection check and called `invoke_jsnapy` with required arguments (#650).
- Module `pyez.py`: Updated snapcheck — replaced `file_name` with `pre_file` argument (#650).

Version 1.0.3 (2024-01-25)
---------------------------
Enhancements
------------
- Supported configuration mode options: private, batch, dynamic, exclusive, and ephemeral (#635).
- Supported power-off functionality on VM host devices (#636).
- Supported installation of JUNOS package on specific member of VC (#613, #397).
- The Read the Docs build system will now require a configuration file `v2 (.readthedocs.yaml)` (#621).

Bugs Fixed
----------
- Updated the documentation link in `jsnapy.rst` and `snapy.py` (#612).
- Fixed issue where passing through credentials on the command line using `-u`, `-k`, or `--private-key` wasn't working after ansible-core 2.13 (#592).
- Fixed `Sphinx` object has no attribute 'add_stylesheet' with Sphinx 7.2.6 (#630).
- Fixed executing RPC with filters returning AttributeError: `'JuniperJunosModule' object has no attribute '_check_type_dict'` (#620).
- Fixed ansible PEZ exception issue when committing the configuration (#638).

Version 1.0.2 (2022-11-16)
---------------------------
Enhancements
------------
- Added changelogs (#596).
- Introduced `commit_sync` and `commit_force_sync` under `juniper.device.config` module (#525).

Bugs Fixed
----------
- Updated functional test playbooks (#598, #600, #603).

Version 1.0.1 (2021-10-05)
---------------------------
Bugs Fixed
----------
- Added `allow_bool_value` flag to be passed for RPC to support boolean values (#538).
- Fixed etree import issue when `libxml2` not installed (#558).

Version 1.0.0 (2021-04-23)
---------------------------
Features Added
--------------
- First release to support Junos modules for Ansible collections.

9 changes: 3 additions & 6 deletions ansible_collections/juniper/device/docs/.readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2
version: 2 # Required version of the configuration file

# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
Expand All @@ -15,8 +13,7 @@ build:
sphinx:
configuration: ansible_collections/juniper/device/docs/conf.py

# We recommend specifying your dependencies to enable reproducible builds:
# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
# Reproducible builds guide: https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: ansible_collections/juniper/device/docs/docreq.txt
- requirements: ansible_collections/juniper/device/docs/docreq.txt
15 changes: 11 additions & 4 deletions ansible_collections/juniper/device/galaxy.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### REQUIRED
# REQUIRED

# The namespace of the collection. This can be a company/brand/organization or product namespace under which all
# content lives. May only contain alphanumeric characters and underscores. Additionally namespaces cannot start with
Expand All @@ -17,19 +17,26 @@ readme: README.md
# A list of the collection's content authors. Can be just the name or in the format 'Full Name <email> (url)
# @nicks:irc/im.site#channel'
authors:
- Juniper Networks <jnpr-community-netdev@juniper.net>
- Juniper Networks <jnpr-community-netdev@juniper.net>

# A short summary description of the collection
description: set of Ansible modules that perform specific operational and configuration tasks on devices running Junos OS.

# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only
# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file'
license:
- Apache-2.0
- Apache-2.0

# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character
# requirements as 'namespace' and 'name'
tags: ['juniper', 'junos', 'network']
tags:
- juniper
- junos
- networking

# Ignore docs configuration
build_ignore:
- antsibull-docs.cfg

# Collections that this collection requires to be installed for it to be usable. The key of the dict is the
# collection label 'namespace.name'. The value is a version range
Expand Down
2 changes: 1 addition & 1 deletion ansible_collections/juniper/device/meta/runtime.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
requires_ansible: ">=2.10"
requires_ansible: ">=2.17.0"
40 changes: 19 additions & 21 deletions ansible_collections/juniper/device/plugins/connection/pyez.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,8 @@ def rollback_configuration(self, id):
self.config.rescue(action="reload")
self.queue_message("log", "Rescue configuration loaded.")
except (
self.pyez_exception.RpcError,
self.pyez_exception.ConnectError,
pyez_exception.RpcError,
pyez_exception.ConnectError,
) as ex:
raise AnsibleError(
"Unable to load the rescue configuraton: " "%s" % (str(ex))
Expand All @@ -707,8 +707,8 @@ def rollback_configuration(self, id):
"log", "Rollback {} configuration loaded.".format(id)
)
except (
self.pyez_exception.RpcError,
self.pyez_exception.ConnectError,
pyez_exception.RpcError,
pyez_exception.ConnectError,
) as ex:
raise AnsibleError(
"Unable to load the rollback %d " "configuraton: %s" % (id, str(ex))
Expand All @@ -727,7 +727,7 @@ def check_configuration(self):
try:
self.config.commit_check()
self.queue_message("log", "Configuration checked.")
except (self.pyez_exception.RpcError, self.pyez_exception.ConnectError) as ex:
except (pyez_exception.RpcError, pyez_exception.ConnectError) as ex:
raise AnsibleError("Failure checking the configuraton: %s" % (str(ex)))

def diff_configuration(self, ignore_warning=False):
Expand All @@ -743,7 +743,7 @@ def diff_configuration(self, ignore_warning=False):
diff = self.config.diff(rb_id=0, ignore_warning=ignore_warning)
self.queue_message("log", "Configuration diff completed.")
return diff
except (self.pyez_exception.RpcError, self.pyez_exception.ConnectError) as ex:
except (pyez_exception.RpcError, pyez_exception.ConnectError) as ex:
raise AnsibleError("Failure diffing the configuraton: %s" % (str(ex)))

def load_configuration(self, config, load_args):
Expand All @@ -760,7 +760,7 @@ def load_configuration(self, config, load_args):
self.queue_message("log", "Load args %s." % str(load_args))
self.config.load(**load_args)
self.queue_message("log", "Configuration loaded.")
except (self.pyez_exception.RpcError, self.pyez_exception.ConnectError) as ex:
except (pyez_exception.RpcError, pyez_exception.ConnectError) as ex:
raise AnsibleError("Failure loading the configuraton: %s" % (str(ex)))

def commit_configuration(
Expand Down Expand Up @@ -797,7 +797,7 @@ def commit_configuration(
sync=sync,
)
self.queue_message("log", "Configuration committed.")
except (self.pyez_exception.RpcError, self.pyez_exception.ConnectError) as ex:
except (pyez_exception.RpcError, pyez_exception.ConnectError) as ex:
raise AnsibleError("Failure committing the configuraton: %s" % (str(ex)))

def system_api(
Expand Down Expand Up @@ -837,17 +837,17 @@ def system_api(
msg = "Did not find expected RPC response."
else:
msg = "%s successfully initiated. Response got %s" % (action, got)
except self.pyez_exception.RpcTimeoutError as ex:
except pyez_exception.RpcTimeoutError as ex:
try:
self.close(raise_exceptions=True)
# This means the device wasn't already disconnected.
raise AnsibleError(
"%s failed. %s may not have been " "initiated." % (action, action)
)
except (self.pyez_exception.RpcError, self.pyez_exception.ConnectError):
except (pyez_exception.RpcError, pyez_exception.ConnectError):
# This is expected. The device has already disconnected.
msg = "%s succeeded." % (action)
except (self.pyez_exception.RpcError, self.pyez_exception.ConnectError) as ex:
except (pyez_exception.RpcError, pyez_exception.ConnectError) as ex:
raise AnsibleError("%s failed. Error: %s" % (action, str(ex)))
return msg

Expand All @@ -864,7 +864,7 @@ def software_api(self, install_params):
)
self.queue_message("log", str(msg))
return msg
except (self.pyez_exception.ConnectError, self.pyez_exception.RpcError) as ex:
except (pyez_exception.ConnectError, pyez_exception.RpcError) as ex:
raise AnsibleError("Installation failed. Error: %s" % str(ex))

def reboot_api(self, all_re, vmhost, member_id=None):
Expand All @@ -891,26 +891,24 @@ def reboot_api(self, all_re, vmhost, member_id=None):
if got is not None:
msg += " Reboot successfully initiated. " "Reboot message: %s" % got
else:
raise AnsibleError(
" Did not find expected response from reboot RPC. "
)
raise AnsibleError(" Did not find expected response from reboot RPC. ")
except self.pyez_exception.RpcTimeoutError as ex:
try:
self.close(raise_exceptions=True)
# This means the device wasn't already disconnected.
raise AnsibleError(" Reboot failed. It may not have been initiated.")
except (
self.pyez_exception.RpcError,
self.pyez_exception.RpcTimeoutError,
self.pyez_exception.ConnectError,
pyez_exception.RpcError,
pyez_exception.RpcTimeoutError,
pyez_exception.ConnectError,
):
# This is expected. The device has already disconnected.
msg += " Reboot succeeded."
except self.ncclient_exception.TimeoutExpiredError:
# This is not really expected. Still consider reboot success as
# Looks like rpc was consumed but no response as its rebooting.
msg += " Reboot succeeded. Ignoring close error."
except (self.pyez_exception.RpcError, self.pyez_exception.ConnectError) as ex:
except (pyez_exception.RpcError, pyez_exception.ConnectError) as ex:
raise AnsibleError(" Reboot failed. Error: %s" % (str(ex)))
else:
try:
Expand All @@ -932,7 +930,7 @@ def scp_file_copy_put(self, local_file, remote_file):
try:
with SCP(self.dev, progress=True) as scp:
scp.put(local_file, remote_file)
except (self.pyez_exception.RpcError, self.pyez_exception.ConnectError) as ex:
except (pyez_exception.RpcError, pyez_exception.ConnectError) as ex:
raise AnsibleError(
"Failure checking the configuraton: {0}".format(str(ex))
) from ex
Expand All @@ -947,7 +945,7 @@ def scp_file_copy_get(self, remote_file, local_file):
try:
with SCP(self.dev, progress=True) as scp:
scp.get(remote_file, local_file)
except (self.pyez_exception.RpcError, self.pyez_exception.ConnectError) as ex:
except (pyez_exception.RpcError, pyez_exception.ConnectError) as ex:
raise AnsibleError(
"Failure checking the configuraton: {0}".format(str(ex))
) from ex
4 changes: 2 additions & 2 deletions ansible_collections/juniper/device/plugins/modules/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@
var: item.stdout
with_items: "{{ response.results }}"

- name: show route with XML output - show version with JSON output
- name: Show route with XML output - show version with JSON output
juniper.device.command:
commands:
- "show route"
Expand All @@ -200,7 +200,7 @@
dest_dir: "../Output"
return_output: false

- name: save output to dest
- name: Save output to dest
juniper.device.command:
command:
- "show route"
Expand Down
8 changes: 4 additions & 4 deletions ansible_collections/juniper/device/plugins/modules/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -744,12 +744,12 @@
port: "22"
retrieve: 'committed'
format: xml
commit: no
check: no
diff: no
commit: false
check: false
diff: false
dest_dir: "/tmp/"
filter: <configuration><groups><name>re0</name></groups></configuration>
return_output: True
return_output: true
register: config_output
"""

Expand Down
4 changes: 2 additions & 2 deletions ansible_collections/juniper/device/plugins/modules/jsnapy.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@

- name: Test based on a test_file directly
juniper.device.jsnapy:
action: "snapcheck"
test_files: "tests/test_junos_interface.yaml"
action: "snapcheck"
test_files: "tests/test_junos_interface.yaml"
register: test2
- name: Verify all JSNAPy tests passed
ansible.builtin.assert:
Expand Down
7 changes: 4 additions & 3 deletions ansible_collections/juniper/device/plugins/modules/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@
- name: "Execute RPC with filters"
juniper.device.rpc:
rpcs:
- "get-config"
- "get-config"
format: xml
filter: <configuration><groups><name>re0</name></groups></configuration>
attr: name=re0
Expand Down Expand Up @@ -255,10 +255,11 @@
rpc: get-interface-information
kwargs:
interface_name: em1
media: True
media: true
format: json
dest: get_interface_information.conf
register: junos"""
register: junos
"""

RETURN = """
attrs:
Expand Down
Loading