Skip to content

Commit

Permalink
Merge pull request #2275 from digitalocean/develop
Browse files Browse the repository at this point in the history
Release v2.3.7
  • Loading branch information
jeremystretch committed Jul 26, 2018
2 parents 09a0356 + 0497539 commit a85e637
Show file tree
Hide file tree
Showing 27 changed files with 303 additions and 196 deletions.
49 changes: 0 additions & 49 deletions .github/ISSUE_TEMPLATE.md

This file was deleted.

34 changes: 34 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
name: :bug: Bug Report
about: Report a reproducible bug in the current release of NetBox
---

<!--
NOTE: This form is only for reproducible bugs. If you need assistance with
NetBox installation, or if you have a general question, DO NOT open an
issue. Instead, post to our mailing list:
https://groups.google.com/forum/#!forum/netbox-discuss
Please describe the environment in which you are running NetBox. Be sure
that you are running an unmodified instance of the latest stable release
before submitting a bug report.
-->
### Environment
* Python version: <!-- Example: 3.5.4 -->
* NetBox version: <!-- Example: 2.3.6 -->

<!--
Describe in detail the steps that someone else can take to reproduce this
bug using the current stable release of NetBox (or the current beta release
where applicable).
-->
### Steps to Reproduce


<!-- What did you expect to happen? -->
### Expected Behavior


<!-- What happened instead? -->
### Observed Behavior
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/documentation_change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: :book: Documentation Change
about: Suggest an addition or modification to the NetBox documentation
---

<!--
Please indicate the nature of the change by placing an X in one of the
boxes below.
-->
### Change Type
[ ] Addition
[ ] Correction
[ ] Deprecation
[ ] Cleanup (formatting, typos, etc.)

<!-- Describe the proposed change(s). -->
### Proposed Changes
53 changes: 53 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
name: :new: Feature Request
about: Propose a new NetBox feature or enhancement
---

<!--
NOTE: This form is only for proposing specific new features or enhancements.
If you have a general idea or question, please post to our mailing list
instead of opening an issue:
https://groups.google.com/forum/#!forum/netbox-discuss
NOTE: Due to an excessive backlog of feature requests, we are not currently
accepting any proposals which significantly extend NetBox's feature scope.
Please describe the environment in which you are running NetBox. Be sure
that you are running an unmodified instance of the latest stable release
before submitting a bug report.
-->
### Environment
* Python version: <!-- Example: 3.5.4 -->
* NetBox version: <!-- Example: 2.3.6 -->

<!--
Describe in detail the new functionality you are proposing. Include any
specific changes to work flows, data models, or the user interface.
-->
### Proposed Functionality


<!--
Convey an example use case for your proposed feature. Write from the
perspective of a NetBox user who would benefit from the proposed
functionality and describe how.
--->
### Use Case


<!--
Note any changes to the database schema necessary to support the new
feature. For example, does the proposal require adding a new model or
field? (Not all new features require database changes.)
--->
### Database Changes


<!--
List any new dependencies on external libraries or services that this new
feature would introduce. For example, does the proposal require the
installation of a new Python package? (Not all new features introduce new
dependencies.)
-->
### External Dependencies
16 changes: 16 additions & 0 deletions .github/ISSUE_TEMPLATE/housekeeping.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
name: :house: Housekeeping
about: A change pertaining to the codebase itself
---

<!--
NOTE: This type of issue should be opened only by those reasonably familiar
with NetBox's code base and interested in contributing to its development.
Describe the proposed change(s) in detail.
-->
### Proposed Changes


<!-- Provide justification for the proposed change(s). -->
### Justification -->
2 changes: 2 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
be able to accept.
Please indicate the relevant feature request or bug report below.
IF YOUR PULL REQUEST DOES NOT REFERENCE AN ACCEPTED BUG REPORT OR
FEATURE REQUEST, IT WILL BE MARKED AS INVALID AND CLOSED.
-->
### Fixes:

Expand Down
12 changes: 7 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,13 @@ appropriate labels will be applied for categorization.

## Submitting Pull Requests

* Be sure to open an issue before starting work on a pull request, and discuss
your idea with the NetBox maintainers before beginning work​. This will help
prevent wasting time on something that might we might not be able to implement.
When suggesting a new feature, also make sure it won't conflict with any work
that's already in progress.
* Be sure to open an issue **before** starting work on a pull request, and
discuss your idea with the NetBox maintainers before beginning work. This will
help prevent wasting time on something that might we might not be able to
implement. When suggesting a new feature, also make sure it won't conflict with
any work that's already in progress.

* Any pull request which does _not_ relate to an accepted issue will be closed.

* When submitting a pull request, please be sure to work off of the `develop`
branch, rather than `master`. The `develop` branch is used for ongoing
Expand Down
27 changes: 15 additions & 12 deletions netbox/dcim/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ def napalm(self, request, pk):
import napalm
except ImportError:
raise ServiceUnavailable("NAPALM is not installed. Please see the documentation for instructions.")
from napalm.base.exceptions import ConnectAuthError, ModuleImportError
from napalm.base.exceptions import ModuleImportError

# Validate the configured driver
try:
Expand All @@ -281,16 +281,8 @@ def napalm(self, request, pk):
if not request.user.has_perm('dcim.napalm_read'):
return HttpResponseForbidden()

# Validate requested NAPALM methods
# Connect to the device
napalm_methods = request.GET.getlist('method')
for method in napalm_methods:
if not hasattr(driver, method):
return HttpResponseBadRequest("Unknown NAPALM method: {}".format(method))
elif not method.startswith('get_'):
return HttpResponseBadRequest("Unsupported NAPALM method: {}".format(method))

