internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: netbox-community/netbox

Issue:
IPAM IP Addresses List no Filter Column Device/VM
### NetBox version

v3.2.4

### Feature type

Change to existing functionality

### Proposed functionality

Filter the IPAM IP Addresses List by Device/VM.

### Use case

Intuitively, you open the list of IP addresses and want to check which IP addresses are assigned to certain devices. This is not possible in this way because the filter ignores the Device/VM column.

So you have to go to the device and list the interfaces.
But this is more complicated if you want to check many devices.

### Database changes

_No response_

### External dependencies

_No response_


Discussion:
I'm working on this issue.

Resolving patch:
diff --git a/netbox/ipam/forms/filtersets.py b/netbox/ipam/forms/filtersets.py
--- a/netbox/ipam/forms/filtersets.py
+++ b/netbox/ipam/forms/filtersets.py
@@ -1,7 +1,8 @@
 from django import forms
 from django.utils.translation import gettext as _
 
-from dcim.models import Location, Rack, Region, Site, SiteGroup
+from dcim.models import Location, Rack, Region, Site, SiteGroup, Device
+from virtualization.models import VirtualMachine
 from ipam.choices import *
 from ipam.constants import *
 from ipam.models import *
@@ -265,6 +266,7 @@ class IPAddressFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
         ('Attributes', ('parent', 'family', 'status', 'role', 'mask_length', 'assigned_to_interface')),
         ('VRF', ('vrf_id', 'present_in_vrf_id')),
         ('Tenant', ('tenant_group_id', 'tenant_id')),
+        ('Device/VM', ('device_id', 'virtual_machine_id')),
     )
     parent = forms.CharField(
         required=False,
@@ -298,6 +300,16 @@ class IPAddressFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
         required=False,
         label=_('Present in VRF')
     )
