Skip to content

Commit

Permalink
Adds Software Version module
Browse files Browse the repository at this point in the history
  • Loading branch information
joewesch committed Jan 28, 2025
1 parent 6de24ff commit 1968bbb
Show file tree
Hide file tree
Showing 6 changed files with 331 additions and 0 deletions.
3 changes: 3 additions & 0 deletions plugins/module_utils/dcim.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
NB_RACK_GROUPS = "rack_groups"
NB_REAR_PORTS = "rear_ports"
NB_REAR_PORT_TEMPLATES = "rear_port_templates"
NB_SOFTWARE_VERSIONS = "software_versions"
NB_VIRTUAL_CHASSIS = "virtual_chassis"


Expand Down Expand Up @@ -117,6 +118,8 @@ def run(self):
name = self.module.params["data"]["master"]
elif data.get("id"):
name = data["id"]
elif endpoint_name == "software_version":
name = data["version"]
elif endpoint_name == "cable":
if self.module.params["termination_a"].get("name"):
termination_a_name = self.module.params["termination_a"]["name"]
Expand Down
4 changes: 4 additions & 0 deletions plugins/module_utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"rack_groups",
"rear_ports",
"rear_port_templates",
"software_versions",
"virtual_chassis",
],
extras=[
Expand Down Expand Up @@ -167,6 +168,7 @@
rear_port_template="name",
rir="name",
route_targets="name",
software_version="version",
status="name",
tenant="name",
tenant_group="name",
Expand Down Expand Up @@ -343,6 +345,7 @@
"route_targets": "route_target",
"services": "services",
"static_group_associations": "static_group_association",
"software_versions": "software_version",
"statuses": "statuses",
"tags": "tags",
"teams": "team",
Expand Down Expand Up @@ -449,6 +452,7 @@
"role": set(["name"]),
"route_target": set(["name"]),
"services": set(["device", "virtual_machine", "name", "port", "protocol"]),
"software_version": set(["version", "platform"]),
"static_group_association": set(["dynamic_group", "associated_object_type", "associated_object_id"]),
"statuses": set(["name"]),
"tags": set(["name"]),
Expand Down
162 changes: 162 additions & 0 deletions plugins/modules/software_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2025, Network to Code (@networktocode) <[email protected]>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function

__metaclass__ = type

DOCUMENTATION = r"""
---
module: software_version
short_description: Creates, updates or removes software versions from Nautobot
description:
- Creates, updates or removes software versions from Nautobot
notes:
- This module requires Nautobot v2.2+
- This should be ran with connection C(local) and hosts C(localhost)
- Tags should be defined as a YAML list
author:
- Joe Wesch (@joewesch)
requirements:
- pynautobot
version_added: "5.7.0"
extends_documentation_fragment:
- networktocode.nautobot.fragments.base
- networktocode.nautobot.fragments.tags
- networktocode.nautobot.fragments.custom_fields
options:
version:
description:
- The version of the software
required: true
type: str
platform:
description:
- The platform the software will be applied to
- Required if I(state=present) and does not exist yet
required: false
type: raw
status:
description:
- The status of the software
- Required if I(state=present) and does not exist yet
required: false
type: str
alias:
description:
- Optional alternative label for this version
required: false
type: str
release_date:
description:
- The date the software was released
required: false
type: str
end_of_support_date:
description:
- The date the software will no longer be supported
required: false
type: str
documentation_url:
description:
- URL to the software documentation
required: false
type: str
long_term_support:
description:
- Whether the software is long term support
required: false
type: bool
pre_release:
description:
- Whether the software is pre-release
required: false
type: bool
"""

EXAMPLES = r"""
---
- name: Create a software version
networktocode.nautobot.software_version:
url: http://nautobot.local
token: thisIsMyToken
version: 1.0.0
platform: Cisco IOS
status: Active
alias: My Alias
release_date: 2024-01-01
end_of_support_date: 2024-12-31
documentation_url: https://example.com
long_term_support: true
pre_release: false
state: present
- name: Update a software version
networktocode.nautobot.software_version:
url: http://nautobot.local
token: thisIsMyToken
version: 1.0.0
state: present
- name: Delete a software version
networktocode.nautobot.software_version:
url: http://nautobot.local
token: thisIsMyToken
version: 1.0.0
state: absent
"""

RETURN = r"""
software_version:
description: Serialized object as created or already existent within Nautobot
returned: success (when I(state=present))
type: dict
msg:
description: Message indicating failure or info about what has been achieved
returned: always
type: str
"""

from ansible_collections.networktocode.nautobot.plugins.module_utils.utils import (
NAUTOBOT_ARG_SPEC,
TAGS_ARG_SPEC,
CUSTOM_FIELDS_ARG_SPEC,
)
from ansible_collections.networktocode.nautobot.plugins.module_utils.dcim import (
NautobotDcimModule,
NB_SOFTWARE_VERSIONS,
)
from ansible.module_utils.basic import AnsibleModule
from copy import deepcopy


def main():
"""
Main entry point for module execution
"""
argument_spec = deepcopy(NAUTOBOT_ARG_SPEC)
argument_spec.update(deepcopy(TAGS_ARG_SPEC))
argument_spec.update(deepcopy(CUSTOM_FIELDS_ARG_SPEC))
argument_spec.update(
dict(
version=dict(required=True, type="str"),
platform=dict(required=False, type="raw"),
status=dict(required=False, type="str"),
alias=dict(required=False, type="str"),
release_date=dict(required=False, type="str"),
end_of_support_date=dict(required=False, type="str"),
documentation_url=dict(required=False, type="str"),
long_term_support=dict(required=False, type="bool"),
pre_release=dict(required=False, type="bool"),
)
)

module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
software_version = NautobotDcimModule(module, NB_SOFTWARE_VERSIONS)
software_version.run()


if __name__ == "__main__": # pragma: no cover
main()
3 changes: 3 additions & 0 deletions tests/integration/nautobot-populate.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ def make_nautobot_calls(endpoint, payload):
cisco_manu = nb.dcim.manufacturers.get(name="Cisco")
arista_manu = nb.dcim.manufacturers.get(name="Arista")

# Create Platforms
platforms = [{"name": "Cisco IOS", "manufacturer": cisco_manu.id, "network_driver": "cisco_ios", "napalm_driver": "ios"}]
created_platforms = make_nautobot_calls(nb.dcim.platforms, platforms)

# Create Device Types
device_types = [
Expand Down
8 changes: 8 additions & 0 deletions tests/integration/targets/latest/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,14 @@
tags:
- vlan_location

- name: "PYNAUTOBOT_SOFTWARE_VERSION TESTS"
include_tasks:
file: "software_version.yml"
apply:
tags:
- software_version
tags:
- software_version

##########################
##
Expand Down
151 changes: 151 additions & 0 deletions tests/integration/targets/latest/tasks/software_version.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
---
- set_fact:
cisco_ios_platform: "{{ lookup('networktocode.nautobot.lookup', 'platforms', api_endpoint=nautobot_url, token=nautobot_token, api_filter='name=\"Cisco IOS\"') }}"

- name: "SOFTWARE VERSION 1: Necessary info creation"
networktocode.nautobot.software_version:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
version: "1.0.0"
platform: "Cisco IOS"
status: "Active"
state: present
register: test_one

- name: "SOFTWARE VERSION 1: ASSERT - Necessary info creation"
assert:
that:
- test_one is changed
- test_one['diff']['before']['state'] == "absent"
- test_one['diff']['after']['state'] == "present"
- test_one['software_version']['version'] == "1.0.0"
- test_one['msg'] == "software_version 1.0.0 created"

- name: "SOFTWARE VERSION 2: Create duplicate"
networktocode.nautobot.software_version:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
version: "1.0.0"
platform: "Cisco IOS"
state: present
register: test_two_duplicate

- name: "SOFTWARE VERSION 2: ASSERT - Create duplicate"
assert:
that:
- not test_two_duplicate['changed']
- test_two_duplicate['software_version']['version'] == "1.0.0"
- test_two_duplicate['msg'] == "software_version 1.0.0 already exists"

- name: "SOFTWARE VERSION 3: Create with all info"
networktocode.nautobot.software_version:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
version: "1.1.0"
platform: "Cisco IOS"
status: "Active"
release_date: "2024-01-01"
end_of_support_date: "2025-01-01"
documentation_url: "https://example.com"
long_term_support: true
pre_release: false
state: present
register: test_three

- name: "SOFTWARE VERSION 3: ASSERT - Create with all info"
assert:
that:
- test_three is changed
- test_three['diff']['before']['state'] == "absent"
- test_three['diff']['after']['state'] == "present"
- test_three['software_version']['version'] == "1.1.0"
- test_three['software_version']['platform'] == cisco_ios_platform['key']
- test_three['software_version']['status'] == active['key']
- test_three['software_version']['release_date'] == "2024-01-01"
- test_three['software_version']['end_of_support_date'] == "2025-01-01"
- test_three['software_version']['documentation_url'] == "https://example.com"
- test_three['software_version']['long_term_support'] == true
- test_three['software_version']['pre_release'] == false
- test_three['msg'] == "software_version 1.1.0 created"

- name: "SOFTWARE VERSION 4: Create with all info duplicate"
networktocode.nautobot.software_version:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
version: "1.1.0"
platform: "Cisco IOS"
status: "Active"
release_date: "2024-01-01"
end_of_support_date: "2025-01-01"
documentation_url: "https://example.com"
long_term_support: true
pre_release: false
state: present
register: test_four

- name: "SOFTWARE VERSION 4: ASSERT - Create with all info duplicate"
assert:
that:
- not test_four['changed']
- test_four['software_version']['version'] == "1.1.0"
- test_four['msg'] == "software_version 1.1.0 already exists"

- name: "SOFTWARE VERSION 5: Update"
networktocode.nautobot.software_version:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
version: "1.1.0"
end_of_support_date: "2026-01-01"
register: test_five

- name: "SOFTWARE VERSION 5: ASSERT - Update"
assert:
that:
- test_five is changed
- test_five['diff']['before']['end_of_support_date'] == "2025-01-01"
- test_five['diff']['after']['end_of_support_date'] == "2026-01-01"

- name: "SOFTWARE VERSION 6: Update duplicate"
networktocode.nautobot.software_version:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
version: "1.1.0"
end_of_support_date: "2026-01-01"
register: test_six

- name: "SOFTWARE VERSION 6: ASSERT - Update duplicate"
assert:
that:
- not test_six['changed']
- test_six['software_version']['version'] == "1.1.0"
- test_six['msg'] == "software_version 1.1.0 already exists"

- name: "SOFTWARE VERSION 7: Delete"
networktocode.nautobot.software_version:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
version: "1.1.0"
state: absent
register: test_seven

- name: "SOFTWARE VERSION 7: ASSERT - Delete"
assert:
that:
- test_seven is changed
- test_seven['diff']['before']['state'] == "present"
- test_seven['diff']['after']['state'] == "absent"
- test_seven['msg'] == "software_version 1.1.0 deleted"

- name: "SOFTWARE VERSION 8: Delete non-existent"
networktocode.nautobot.software_version:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
version: "1.1.0"
state: absent
register: test_eight

- name: "SOFTWARE VERSION 8: ASSERT - Delete non-existent"
assert:
that:
- not test_eight['changed']
- test_eight['msg'] == "software_version 1.1.0 already absent"

0 comments on commit 1968bbb

Please sign in to comment.