Extend the behaviour of the {module} variable in components of module types to account for different module bay layouts #11333

Open
opened 2025-12-29 21:43:46 +01:00 by adam · 9 comments
Owner

Originally created by @sol1-matt on GitHub (Jul 1, 2025).

NetBox version

v4.2.8

Feature type

Change to existing functionality

Proposed functionality

This is a FR related to #19414 to fulfil the request by arthanson .

The proposed functionality would allow for the definition of multiple naming conventions using {module} such that the same module type can be used with devices with in different levels of module bay configurations.

The implementation of this could be managed in different ways with the desired outcome to be the creation of values like

1 level:  port-1
2 levels: port-1-1
3 levels: port-1-1-1

Possible Implementations

List all possible combinations

port-{module},port-{module}-{module},port-{module}-{module}-{module}

Assume stop once all modules values are consumed

port-{module}-{module}-{module}

Regex optional repeat

port-{module}(-{module}){0,2}

Use case

The current functionality of module bays and module types correctly allows for nested designs

eg: device -> module bays -> module type -> module bays -> module type -> interface

A practical example of this would be a Server with a OCP bay (device -> module bay) which is filled with a dual port SFP nic (module type -> module bays), each port is then filled with a SFP module (module type -> interface).

For this to work in Netbox the SFP module needs to have the interface name set with 2 {module} variables
eg: port-{module}-{module}

However the same SFP module can not be used in another device which doesn't have this nested structure.

eg: device -> module bays -> module type -> interface

A practical example of this would be a Switch with SFP ports (module type -> module bays), each port is then filled with a SFP module (module type -> interface).

For this to work in Netbox the SFP module needs to have the interface name set with 1 {module} variable
eg: port-{module}

The Server and the Switch require different variables for the SFP Module which currently isn't possible.

The error message seen when trying to add a module type with the incorrect number of {module} vars for a given device configuration is
Cannot install module with placeholder values in a module bay tree <x> in tree but <y> placeholders given.

Workarounds

Duplicate Module Types
A work around to this would be to have multiple SFP Modules of the same type with different nesting vars for each one.

eg:
SFP Module (nest 1) = port-{module}
SFP Module (nest 2) = port-{module}-{module}
SFP Module (nest 3) = port-{module}-{module}-{module}

This can end up messy as you end up with multiple modules that are identical except for how they are used and requires the user to understand this specific problem/workaround.

Untick Replicate Components
When adding the module to a bay that has unsupported nesting untick the Replicate Components option and then manually create the interfaces and link them back to the correct bays.

This is additional work that isn't required when the {module} count matches with the potential for human error.

Alter the Module Type each time it is used in a different nesting format
Each time you get the error message Cannot install module with placeholder values in a module bay tree <x> in tree but <y> placeholders given. go to the Module Type and alter the {module} format to suit the current device.

This is additional work that isn't required when the {module} count matches but would need to be done each time the module is used on a device with nesting that is different from the last time it was used.

Reproducible test case

Types

  • Create a Device Type Server with a OCP bay with 1 Module Bay named OCP
  • Create a Device Type 24 port Switch with 2 Module Bays named SFP 1 and SFP 2 using positions 1 and 2
  • Create a Module Type of Dual port SFP nic with 2 Module Bays named SFP 1 and SFP 2 using positions 1 and 2
  • Create a Module Type of SFP module with a single interface name port-{module}

Server

  • Create a Device with a Device Type of Server with a OCP bay
  • Add a Module Type of Dual port SFP nic to the available OCP Module Bay
  • Add a Module Type of SFP module to the SFP 1 Module Bay SFP 1, you will get error message
    Cannot install module with placeholder values in a module bay tree <x> in tree but <y> placeholders given.
  • Change the Module Type of SFP module with a single interface name of port-{module} to have a interface name of port-{module}-{module}
  • Add a Module Type of SFP module to the SFP 1 Module Bay SFP 1, it will work and create a interface linked to the module called port-1-1

Switch

  • Create a Device with a Device Type of 24 port Switch
  • Add a Module Type of SFP module to the SFP 1 Module Bay SFP 1, you will get error message
    Cannot install module with placeholder values in a module bay tree <x> in tree but <y> placeholders given.
  • Change the Module Type of SFP module with a single interface name of port-{module}-{module} to have a interface name of port-{module}
  • Add a Module Type of SFP module to the SFP 1 Module Bay SFP 1, it will work and create a interface linked to the module called port-1

Database changes

No response

External dependencies

No response

Originally created by @sol1-matt on GitHub (Jul 1, 2025). ### NetBox version v4.2.8 ### Feature type Change to existing functionality ### Proposed functionality This is a FR related to #19414 to fulfil the request by [arthanson](https://github.com/netbox-community/netbox/issues/19414#issuecomment-2920128512) . The proposed functionality would allow for the definition of multiple naming conventions using `{module}` such that the same module type can be used with devices with in different levels of module bay configurations. The implementation of this could be managed in different ways with the desired outcome to be the creation of values like ``` 1 level: port-1 2 levels: port-1-1 3 levels: port-1-1-1 ``` #### Possible Implementations **List all possible combinations** ``` port-{module},port-{module}-{module},port-{module}-{module}-{module} ``` **Assume stop once all modules values are consumed** ``` port-{module}-{module}-{module} ``` **Regex optional repeat** ``` port-{module}(-{module}){0,2} ``` ### Use case The current functionality of module bays and module types correctly allows for nested designs eg: device -> module bays -> module type -> module bays -> module type -> interface A practical example of this would be a Server with a OCP bay (device -> module bay) which is filled with a dual port SFP nic (module type -> module bays), each port is then filled with a SFP module (module type -> interface). For this to work in Netbox the SFP module needs to have the interface name set with 2 `{module}` variables eg: `port-{module}-{module}` However the same SFP module can not be used in another device which doesn't have this nested structure. eg: device -> module bays -> module type -> interface A practical example of this would be a Switch with SFP ports (module type -> module bays), each port is then filled with a SFP module (module type -> interface). For this to work in Netbox the SFP module needs to have the interface name set with 1 `{module}` variable eg: `port-{module}` The Server and the Switch require different variables for the SFP Module which currently isn't possible. The error message seen when trying to add a module type with the incorrect number of `{module}` vars for a given device configuration is ```Cannot install module with placeholder values in a module bay tree <x> in tree but <y> placeholders given.``` #### Workarounds **Duplicate Module Types** A work around to this would be to have multiple SFP Modules of the same type with different nesting vars for each one. eg: SFP Module (nest 1) = `port-{module}` SFP Module (nest 2) = `port-{module}-{module}` SFP Module (nest 3) = `port-{module}-{module}-{module}` This can end up messy as you end up with multiple modules that are identical except for how they are used and requires the user to understand this specific problem/workaround. **Untick Replicate Components** When adding the module to a bay that has unsupported nesting untick the `Replicate Components` option and then manually create the interfaces and link them back to the correct bays. This is additional work that isn't required when the `{module}` count matches with the potential for human error. **Alter the Module Type each time it is used in a different nesting format** Each time you get the error message `Cannot install module with placeholder values in a module bay tree <x> in tree but <y> placeholders given.` go to the Module Type and alter the `{module}` format to suit the current device. This is additional work that isn't required when the `{module}` count matches but would need to be done each time the module is used on a device with nesting that is different from the last time it was used. ### Reproducible test case **Types** * Create a Device Type `Server with a OCP bay` with 1 Module Bay named `OCP` * Create a Device Type `24 port Switch` with 2 Module Bays named `SFP 1` and `SFP 2` using positions 1 and 2 * Create a Module Type of `Dual port SFP nic` with 2 Module Bays named `SFP 1` and `SFP 2` using positions 1 and 2 * Create a Module Type of `SFP module` with a single interface name `port-{module}` **Server** * Create a Device with a Device Type of `Server with a OCP bay` * Add a Module Type of `Dual port SFP nic` to the available `OCP` Module Bay * Add a Module Type of `SFP module` to the `SFP 1` Module Bay `SFP 1`, you will get error message ```Cannot install module with placeholder values in a module bay tree <x> in tree but <y> placeholders given. ``` * Change the Module Type of `SFP module` with a single interface name of `port-{module}` to have a interface name of `port-{module}-{module}` * Add a Module Type of `SFP module` to the `SFP 1` Module Bay `SFP 1`, it will work and create a interface linked to the module called `port-1-1` **Switch** * Create a Device with a Device Type of `24 port Switch` * Add a Module Type of `SFP module` to the `SFP 1` Module Bay `SFP 1`, you will get error message ```Cannot install module with placeholder values in a module bay tree <x> in tree but <y> placeholders given. ``` * Change the Module Type of `SFP module` with a single interface name of `port-{module}-{module}` to have a interface name of `port-{module}` * Add a Module Type of `SFP module` to the `SFP 1` Module Bay `SFP 1`, it will work and create a interface linked to the module called `port-1` ### Database changes _No response_ ### External dependencies _No response_
adam added the type: featurestatus: under reviewnetbox labels 2025-12-29 21:43:46 +01:00
Author
Owner

@smasharov commented on GitHub (Jul 3, 2025):

just checked it on 4.3.1 and it's working, but I want some more functional.

for example I have Juniper FPC MX-MPC2E-3D-P and couple MIC-3D-4XGE-XFP installed in it.
template xe-{module}/{module}/[0-1] works, but the module MIC-3D-4XGE-XFP have two subnumbers: 0 and 1, and resulting numbers should be like {module}/{module*2}/[0-1] and {module}/{module*2+1}/[0-1]
I have tried syntax like {module+1} but it just not works at all, nothing happens then I try to install this type of module

@smasharov commented on GitHub (Jul 3, 2025): just checked it on 4.3.1 and it's working, but I want some more functional. for example I have Juniper FPC MX-MPC2E-3D-P and couple MIC-3D-4XGE-XFP installed in it. template `xe-{module}/{module}/[0-1]` works, but the module MIC-3D-4XGE-XFP have two subnumbers: 0 and 1, and resulting numbers should be like `{module}/{module*2}/[0-1]` and `{module}/{module*2+1}/[0-1]` I have tried syntax like `{module+1}` but it just not works at all, nothing happens then I try to install this type of module
Author
Owner

@sol1-matt commented on GitHub (Jul 7, 2025):

just checked it on 4.3.1 and it's working

I've checked 4.3.3 myself and I get exactly the same functionality as described originally. If the number of {module}'s vars don't match the module bay nesting in use on a given device the module can't be added.

@sol1-matt commented on GitHub (Jul 7, 2025): > just checked it on 4.3.1 and it's working I've checked 4.3.3 myself and I get exactly the same functionality as described originally. If the number of `{module}`'s vars don't match the module bay nesting in use on a given device the module can't be added.
Author
Owner

@michaelmcdonald commented on GitHub (Jul 9, 2025):

I have run into the same (frustrating) issue and am not sure of a good way forward. I attempted to utilize a script and tags on module creation that would detect if multiple {module} variables were needed but not there (or multiple {module} variables present but not needed) and correct accordingly; however that did not pan out.

@jeremystretch: is there a defined way to handle when multiple {module} variables are / are not needed and how we can accommodate that?

@michaelmcdonald commented on GitHub (Jul 9, 2025): I have run into the same (frustrating) issue and am not sure of a good way forward. I attempted to utilize a script and tags on module creation that would detect if multiple `{module}` variables were needed but not there (or multiple `{module}` variables present but not needed) and correct accordingly; however that did not pan out. @jeremystretch: is there a defined way to handle when multiple `{module}` variables are / are not needed and how we can accommodate that?
Author
Owner

@jeremystretch commented on GitHub (Jul 9, 2025):

Please stop pinging me for issues on which I have not engaged. I cannot and will not weigh in on every FR.

@jeremystretch commented on GitHub (Jul 9, 2025): _Please_ stop pinging me for issues on which I have not engaged. I cannot and will not weigh in on every FR.
Author
Owner

@michaelmcdonald commented on GitHub (Jul 9, 2025):

Apologize; simply assumed as the lead developer you would have insight on how a situation like this is to be handled.

@michaelmcdonald commented on GitHub (Jul 9, 2025): Apologize; simply assumed as the lead developer you would have insight on how a situation like this is to be handled.
Author
Owner

@TekunoKage commented on GitHub (Jul 11, 2025):

SubModule Bay:

Image

SubModule:
Image

SubModule Lable Not Take Module Position:
Image

SubModule Interfacce Definition
Image

SubModule Interface Description Not populated

Image

Netbox Version:
Community v4.3.3

On my case, just those few things need to be corrected to get this working properly.

Thanks!!!

@TekunoKage commented on GitHub (Jul 11, 2025): SubModule Bay: <img width="1563" height="334" alt="Image" src="https://github.com/user-attachments/assets/ea6d5440-4f26-4eee-bd4b-04672d02b133" /> SubModule: <img width="1556" height="626" alt="Image" src="https://github.com/user-attachments/assets/c293593c-b1ac-4864-a452-42f1528e21f1" /> SubModule Lable Not Take Module Position: <img width="1524" height="151" alt="Image" src="https://github.com/user-attachments/assets/0fa6f575-7637-466d-b582-1ca88a2603a4" /> SubModule Interfacce Definition <img width="1577" height="298" alt="Image" src="https://github.com/user-attachments/assets/864ee086-1178-4724-8854-ec034e9aac7b" /> SubModule Interface Description Not populated <img width="1837" height="305" alt="Image" src="https://github.com/user-attachments/assets/f6f3e954-bd5b-47ae-80cd-b97f68ddccf6" /> Netbox Version: Community v4.3.3 On my case, just those few things need to be corrected to get this working properly. Thanks!!!
Author
Owner

@fzs commented on GitHub (Jul 15, 2025):

I just came across the same behaviour. 👍 for this FR. The example of modeling SFPs as modules now is the prime example why this is needed.

In my case I assumed that the {module} placeholder in the position is filled in with the value from the position in the device. But apparently it isn't. I would think that for a module inserted into a module bay, the name as well as the position for module bays are resolved. Because then this would already work.

Here is an example:

A device type with two module bays:

manufacturer: Generic
model: 2-bay device
slug: 2-bay-device
u_height: 1.0
is_full_depth: true
module-bays:
- name: Bay 1
  position: A
- name: Bay 2
  position: B

A module type having again two module bays itself:

manufacturer: Generic
model: 2-bay module
module-bays:
- name: 'Module bay {module}-1'
  position: '{module}1'
- name: 'Module bay {module}-2'
  position: '2'

And finally a SFP module providing one ethernet interface:

manufacturer: Generic
model: 1-interface SFP
interfaces:
- name: '{module}'
  type: 1000base-t
  enabled: true
  mgmt_only: false

Now let's create a device of type " 2-bay device". It will have two module bays with positions A and B.

Image

If we instantiate a module of type "2-bay module" into the device's module bay A, we get a module with two module bays of its own. In sum we now have four module bays. The names of the module bays in the module have been resolved. The positions not.

Image

If the position had been resolved, and if the position of the module's module bay would actually be used in this case, then the interface of the SFP module would have been named A1 when inserted into module bay "Module bay A-1".

But I am not able to insert the "1-interface SFP" module type into either "Module bay A-1" or "Module bay A-2". In both cases I get the aforementioned error message. So apparently the name is resolved from a tree of postions through the module chain which requires the name to have the exact number of {module} placeholders in there.

I question that this makes sense. For SFP modules that can be inserted at any level it certainly makes absolutely no sense. In my mind it would be more consitent and easier to understand if the placeholder would be filled in with the position value at the module bay level that it is inserted to. Which would require to resolve the placeholder for module bay positions, too.

@fzs commented on GitHub (Jul 15, 2025): I just came across the same behaviour. 👍 for this FR. The example of modeling SFPs as modules now is the prime example why this is needed. In my case I assumed that the `{module}` placeholder in the position is filled in with the value from the position in the device. But apparently it isn't. I would think that for a module inserted into a module bay, the name as well as the position for module bays are resolved. Because then this would already work. Here is an example: A device type with two module bays: ```yaml manufacturer: Generic model: 2-bay device slug: 2-bay-device u_height: 1.0 is_full_depth: true module-bays: - name: Bay 1 position: A - name: Bay 2 position: B ``` A module type having again two module bays itself: ```yaml manufacturer: Generic model: 2-bay module module-bays: - name: 'Module bay {module}-1' position: '{module}1' - name: 'Module bay {module}-2' position: '2' ``` And finally a SFP module providing one ethernet interface: ```yaml manufacturer: Generic model: 1-interface SFP interfaces: - name: '{module}' type: 1000base-t enabled: true mgmt_only: false ``` Now let's create a device of type " 2-bay device". It will have two module bays with positions A and B. <img width="449" height="323" alt="Image" src="https://github.com/user-attachments/assets/3f6bba7d-459e-49cb-b26f-7dc3ab145f7d" /> If we instantiate a module of type "2-bay module" into the device's module bay A, we get a module with two module bays of its own. In sum we now have four module bays. The names of the module bays in the module have been resolved. The positions not. <img width="560" height="399" alt="Image" src="https://github.com/user-attachments/assets/03004bbb-60d8-4677-9680-b6e39301a157" /> If the position had been resolved, and if the position of the module's module bay would actually be used in this case, then the interface of the SFP module would have been named A1 when inserted into module bay "Module bay A-1". But I am not able to insert the "1-interface SFP" module type into either "Module bay A-1" or "Module bay A-2". In both cases I get the aforementioned error message. So apparently the name is resolved from a tree of postions through the module chain which requires the name to have the exact number of `{module}` placeholders in there. I question that this makes sense. For SFP modules that can be inserted at any level it certainly makes absolutely no sense. In my mind it would be more consitent and easier to understand if the placeholder would be filled in with the position value at the module bay level that it is inserted to. Which would require to resolve the placeholder for module bay positions, too.
Author
Owner

@sol1-matt commented on GitHub (Jul 16, 2025):

I hadn't considered allowing the position to inherit the parent position @fzs

  • Create a Device Type Server with a OCP bay with 1 Module Bay named OCP with a position of 1
  • Create a Module Type of Dual port SFP nic with 2 Module Bays named {module}-SFP 1 and {module}-SFP 2 using positions {module}-1 and {module}-2
  • Create a device Example server with a OCP bay and add the module Dual port SFP nic to the OCP bay
  • Create a Module Type of SFP module with a single interface name port-{module}
  • Add SFP module to a SFP bay on the example server - This fails in Netbox 4.3.3
  • Edit the Module Type have a interface name of port-{module}-{module}
  • Add SFP module to the second SFP bay on the example server - This works but the interface name is port-1-{module}-2 which is wrong

But I'm assuming what we want when the Dual port SFP nic is added to the server it has 2 bays named 1-SFP 1 and 1-SFP 2.
And adding a SFP module to a SFP bay would end up with a port name along the lines of port-1-1 or port-1-2.

I like this better than the solutions I originally gave. It is neater and allows different naming conventions of based on the bays used if required where as all my suggestions the module interface will always have the same naming convention.
eg1:

  • level 1 position: ocp[1-2]
  • level 2 position: {module}-sfp[1-2]
  • interface name: port-{module}

and we end up with port names of

  • port-ocp1-sfp1
  • port-ocp1-sfp2
  • port-ocp2-sfp1
  • port-ocp2-sfp2

eg2:

  • level 1 position: [A1-2]
  • level 2 position: {module}-[1-2]
  • interface name: port-{module}

and we end up with port names of

  • port-A1-1
  • port-A1-2
  • port-A2-1
  • port-A2-2
@sol1-matt commented on GitHub (Jul 16, 2025): I hadn't considered allowing the position to inherit the parent position @fzs * Create a Device Type Server with a OCP bay with 1 Module Bay named `OCP` with a position of `1` * Create a Module Type of Dual port SFP nic with 2 Module Bays named `{module}-SFP 1` and `{module}-SFP 2` using positions `{module}-1` and `{module}-2` * Create a device Example server with a OCP bay and add the module Dual port SFP nic to the OCP bay * Create a Module Type of SFP module with a single interface name `port-{module}` * Add SFP module to a SFP bay on the example server - _This fails in Netbox 4.3.3_ * Edit the Module Type have a interface name of `port-{module}-{module}` * Add SFP module to the second SFP bay on the example server - _This works but the interface name is `port-1-{module}-2` which is wrong_ But I'm assuming what we want when the Dual port SFP nic is added to the server it has 2 bays named 1-SFP 1 and 1-SFP 2. And adding a SFP module to a SFP bay would end up with a port name along the lines of `port-1-1` or `port-1-2`. I like this better than the solutions I originally gave. It is neater and allows different naming conventions of based on the bays used if required where as all my suggestions the module interface will always have the same naming convention. eg1: * level 1 position: ocp[1-2] * level 2 position: {module}-sfp[1-2] * interface name: `port-{module}` and we end up with port names of * port-ocp1-sfp1 * port-ocp1-sfp2 * port-ocp2-sfp1 * port-ocp2-sfp2 eg2: * level 1 position: [A1-2] * level 2 position: {module}-[1-2] * interface name: `port-{module}` and we end up with port names of * port-A1-1 * port-A1-2 * port-A2-1 * port-A2-2
Author
Owner

@RichardVReyden commented on GitHub (Aug 5, 2025):

just checked it on 4.3.1 and it's working, but I want some more functional.

for example I have Juniper FPC MX-MPC2E-3D-P and couple MIC-3D-4XGE-XFP installed in it. template xe-{module}/{module}/[0-1] works, but the module MIC-3D-4XGE-XFP have two subnumbers: 0 and 1, and resulting numbers should be like {module}/{module*2}/[0-1] and {module}/{module*2+1}/[0-1] I have tried syntax like {module+1} but it just not works at all, nothing happens then I try to install this type of module

I have also come across the same issue with Juniper daughter modules.

@RichardVReyden commented on GitHub (Aug 5, 2025): > just checked it on 4.3.1 and it's working, but I want some more functional. > > for example I have Juniper FPC MX-MPC2E-3D-P and couple MIC-3D-4XGE-XFP installed in it. template `xe-{module}/{module}/[0-1]` works, but the module MIC-3D-4XGE-XFP have two subnumbers: 0 and 1, and resulting numbers should be like `{module}/{module*2}/[0-1]` and `{module}/{module*2+1}/[0-1]` I have tried syntax like `{module+1}` but it just not works at all, nothing happens then I try to install this type of module I have also come across the same issue with Juniper daughter modules.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#11333