Skip to content

Commit c1d2cd9

Browse files
authored
Merge pull request #731 from nautobot/develop
Release v6.2.0
2 parents 9c2700e + 29ca1af commit c1d2cd9

79 files changed

Lines changed: 6454 additions & 1374 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
name: "Scheduled CI - ansible-core devel"
3+
on: # yamllint disable
4+
schedule:
5+
# Run every Wednesday at 03:20 UTC (offset from Monday stable run)
6+
- cron: "20 3 * * 3"
7+
workflow_dispatch:
8+
inputs:
9+
branch:
10+
description: "The ansible-core branch to test against"
11+
required: false
12+
default: "devel"
13+
type: string
14+
15+
env:
16+
ANSIBLE_CORE_BRANCH: "${{ inputs.branch || 'devel' }}"
17+
18+
jobs:
19+
unit:
20+
runs-on: "ubuntu-latest"
21+
strategy:
22+
fail-fast: false
23+
matrix:
24+
python-version:
25+
- "3.12"
26+
env:
27+
INVOKE_NAUTOBOT_ANSIBLE_PYTHON_VER: "${{ matrix.python-version }}"
28+
# Allow failures — devel breakage is expected and should not block anything
29+
continue-on-error: true
30+
steps:
31+
- name: "Check out repository code"
32+
uses: "actions/checkout@v4"
33+
- name: "Install invoke"
34+
run: "pip install -U pip && pip install invoke packaging"
35+
- name: "Run tests against ansible-core ${{ env.ANSIBLE_CORE_BRANCH }}"
36+
run: "invoke unit --ansible-core-branch ${{ env.ANSIBLE_CORE_BRANCH }} --skip lint"

CHANGELOG.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,54 @@ This document describes all new features and changes in the release. The format
44

55
<!-- towncrier release notes start -->
66

7+
## [v6.2.0](https://github.com/nautobot/nautobot-ansible/releases/tag/v6.2.0)
8+
9+
### Added
10+
11+
- [#696](https://github.com/nautobot/nautobot-ansible/issues/696) - Added meta/execution-environment.yml for Ansible Builder support.
12+
- [#705](https://github.com/nautobot/nautobot-ansible/issues/705) - Added graphql_info and graphql_facts modules to replace query_graphql, following Ansible naming conventions for info and facts modules.
13+
- [#711](https://github.com/nautobot/nautobot-ansible/issues/711) - Added provider_network module for managing provider networks within Nautobot.
14+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Added the ability to assign secrets to a secrets group when using the `secrets_group` module.
15+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Added the ability to assign static group associations when using the `dynamic_group` module.
16+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Added the ability to assign prefixes to a cloud network when using the `cloud_network` module.
17+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Added the ability to assign cloud networks to a cloud service when using the `cloud_service` module.
18+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Added the ability to assign vrfs to a device, virtual machine, or virtual device context when using the respective module.
19+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Added the ability to assign clusters to a device when using the `device` module.
20+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Added the ability to assign ip addresses to a device interface or vm interface when using the respective module.
21+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Added the ability to assign prefixes or vlans to a location when using the `location` module.
22+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Added the ability to assign provider networks to a provider when using the `provider` module.
23+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Added the ability to manage custom field choices to a custom field when using the `custom_field` module.
24+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Added the ability to manage metadata choices to a metadata type when using the `metadata_type` module.
25+
26+
### Deprecated
27+
28+
- [#705](https://github.com/nautobot/nautobot-ansible/issues/705) - Deprecated query_graphql module. Use graphql_info (returns data only) or graphql_facts (sets ansible_facts) instead.
29+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `secrets_groups_association` module. Use the `secrets` option of the `secrets_group` module instead.
30+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `static_group_association` module. Use the `static_group_associations` option of the `dynamic_group` module instead.
31+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `cloud_network_prefix_assignment` module. Use the `prefixes` option of the `cloud_network` module instead.
32+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `cloud_service_network_assignment` module. Use the `cloud_networks` option of the `cloud_service` module instead.
33+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `vrf_device_assignment` module. Use the `vrfs` option of the `device`, `virtual_machine`, or `virtual_device_context` module instead.
34+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `device_cluster_assignment` module. Use the `clusters` option of the `device` module instead.
35+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `ip_address_to_interface` module. Use the `ip_addresses` option of the `device_interface` or `vm_interface` module instead.
36+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `prefix_location` module. Use the `prefixes` option of the `location` module instead.
37+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `vlan_location` module. Use the `vlans` option of the `location` module instead.
38+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `custom_field_choice` module. Use the `custom_field_choices` option of the `custom_field` module instead.
39+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `metadata_choice` module. Use the `metadata_choices` option of the `metadata_type` module instead.
40+
- [#728](https://github.com/nautobot/nautobot-ansible/issues/728) - Deprecated the `provider_network` module. Use the `provider_networks` option of the `provider` module instead.
41+
42+
### Documentation
43+
44+
- [#694](https://github.com/nautobot/nautobot-ansible/issues/694) - Added Code of Conduct link to README for Ansible inclusion compliance.
45+
- [#695](https://github.com/nautobot/nautobot-ansible/issues/695) - Add CONTRIBUTING.md that links to the official documentation.
46+
- [#697](https://github.com/nautobot/nautobot-ansible/issues/697) - Updated Python and Ansible version requirements in README to reflect actual supported versions.
47+
- [#703](https://github.com/nautobot/nautobot-ansible/issues/703) - Added Communication section to README with Ansible Forum links per Ansible inclusion requirements.
48+
- [#709](https://github.com/nautobot/nautobot-ansible/issues/709) - Added missing RETURN block to the service module.
49+
50+
### Housekeeping
51+
52+
- [#709](https://github.com/nautobot/nautobot-ansible/issues/709) - Added unit tests to validate all modules have required Ansible documentation blocks (DOCUMENTATION, EXAMPLES, RETURN, version_added).
53+
- [#718](https://github.com/nautobot/nautobot-ansible/issues/718) - Added CI testing against ansible-core devel branch and `--ansible-core-branch` flag on `invoke unit` for local testing.
54+
755
## [v6.1.1](https://github.com/nautobot/nautobot-ansible/releases/tag/v6.1.1)
856

957
### Added

CONTRIBUTING.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Contributing
2+
3+
Thank you for your interest in contributing to Nautobot Ansible!
4+
5+
Please see the main contributing guide here:
6+
7+
https://docs.nautobot.com/projects/ansible/en/stable/getting_started/
8+
9+
That guide covers contributing guidelines, MkDocs documentation workflow, changelog fragments, and the release process. This file is intentionally brief and simply redirects to the authoritative docs.

Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ ENV SKIP_LINT_TESTS=${SKIP_LINT_TESTS}
4949
# Install dev dependencies
5050
RUN poetry install
5151

52+
# Optionally install ansible-core from a specific branch (e.g. "devel" or "milestone")
53+
# This must come AFTER poetry install so the lock file version doesn't overwrite it.
54+
ARG ANSIBLE_CORE_BRANCH
55+
RUN if [ -n "${ANSIBLE_CORE_BRANCH}" ]; then \
56+
pip install --upgrade pip setuptools && \
57+
pip install --force-reinstall --no-deps \
58+
"https://github.com/ansible/ansible/archive/${ANSIBLE_CORE_BRANCH}.tar.gz"; \
59+
fi
60+
5261
# Copy in the application source and everything not explicitly banned by .dockerignore
5362
COPY . .
5463

README.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,28 @@ This collection provides Ansible plugins (modules, inventory, lookup/filters) to
6969

7070
Testing is completed via the GitHub actions located in the `.github/workflows` directory.
7171

72-
## Contributing
72+
## Communication
7373

74-
Check out the docs at https://docs.nautobot.com/projects/ansible/en/stable/getting_started/
74+
* Join the Ansible forum:
75+
* [Get Help](https://forum.ansible.com/c/help/6): get help or help others. Please add the [`nautobot`](https://forum.ansible.com/tag/nautobot) tag if you start new discussions.
76+
* [Posts tagged with 'nautobot'](https://forum.ansible.com/tag/nautobot): subscribe to participate in collection-related conversations.
77+
* [Social Spaces](https://forum.ansible.com/c/chat/4): gather and interact with fellow enthusiasts.
78+
* [News & Announcements](https://forum.ansible.com/c/news/5): track project-wide announcements including social events.
79+
80+
* Additional community resources:
81+
* [Network to Code Slack](https://networktocode.slack.com) ([sign up](https://slack.networktocode.com))
82+
* [GitHub Issues](https://github.com/nautobot/nautobot-ansible/issues): report bugs or request features
83+
84+
## Code of Conduct
85+
86+
This project adheres to the [Network to Code Code of Conduct](CODE_OF_CONDUCT). By participating, you are expected to uphold this code.
7587

7688
## Support
89+
For more information about communication, see the [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
90+
91+
## Contributing
7792

78-
For issues please use [GitHub Issues](https://github.com/nautobot/nautobot-ansible) to open any issue that you may have. Additional community is available at the [Network to Code Slack](https://networktocode.slack.com) and [sign up](https://slack.networktocode.com).
93+
Check out the docs at https://docs.nautobot.com/projects/ansible/en/stable/getting_started/
7994

8095
## Release Notes and Roadmap
8196

changelogs/changelog.yaml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,3 +761,60 @@ releases:
761761
minor_changes:
762762
- (#684) - Added tenant option to the `namespace` module so that tenants can be associated with namespaces.
763763
- (#685) - Added description option to the `rir` module so that descriptions can be configured with RIRs.
764+
6.2.0:
765+
changes:
766+
release_summary: 'This release adds the ability to manage many-to-many fields inline on parent modules.
767+
768+
Previously, managing these associations required using separate standalone modules
769+
(e.g., `vrf_device_assignment`, `prefix_location`, `secrets_groups_association`).
770+
Now you can manage them inline on the parent module using the appropriate M2M field options.
771+
772+
M2M fields have a separate state (merge, replace, or delete) from the parent object to control the association state.'
773+
minor_changes:
774+
- (#696) - Added meta/execution-environment.yml for Ansible Builder support.
775+
- (#705) - Added graphql_info and graphql_facts modules to replace query_graphql, following Ansible naming conventions for info and facts modules.
776+
- (#711) - Added provider_network module for managing provider networks within Nautobot.
777+
- (#728) - Added the ability to assign secrets to a secrets group when using the `secrets_group` module.
778+
- (#728) - Added the ability to assign static group associations when using the `dynamic_group` module.
779+
- (#728) - Added the ability to assign prefixes to a cloud network when using the `cloud_network` module.
780+
- (#728) - Added the ability to assign cloud networks to a cloud service when using the `cloud_service` module.
781+
- (#728) - Added the ability to assign vrfs to a device, virtual machine, or virtual device context when using the respective module.
782+
- (#728) - Added the ability to assign clusters to a device when using the `device` module.
783+
- (#728) - Added the ability to assign ip addresses to a device interface or vm interface when using the respective module.
784+
- (#728) - Added the ability to assign prefixes or vlans to a location when using the `location` module.
785+
- (#728) - Added the ability to assign provider networks to a provider when using the `provider` module.
786+
- (#728) - Added the ability to manage custom field choices to a custom field when using the `custom_field` module.
787+
- (#728) - Added the ability to manage metadata choices to a metadata type when using the `metadata_type` module.
788+
deprecated_features:
789+
- (#705) - Deprecated query_graphql module. Use graphql_info (returns data only) or graphql_facts (sets ansible_facts) instead.
790+
- (#728) - Deprecated the `secrets_groups_association` module. Use the `secrets` option of the `secrets_group` module instead.
791+
- (#728) - Deprecated the `static_group_association` module. Use the `static_group_associations` option of the `dynamic_group` module instead.
792+
- (#728) - Deprecated the `cloud_network_prefix_assignment` module. Use the `prefixes` option of the `cloud_network` module instead.
793+
- (#728) - Deprecated the `cloud_service_network_assignment` module. Use the `cloud_networks` option of the `cloud_service` module instead.
794+
- (#728) - Deprecated the `vrf_device_assignment` module.
795+
Use the `vrfs` option of the `device`, `virtual_machine`, or `virtual_device_context` module instead.
796+
- (#728) - Deprecated the `device_cluster_assignment` module. Use the `clusters` option of the `device` module instead.
797+
- (#728) - Deprecated the `ip_address_to_interface` module. Use the `ip_addresses` option of the `device_interface` or `vm_interface` module instead.
798+
- (#728) - Deprecated the `prefix_location` module. Use the `prefixes` option of the `location` module instead.
799+
- (#728) - Deprecated the `vlan_location` module. Use the `vlans` option of the `location` module instead.
800+
- (#728) - Deprecated the `custom_field_choice` module. Use the `custom_field_choices` option of the `custom_field` module instead.
801+
- (#728) - Deprecated the `metadata_choice` module. Use the `metadata_choices` option of the `metadata_type` module instead.
802+
- (#728) - Deprecated the `provider_network` module. Use the `provider_networks` option of the `provider` module instead.
803+
trivial:
804+
- (#694) - Added Code of Conduct link to README for Ansible inclusion compliance.
805+
- (#695) - Add CONTRIBUTING.md that links to the official documentation.
806+
- (#697) - Updated Python and Ansible version requirements in README to reflect actual supported versions.
807+
- (#703) - Added Communication section to README with Ansible Forum links per Ansible inclusion requirements.
808+
- (#709) - Added missing RETURN block to the service module.
809+
- (#709) - Added unit tests to validate all modules have required Ansible documentation blocks (DOCUMENTATION, EXAMPLES, RETURN, version_added).
810+
- (#718) - Added CI testing against ansible-core devel branch and `--ansible-core-branch` flag on `invoke unit` for local testing.
811+
modules:
812+
- name: graphql_info
813+
description: Returns the results of a GraphQL query from Nautobot
814+
namespace: ''
815+
- name: graphql_facts
816+
description: Sets the results of a GraphQL query from Nautobot as ansible_facts
817+
namespace: ''
818+
- name: provider_network
819+
description: Creates or removes provider networks from Nautobot
820+
namespace: ''

changes/696.added

Lines changed: 0 additions & 1 deletion
This file was deleted.

changes/697.documentation

Lines changed: 0 additions & 1 deletion
This file was deleted.

docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
x-args:
33
&args
44
PYTHON_VER: ${PYTHON_VER}
5+
ANSIBLE_CORE_BRANCH: ${ANSIBLE_CORE_BRANCH:-}
56
ANSIBLE_SANITY_ARGS: ${ANSIBLE_SANITY_ARGS:-}
67
ANSIBLE_UNIT_ARGS: ${ANSIBLE_UNIT_ARGS:-}
78
SKIP_LINT_TESTS: ${SKIP_LINT_TESTS:-}

docs/getting_started/contributing/modules/architecture.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,49 @@ The next few lines manipulate the data and prepare it for sending to Nautobot.
291291
- Converts any fields that are namespaced to prevent conflicts when searching for them (e.g. device_role, ipam_role, rack_group, etc.)
292292

293293
If all those pass, it sets the manipulated data to `self.data` that is used in the module util apps.
294+
295+
## Inline M2M Fields
296+
297+
+++ 6.2.0
298+
299+
Some parent modules support inline many-to-many (M2M) association fields. These are declared in the `M2M_FIELDS` global dict in `utils.py`, which maps each endpoint to its supported M2M fields and their association API endpoints:
300+
301+
```python
302+
M2M_FIELDS = {
303+
"devices": {
304+
"vrfs": "vrf_device_assignments",
305+
"clusters": "device_cluster_assignments",
306+
},
307+
"locations": {
308+
"prefixes": "prefix_location_assignments",
309+
"vlans": "vlan_location_assignments",
310+
},
311+
# ... etc.
312+
}
313+
```
314+
315+
### How M2M Fields Are Processed
316+
317+
During `__init__`, M2M fields are handled separately from regular fields to prevent collisions with `_find_ids`:
318+
319+
1. **Extraction**: M2M field data is popped from the data dict *before* `_find_ids` runs on the parent data. This prevents M2M field names (like `prefixes`) from being mistakenly resolved as direct FK relationships.
320+
2. **Child resolution**: Each M2M object's child key (e.g., `vrf`, `prefix`, `ip_address`) is individually run through `_find_ids` to resolve names to UUIDs. This supports both simple strings (`vrf: "My VRF"`) and dicts for disambiguation (`ip_address: {address: "10.0.0.1/24", namespace: "Global"}`).
321+
3. **Payload stripping**: M2M field names are added to `remove_keys` so they are stripped from the REST API payload sent for the parent object.
322+
323+
After the parent object is created or updated, `_ensure_object_exists` calls `_process_m2m_fields` which iterates through each M2M field and:
324+
325+
- Fetches current associations from the API
326+
- Compares desired vs current using normalized comparison keys
327+
- Applies the requested state (`merge`, `replace`, or `delete`) via bulk create/delete operations
328+
329+
### Adding M2M Support to a New Module
330+
331+
If a new association endpoint is added to Nautobot and you want to support inline management:
332+
333+
1. Add the mapping to `M2M_FIELDS` in `utils.py`
334+
2. Add the M2M argument to the parent module's `argument_spec` following the standard structure (state/objects/child_key suboptions)
335+
3. Add matching `DOCUMENTATION` with suboptions
336+
4. Ensure the child key is in `CONVERT_TO_ID` and has appropriate `QUERY_TYPES`, `ENDPOINT_NAME_MAPPING`, and `ALLOWED_QUERY_PARAMS` entries
337+
5. Add integration tests covering merge, replace, delete, and idempotency
338+
339+
No changes to the module's `main()` function or constructor are needed -- the framework auto-detects M2M fields from `M2M_FIELDS` based on `self.endpoint`.

0 commit comments

Comments
 (0)