# Connect to the device and execute the requested methods
# TODO: Improve error handling
response = OrderedDict([(m, None) for m in napalm_methods])
ip_address = str(device.primary_ip.address.ip)
d = driver(
Expand All @@ -302,12 +294,23 @@ def napalm(self, request, pk):
)
try:
d.open()
for method in napalm_methods:
response[method] = getattr(d, method)()
except Exception as e:
raise ServiceUnavailable("Error connecting to the device at {}: {}".format(ip_address, e))

# Validate and execute each specified NAPALM method
for method in napalm_methods:
if not hasattr(driver, method):
response[method] = {'error': 'Unknown NAPALM method'}
continue
if not method.startswith('get_'):
response[method] = {'error': 'Only get_* NAPALM methods are supported'}
continue
try:
response[method] = getattr(d, method)()
except NotImplementedError:
response[method] = {'error': 'Method not implemented for NAPALM driver {}'.format(driver)}
d.close()

return Response(response)


Expand Down
2 changes: 1 addition & 1 deletion netbox/dcim/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ def search(self, queryset, name, value):
Q(name__icontains=value) |
Q(serial__icontains=value.strip()) |
Q(inventory_items__serial__icontains=value.strip()) |
Q(asset_tag=value.strip()) |
Q(asset_tag__icontains=value.strip()) |
Q(comments__icontains=value)
).distinct()

Expand Down
3 changes: 0 additions & 3 deletions netbox/dcim/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,9 +781,6 @@ class Meta:
def __str__(self):
return self.name

def get_absolute_url(self):
return "{}?role={}".format(reverse('dcim:device_list'), self.slug)

def to_csv(self):
return (
self.name,
Expand Down
7 changes: 1 addition & 6 deletions netbox/dcim/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,8 @@ def assign_virtualchassis_master(instance, created, **kwargs):
"""
When a VirtualChassis is created, automatically assign its master device to the VC.
"""
# Default to 1 but don't overwrite an existing position (see #2087)
if instance.master.vc_position is not None:
vc_position = instance.master.vc_position
else:
vc_position = 1
if created:
Device.objects.filter(pk=instance.master.pk).update(virtual_chassis=instance, vc_position=vc_position)
Device.objects.filter(pk=instance.master.pk).update(virtual_chassis=instance, vc_position=None)


@receiver(pre_delete, sender=VirtualChassis)
Expand Down
1 change: 0 additions & 1 deletion netbox/dcim/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,6 @@ class Meta(BaseTable.Meta):

class DeviceRoleTable(BaseTable):
pk = ToggleColumn()
name = tables.LinkColumn(verbose_name='Name')
device_count = tables.TemplateColumn(
template_code=DEVICEROLE_DEVICE_COUNT,
accessor=Accessor('devices.count'),
Expand Down
3 changes: 2 additions & 1 deletion netbox/ipam/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,9 @@ def available_ips(self, request, pk=None):

# Assign addresses from the list of available IPs and copy VRF assignment from the parent prefix
available_ips = iter(available_ips)
prefix_length = prefix.prefix.prefixlen
for requested_ip in requested_ips:
requested_ip['address'] = next(available_ips)
requested_ip['address'] = '{}/{}'.format(next(available_ips), prefix_length)
requested_ip['vrf'] = prefix.vrf.pk if prefix.vrf else None

# Initialize the serializer with a list or a single object depending on what was requested
Expand Down
40 changes: 29 additions & 11 deletions netbox/ipam/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,17 +194,35 @@ class Meta(BaseTable.Meta):


class RIRDetailTable(RIRTable):
stats_total = tables.Column(accessor='stats.total', verbose_name='Total',
footer=lambda table: sum(r.stats['total'] for r in table.data))
stats_active = tables.Column(accessor='stats.active', verbose_name='Active',
footer=lambda table: sum(r.stats['active'] for r in table.data))
stats_reserved = tables.Column(accessor='stats.reserved', verbose_name='Reserved',
footer=lambda table: sum(r.stats['reserved'] for r in table.data))
stats_deprecated = tables.Column(accessor='stats.deprecated', verbose_name='Deprecated',
footer=lambda table: sum(r.stats['deprecated'] for r in table.data))
stats_available = tables.Column(accessor='stats.available', verbose_name='Available',
footer=lambda table: sum(r.stats['available'] for r in table.data))
utilization = tables.TemplateColumn(template_code=RIR_UTILIZATION, verbose_name='Utilization')
stats_total = tables.Column(
accessor='stats.total',
verbose_name='Total',
footer=lambda table: sum(r.stats['total'] for r in table.data)
)
stats_active = tables.Column(
accessor='stats.active',
verbose_name='Active',
footer=lambda table: sum(r.stats['active'] for r in table.data)
)
stats_reserved = tables.Column(
accessor='stats.reserved',
verbose_name='Reserved',
footer=lambda table: sum(r.stats['reserved'] for r in table.data)
)
stats_deprecated = tables.Column(
accessor='stats.deprecated',
verbose_name='Deprecated',
footer=lambda table: sum(r.stats['deprecated'] for r in table.data)
)
stats_available = tables.Column(
accessor='stats.available',
verbose_name='Available',
footer=lambda table: sum(r.stats['available'] for r in table.data)
)
utilization = tables.TemplateColumn(
template_code=RIR_UTILIZATION,
verbose_name='Utilization'
)

class Meta(RIRTable.Meta):
fields = (
Expand Down
Loading

0 comments on commit a85e637

Please sign in to comment.