+    device_id = DynamicModelMultipleChoiceField(
+        queryset=Device.objects.all(),
+        required=False,
+        label=_('Assigned Device'),
+    )
+    virtual_machine_id = DynamicModelMultipleChoiceField(
+        queryset=VirtualMachine.objects.all(),
+        required=False,
+        label=_('Assigned VM'),
+    )
     status = MultipleChoiceField(
         choices=IPAddressStatusChoices,
         required=False


Test patch:
Repository: netbox-community/netbox

Issue:
v3.3-beta1: Typo in CableEditView
### NetBox version

v3.3-beta1

### Python version

3.8

### Steps to Reproduce

NetBox/dcim/views.py content:

```
b_type = termination_b.termination._meta.model if termination_a else None
```


### Expected Behavior

b_type depends on termination_b.

### Observed Behavior

b_type depends on termination_a.


Discussion:

Resolving patch:
diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py
--- a/netbox/dcim/views.py
+++ b/netbox/dcim/views.py
@@ -2850,7 +2850,7 @@ def get_object(self, **kwargs):
             termination_a = obj.terminations.filter(cable_end='A').first()
             a_type = termination_a.termination._meta.model if termination_a else None
             termination_b = obj.terminations.filter(cable_end='B').first()
-            b_type = termination_b.termination._meta.model if termination_a else None
+            b_type = termination_b.termination._meta.model if termination_b else None
             self.form = forms.get_cable_form(a_type, b_type)
 
         return obj


Test patch:
Repository: netbox-community/netbox

Issue:
Broken image URLs in rack view
### NetBox version

v3.2.5

### Python version

3.9

### Steps to Reproduce

1. Have device types with front and rear device pictures uploaded and hosted on a separate domain (we use it for static content, let's say https://static.domain/images/front.png)
2. Have devices installed in a rack
3. View the rack with https://your.netbox.domain/dcim/racks/$some_id/

### Expected Behavior

Front and Rear rack view filled with images of device types of the devices installed to this rack.

### Observed Behavior

Blueish tint instead of images because the URLs for images are now prefixed with the netbox domain (like https://your.netbox.domainhttps://static.domain/images/front.png which is obviously unavailable)
Seems like this is caused by https://github.com/netbox-community/netbox/issues/9503. Rack views were fine on 3.1 which we had before the update.
Device type views (https://your.netbox.domain/dcim/device-types/$id/) show images just fine on 3.2.5, links are not broken.


Discussion:
> Have device types with front and rear device pictures uploaded and hosted on a separate domain

Please elaborate on exactly how you have NetBox configured, so that someone else can attempt to replicate the reported problem.
Yes, sorry. Static content storage is configured via
STORAGE_BACKEND
STORAGE_CONFIG
configuration parameters as described in https://docs.netbox.dev/en/stable/configuration/optional-settings/#storage_backend
The "https://static.domain" is stored as the `AWS_S3_ENDPOINT_URL`.

Resolving patch:
diff --git a/netbox/dcim/svg.py b/netbox/dcim/svg.py
--- a/netbox/dcim/svg.py
+++ b/netbox/dcim/svg.py
@@ -113,8 +113,12 @@ def _draw_device_front(self, drawing, device, start, end, text):
 
         # Embed front device type image if one exists
         if self.include_images and device.device_type.front_image:
+            url = device.device_type.front_image.url
+            # Convert any relative URLs to absolute
+            if url.startswith('/'):
+                url = '{}{}'.format(self.base_url, url)
             image = drawing.image(
-                href='{}{}'.format(self.base_url, device.device_type.front_image.url),
+                href=url,
                 insert=start,
                 size=end,
                 class_='device-image'
@@ -139,8 +143,12 @@ def _draw_device_rear(self, drawing, device, start, end, text):
 
         # Embed rear device type image if one exists
         if self.include_images and device.device_type.rear_image:
+            url = device.device_type.rear_image.url
+            # Convert any relative URLs to absolute
+            if url.startswith('/'):
+                url = '{}{}'.format(self.base_url, url)
             image = drawing.image(
-                href='{}{}'.format(self.base_url, device.device_type.rear_image.url),
+                href=url,
                 insert=start,
                 size=end,
                 class_='device-image'


Test patch:
Repository: netbox-community/netbox

Issue:
Validation error when adding a new cable
### NetBox version

3.3.0-beta1

### Python version

3.10

### Steps to Reproduce

1. Create a site ("Test")
2. Create a manufacturer ("Panduit")
3. Create a manufacturer ("Cisco")
4. Create a device type ("C9200-48T") with "Cisco" manufacturer
5. Create a device type ("Patch Panel") with "Panduit" manufacturer
6. Add (1) 12 position rear port to "Patch Panel"
7. Add (12) front ports to "Patch Panel"
8. Add (48) 1000base-t interfaces to "C9200-48T"
9. Create a device role ("Access Switch")
10. Create a device role ("Fiber Patch Panel")
11. Create (2) devices of type "Patch Panel" ("P1", "P2") in site "Test" with role "Fiber Patch Panel"
12. Create (2) devices of type "C9200-48T" ("S1", "S2") in site "Test" with role "Access Switch"
13. On "Patch Panel", attempt to connect rear-port on P1 to rear-port on P2

### Expected Behavior

Cable created successfully

### Observed Behavior

"Must define A and B terminations when creating a new cable."


Discussion:
The error is throw in:

https://github.com/netbox-community/netbox/blob/868e94fb730e24e174abba13a77cdef32c619e6e/netbox/dcim/models/cables.py#L149

Because this is in clean() instead of save, the instance terminations must be set in clean() on the form instead of save() as below:

https://github.com/netbox-community/netbox/blob/868e94fb730e24e174abba13a77cdef32c619e6e/netbox/dcim/forms/connections.py#L163-L169


Another thing of note, this may also impact elsewhere (API, etc), I only currently looked quickly at the form.

Resolving patch:
diff --git a/netbox/dcim/forms/connections.py b/netbox/dcim/forms/connections.py
--- a/netbox/dcim/forms/connections.py
+++ b/netbox/dcim/forms/connections.py
@@ -160,12 +160,11 @@ def __init__(self, *args, **kwargs):
                 self.initial['a_terminations'] = self.instance.a_terminations
                 self.initial['b_terminations'] = self.instance.b_terminations
 
-        def save(self, *args, **kwargs):
+        def clean(self):
+            super().clean()
 
             # Set the A/B terminations on the Cable instance
             self.instance.a_terminations = self.cleaned_data['a_terminations']
             self.instance.b_terminations = self.cleaned_data['b_terminations']
 
-            return super().save(*args, **kwargs)
-
     return _CableForm


Test patch:
Repository: netbox-community/netbox

Issue:
Typo in REARPORT_BUTTONS template code
### NetBox version

v3.3-beta

### Python version

3.8

### Steps to Reproduce

1. Analyse code in `dcim/tables/template_code.py` -> `REARPORT_BUTTONS`

### Expected Behavior

b_termination_type points to `circuits.circuittermination` and not to `circuits.circuitterminations` (s)

### Observed Behavior

Actual code:
```
                <li><a class="dropdown-item" href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ record.pk }}&b_terminations_type=circuits.circuitterminations&return_url={% url 'dcim:device_rearports' pk=object.pk %}">Circuit Termination</a></li>
```


Discussion:

Resolving patch:
diff --git a/netbox/dcim/tables/template_code.py b/netbox/dcim/tables/template_code.py
--- a/netbox/dcim/tables/template_code.py
+++ b/netbox/dcim/tables/template_code.py
@@ -343,7 +343,7 @@
                 <li><a class="dropdown-item" href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ record.pk }}&b_terminations_type=dcim.consoleport&return_url={% url 'dcim:device_rearports' pk=object.pk %}">Console Port</a></li>
                 <li><a class="dropdown-item" href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ record.pk }}&b_terminations_type=dcim.frontport&return_url={% url 'dcim:device_rearports' pk=object.pk %}">Front Port</a></li>
                 <li><a class="dropdown-item" href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ record.pk }}&b_terminations_type=dcim.rearport&return_url={% url 'dcim:device_rearports' pk=object.pk %}">Rear Port</a></li>
