diff --git a/docs/requirements.txt b/docs/requirements.txt index 787bd591e..807fdc428 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ ansible antsibull==0.48.0 -sphinx==3.4.2 +sphinx Jinja2<3.2 sphinx_rtd_theme \ No newline at end of file diff --git a/meta/runtime.yml b/meta/runtime.yml index 45afe534c..1c3faae8c 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -81,6 +81,7 @@ action_groups: - netbox_vlan - netbox_vlan_group - netbox_vm_interface + - netbox_virtual_disk - netbox_vrf - netbox_webhook - netbox_wireless_lan diff --git a/plugins/module_utils/netbox_utils.py b/plugins/module_utils/netbox_utils.py index 49640a317..2695df7b4 100644 --- a/plugins/module_utils/netbox_utils.py +++ b/plugins/module_utils/netbox_utils.py @@ -112,6 +112,7 @@ "cluster_types", "clusters", "virtual_machines", + "virtual_disks", ], wireless=["wireless_lans", "wireless_lan_groups", "wireless_links"], ) @@ -374,6 +375,7 @@ "tenant_groups": "tenant_group", "virtual_chassis": "virtual_chassis", "virtual_machines": "virtual_machine", + "virtual_disks": "virtual_disk", "vlans": "vlan", "vlan_groups": "vlan_group", "vrfs": "vrf", @@ -508,6 +510,7 @@ "untagged_vlan": set(["group", "name", "site", "vid", "vlan_group", "tenant"]), "virtual_chassis": set(["name", "master"]), "virtual_machine": set(["name", "cluster"]), + "virtual_disk": set(["name", "virtual_machine"]), "vm_bridge": set(["name"]), "vlan": set(["group", "name", "site", "tenant", "vid", "vlan_group"]), "vlan_group": set(["name", "slug", "site", "scope"]), diff --git a/plugins/module_utils/netbox_virtualization.py b/plugins/module_utils/netbox_virtualization.py index 64723bafd..cbee6871e 100644 --- a/plugins/module_utils/netbox_virtualization.py +++ b/plugins/module_utils/netbox_virtualization.py @@ -17,6 +17,7 @@ NB_CLUSTER_GROUP = "cluster_groups" NB_CLUSTER_TYPE = "cluster_types" NB_VM_INTERFACES = "interfaces" +NB_VIRTUAL_DISKS = "virtual_disks" class NetboxVirtualizationModule(NetboxModule): diff --git a/plugins/modules/netbox_circuit_type.py b/plugins/modules/netbox_circuit_type.py index 922d9e21f..5b0958afd 100644 --- a/plugins/modules/netbox_circuit_type.py +++ b/plugins/modules/netbox_circuit_type.py @@ -47,6 +47,12 @@ - This is auto-generated following NetBox rules if not provided required: false type: str + color: + description: + - Color to associate the circuit type with + required: false + type: str + version_added: "3.17.0" tags: description: - The tags to add/update @@ -122,6 +128,7 @@ def main(): name=dict(required=True, type="str"), description=dict(required=False, type="str"), slug=dict(required=False, type="str"), + color=dict(required=False, type="str"), tags=dict(required=False, type="list", elements="raw"), custom_fields=dict(required=False, type="dict"), ), diff --git a/plugins/modules/netbox_virtual_disk.py b/plugins/modules/netbox_virtual_disk.py new file mode 100644 index 000000000..fc330c640 --- /dev/null +++ b/plugins/modules/netbox_virtual_disk.py @@ -0,0 +1,139 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright: (c) 2024, Martin Rødvand (@rodvand) +# 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: netbox_virtual_disk +short_description: Creates or removes disks from virtual machines in NetBox +description: + - Creates or removes disks from virtual machines in NetBox +notes: + - Tags should be defined as a YAML list + - This should be ran with connection C(local) and hosts C(localhost) +author: + - Martin Rødvand (@rodvand) +requirements: + - pynetbox +version_added: "3.17.0" +extends_documentation_fragment: + - netbox.netbox.common +options: + data: + description: + - Defines the vm disk configuration + suboptions: + virtual_machine: + description: + - Name of the virtual machine the disk will be associated with (case-sensitive) + required: false + type: raw + name: + description: + - Name of the disk to be created + required: true + type: str + description: + description: + - The description of the disk + required: false + type: str + size: + description: + - The size (in GB) of the disk + required: false + type: int + tags: + description: + - Any tags that the virtual disk may need to be associated with + required: false + type: list + elements: raw + custom_fields: + description: + - Must exist in NetBox + required: false + type: dict + required: true + type: dict +""" + +EXAMPLES = r""" +- name: "Test NetBox virtual disk module" + connection: local + hosts: localhost + gather_facts: False + tasks: + - name: Create virtual disk + netbox_virtual_disk: + data: + virtual_machine: test100 + name: disk0 + size: 50 + state: present +""" + +RETURN = r""" +virtual_disk: + description: Serialized object as created or already existent within NetBox + returned: on creation + type: dict +msg: + description: Message indicating failure or info about what has been achieved + returned: always + type: str +""" + +from ansible_collections.netbox.netbox.plugins.module_utils.netbox_utils import ( + NetboxAnsibleModule, + NETBOX_ARG_SPEC, +) +from ansible_collections.netbox.netbox.plugins.module_utils.netbox_virtualization import ( + NetboxVirtualizationModule, + NB_VIRTUAL_DISKS, +) +from copy import deepcopy + + +def main(): + """ + Main entry point for module execution + """ + argument_spec = deepcopy(NETBOX_ARG_SPEC) + argument_spec.update( + dict( + data=dict( + type="dict", + required=True, + options=dict( + virtual_machine=dict(required=False, type="raw"), + name=dict(required=True, type="str"), + description=dict(required=False, type="str"), + size=dict(required=False, type="int"), + tags=dict(required=False, type="list", elements="raw"), + custom_fields=dict(required=False, type="dict"), + ), + ), + ) + ) + + required_if = [ + ("state", "present", ["virtual_machine", "name"]), + ("state", "absent", ["virtual_machine", "name"]), + ] + + module = NetboxAnsibleModule( + argument_spec=argument_spec, supports_check_mode=True, required_if=required_if + ) + + netbox_virtual_disk = NetboxVirtualizationModule(module, NB_VIRTUAL_DISKS) + netbox_virtual_disk.run() + + +if __name__ == "__main__": # pragma: no cover + main() diff --git a/tests/integration/targets/v3.7/tasks/main.yml b/tests/integration/targets/v3.7/tasks/main.yml index a00139f83..d1c4b6fe7 100644 --- a/tests/integration/targets/v3.7/tasks/main.yml +++ b/tests/integration/targets/v3.7/tasks/main.yml @@ -311,3 +311,8 @@ include_tasks: "netbox_config_template.yml" tags: - netbox_config_template + +- name: "NETBOX_VIRTUAL_DISK" + include_tasks: "netbox_virtual_disk.yml" + tags: + - netbox_virtual_disk diff --git a/tests/integration/targets/v3.7/tasks/netbox_virtual_disk.yml b/tests/integration/targets/v3.7/tasks/netbox_virtual_disk.yml new file mode 100644 index 000000000..999d3edc3 --- /dev/null +++ b/tests/integration/targets/v3.7/tasks/netbox_virtual_disk.yml @@ -0,0 +1,87 @@ +--- +## +## +### NETBOX_VIRTUAL_DISK +## +## +- name: "NETBOX_VIRTUAL_DISK 1: Necessary info creation" + netbox.netbox.netbox_virtual_disk: + netbox_url: http://localhost:32768 + netbox_token: 0123456789abcdef0123456789abcdef01234567 + data: + virtual_machine: "test100-vm" + name: "disk0" + size: 50 + state: present + register: test_one + +- name: "NETBOX_VIRTUAL_DISK 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['virtual_disk']['name'] == "disk0" + - test_one['virtual_disk']['virtual_machine'] == 1 + - test_one['msg'] == "virtual_disk disk0 created" + +- name: "NETBOX_VIRTUAL_DISK 2: Create duplicate" + netbox.netbox.netbox_virtual_disk: + netbox_url: http://localhost:32768 + netbox_token: 0123456789abcdef0123456789abcdef01234567 + data: + virtual_machine: "test100-vm" + name: "disk0" + size: 50 + state: present + register: test_two + +- name: "NETBOX_VIRTUAL_DISK 2: ASSERT - Create duplicate" + assert: + that: + - not test_two['changed'] + - test_two['virtual_disk']['name'] == "disk0" + - test_two['virtual_disk']['virtual_machine'] == 1 + - test_two['msg'] == "virtual_disk disk0 already exists" + +- name: "NETBOX_VIRTUAL_DISK 3: Update" + netbox.netbox.netbox_virtual_disk: + netbox_url: http://localhost:32768 + netbox_token: 0123456789abcdef0123456789abcdef01234567 + data: + virtual_machine: "test100-vm" + name: "disk0" + size: 60 + tags: + - "Schnozzberry" + state: present + register: test_three + +- name: "NETBOX_VIRTUAL_DISK 4: ASSERT - Updated" + assert: + that: + - test_three is changed + - test_three['diff']['after']['size'] == 60 + - test_three['virtual_disk']['name'] == "disk0" + - test_three['virtual_disk']['virtual_machine'] == 1 + - test_three['virtual_disk']['size'] == 60 + - test_three['virtual_disk']['tags'][0] == 4 + - test_three['msg'] == "virtual_disk disk0 updated" + +- name: "NETBOX_VIRTUAL_DISK 4: ASSERT - Delete" + netbox.netbox.netbox_virtual_disk: + netbox_url: http://localhost:32768 + netbox_token: 0123456789abcdef0123456789abcdef01234567 + data: + name: "disk0" + virtual_machine: "test100-vm" + state: absent + register: test_four + +- name: "NETBOX_VIRTUAL_DISK 4: ASSERT - Delete" + assert: + that: + - test_four is changed + - test_four['virtual_disk']['name'] == "disk0" + - test_four['virtual_disk']['virtual_machine'] == 1 + - test_four['msg'] == "virtual_disk disk0 deleted"