Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v2.4.6 #2494

Merged
merged 17 commits into from
Oct 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
v2.4.6 (2018-10-05)

## Enhancements

* [#2479](https://github.com/digitalocean/netbox/issues/2479) - Add user permissions for creating/modifying API tokens
* [#2487](https://github.com/digitalocean/netbox/issues/2487) - Return abbreviated API output when passed `?brief=1`

## Bug Fixes

* [#2393](https://github.com/digitalocean/netbox/issues/2393) - Fix Unicode support for CSV import under Python 2
* [#2483](https://github.com/digitalocean/netbox/issues/2483) - Set max item count of API-populated form fields to MAX_PAGE_SIZE
* [#2484](https://github.com/digitalocean/netbox/issues/2484) - Local config context not available on the Virtual Machine Edit Form
* [#2485](https://github.com/digitalocean/netbox/issues/2485) - Fix cancel button when assigning a service to a device/VM
* [#2491](https://github.com/digitalocean/netbox/issues/2491) - Fix exception when importing devices with invalid device type
* [#2492](https://github.com/digitalocean/netbox/issues/2492) - Sanitize hostname and port values returned through LLDP

---

v2.4.5 (2018-10-02)

## Enhancements
Expand Down
3 changes: 3 additions & 0 deletions docs/api/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ The NetBox API employs token-based authentication. For convenience, cookie authe

A token is a unique identifier that identifies a user to the API. Each user in NetBox may have one or more tokens which he or she can use to authenticate to the API. To create a token, navigate to the API tokens page at `/user/api-tokens/`.

!!! note
The creation and modification of API tokens can be restricted per user by an administrator. If you don't see an option to create an API token, ask an administrator to grant you access.

Each token contains a 160-bit key represented as 40 hexadecimal characters. When creating a token, you'll typically leave the key field blank so that a random key will be automatically generated. However, NetBox allows you to specify a key in case you need to restore a previously deleted token to operation.

By default, a token can be used for all operations available via the API. Deselecting the "write enabled" option will restrict API requests made with the token to read operations (e.g. GET) only.
Expand Down
30 changes: 30 additions & 0 deletions netbox/circuits/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ def test_list_providers(self):

self.assertEqual(response.data['count'], 3)

def test_list_providers_brief(self):

url = reverse('circuits-api:provider-list')
response = self.client.get('{}?brief=1'.format(url), **self.header)

self.assertEqual(
sorted(response.data['results'][0]),
['id', 'name', 'slug', 'url']
)

def test_create_provider(self):

data = {
Expand Down Expand Up @@ -147,6 +157,16 @@ def test_list_circuittypes(self):

self.assertEqual(response.data['count'], 3)

def test_list_circuittypes_brief(self):

url = reverse('circuits-api:circuittype-list')
response = self.client.get('{}?brief=1'.format(url), **self.header)

self.assertEqual(
sorted(response.data['results'][0]),
['id', 'name', 'slug', 'url']
)

def test_create_circuittype(self):

data = {
Expand Down Expand Up @@ -216,6 +236,16 @@ def test_list_circuits(self):

self.assertEqual(response.data['count'], 3)

def test_list_circuits_brief(self):

url = reverse('circuits-api:circuit-list')
response = self.client.get('{}?brief=1'.format(url), **self.header)

self.assertEqual(
sorted(response.data['results'][0]),
['cid', 'id', 'url']
)

def test_create_circuit(self):

data = {
Expand Down
21 changes: 20 additions & 1 deletion netbox/dcim/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,15 @@ class Meta:
fields = ['id', 'device', 'name', 'cs_port', 'connection_status', 'tags']


class NestedConsolePortSerializer(TaggitSerializer, ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail')
device = NestedDeviceSerializer(read_only=True)

class Meta:
model = ConsolePort
fields = ['id', 'url', 'device', 'name']


#
# Power outlets
#
Expand Down Expand Up @@ -529,6 +538,15 @@ class Meta:
fields = ['id', 'device', 'name', 'power_outlet', 'connection_status', 'tags']


class NestedPowerPortSerializer(TaggitSerializer, ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail')
device = NestedDeviceSerializer(read_only=True)

class Meta:
model = PowerPort
fields = ['id', 'url', 'device', 'name']


#
# Interfaces
#
Expand Down Expand Up @@ -652,10 +670,11 @@ class Meta:

class NestedDeviceBaySerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebay-detail')
device = NestedDeviceSerializer(read_only=True)

class Meta:
model = DeviceBay
fields = ['id', 'url', 'name']
fields = ['id', 'url', 'device', 'name']


#
Expand Down
5 changes: 5 additions & 0 deletions netbox/dcim/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@ def get_serializer_class(self):
"""
if self.action == 'retrieve':
return serializers.DeviceWithConfigContextSerializer

request = self.get_serializer_context()['request']
if request.query_params.get('brief', False):
return serializers.NestedDeviceSerializer

return serializers.DeviceSerializer

@action(detail=True, url_path='napalm')
Expand Down
2 changes: 1 addition & 1 deletion netbox/dcim/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1400,7 +1400,7 @@ def clean(self):
})

# Validate manufacturer/platform
if self.device_type and self.platform:
if hasattr(self, 'device_type') and self.platform:
if self.platform.manufacturer and self.platform.manufacturer != self.device_type.manufacturer:
raise ValidationError({
'platform': "The assigned platform is limited to {} device types, but this device's type belongs "
Expand Down
Loading