Skip to content

Commit

Permalink
Make vlan and prefix endpoints writable (Fixes #1758)
Browse files Browse the repository at this point in the history
  • Loading branch information
John-Magne Bredal committed Aug 24, 2018
1 parent d130914 commit e5b5535
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 4 deletions.
46 changes: 46 additions & 0 deletions python/nav/web/api/v1/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,17 +257,63 @@ class Meta(object):

class VlanSerializer(serializers.ModelSerializer):
"""Serializer for the vlan model"""
VALID_NET_TYPES = ["scope", "reserved"]

class Meta(object):
model = manage.Vlan
fields = '__all__'

def validate_net_type(self, value):
"""Validate net_type
:type value: nav.models.manage.NetType
"""
if value.id not in VlanSerializer.VALID_NET_TYPES:
raise serializers.ValidationError(
"net_type must be {}".format(
' or '.join(VlanSerializer.VALID_NET_TYPES)))
return value


class PrefixSerializer(serializers.ModelSerializer):
"""Serializer for prefix model"""

usages = serializers.PrimaryKeyRelatedField(
many=True, read_only=False, required=False,
queryset=manage.Usage.objects.all())

class Meta(object):
model = manage.Prefix
fields = '__all__'

def update(self, instance, validated_data):
if 'usages' in validated_data:
new_usages = set(u.id for u in validated_data.pop('usages'))
current_usages = set(u.id for u in instance.usages.all())
to_add = new_usages - current_usages
to_delete = current_usages - new_usages

for usage in to_add:
manage.PrefixUsage(
prefix=instance,
usage=manage.Usage.objects.get(pk=usage)
).save()

manage.PrefixUsage.objects.filter(
prefix=instance, usage__in=list(to_delete)).delete()
return super(PrefixSerializer, self).update(instance, validated_data)

def create(self, validated_data):
usages = validated_data.pop('usages', [])
instance = super(PrefixSerializer, self).create(validated_data)
for usage in usages:
manage.PrefixUsage(
prefix=instance,
usage=usage
).save()

return instance


class PrefixUsageSerializer(serializers.Serializer):
"""Serializer for prefix usage queries"""
Expand Down
4 changes: 2 additions & 2 deletions python/nav/web/api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ def get_queryset(self):
return queryset


class VlanViewSet(NAVAPIMixin, viewsets.ReadOnlyModelViewSet):
class VlanViewSet(NAVAPIMixin, viewsets.ModelViewSet):
"""Lists all vlans.
Search
Expand All @@ -601,7 +601,7 @@ class VlanViewSet(NAVAPIMixin, viewsets.ReadOnlyModelViewSet):
search_fields = ['net_ident', 'description']


class PrefixViewSet(NAVAPIMixin, viewsets.ReadOnlyModelViewSet):
class PrefixViewSet(NAVAPIMixin, viewsets.ModelViewSet):
"""Lists all prefixes.
Filters
Expand Down
75 changes: 73 additions & 2 deletions tests/integration/api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@
'room': {
'id': 'blapp',
'location': 'mylocation'
},
'vlan': {
'net_type': 'scope',
},
'prefix': {
'net_address': '158.38.240.0/25'
}
}

Expand All @@ -61,7 +67,7 @@ def test_allowed_endpoints(db, api_client, token, serializer_models, name, url):


@pytest.mark.parametrize("endpoint",
['account', 'location', 'room'])
['account', 'location', 'room', 'vlan'])
def test_delete(db, api_client, token, endpoint):
create_token_endpoint(token, endpoint)
response_create = create(api_client, endpoint, TEST_DATA.get(endpoint))
Expand All @@ -77,7 +83,7 @@ def test_delete(db, api_client, token, endpoint):


@pytest.mark.parametrize("endpoint",
['account', 'netbox', 'location', 'room'])
['account', 'netbox', 'location', 'room', 'vlan'])
def test_create(db, api_client, token, endpoint):
create_token_endpoint(token, endpoint)
response = create(api_client, endpoint, TEST_DATA.get(endpoint))
Expand Down Expand Up @@ -208,6 +214,69 @@ def test_delete_room_wrong_room(db, api_client, token):
assert response.status_code == 404


def test_validate_vlan(db, api_client, token):
endpoint = 'vlan'
create_token_endpoint(token, 'vlan')
testdata = dict(TEST_DATA.get(endpoint))
testdata.update({'net_type': 'core'})
response = create(api_client, endpoint, testdata)

print(response)
assert response.status_code == 400


def prepare_prefix_test(db, api_client, token):
token.endpoints = {
'prefix': ENDPOINTS.get('prefix'),
'vlan': ENDPOINTS.get('vlan')
}
token.save()
testdata = dict(TEST_DATA.get('prefix'))

vlan_response = create(api_client, 'vlan', TEST_DATA.get('vlan'))
vlan = json.loads(vlan_response.content.decode('utf-8'))
testdata.update({'vlan': vlan.get('id')})
return testdata


def test_create_prefix(db, api_client, token):
endpoint = 'prefix'
testdata = prepare_prefix_test(db, api_client, token)
response = create(api_client, endpoint, testdata)

print(response)
assert response.status_code == 201


def test_create_prefix_with_usage(db, api_client, token, serializer_models):
endpoint = 'prefix'
testdata = prepare_prefix_test(db, api_client, token)
testdata.update({
'usages': ['ans']
})

response = create(api_client, endpoint, testdata)
json_response = json.loads(response.content.decode('utf-8'))
assert json_response.get('usages') == ['ans']


def test_update_prefix_remove_usage(db, api_client, token, serializer_models):
endpoint = 'prefix'
testdata = prepare_prefix_test(db, api_client, token)
testdata.update({
'usages': ['ans', 'student']
})
response = create(api_client, endpoint, testdata)
prefix = json.loads(response.content.decode('utf-8'))

testdata.update({
'usages': ['ans']
})
response = update(api_client, endpoint, prefix.get('id'), testdata)
json_response = json.loads(response.content.decode('utf-8'))
assert json_response.get('usages') == ['ans']


# Helpers

def create_token_endpoint(token, name):
Expand Down Expand Up @@ -285,3 +354,5 @@ def serializer_models():
end_time=INFINITY).save()
admin = profiles.Account.objects.get(login='admin')
auditlog.LogEntry.add_log_entry(admin, verb='verb', template='asd')
manage.Usage(id='ans', description='Ansatte').save()
manage.Usage(id='student', description='Studenter').save()

0 comments on commit e5b5535

Please sign in to comment.