Repository: netbox-community/netbox

Issue:
Allow setting Virtual Chassis fields from Device create/update forms
### NetBox version

v3.2.3

### Feature type

New functionality

### Proposed functionality

It would be really nice to be able set the *vc\** fields directly on the Device forms. As they are already part of the Device model, this should just require creating the 3 fields (Virtual Chassis, Position, Priority) in the corresponding forms. With the way that things are currently modeled, I'm not sure why this isn't already an option, so maybe there's some other technical limitation that I'm missing.

Optionally, using any Site, Location, or Rack fields that are set to filter the list of Virtual Chassis to choose from, kind of like how the *Add Member* form works, might be nice.

If possible, adding a field to allow setting the device as master would also be helpful. I understand if this might cause validation issues by the device not being a member of the Virtual Chassis first.

### Use case

When adding a switch to a stack, today you have to add the Device, then go to the Virtual Chassis, add a new member, then search for the switch before it can be added. This would greatly simplify that process and I think could also help to resolve #8648.

You could put something like `{member}` in the Module Bay Position field of a Device Type or in an Interface Name, which would then be replaced by the Position within the selected Virtual Chassis, just like is done for Modules today. That way, the Module Bay Position could become something like `1/1` instead of just `1` and you could replace the Module templates with something like `Gi{module}/1` instead of `Gi1/{module}/1`. Or, if you want to keep it as `1`, then your template could be `Gi{member}/{module}/1`. I'm assuming that would get around the issue of components being created before Virtual Chassis assignment.

### Database changes

None

### External dependencies

None


Discussion:
The API already permits this - all that would be needed, I think, would be to extend the GUI to include the selection of a virtual chassis and if selected, require the user to enter in a vc_position, and if desired, a vc_priority as well. I'd be willing to try and implement this on the GUI side if approved.
After playing around with things, just to get a better understanding of Django and the Netbox codebase, I believe I've got a minimum tweak to add this functionality. 

Unfortunately, from my understanding of how the disabled-indicator functions (based on whether a field is populated, and not the value of the field), as well as in the interest of avoid vendor or device specific constraints (some Cisco have a max of 8 members, others 9, and that's not counting other manufacturers), I wasn't able to make a fancy drop-down for vc_position. The user will be required to cross-compare with a switch stack to know which members are open.

Regardless, the back-end API should handle invalid vc_position and vc_priority numbers, and spits back an error message to the user when it fails, giving them the option to change it.

Resolving patch:
diff --git a/netbox/dcim/forms/models.py b/netbox/dcim/forms/models.py
--- a/netbox/dcim/forms/models.py
+++ b/netbox/dcim/forms/models.py
@@ -521,13 +521,26 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
         required=False,
         label=''
     )
+    virtual_chassis = DynamicModelChoiceField(
+        queryset=VirtualChassis.objects.all(),
+        required=False
+    )
+    vc_position = forms.IntegerField(
+        required=False,
+        help_text="The position in the virtual chassis this device is identified by"
+    )
+    vc_priority = forms.IntegerField(
+        required=False,
+        help_text="The priority of the device in the virtual chassis"
+    )
 
     class Meta:
         model = Device
         fields = [
             'name', 'device_role', 'device_type', 'serial', 'asset_tag', 'region', 'site_group', 'site', 'rack',
             'location', 'position', 'face', 'status', 'airflow', 'platform', 'primary_ip4', 'primary_ip6',
-            'cluster_group', 'cluster', 'tenant_group', 'tenant', 'comments', 'tags', 'local_context_data'
+            'cluster_group', 'cluster', 'tenant_group', 'tenant', 'virtual_chassis', 'vc_position', 'vc_priority',
+            'comments', 'tags', 'local_context_data'
         ]
         help_texts = {
             'device_role': "The function this device serves",


Test patch: