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

Issue:
Cached REST API spec introduced in #6423 is stale after updates
### NetBox version

v3.1.11

### Python version

3.8

### Steps to Reproduce

1. Install Netbox v3.0.5+
2. Fetch http://netbox/api/docs/?format=openapi to populate Redis cache
3. Update to another Netbox version.
4. Fetch http://netbox/api/docs/?format=openapi and get the old openapi definition

### Expected Behavior

The correct openapi definition should be returned.

### Observed Behavior

Stale cached version of the openapi definition is returned.

Honestly I'm not 100% sure why this is happening. My reading of the Django cache documentation (https://docs.djangoproject.com/en/4.0/topics/cache/ and https://docs.djangoproject.com/en/4.0/ref/settings/#std:setting-CACHES-KEY_FUNCTION) makes it sound like the cache should use the Netbox version as a key, which would make it a different entry in the cache so this shouldn't be a problem.

Hopefully someone with more knowledge about Django caching can reproduce this and figure out why this is happening.


Discussion:
@jeremystretch - Would it make sense to clear the entire cache in the upgrade script? It would require re-adding the command for clearing the cache. netbox-docker would probably also have to be adjusted.

The cache is very sparsely used currently.
I think that makes sense, yeah. It's probably good practice to clear the cache on upgrade anyway.

Related, I also want to look into pre-rendering the API spec at release time. I'm not sure exactly what that process would look like, but it would avoid the caching issue entirely, and potentially allow us to add the REST API spec to the documentation using [mkdocs-plugins](https://github.com/Neoteroi/mkdocs-plugins). (But that's another discussion.)

Resolving patch:
diff --git a/netbox/extras/management/commands/clearcache.py b/netbox/extras/management/commands/clearcache.py
new file mode 100644
--- /dev/null
+++ b/netbox/extras/management/commands/clearcache.py
@@ -0,0 +1,11 @@
+from django.core.cache import cache
+from django.core.management.base import BaseCommand
+
+
+class Command(BaseCommand):
+    """Command to clear the entire cache."""
+    help = 'Clears the cache.'
+
+    def handle(self, *args, **kwargs):
+        cache.clear()
+        self.stdout.write('Cache has been cleared.', ending="\n")


Test patch:
Repository: netbox-community/netbox

Issue:
Interface Role have extra entry 'r'
### NetBox version

V3.2.2

### Python version

3.8

### Steps to Reproduce

1: Create / Edit IP address
2: Open Role Drop-down and scroll to bottom


### Expected Behavior

Last entry is "CARP"

![image](https://user-images.githubusercontent.com/2497502/166116153-d646e08a-fc3d-413e-acfe-0c250274500d.png)


### Observed Behavior

Last entry is "r"

![image](https://user-images.githubusercontent.com/2497502/166116051-4621c744-9b09-4a7e-96c2-19817eff8e18.png)

This is observed in both local install and online Demo


Discussion:
Seems to be a typo in  b3ea007e0a286ad414162a53b10dc248e134723f

```python
    CHOICES = (
        (ROLE_LOOPBACK, 'Loopback', 'gray'),
        (ROLE_SECONDARY, 'Secondary', 'blue'),
        (ROLE_ANYCAST, 'Anycast', 'yellow'),
        (ROLE_VIP, 'VIP', 'purple'),
        (ROLE_VRRP, 'VRRP', 'green'),
        (ROLE_HSRP, 'HSRP', 'green'),
        (ROLE_GLBP, 'GLBP', 'green'),
        (ROLE_CARP, 'CARP'), 'green',
    )
```
i.e. the `ROLE_CARP` tuple is closed prematurely (after just 2 elements)
.. the leftover literal  `'green'`  is treated as a separate choice `['g','r','e',...]`
.. and thus displayed as  `r`  (second element is display_value)

.. the obvious fix being
```diff
-        (ROLE_CARP, 'CARP'), 'green',
+        (ROLE_CARP, 'CARP', 'green'),
```

Resolving patch:
diff --git a/netbox/ipam/choices.py b/netbox/ipam/choices.py
--- a/netbox/ipam/choices.py
+++ b/netbox/ipam/choices.py
@@ -91,7 +91,7 @@ class IPAddressRoleChoices(ChoiceSet):
         (ROLE_VRRP, 'VRRP', 'green'),
         (ROLE_HSRP, 'HSRP', 'green'),
         (ROLE_GLBP, 'GLBP', 'green'),
-        (ROLE_CARP, 'CARP'), 'green',
+        (ROLE_CARP, 'CARP', 'green'),
     )
 
 


Test patch:
Repository: netbox-community/netbox

Issue:
Linkify device type in manufacturer table
### NetBox version

v3.2.3-dev

### Feature type

New functionality

### Proposed functionality

Device type under manufacturer list page should be clickable to filter the types by the manufacturer

### Use case

It would make it easier to filter the results directly from the manufacturer page to device types

![image](https://user-images.githubusercontent.com/5083532/166249700-6e168dd1-dd24-4893-bc37-67b69a68aa06.png)

### Database changes

None

### External dependencies

None


Discussion:
I will implement this.
@huntabyte - All yours.

Resolving patch:
diff --git a/netbox/dcim/tables/devicetypes.py b/netbox/dcim/tables/devicetypes.py
--- a/netbox/dcim/tables/devicetypes.py
+++ b/netbox/dcim/tables/devicetypes.py
@@ -31,7 +31,9 @@ class ManufacturerTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
-    devicetype_count = tables.Column(
+    devicetype_count = columns.LinkedCountColumn(
+        viewname='dcim:devicetype_list',
+        url_params={'manufacturer_id': 'pk'},
         verbose_name='Device Types'
     )
     inventoryitem_count = tables.Column(


Test patch:
Repository: netbox-community/netbox

Issue:
Allow MultiObjectVar to accept PKs higher than 9 when script is called with a single URL param
### NetBox version

v3.2.3

### Python version

3.9

### Steps to Reproduce

0. Start with a clean, empty installation
1. Create a custom script `testscript.py`:
> ```python
> from extras.scripts import *
> from dcim.models import Device
> 
> class MultiObjectVarTest(Script):
>     devices = MultiObjectVar (model=Device)
> 
>     def run(data, commit):
>         pass
> ```
2. Create a dummy `Manufacturer` and `DeviceType`
3. Fill the database with multiple `Device` objects (more than 10)
4. Confirm that devices have at least picked up PKs 1 thru 10
5. Access `http://netbox/extras/scripts/testscript.MultiObjectVarTest/?devices=1` (1 is a valid, existing device pk) -> Confirm that the `devices` field is properly populated with the `Device` which has pk 1
6. Access `http://netbox/extras/scripts/testscript.MultiObjectVarTest/?devices=10` (10 is also a valid, existing device pk) -> Notice that the `devices` field is now empty


### Expected Behavior

Access `http://netbox/extras/scripts/testscript.MultiObjectVarTest/?devices=10` (10 is a valid, existing device pk) and confirm that the `devices` field is properly populated with the `Device` which has pk 10

### Observed Behavior

The devices field is not populated with the `Device` which has PK 10, but can be searched manually.


I believe that this is due to the widget only prefetching the first few items and not knowing what to do with higher-count objects.


Discussion:

Resolving patch:
diff --git a/netbox/utilities/forms/fields/dynamic.py b/netbox/utilities/forms/fields/dynamic.py
--- a/netbox/utilities/forms/fields/dynamic.py
+++ b/netbox/utilities/forms/fields/dynamic.py
@@ -88,7 +88,12 @@ def get_bound_field(self, form, field_name):
         # Modify the QuerySet of the field before we return it. Limit choices to any data already bound: Options
         # will be populated on-demand via the APISelect widget.
         data = bound_field.value()
+
         if data:
+            # When the field is multiple choice pass the data as a list if it's not already
+            if isinstance(bound_field.field, DynamicModelMultipleChoiceField) and not type(data) is list:
+                data = [data]
+
             field_name = getattr(self, 'to_field_name') or 'pk'
             filter = self.filter(field_name=field_name)
             try:


Test patch:
Repository: netbox-community/netbox

Issue:
Allow inheritance/composition when creating custom scripts
### NetBox version

v3.2.3

### Feature type

Change to existing functionality

### Proposed functionality

I would like to be able to do the following:

```
class BaseTestScript:
    test = BooleanVar(label="This is a test!")

    def shared_function(self):
        pass

class FancyTestScript(BaseTestScript, Script):
    class Meta:
        name = "Fancy testing"
        commit_default = True
   
    def run(self, data, commit):
        is_test = self.data['test']
        
        if is_test:
            self.log_success("test!")

class AwesomeTestScript(BaseTestScript, Script):
    class Meta:
        name = "Awesome testing"
        commit_default = True
   
    def run(self, data, commit):
        is_test = self.data['test']
        
        if is_test:
            self.log_failure("test!")
```

This currently doesn't work. The script is recognized, but none of the ScriptVars are present. The reason is here:

https://github.com/netbox-community/netbox/blob/2e5a5f71ba4622b2989d892d4215e2aefe59b91c/netbox/extras/scripts.py#L307-L311

`__dict__` only contains attributes of the class itself, without attributes inherited from base classes.

I propose changing the code to:

```python
# Iterate all base classes looking for ScriptVariables
for base_class in inspect.getmro(cls):
    for name, attr in base_class.__dict__.items():
        if name not in vars and issubclass(attr.__class__, ScriptVariable):
            vars[name] = attr
```

It will search all base classes for subclasses of ScriptVariable. From quick testing it seemed to work great without breaking existing scripts. If accepted I will provide the implementation.

### Use case

Managing a lot of scripts is tedious and duplication of code is hard to avoid. Allowing to define base classes which can be extended to provide scripts that have similar but different functionality would help in keeping stuff clean and maintainable.

### Database changes

None

### External dependencies

None


Discussion:

Resolving patch:
diff --git a/netbox/extras/scripts.py b/netbox/extras/scripts.py
--- a/netbox/extras/scripts.py
+++ b/netbox/extras/scripts.py
@@ -306,9 +306,16 @@ def job_timeout(self):
     @classmethod
     def _get_vars(cls):
         vars = {}
-        for name, attr in cls.__dict__.items():
-            if name not in vars and issubclass(attr.__class__, ScriptVariable):
-                vars[name] = attr
+
+        # Iterate all base classes looking for ScriptVariables
+        for base_class in inspect.getmro(cls):
+            # When object is reached there's no reason to continue
+            if base_class is object:
+                break
+
+            for name, attr in base_class.__dict__.items():
+                if name not in vars and issubclass(attr.__class__, ScriptVariable):
+                    vars[name] = attr
 
         # Order variables according to field_order
         field_order = getattr(cls.Meta, 'field_order', None)


Test patch:
Repository: netbox-community/netbox

Issue:
List of services associated to IP address is missing services listening on "All IPs"
### NetBox version

v3.2.4

### Python version

3.8

### Steps to Reproduce

1. Create a Device or VM
2. Add Interface(s) and IP(s)
3. Add a Service and set an IP Address
4. Add another Service and leave IP Address empty (listening on "All IPs")
5. Open IP address page ( /ipam/ip-addresses/XXX/ )

### Expected Behavior

Show all Services.

### Observed Behavior

Services listening on "All IPs" are missing.

Related to: #8922


Discussion:

Resolving patch:
diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py
--- a/netbox/ipam/views.py
+++ b/netbox/ipam/views.py
@@ -7,12 +7,12 @@
 from circuits.models import Provider, Circuit
 from circuits.tables import ProviderTable
 from dcim.filtersets import InterfaceFilterSet
-from dcim.models import Interface, Site
+from dcim.models import Interface, Site, Device
 from dcim.tables import SiteTable
 from netbox.views import generic
 from utilities.utils import count_related
 from virtualization.filtersets import VMInterfaceFilterSet
-from virtualization.models import VMInterface
+from virtualization.models import VMInterface, VirtualMachine
 from . import filtersets, forms, tables
 from .constants import *
 from .models import *
@@ -676,7 +676,19 @@ def get_extra_context(self, request, instance):
         related_ips_table = tables.IPAddressTable(related_ips, orderable=False)
         related_ips_table.configure(request)
 
-        services = Service.objects.restrict(request.user, 'view').filter(ipaddresses=instance)
+        # Find services belonging to the IP
+        service_filter = Q(ipaddresses=instance)
+
+        # Find services listening on all IPs on the assigned device/vm
+        if instance.assigned_object and instance.assigned_object.parent_object:
+            parent_object = instance.assigned_object.parent_object
+
+            if isinstance(parent_object, VirtualMachine):
+                service_filter |= (Q(virtual_machine=parent_object) & Q(ipaddresses=None))
+            elif isinstance(parent_object, Device):
+                service_filter |= (Q(device=parent_object) & Q(ipaddresses=None))
+
+        services = Service.objects.restrict(request.user, 'view').filter(service_filter)
 
         return {
             'parent_prefixes_table': parent_prefixes_table,


Test patch:
Repository: netbox-community/netbox

Issue:
API created sites duplicated in search results (both GUI and API)
### NetBox version

v3.2.3

### Python version

3.9

### Steps to Reproduce

* Create RIR
* Create two ASNs 123 & 1234
* Create site test123 with both ASNs assigned 
* Search for Sites with the q value "123"

### Expected Behavior

Only showing one result for the site

### Observed Behavior

Duplicate site referring to the same site id.


Discussion:
We have 3 different setups (dev/qa/prod), all using the docker version, all having the exact same issue
Thank you for opening a bug report. I was unable to reproduce the reported behavior on NetBox v3.2.4. Please re-confirm the reported behavior on the current stable release and adjust your post above as necessary. Remember to provide detailed steps that someone else can follow using a clean installation of NetBox to reproduce the issue. Remember to include the steps taken to create any initial objects or other data.

Creating two sites in pynetbox like this:

```
nb.dcim.sites.create(name="703-Site1", slug="703-Site1", status="planned")
nb.dcim.sites.create(name="703-Site2", slug="703-Site2", status="planned")
```

And searching with  `/api/dcim/sites/?q=703&obj_type=` did not return multiple of the same site.
Please also note that for us to accept the bug report, it needs to include reproduction steps using raw API requests (not using the pynetbox client, which may introduce bugs outside our control).
It's related to the new ASN model, if you have more than one AS number attached to a site, it'll show up mulitple times in search. I reproduced the issue on demo.netbox.dev: https://demo.netbox.dev/search/?q=840&obj_type=

Just create a site, and attach more than one AS number, the amount of AS' attached is the same as the amount of times the site shows up in the search results.

In this case the naming standard is ABC-xxx-NAME (xxx = int), and if I search for "xxx", or "-xxx", the site will show up multiple times, if there's ASN' attached.

Search with problem: https://demo.netbox.dev/search/?q=840&obj_type=
Search with problem: https://demo.netbox.dev/search/?q=-840&obj_type=
Search with correct results: https://demo.netbox.dev/search/?q=GBR-840&obj_type=
Search with correct results: https://demo.netbox.dev/search/?q=840-&obj_type=

Resolving patch:
diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py
--- a/netbox/dcim/filtersets.py
+++ b/netbox/dcim/filtersets.py
@@ -163,7 +163,7 @@ def search(self, queryset, name, value):
             qs_filter |= Q(asns__asn=int(value.strip()))
         except ValueError:
             pass
-        return queryset.filter(qs_filter)
+        return queryset.filter(qs_filter).distinct()
 
 
 class LocationFilterSet(TenancyFilterSet, ContactModelFilterSet, OrganizationalModelFilterSet):


Test patch:
Repository: netbox-community/netbox

Issue:
Provide Markdown help with links to local documentation pages
### NetBox version

v3.2.4

### Feature type

New functionality

### Proposed functionality

Currently netbox supports a documentation package as part of the main release due to https://github.com/netbox-community/netbox/issues/6328

I propose to change the Markdown assistance available in some text areas ( for example in comments fields) that is currently going to "https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet" to another URL as part of the offline documentation package 
![image](https://user-images.githubusercontent.com/44149262/173758856-79739e48-1eb3-4173-9b09-9908fa1c92df.png)

I propose that a new section in the documentation package is created, based in the github url above, and use the corresponding link within this assistance fields. 

The final url could be something like, if this section is placed under references. 
https://netboxfqdn/static/docs/reference/markdown/

### Use case



The following use cases are applicable:

    Provide the correct documentation that is always related to the specific version being used, instead of the online version that refers the latest version.
    Provide access to the documentation to system installed in a isolated management environment that do not have internet access.


### Database changes

none

### External dependencies

none


Discussion:
Thanks for capturing this. There's a `TODO` line in the code for this that's been around for ~5 years that just never made it into an issue. :laughing: 
 No problem. I have also identified this at some point but never went trough to this process of creating the ticket 

I guess this week when i faced the issue again of needing access to internet just for the reference to I realised that this can be incorporated in local docs packaging

Cheers
José
 

Resolving patch:
diff --git a/netbox/utilities/forms/fields/fields.py b/netbox/utilities/forms/fields/fields.py
--- a/netbox/utilities/forms/fields/fields.py
+++ b/netbox/utilities/forms/fields/fields.py
@@ -3,6 +3,7 @@
 from django import forms
 from django.db.models import Count
 from django.forms.fields import JSONField as _JSONField, InvalidJSONInput
+from django.templatetags.static import static
 from netaddr import AddrFormatError, EUI
 
 from utilities.forms import widgets
@@ -26,10 +27,9 @@ class CommentField(forms.CharField):
     A textarea with support for Markdown rendering. Exists mostly just to add a standard `help_text`.
     """
     widget = forms.Textarea
-    # TODO: Port Markdown cheat sheet to internal documentation
-    help_text = """
+    help_text = f"""
         <i class="mdi mdi-information-outline"></i>
-        <a href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet" target="_blank" tabindex="-1">
+        <a href="{static('docs/reference/markdown/')}" target="_blank" tabindex="-1">
         Markdown</a> syntax is supported
     """
 


Test patch:
Repository: netbox-community/netbox

Issue:
Set default manufacturer on module insert
### NetBox version

v3.2.3

### Feature type

Change to existing functionality

### Proposed functionality

When inserting a module into a device, the manufacturer of the module should default to the same manufacturer as the parent device.  Eg, if I'm inserting a module into a Cisco ASR-9010, then the manufacturer of the module should be set to Cisco by default.  

### Use case

Saves time by not having to select the manufacturer of the module.  The manufacturer of the module will almost always be the same as the manufacturer of the parent.  The only exception being things like hard drive slots on servers and passive devices like modular distribution frames/patch panels.  This is why the mfg field should only **default** to the parent's mfg and not be a read-only field.    

### Database changes

None

### External dependencies

None


Discussion:
This can be accomplished by pre-populating the device's manufacturer in the "add module" link: `&manufacturer_id={{ object.device_type.manufacturer_id }}` (something like that).
Thanks!  And where would one go to make those changes to the link?

> On May 24, 2022, at 3:41 PM, Jeremy Stretch ***@***.***> wrote:
> 
> ﻿
> This can be accomplished by pre-populating the device's manufacturer in the "add module" link: &manufacturer_id={{ object.device_type.manufacturer_id }} (something like that).
> 
> —
> Reply to this email directly, view it on GitHub, or unsubscribe.
> You are receiving this because you authored the thread.

Sorry that was just a general note for anyone who would like to implement this. It's a change to be made in one (or more) of the HTML templates.
I can implement this functionality.

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
@@ -385,7 +385,7 @@
             <i class="mdi mdi-server-minus" aria-hidden="true" title="Remove module"></i>
         </a>
     {% else %}
-        <a href="{% url 'dcim:module_add' %}?device={{ record.device.pk }}&module_bay={{ record.pk }}&return_url={% url 'dcim:device_modulebays' pk=object.pk %}" class="btn btn-success btn-sm">
+        <a href="{% url 'dcim:module_add' %}?device={{ record.device.pk }}&module_bay={{ record.pk }}&manufacturer={{ object.device_type.manufacturer_id }}&return_url={% url 'dcim:device_modulebays' pk=object.pk %}" class="btn btn-success btn-sm">
             <i class="mdi mdi-server-plus" aria-hidden="true" title="Install module"></i>
         </a>
     {% endif %}


Test patch:
Repository: netbox-community/netbox

Issue:
class 'AttributeError' 'FHRPGroup' object has no attribute 'parent_object'
### NetBox version

v3.2.5

### Python version

3.9

### Steps to Reproduce

I dont have any special steps, but rather I would like to inform that something like this happened:
After updating to 3.2.5 from 3.2.4, clicking any IP address object that is under vrrpv2 FHR group, i get the result:
`<class 'AttributeError'> 'FHRPGroup' object has no attribute 'parent_object'`

Newly added or old, doesnt matter. Tried changing status and role, no go.
Not sure why this happens, reverted to 3.2.4 and it works fine. After update I didnt do much, few added FHR's and IP's attached to intefaces in devices, nothing mind bogling.

### Expected Behavior

Can view IP details after clicking it.


### Observed Behavior

`<class 'AttributeError'> 'FHRPGroup' object has no attribute 'parent_object'.`


Discussion:
I am the same error as well in 3.2.5
I am working on this.

Resolving patch:
diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py
--- a/netbox/ipam/views.py
+++ b/netbox/ipam/views.py
@@ -680,13 +680,16 @@ def get_extra_context(self, request, instance):
         service_filter = Q(ipaddresses=instance)
 
         # Find services listening on all IPs on the assigned device/vm
-        if instance.assigned_object and instance.assigned_object.parent_object:
-            parent_object = instance.assigned_object.parent_object
-
-            if isinstance(parent_object, VirtualMachine):
-                service_filter |= (Q(virtual_machine=parent_object) & Q(ipaddresses=None))
-            elif isinstance(parent_object, Device):
-                service_filter |= (Q(device=parent_object) & Q(ipaddresses=None))
+        try:
+            if instance.assigned_object and instance.assigned_object.parent_object:
+                parent_object = instance.assigned_object.parent_object
+
+                if isinstance(parent_object, VirtualMachine):
+                    service_filter |= (Q(virtual_machine=parent_object) & Q(ipaddresses=None))
+                elif isinstance(parent_object, Device):
+                    service_filter |= (Q(device=parent_object) & Q(ipaddresses=None))
+        except AttributeError:
+            pass
 
         services = Service.objects.restrict(request.user, 'view').filter(service_filter)
 


Test patch: