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
1 change: 1 addition & 0 deletions plugins/module_utils/netbox_extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
NB_CONFIG_CONTEXTS = "config_contexts"
NB_TAGS = "tags"
NB_CUSTOM_FIELDS = "custom_fields"
NB_CUSTOM_FIELD_CHOICE_SETS = "custom_field_choice_sets"
NB_CUSTOM_LINKS = "custom_links"
NB_EXPORT_TEMPLATES = "export_templates"
NB_JOURNAL_ENTRIES = "journal_entries"
Expand Down
6 changes: 6 additions & 0 deletions plugins/module_utils/netbox_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"config_templates": {},
"tags": {},
"custom_fields": {},
"custom_field_choice_sets": {},
"custom_links": {},
"export_templates": {},
"journal_entries": {},
Expand Down Expand Up @@ -145,6 +146,7 @@
contact_group="name",
contact_role="name",
custom_field="name",
choice_set="name",
custom_link="name",
device="name",
device_role="slug",
Expand Down Expand Up @@ -226,6 +228,7 @@
"config_context": "config_contexts",
"config_template": "config_templates",
"contact_groups": "contact_groups",
"choice_set": "custom_field_choice_sets",
"dcim.consoleport": "console_ports",
"dcim.consoleserverport": "console_server_ports",
"dcim.frontport": "front_ports",
Expand Down Expand Up @@ -338,6 +341,7 @@
"contact_groups": "contact_group",
"contact_roles": "contact_role",
"custom_fields": "custom_field",
"custom_field_choice_sets": "choice_set",
"custom_links": "custom_link",
"device_bays": "device_bay",
"device_bay_templates": "device_bay_template",
Expand Down Expand Up @@ -438,6 +442,8 @@
"contact_group": set(["name"]),
"contact_role": set(["name"]),
"custom_field": set(["name"]),
"custom_field_choice_set": set(["name"]),
"choice_set": set(["name"]),
"custom_link": set(["name"]),
"dcim.consoleport": set(["name", "device"]),
"dcim.consoleserverport": set(["name", "device"]),
Expand Down
24 changes: 19 additions & 5 deletions plugins/modules/netbox_custom_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,11 @@
- The regular expression to enforce on text fields
required: false
type: str
choices:
choice_set:
description:
- List of available choices (for selection fields)
- The name of the choice set to use (for selection fields)
required: false
type: list
elements: str
type: str
required: true
"""

Expand All @@ -157,6 +156,18 @@
name: A Custom Field
type: text

- name: Create a custom field of type selection
netbox.netbox.netbox_custom_field:
netbox_url: http://netbox.local
netbox_token: thisIsMyToken
data:
name: "Custom_Field"
content_types:
- dcim.device
- virtualization.virtualmachine
type: select
choice_set: A Choice Set name

- name: Update the custom field to make it required
netbox.netbox.netbox_custom_field:
netbox_url: http://netbox.local
Expand Down Expand Up @@ -258,7 +269,10 @@ def main():
validation_minimum=dict(required=False, type="int"),
validation_maximum=dict(required=False, type="int"),
validation_regex=dict(required=False, type="str"),
choices=dict(required=False, type="list", elements="str"),
choice_set=dict(
required=False,
type="str",
),
),
)
)
Expand Down
164 changes: 164 additions & 0 deletions plugins/modules/netbox_custom_field_choice_set.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2024, Philipp Rintz (@p-rintz) <[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: netbox_custom_field_choice_set
short_description: Creates, updates or deletes custom field choice sets within Netbox
description:
- Creates, updates or removes custom fields choice sets from Netbox
notes:
- This should be run with connection C(local) and hosts C(localhost)
author:
- Philipp Rintz (@p-rintz)
requirements:
- pynetbox
version_added: "3.6.0"
extends_documentation_fragment:
- netbox.netbox.common
options:
data:
type: dict
description:
- Defines the choice set
suboptions:
name:
description:
- Name of the choice set
required: true
type: str
description:
description:
- Description of the choice set
required: false
type: str
extra_choices:
description:
- List of available choices in the choice set
required: false
default: []
type: list
elements: list
base_choices:
description:
- Selection of base choice to use in the choice set
required: false
type: str
choices:
- IATA
- ISO_3166
- UN_LOCODE
order_alphabetically:
description:
- Order the choices alphabetically
required: false
type: bool
required: true
"""

EXAMPLES = r"""
- name: "Test Netbox custom_field_choice_set module"
connection: local
hosts: localhost
tasks:
- name: Create a choice set with choices
netbox.netbox.netbox_custom_field_choice_set:
netbox_url: http://netbox.local
netbox_token: thisIsMyToken
data:
name: "ChoiceSetName"
description: "Choice Set Description"
extra_choices:
- ['choice1', 'label1']
- ['choice2', 'label2']

- name: Create a choice set with a base choice
netbox.netbox.netbox_custom_field_choice_set:
netbox_url: http://netbox.local
netbox_token: thisIsMyToken
data:
name: "ChoiceSetName"
description: "Choice Set Description"
order_alphabetically: true
base_choices: "IATA"
"""

RETURN = r"""
custom_field_choice_set:
description: Serialized object as created/existent/updated/deleted within NetBox
returned: always
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_extras import (
NetboxExtrasModule,
NB_CUSTOM_FIELD_CHOICE_SETS,
)
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(
name=dict(required=True, type="str"),
description=dict(required=False, type="str"),
base_choices=dict(
required=False,
type="str",
choices=[
"IATA",
"ISO_3166",
"UN_LOCODE",
],
),
extra_choices=dict(
required=False,
default=[],
type="list",
elements="list",
),
order_alphabetically=dict(required=False, type="bool"),
),
)
)
)

required_if = [
("state", "present", ["name"]),
("state", "absent", ["name"]),
]

module = NetboxAnsibleModule(
argument_spec=argument_spec, supports_check_mode=True, required_if=required_if
)

netbox_custom_field_choice_set = NetboxExtrasModule(
module, NB_CUSTOM_FIELD_CHOICE_SETS
)
netbox_custom_field_choice_set.run()


if __name__ == "__main__": # pragma: no cover
main()
5 changes: 5 additions & 0 deletions tests/integration/targets/v3.6/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,8 @@
include_tasks: "netbox_config_template.yml"
tags:
- netbox_config_template

- name: "NETBOX_CUSTOM_FIELD_CHOICE_SET"
include_tasks: "netbox_custom_field_choice_set.yml"
tags:
- netbox_custom_field_choice_set
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
##
##
### NETBOX_CUSTOM_FIELD_CHOICE_SET
##
##
- name: "CUSTOM_FIELD_CHOICE_SET 1: Base Choice set creation"
netbox.netbox.netbox_custom_field_choice_set:
netbox_url: http://localhost:32768
netbox_token: 0123456789abcdef0123456789abcdef01234567
data:
name: "A_ChoiceSet"
description: "Added a description"
base_choices: "IATA"
state: present
register: test_one

- name: "CUSTOM_FIELD_CHOICE_SET 1: ASSERT - Base Choice set creation"
assert:
that:
- test_one is changed
- test_one['diff']['before']['state'] == "absent"
- test_one['diff']['after']['state'] == "present"
- test_one['choice_set']['name'] == "A_ChoiceSet"
- test_one['choice_set']['description'] == "Added a description"
- test_one['choice_set']['display'] == "A_ChoiceSet"
- test_one['choice_set']['order_alphabetically'] == false
- test_one['choice_set']['extra_choices'] == []
- test_one['msg'] == "choice_set A_ChoiceSet created"

- name: "CUSTOM_FIELD_CHOICE_SET 2: Create duplicate"
netbox.netbox.netbox_custom_field_choice_set:
netbox_url: http://localhost:32768
netbox_token: 0123456789abcdef0123456789abcdef01234567
data:
name: "A_ChoiceSet"
description: "Added a description"
base_choices: "IATA"
state: present
register: test_two

- name: "CUSTOM_FIELD_CHOICE_SET 2: ASSERT - Create duplicate"
assert:
that:
- not test_two['changed']
- test_two['choice_set']['name'] == "A_ChoiceSet"
- test_two['msg'] == "choice_set A_ChoiceSet already exists"

- name: "CUSTOM_FIELD_CHOICE_SET 3: Update data and change base_choice"
netbox.netbox.netbox_custom_field_choice_set:
netbox_url: http://localhost:32768
netbox_token: 0123456789abcdef0123456789abcdef01234567
data:
name: "A_ChoiceSet"
description: "Added a description"
base_choices: "ISO_3166"
state: present
register: test_three

- name: "CUSTOM_FIELD_CHOICE_SET 3: ASSERT - Updated"
assert:
that:
- test_three is changed
- test_three['diff']['after']['base_choices'] == "ISO_3166"
- test_three['choice_set']['name'] == "A_ChoiceSet"
- test_three['msg'] == "choice_set A_ChoiceSet updated"

- name: "CUSTOM_FIELD_CHOICE_SET 4: Update extra choice and order alphabetically"
netbox.netbox.netbox_custom_field_choice_set:
netbox_url: http://localhost:32768
netbox_token: 0123456789abcdef0123456789abcdef01234567
data:
name: "A_ChoiceSet"
description: "Added a description"
order_alphabetically: true
extra_choices:
- ['test', 'label']
- ['test2', 'label2']
state: present
register: test_four

- name: "CUSTOM_FIELD_CHOICE_SET 4: ASSERT - Change extra choice and order alphabetically"
assert:
that:
- test_four is changed
- test_four['diff']['after']['extra_choices'] == [["test","label"],["test2","label2"]]
- test_four['diff']['after']['order_alphabetically'] == true
- test_four['choice_set']['name'] == "A_ChoiceSet"
- test_four['msg'] == "choice_set A_ChoiceSet updated"

- name: "CUSTOM_FIELD_CHOICE_SET 5: Delete"
netbox.netbox.netbox_custom_field_choice_set:
netbox_url: http://localhost:32768
netbox_token: 0123456789abcdef0123456789abcdef01234567
data:
name: "A_ChoiceSet"
state: absent
register: test_five

- name: "CUSTOM_FIELD_CHOICE_SET 5: ASSERT - Deleted"
assert:
that:
- test_five is changed
- test_five['diff']['after']['state'] == "absent"
- test_five['choice_set']['name'] == "A_ChoiceSet"
- test_five['msg'] == "choice_set A_ChoiceSet deleted"