Skip to content

Commit

Permalink
Merge branch 'develop' into u/tsm1th-add-job-button
Browse files Browse the repository at this point in the history
  • Loading branch information
tsm1th committed Dec 16, 2024
2 parents a280bc0 + 0eccc50 commit 005266c
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 0 deletions.
2 changes: 2 additions & 0 deletions plugins/lookup/lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ def get_endpoint(nautobot, term):
"device-types": {"endpoint": nautobot.dcim.device_types},
"device-redundancy-groups": {"endpoint": nautobot.dcim.device_redundancy_groups},
"devices": {"endpoint": nautobot.dcim.devices},
"dynamic-groups": {"endpoint": nautobot.extras.dynamic_groups},
"export-templates": {"endpoint": nautobot.dcim.export_templates},
"front-port-templates": {"endpoint": nautobot.dcim.front_port_templates},
"front-ports": {"endpoint": nautobot.dcim.front_ports},
Expand Down Expand Up @@ -242,6 +243,7 @@ def get_endpoint(nautobot, term):
"secrets": {"endpoint": nautobot.extras.secrets},
"secrets-groups": {"endpoint": nautobot.extras.secrets_groups},
"services": {"endpoint": nautobot.ipam.services},
"static-group-associations": {"endpoint": nautobot.extras.static_group_associations},
"statuses": {"endpoint": nautobot.extras.statuses},
"tags": {"endpoint": nautobot.extras.tags},
"teams": {"endpoint": nautobot.extras.teams},
Expand Down
3 changes: 3 additions & 0 deletions plugins/module_utils/extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
NB_TAGS = "tags"
NB_STATUS = "statuses"
NB_RELATIONSHIP_ASSOCIATIONS = "relationship_associations"
NB_STATIC_GROUP_ASSOCIATIONS = "static_group_associations"
NB_CUSTOM_FIELDS = "custom_fields"
NB_CUSTOM_FIELD_CHOICES = "custom_field_choices"
NB_CONTACT = "contacts"
Expand Down Expand Up @@ -51,6 +52,8 @@ def run(self):
name = data["name"]
elif endpoint_name == "relationship_associations":
name = f"{data['source_type']} -> {data['destination_type']}"
elif endpoint_name == "static_group_association":
name = f"{data['dynamic_group']} -> {data['associated_object_id']}"
elif endpoint_name == "custom_field":
name = data["label"]
elif endpoint_name in ["custom_field_choice", "metadata_choice"]:
Expand Down
3 changes: 3 additions & 0 deletions plugins/module_utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
"job_buttons",
"relationship_associations",
"roles",
"static_group_associations",
"statuses",
"tags",
"teams",
Expand Down Expand Up @@ -337,6 +338,7 @@
"roles": "role",
"route_targets": "route_target",
"services": "services",
"static_group_associations": "static_group_association",
"statuses": "statuses",
"tags": "tags",
"teams": "team",
Expand Down Expand Up @@ -441,6 +443,7 @@
"role": set(["name"]),
"route_target": set(["name"]),
"services": set(["device", "virtual_machine", "name", "port", "protocol"]),
"static_group_association": set(["dynamic_group", "associated_object_type", "associated_object_id"]),
"statuses": set(["name"]),
"tags": set(["name"]),
"tagged_vlans": set(["group", "name", "location", "vid", "vlan_group", "tenant"]),
Expand Down
109 changes: 109 additions & 0 deletions plugins/modules/static_group_association.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2022, Network to Code (@networktocode) <info@networktocode.com>
# 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: static_group_association
short_description: Creates or removes a static group association from Nautobot
description:
- Creates or removes a static group association from Nautobot
author:
- Network to Code (@networktocode)
- Travis Smith (@tsm1th)
version_added: "5.5.0"
extends_documentation_fragment:
- networktocode.nautobot.fragments.base
- networktocode.nautobot.fragments.custom_fields
options:
dynamic_group:
description:
- The dynamic group to add the association to
required: true
type: raw
associated_object_type:
description:
- The app_label.model for the object in the relationship
required: true
type: str
associated_object_id:
description:
- The UUID of the object in the relationship
required: true
type: str
"""

EXAMPLES = r"""
- name: "Test static group association creation/deletion"
connection: local
hosts: localhost
gather_facts: False
tasks:
- name: Create static group association
networktocode.nautobot.static_group_association:
url: http://nautobot.local
token: thisIsMyToken
dynamic_group: 01234567-abcd-0123-abcd-012345678901
associated_object_type: dcim.device
associated_object_id: abcdefgh-0123-abcd-0123-abcdefghijkl
- name: Delete static group association
networktocode.nautobot.static_group_association:
url: http://nautobot.local
token: thisIsMyToken
dynamic_group: 01234567-abcd-0123-abcd-012345678901
associated_object_type: dcim.device
associated_object_id: abcdefgh-0123-abcd-0123-abcdefghijkl
state: absent
"""

RETURN = r"""
static_group_association:
description: Serialized object as created/existent/updated/deleted within Nautobot
returned: always
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,
CUSTOM_FIELDS_ARG_SPEC,
)
from ansible_collections.networktocode.nautobot.plugins.module_utils.extras import (
NautobotExtrasModule,
NB_STATIC_GROUP_ASSOCIATIONS,
)
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(CUSTOM_FIELDS_ARG_SPEC))
argument_spec.update(
dict(
dynamic_group=dict(required=True, type="raw"),
associated_object_type=dict(required=True, type="str"),
associated_object_id=dict(required=True, type="str"),
)
)

module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)

static_group_association = NautobotExtrasModule(module, NB_STATIC_GROUP_ASSOCIATIONS)
static_group_association.run()


if __name__ == "__main__": # pragma: no cover
main()
4 changes: 4 additions & 0 deletions tests/integration/nautobot-populate.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,10 @@ def make_nautobot_calls(endpoint, payload):
]
created_metadata_types = make_nautobot_calls(nb.extras.metadata_types, metadata_types)

# Create dynamic group of type static assignment
dynamic_groups = [{"name": "TestStaticAssociations", "content_type": "dcim.device", "group_type": "static"}]
created_dynamic_groups = make_nautobot_calls(nb.extras.dynamic_groups, dynamic_groups)

# Enable example job for job tests
example_job_receiver = nb.extras.jobs.get(name="Example Simple Job Button Receiver")
example_job_receiver.enabled = True
Expand Down
9 changes: 9 additions & 0 deletions tests/integration/targets/latest/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,15 @@
tags:
- object_metadata

- name: "PYNAUTOBOT_STATIC_GROUP_ASSOCIATION TESTS"
include_tasks:
file: "static_group_association.yml"
apply:
tags:
- static_group_association
tags:
- static_group_association

- name: "PYNAUTOBOT_JOB_BUTTON TESTS"
include_tasks:
file: "job_button.yml"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
##
##
### PYNAUTOBOT_STATIC_GROUP_ASSOCIATION
##
##

- name: "NAUTOBOT 2.3+ STATIC GROUP ASSOCIATION TESTS"
when:
- "nautobot_version is version('2.3', '>=')"
block:
- set_fact:
static_dynamic_group: "{{ lookup('networktocode.nautobot.lookup', 'dynamic-groups', api_endpoint=nautobot_url, token=nautobot_token, api_filter='name=\"TestStaticAssociations\"') }}"
static_device: "{{ lookup('networktocode.nautobot.lookup', 'devices', api_endpoint=nautobot_url, token=nautobot_token, api_filter='name=TestDeviceR1') }}"

- name: "STATIC GROUP ASSOCIATION 1: Necessary info creation"
networktocode.nautobot.static_group_association:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
dynamic_group: "TestStaticAssociations"
associated_object_type: "dcim.device"
associated_object_id: "{{ static_device['key'] }}"
state: present
register: test_one

- name: "STATIC GROUP ASSOCIATION 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['static_group_association']['dynamic_group'] == static_dynamic_group['key']
- test_one['static_group_association']['associated_object_type'] == "dcim.device"
- test_one['static_group_association']['associated_object_id'] == static_device['key']
- "'created' in test_one['msg']"

- name: "STATIC GROUP ASSOCIATION 2: Test duplication association (Idempotency)"
networktocode.nautobot.static_group_association:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
dynamic_group: "TestStaticAssociations"
associated_object_type: "dcim.device"
associated_object_id: "{{ static_device['key'] }}"
state: present
register: test_two

- name: "STATIC GROUP ASSOCIATION 2: ASSERT - Item already exists (Idempotency)"
assert:
that:
- test_two is not changed
- test_two['static_group_association']['dynamic_group'] == static_dynamic_group['key']
- "'already exists' in test_two['msg']"

- name: "STATIC GROUP ASSOCIATION 3: Test absent state"
networktocode.nautobot.static_group_association:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
dynamic_group: "TestStaticAssociations"
associated_object_type: "dcim.device"
associated_object_id: "{{ static_device['key'] }}"
state: absent
register: test_three

- name: "STATIC GROUP ASSOCIATION 3: ASSERT - Item removed"
assert:
that:
- test_three is changed
- test_three['diff']['before']['state'] == "present"
- test_three['diff']['after']['state'] == "absent"
- test_three['static_group_association']['dynamic_group'] == static_dynamic_group['key']
- test_three['static_group_association']['associated_object_type'] == "dcim.device"
- test_three['static_group_association']['associated_object_id'] == static_device['key']
- "'deleted' in test_three['msg']"

- name: "STATIC GROUP ASSOCIATION 4: Test absent state (Idempotent)"
networktocode.nautobot.static_group_association:
url: "{{ nautobot_url }}"
token: "{{ nautobot_token }}"
dynamic_group: "TestStaticAssociations"
associated_object_type: "dcim.device"
associated_object_id: "{{ static_device['key'] }}"
state: absent
register: test_four

- name: "STATIC GROUP ASSOCIATION 4: ASSERT - Item not removed (Idempotent)"
assert:
that:
- test_four is not changed
- "'already absent' in test_four['msg']"

0 comments on commit 005266c

Please sign in to comment.