Parcourir la source

Merge branch 'develop' into api2

Jeremy Stretch il y a 8 ans
Parent
commit
f02dd2f439
5 fichiers modifiés avec 29 ajouts et 4 suppressions
  1. 4 0
      README.md
  2. 16 0
      docs/data-model/extras.md
  3. 6 1
      netbox/dcim/views.py
  4. 1 1
      netbox/utilities/forms.py
  5. 2 2
      netbox/utilities/views.py

+ 4 - 0
README.md

@@ -1,3 +1,7 @@
+**The [2017 NetBox User Survey](https://goo.gl/forms/75HnNS2iE0Y1hVFH3) is open!** Please consider taking a moment to respond. Your feedback helps shape the pace and focus of NetBox development. The survey will remain open until 2017-03-31. Results will be published on the mailing list.
+
+---
+
 ![NetBox](docs/netbox_logo.png "NetBox logo")
 ![NetBox](docs/netbox_logo.png "NetBox logo")
 
 
 NetBox is an IP address management (IPAM) and data center infrastructure management (DCIM) tool. Initially conceived by the network engineering team at [DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically to address the needs of network and infrastructure engineers.
 NetBox is an IP address management (IPAM) and data center infrastructure management (DCIM) tool. Initially conceived by the network engineering team at [DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically to address the needs of network and infrastructure engineers.

+ 16 - 0
docs/data-model/extras.md

@@ -90,6 +90,22 @@ NetBox does not have the ability to generate graphs natively, but this feature a
 * **Source URL:** The source of the image to be embedded. The associated object will be available as a template variable named `obj`.
 * **Source URL:** The source of the image to be embedded. The associated object will be available as a template variable named `obj`.
 * **Link URL (optional):** A URL to which the graph will be linked. The associated object will be available as a template variable named `obj`.
 * **Link URL (optional):** A URL to which the graph will be linked. The associated object will be available as a template variable named `obj`.
 
 
+## Examples
+
+You only need to define one graph object for each graph you want to include when viewing an object. For example, if you want to include a graph of traffic through an interface over the past five minutes, your graph source might looks like this:
+
+```
+https://my.nms.local/graphs/?node={{ obj.device.name }}&interface={{ obj.name }}&duration=5m
+```
+
+You can define several graphs to provide multiple contexts when viewing an object. For example:
+
+```
+https://my.nms.local/graphs/?type=throughput&node={{ obj.device.name }}&interface={{ obj.name }}&duration=60m
+https://my.nms.local/graphs/?type=throughput&node={{ obj.device.name }}&interface={{ obj.name }}&duration=24h
+https://my.nms.local/graphs/?type=errors&node={{ obj.device.name }}&interface={{ obj.name }}&duration=60m
+```
+
 # Topology Maps
 # Topology Maps
 
 
 NetBox can generate simple topology maps from the physical network connections recorded in its database. First, you'll need to create a topology map definition under the admin UI at Extras > Topology Maps.
 NetBox can generate simple topology maps from the physical network connections recorded in its database. First, you'll need to create a topology map definition under the admin UI at Extras > Topology Maps.

+ 6 - 1
netbox/dcim/views.py

@@ -90,7 +90,12 @@ class ComponentCreateView(View):
                     self.parent_field: parent.pk,
                     self.parent_field: parent.pk,
                     'name': name,
                     'name': name,
                 }
                 }
-                component_data.update(data)
+                # Replace objects with their primary key to keep component_form.clean() happy
+                for k, v in data.items():
+                    if hasattr(v, 'pk'):
+                        component_data[k] = v.pk
+                    else:
+                        component_data[k] = v
                 component_form = self.model_form(component_data)
                 component_form = self.model_form(component_data)
                 if component_form.is_valid():
                 if component_form.is_valid():
                     new_components.append(component_form.save(commit=False))
                     new_components.append(component_form.save(commit=False))

+ 1 - 1
netbox/utilities/forms.py

@@ -57,7 +57,7 @@ def parse_numeric_range(string, base=10):
             begin, end = dash_range.split('-')
             begin, end = dash_range.split('-')
         except ValueError:
         except ValueError:
             begin, end = dash_range, dash_range
             begin, end = dash_range, dash_range
-        begin, end = int(begin.strip()), int(end.strip(), base=base) + 1
+        begin, end = int(begin.strip(), base=base), int(end.strip(), base=base) + 1
         values.extend(range(begin, end))
         values.extend(range(begin, end))
     return list(set(values))
     return list(set(values))
 
 

+ 2 - 2
netbox/utilities/views.py

@@ -434,7 +434,7 @@ class BulkEditView(View):
 
 
         # Are we editing *all* objects in the queryset or just a selected subset?
         # Are we editing *all* objects in the queryset or just a selected subset?
         if request.POST.get('_all') and self.filter is not None:
         if request.POST.get('_all') and self.filter is not None:
-            pk_list = [obj.pk for obj in self.filter(request.GET, self.cls.objects.only('pk'))]
+            pk_list = [obj.pk for obj in self.filter(request.GET, self.cls.objects.only('pk')).qs]
         else:
         else:
             pk_list = [int(pk) for pk in request.POST.getlist('pk')]
             pk_list = [int(pk) for pk in request.POST.getlist('pk')]
 
 
@@ -572,7 +572,7 @@ class BulkDeleteView(View):
 
 
         # Are we deleting *all* objects in the queryset or just a selected subset?
         # Are we deleting *all* objects in the queryset or just a selected subset?
         if request.POST.get('_all') and self.filter is not None:
         if request.POST.get('_all') and self.filter is not None:
-            pk_list = [obj.pk for obj in self.filter(request.GET, self.cls.objects.only('pk'))]
+            pk_list = [obj.pk for obj in self.filter(request.GET, self.cls.objects.only('pk')).qs]
         else:
         else:
             pk_list = [int(pk) for pk in request.POST.getlist('pk')]
             pk_list = [int(pk) for pk in request.POST.getlist('pk')]