-                <li><a class="dropdown-item" href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ record.pk }}&b_terminations_type=circuits.circuitterminations&return_url={% url 'dcim:device_rearports' pk=object.pk %}">Circuit Termination</a></li>
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ record.pk }}&b_terminations_type=circuits.circuittermination&return_url={% url 'dcim:device_rearports' pk=object.pk %}">Circuit Termination</a></li>
             </ul>
         </span>
     {% else %}


Test patch:
Repository: netbox-community/netbox

Issue:
Circuit termination on interface not working when accesssed from interface table
### NetBox version

v3.3-beta1

### Python version

3.9

### Steps to Reproduce

1. Create device with interfaces
2. Create circuit with Z-side on same site as device
3. Try to connect interface to circuit termination from interface table
4. Select B Side Cicuit
5. Try to select Side for circuit

### Expected Behavior

On B Side you are able to select side for circuit

### Observed Behavior

Side option menu is empty because.

This is caused because $ is missing for `$termination_{cable_end}_circuit`

https://github.com/netbox-community/netbox/blob/abfa6a325af17d65038304feed2536330d8c60a7/netbox/dcim/forms/connections.py#L141
Circuit termination on interface not working when accesssed from interface table
### NetBox version

v3.3-beta1

### Python version

3.9

### Steps to Reproduce

1. Create device with interfaces
2. Create circuit with Z-side on same site as device
3. Try to connect interface to circuit termination from interface table
4. Select B Side Cicuit
5. Try to select Side for circuit

### Expected Behavior

On B Side you are able to select side for circuit

### Observed Behavior

Side option menu is empty because.

This is caused because $ is missing for `$termination_{cable_end}_circuit`

https://github.com/netbox-community/netbox/blob/abfa6a325af17d65038304feed2536330d8c60a7/netbox/dcim/forms/connections.py#L141


Discussion:
@jaylik Do you want to do a PR for this?
@jaylik Do you want to do a PR for this?

Resolving patch:
diff --git a/netbox/dcim/forms/connections.py b/netbox/dcim/forms/connections.py
--- a/netbox/dcim/forms/connections.py
+++ b/netbox/dcim/forms/connections.py
@@ -138,7 +138,7 @@ def __new__(mcs, name, bases, attrs):
                         label='Side',
                         disabled_indicator='_occupied',
                         query_params={
-                            'circuit_id': f'termination_{cable_end}_circuit',
+                            'circuit_id': f'$termination_{cable_end}_circuit',
                         }
                     )
 


Test patch:
Repository: netbox-community/netbox

Issue:
Add Contacts field to Virtual Machines table view
### NetBox version

v3.2.7

### Feature type

Change to existing functionality

### Proposed functionality

I would suggest to add contacts field to Virtual Machines table view/export, similarly to what we have in Devices. 
Currently in Devices in the "Configure Table" it's possible to select "Contacts" as a column, but it's not available in Virtual Machines. 

### Use case

When browsing through or exporting Virtual Machines it would be nice to be able to see who the owner/contact is. 

### Database changes

_No response_

### External dependencies

_No response_


Discussion:

Resolving patch:
diff --git a/netbox/virtualization/tables/virtualmachines.py b/netbox/virtualization/tables/virtualmachines.py
--- a/netbox/virtualization/tables/virtualmachines.py
+++ b/netbox/virtualization/tables/virtualmachines.py
@@ -48,6 +48,9 @@ class VirtualMachineTable(TenancyColumnsMixin, NetBoxTable):
         order_by=('primary_ip4', 'primary_ip6'),
         verbose_name='IP Address'
     )
+    contacts = columns.ManyToManyColumn(
+        linkify_item=True
+    )
     tags = columns.TagColumn(
         url_name='virtualization:virtualmachine_list'
     )
@@ -56,7 +59,7 @@ class Meta(NetBoxTable.Meta):
         model = VirtualMachine
         fields = (
             'pk', 'id', 'name', 'status', 'cluster', 'role', 'tenant', 'tenant_group', 'platform', 'vcpus', 'memory', 'disk',
-            'primary_ip4', 'primary_ip6', 'primary_ip', 'comments', 'tags', 'created', 'last_updated',
+            'primary_ip4', 'primary_ip6', 'primary_ip', 'comments', 'contacts', 'tags', 'created', 'last_updated',
         )
         default_columns = (
             'pk', 'name', 'status', 'cluster', 'role', 'tenant', 'vcpus', 'memory', 'disk', 'primary_ip',


Test patch:
Repository: netbox-community/netbox

Issue:
Add nat_outside to the IPAddress table
### NetBox version

v3.2.4

### Feature type

Change to existing functionality

### Proposed functionality

Add the nat_outside field (as NAT (Outside)) to the IPAddressTable class [(netbox/netbox/ipam/tables/ip.py).](https://github.com/netbox-community/netbox/blob/develop/netbox/ipam/tables/ip.py#L343) The nat_inside field already exists.

### Use case

We manage several DMZs. Adding the nat_outside would help in identifying these relationships in the IP Address table as we typically reference these addresses by the inside NAT.

### Database changes

None

### External dependencies

None


Discussion:
FYI the `nat_outside` relationship will return a list of objects in NetBox v3.3 and later (see #1202).
Thanks for the info @jeremystretch. Will this new one-to-many relationship cause issues implementing this request, to add the nat_outside field to the list of available columns for the IP Address UI list? If not, I could submit a pull request for this. Thanks. 

Resolving patch:
diff --git a/netbox/ipam/tables/ip.py b/netbox/ipam/tables/ip.py
--- a/netbox/ipam/tables/ip.py
+++ b/netbox/ipam/tables/ip.py
@@ -369,6 +369,11 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
         orderable=False,
         verbose_name='NAT (Inside)'
     )
+    nat_outside = tables.Column(
+        linkify=True,
+        orderable=False,
+        verbose_name='NAT (Outside)'
+    )
     assigned = columns.BooleanColumn(
         accessor='assigned_object_id',
         linkify=True,
@@ -381,7 +386,7 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
     class Meta(NetBoxTable.Meta):
         model = IPAddress
         fields = (
-            'pk', 'id', 'address', 'vrf', 'status', 'role', 'tenant', 'tenant_group', 'nat_inside', 'assigned', 'dns_name', 'description',
+            'pk', 'id', 'address', 'vrf', 'status', 'role', 'tenant', 'tenant_group', 'nat_inside', 'nat_outside', 'assigned', 'dns_name', 'description',
             'tags', 'created', 'last_updated',
         )
         default_columns = (


Test patch:
Repository: netbox-community/netbox

Issue:
Device Management IPv4 Address shows erroneous text "(NAT:)" when IP has no NAT associations
### NetBox version

v3.3.0

### Python version

3.8

### Steps to Reproduce

This is a **minor** / Display Bug

I am seeing this on *all* Device instances in my installation (which was upgraded from 3.2.8 to 3.3.0). 
It is also reproducible on a newly-created Device / Interface / IP combo.

1. Create a Device with at least one Interface
2. Set (or create) an IP Address on that Interface, and check the box to make it the "Primary IP for this device" (i.e. management address)
3. View the Device's overview page, note that in the "Management" box there is the text "(NAT:)" after the IP address

Screenshot from my own installation with a pre-existing device:
![image](https://user-images.githubusercontent.com/4011850/185256582-5d75ec97-d5d4-4820-846e-046bb0a9cfaa.png)


### Expected Behavior

Would not expect to see any information about NAT when the IP address has no NAT relationships defined. (Suspect this is related to the change in the `nat_outside` relation to return zero or more IPs instead of the past "None or one"?)

### Observed Behavior

UI displays spurious "(NAT:)" text when it shouldn't


Discussion:
I can work on this.

Resolving patch:
diff --git a/netbox/ipam/tables/ip.py b/netbox/ipam/tables/ip.py
--- a/netbox/ipam/tables/ip.py
+++ b/netbox/ipam/tables/ip.py
@@ -360,8 +360,8 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
         orderable=False,
         verbose_name='NAT (Inside)'
     )
-    nat_outside = tables.Column(
-        linkify=True,
+    nat_outside = tables.ManyToManyColumn(
+        linkify_item=True,
         orderable=False,
         verbose_name='NAT (Outside)'
     )


Test patch:
Repository: netbox-community/netbox

Issue:
Contact Assignments Create and Add Another 
### NetBox version

v3.3.0

### Python version

3.8

### Steps to Reproduce

1. Click 'Add a Contact' on a Device or Virtual Machine (possibly others) detail page.
2. Enter Contact and Role.
3. Click 'Create & Add Another'

### Expected Behavior

Returns to the Contact Assignment Page for the previous Device/Virtual Machine.

### Observed Behavior

Contact is created but redirects to /tenancy/contact-assignments/add/ without the content_type and object_id parameters resulting in Page Not Found.
![image](https://user-images.githubusercontent.com/52260120/185956494-983e4c9b-c2de-4bdd-b86d-ccc2eade13e8.png)



Discussion:

Resolving patch:
diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py
--- a/netbox/netbox/views/generic/object_views.py
+++ b/netbox/netbox/views/generic/object_views.py
@@ -327,6 +327,12 @@ def alter_object(self, obj, request, url_args, url_kwargs):
         """
         return obj
 
+    def get_extra_addanother_params(self, request):
+        """
+        Return a dictionary of extra parameters to use on the Add Another button.
+        """
+        return {}
+
     #
     # Request handlers
     #
@@ -399,6 +405,7 @@ def post(self, request, *args, **kwargs):
 
                     # If cloning is supported, pre-populate a new instance of the form
                     params = prepare_cloned_fields(obj)
+                    params.update(self.get_extra_addanother_params(request))
                     if params:
                         if 'return_url' in request.GET:
                             params['return_url'] = request.GET.get('return_url')
diff --git a/netbox/tenancy/views.py b/netbox/tenancy/views.py
--- a/netbox/tenancy/views.py
+++ b/netbox/tenancy/views.py
@@ -1,4 +1,5 @@
 from django.contrib.contenttypes.models import ContentType
+from django.http import QueryDict
 from django.shortcuts import get_object_or_404
 
 from circuits.models import Circuit
@@ -365,6 +366,12 @@ def alter_object(self, instance, request, args, kwargs):
             instance.object = get_object_or_404(content_type.model_class(), pk=request.GET.get('object_id'))
         return instance
 
+    def get_extra_addanother_params(self, request):
+        return {
+            'content_type': request.GET.get('content_type'),
+            'object_id': request.GET.get('object_id'),
+        }
+
 
 class ContactAssignmentDeleteView(generic.ObjectDeleteView):
     queryset = ContactAssignment.objects.all()
diff --git a/netbox/utilities/utils.py b/netbox/utilities/utils.py
--- a/netbox/utilities/utils.py
+++ b/netbox/utilities/utils.py
@@ -285,7 +285,7 @@ def prepare_cloned_fields(instance):
     """
     # Generate the clone attributes from the instance
     if not hasattr(instance, 'clone'):
-        return QueryDict()
+        return QueryDict(mutable=True)
     attrs = instance.clone()
 
     # Prepare querydict parameters


Test patch: