Skip to content

Add airflow and rack_type field support to netbox_rack module#1519

Draft
richbibby wants to merge 4 commits intodevelfrom
feature/add-airflow-racktype-to-rack
Draft

Add airflow and rack_type field support to netbox_rack module#1519
richbibby wants to merge 4 commits intodevelfrom
feature/add-airflow-racktype-to-rack

Conversation

@richbibby
Copy link
Contributor

Related Issue

#1450

New Behavior

The netbox_rack module now supports two additional fields:

  • airflow: Manages the airflow direction of racks (front-to-rear, rear-to-front)
  • rack_type: Associates racks with predefined rack types that define characteristics like width, u_height, form factor, etc.

Both fields were introduced in NetBox 4.1 and are now fully supported by the Ansible collection.

Contrast to Current Behavior

Previously, the netbox_rack module did not support the airflow or rack_type fields. Users had to manage these fields through other means (direct API calls, NetBox UI) rather than through Ansible automation.

With this change, users can now fully manage rack objects including airflow direction and rack type associations directly through Ansible playbooks, providing complete infrastructure-as-code capabilities for rack management.

Discussion: Benefits and Drawbacks

Benefits:

  • Complete rack management through Ansible - users can now automate all rack attributes including airflow and rack type
  • Rack types enable standardization - define rack templates with predefined characteristics that can be reused across multiple racks
  • Airflow tracking - helps with data center capacity planning and cooling management
  • Follows NetBox API capabilities - brings the module in line with NetBox 4.1+ features

Drawbacks:

  • None identified

Backward Compatibility:

  • Fully backward compatible - both fields are optional
  • Existing playbooks continue to work without modification
  • Tests added to v4.1, v4.2, and v4.3 integration suites (v4.0 excluded as these fields don't exist in NetBox 4.0)

Changes to the Documentation

Module Documentation:

  • Added airflow field documentation with choices (front-to-rear, rear-to-front)
  • Added rack_type field documentation describing its relationship to rack types endpoint
  • Added example showing usage of both new fields
  • Both fields marked with version_added: "3.23.0"

Changelog:

  • Added changelog fragment: changelogs/fragments/add-airflow-racktype-to-rack.yml
  • Entry: "netbox_rack - Add airflow and rack_type field support"

Integration Tests:

  • Added comprehensive tests to v4.1, v4.2, and v4.3 integration suites
  • Tests cover: create, update, idempotency, and delete operations for both fields
  • Test data prerequisites added to tests/integration/netbox-deploy.py

Proposed Release Note Entry

netbox_rack - Add airflow and rack_type field support (https://github.com/netbox-community/ansible_modules/issues/1450)

Double Check

  • I have read the comments and followed the CONTRIBUTING.md.
  • I have explained my PR according to the information in the comments or in a linked issue.
  • My PR targets the devel branch.

richbibby and others added 2 commits February 2, 2026 09:45
- Add airflow field with choices: front-to-rear, rear-to-front
- Add rack_type field to reference rack type objects
- Add NB_RACK_TYPES constant to netbox_dcim.py
- Update netbox_utils.py with rack_type mappings
- Add changelog fragment for release notes
- Add example demonstrating new fields usage

Resolves #1450

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated to follow existing test patterns:
- Added rack types to netbox-deploy.py (like other test data)
- Tests reference rack_type by model name (not API calls)
- Removed uri: module usage and SETUP/CLEANUP tasks
- Tests match existing relational field patterns (device_type, rack_role, etc.)
- Airflow tests: create, update, delete (tests 9-11)
- Rack_type tests: create, idempotency, update, delete (tests 12-15)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds NetBox 4.1+ support for managing rack airflow and associating rack_type via the netbox_rack Ansible module, with supporting utils and integration coverage.

Changes:

  • Extend netbox_rack module options/documentation to include airflow (choices) and rack_type (relation).
  • Update NetBox utility mappings to resolve rack_type against the rack_types endpoint and treat airflow as a choice field.
  • Add integration test tasks for NetBox v4.1/v4.2/v4.3 and seed rack types in the integration deploy script.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tests/integration/targets/v4.3/tasks/netbox_rack.yml Adds airflow and rack_type integration scenarios for NetBox v4.3
tests/integration/targets/v4.2/tasks/netbox_rack.yml Adds airflow and rack_type integration scenarios for NetBox v4.2
tests/integration/targets/v4.1/tasks/netbox_rack.yml Adds airflow and rack_type integration scenarios for NetBox v4.1
tests/integration/netbox-deploy.py Seeds rack types for integration tests
plugins/modules/netbox_rack.py Adds airflow/rack_type module parameters + docs/examples
plugins/module_utils/netbox_utils.py Adds rack_types endpoint + rack_type resolution and airflow choice handling
plugins/module_utils/netbox_dcim.py Introduces NB_RACK_TYPES constant
changelogs/fragments/add-airflow-racktype-to-rack.yml Changelog entry for the new rack fields support

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +296 to +304
- name: 12 - ASSERT
ansible.builtin.assert:
that:
- test_twelve is changed
- test_twelve['diff']['before']['state'] == "absent"
- test_twelve['diff']['after']['state'] == "present"
- test_twelve['rack']['name'] == "Test Rack With Type"
- test_twelve['rack']['rack_type'] is not none
- test_twelve['msg'] == "rack Test Rack With Type created"
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rack_type assertions only check is not none, which wouldn't catch mapping to the wrong rack type. Consider asserting the expected rack_type ID (e.g. first created type vs second) for both create and update so the test validates correct association, not just presence.

Copilot uses AI. Check for mistakes.
Comment on lines +228 to +248
- name: 9 - Create rack with airflow
netbox.netbox.netbox_rack:
netbox_url: http://localhost:32768
netbox_token: "0123456789abcdef0123456789abcdef01234567"
data:
name: Test Rack Airflow
site: Test Site
airflow: front-to-rear
state: present
register: test_nine

- name: 9 - ASSERT
ansible.builtin.assert:
that:
- test_nine is changed
- test_nine['diff']['before']['state'] == "absent"
- test_nine['diff']['after']['state'] == "present"
- test_nine['rack']['name'] == "Test Rack Airflow"
- test_nine['rack']['airflow'] == "front-to-rear"
- test_nine['msg'] == "rack Test Rack Airflow created"

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These airflow tests cover create/update/delete but not idempotency. Add a second state: present run with the same airflow value and assert changed is false to ensure the new field is idempotent (and to match the PR description/test intent).

Copilot uses AI. Check for mistakes.
Comment on lines +228 to +248
- name: 9 - Create rack with airflow
netbox.netbox.netbox_rack:
netbox_url: http://localhost:32768
netbox_token: "0123456789abcdef0123456789abcdef01234567"
data:
name: Test Rack Airflow
site: Test Site
airflow: front-to-rear
state: present
register: test_nine

- name: 9 - ASSERT
ansible.builtin.assert:
that:
- test_nine is changed
- test_nine['diff']['before']['state'] == "absent"
- test_nine['diff']['after']['state'] == "present"
- test_nine['rack']['name'] == "Test Rack Airflow"
- test_nine['rack']['airflow'] == "front-to-rear"
- test_nine['msg'] == "rack Test Rack Airflow created"

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These airflow tests cover create/update/delete but not idempotency. Add a second state: present run with the same airflow value and assert changed is false to ensure the new field is idempotent (and to match the PR description/test intent).

Copilot uses AI. Check for mistakes.
"racks": {},
"rack_groups": {},
"rack_roles": {},
"rack_types": {},
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rack_types was introduced in NetBox 4.1; without an introduced gate here, using rack_type against a NetBox 4.0 instance will attempt to access nb.dcim.rack_types during ID resolution and crash with an AttributeError. Add an {"introduced": "4.1"} marker for this endpoint (as done for other version-gated endpoints) so older versions are handled predictably.

Suggested change
"rack_types": {},
"rack_types": {"introduced": "4.1"},

Copilot uses AI. Check for mistakes.
Comment on lines +296 to +304
- name: 12 - ASSERT
ansible.builtin.assert:
that:
- test_twelve is changed
- test_twelve['diff']['before']['state'] == "absent"
- test_twelve['diff']['after']['state'] == "present"
- test_twelve['rack']['name'] == "Test Rack With Type"
- test_twelve['rack']['rack_type'] is not none
- test_twelve['msg'] == "rack Test Rack With Type created"
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rack_type assertions only check is not none, which wouldn't catch mapping to the wrong rack type. Consider asserting the expected rack_type ID (e.g. first created type vs second) for both create and update so the test validates correct association, not just presence.

Copilot uses AI. Check for mistakes.
Comment on lines 283 to 300
# Create Rack Types
rack_types = [
{
"manufacturer": cisco_manu.id,
"model": "Standard 42U",
"slug": "standard-42u",
"form_factor": "4-post-frame",
"u_height": 42,
},
{
"manufacturer": cisco_manu.id,
"model": "Standard 48U",
"slug": "standard-48u",
"form_factor": "4-post-cabinet",
"u_height": 48,
},
]
created_rack_types = make_netbox_calls(nb.dcim.rack_types, rack_types)
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nb.dcim.rack_types is only available in NetBox >= 4.1, but this deploy script runs for other integration targets (e.g. v4.0). Creating rack types unconditionally will raise an AttributeError / API error and break those test runs. Wrap rack type creation in a if nb_version >= version.parse("4.1"): guard (or feature-detect the endpoint) and skip otherwise.

Suggested change
# Create Rack Types
rack_types = [
{
"manufacturer": cisco_manu.id,
"model": "Standard 42U",
"slug": "standard-42u",
"form_factor": "4-post-frame",
"u_height": 42,
},
{
"manufacturer": cisco_manu.id,
"model": "Standard 48U",
"slug": "standard-48u",
"form_factor": "4-post-cabinet",
"u_height": 48,
},
]
created_rack_types = make_netbox_calls(nb.dcim.rack_types, rack_types)
# Create Rack Types (NetBox >= 4.1 only)
created_rack_types = []
if nb_version >= version.parse("4.1"):
rack_types = [
{
"manufacturer": cisco_manu.id,
"model": "Standard 42U",
"slug": "standard-42u",
"form_factor": "4-post-frame",
"u_height": 42,
},
{
"manufacturer": cisco_manu.id,
"model": "Standard 48U",
"slug": "standard-48u",
"form_factor": "4-post-cabinet",
"u_height": 48,
},
]
created_rack_types = make_netbox_calls(nb.dcim.rack_types, rack_types)

Copilot uses AI. Check for mistakes.
site: Test Site
location: Test Location
airflow: front-to-rear
rack_type: Standard 42U Rack
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example value rack_type: Standard 42U Rack will be slugified to standard-42u-rack for lookup, which is unlikely to exist and may mislead users. Use a value that matches how rack types are resolved (e.g. the rack type's model/name like Standard 42U, its slug standard-42u, or a dict specifying slug).

Suggested change
rack_type: Standard 42U Rack
rack_type: Standard 42U

Copilot uses AI. Check for mistakes.
Comment on lines +228 to +248
- name: 9 - Create rack with airflow
netbox.netbox.netbox_rack:
netbox_url: http://localhost:32768
netbox_token: "0123456789abcdef0123456789abcdef01234567"
data:
name: Test Rack Airflow
site: Test Site
airflow: front-to-rear
state: present
register: test_nine

- name: 9 - ASSERT
ansible.builtin.assert:
that:
- test_nine is changed
- test_nine['diff']['before']['state'] == "absent"
- test_nine['diff']['after']['state'] == "present"
- test_nine['rack']['name'] == "Test Rack Airflow"
- test_nine['rack']['airflow'] == "front-to-rear"
- test_nine['msg'] == "rack Test Rack Airflow created"

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These airflow tests cover create/update/delete but not idempotency. Add a second state: present run with the same airflow value and assert changed is false to ensure the new field is idempotent (and to match the PR description/test intent).

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 1 to 3
---
minor_changes:
- "netbox_custom_field - Add support for 'unique' field to enforce unique value constraints (https://github.com/netbox-community/ansible_modules/issues/1452)"
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changelog fragment documents netbox_custom_field support for unique and links to issue #1452, which is not mentioned in the PR title/description (focused on #1450 / netbox_rack). Please align the PR metadata with this additional change, or move this fragment (and related code/tests) to a separate PR.

Copilot uses AI. Check for mistakes.
type: raw
rack_type:
description:
- The rack type that defines predefined characteristics like width, u_height, and others
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new rack_type option is only available starting with NetBox 4.1 (rack types were introduced in 4.1), but the option description doesn’t mention the NetBox version constraint. Please update the option documentation to explicitly call out the NetBox 4.1+ requirement to prevent confusion for users on older NetBox versions.

Suggested change
- The rack type that defines predefined characteristics like width, u_height, and others
- The rack type that defines predefined characteristics like width, u_height, and others (NetBox 4.1+)

Copilot uses AI. Check for mistakes.
Comment on lines +168 to +176
airflow:
description:
- Airflow direction of the rack
choices:
- front-to-rear
- rear-to-front
required: false
type: str
version_added: "3.23.0"
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new airflow field is a NetBox 4.1+ rack attribute, but the option description doesn’t mention the NetBox version constraint. Please note the NetBox 4.1+ requirement in the documentation (similar to how other options call out version-specific behavior).

Copilot uses AI. Check for mistakes.
Comment on lines 95 to 100
unique:
description:
- Whether the custom field must have unique values
required: false
type: bool
version_added: "3.23.0"
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR adds new functionality beyond the stated scope/title/description: netbox_custom_field gains a new unique option (plus tests and a changelog fragment referencing issue #1452), but the PR metadata only describes changes to netbox_rack (#1450). Please either update the PR title/description to include the custom-field feature (and reference the related issue), or split the custom-field work into a separate PR to keep changes focused.

Copilot uses AI. Check for mistakes.
@richbibby richbibby marked this pull request as draft February 4, 2026 10:48
richbibby and others added 2 commits February 4, 2026 10:57
Both features were introduced in NetBox 4.1 (September 2024), so tests
should run against v4.1, v4.2, and v4.3.

- v4.0: No changes (features don't exist in this version)
- v4.1: Added tests for airflow and rack_type
- v4.2: Added tests for airflow and rack_type
- v4.3: Already had tests

This ensures backward compatibility testing across all supported versions
that have these features.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixes NetBox 4.0 compatibility issues by adding version gates to prevent AttributeError when rack_types endpoint is accessed on older NetBox versions. Adds missing airflow idempotency tests and corrects example documentation to match test data.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@richbibby richbibby force-pushed the feature/add-airflow-racktype-to-rack branch from 694505e to 17a2431 Compare February 4, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant