Skip to content
This repository has been archived by the owner on May 19, 2020. It is now read-only.

[api] RESTful api for Subnet and IpAddress #30

Merged
merged 1 commit into from Jul 11, 2018
Merged

[api] RESTful api for Subnet and IpAddress #30

merged 1 commit into from Jul 11, 2018

Conversation

anurag-ks
Copy link
Contributor

Implements and closes #10

This is a WIP PR, I wanted to confirm all the endpoints that we would be implementing in django-ipam.

@anurag-ks anurag-ks self-assigned this Jul 6, 2018
@anurag-ks anurag-ks added this to To do in [GSOC-18] openwisp-ipam via automation Jul 6, 2018
@coveralls
Copy link

coveralls commented Jul 6, 2018

Pull Request Test Coverage Report for Build 98

  • 66 of 66 (100.0%) changed or added relevant lines in 3 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 100.0%

Totals Coverage Status
Change from base Build 87: 0.0%
Covered Lines: 273
Relevant Lines: 273

💛 - Coveralls

Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anurag-ks where are the tests and the reusable views?

@anurag-ks
Copy link
Contributor Author

@nemesisdesign I first wanted to confirm these endpoints are okay or not and then move on to writing tests for these views.

@nemesifier nemesifier moved this from To do to In progress in [GSOC-18] openwisp-ipam Jul 9, 2018
@nemesifier
Copy link
Member

@anurag-ks you have to implement CRUD operations as described in http://openwisp.org/gsoc/ideas-2018.html

Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good progress. See below.

def test_read_subnet_api(self):
subnet_id = self._create_subnet(dict(subnet="fdb6:21b:a477::9f7/64")).id
response = self.client.get(reverse('ipam:subnet', args=(subnet_id,)))
self.assertEqual(response.status_code, 200)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perform a basic check of the contents also please

subnet_id = self._create_subnet(dict(subnet="10.0.0.0/32")).id
response = self.client.delete(reverse('ipam:subnet', args=(subnet_id,)))
self.assertEqual(response.status_code, 204)
self.assertEqual(len(Subnet.objects.all()), 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use Subnet.objects.count() which is faster

data=json.dumps(data),
content_type='application/json')
self.assertEqual(response.status_code, 201)
self.assertEqual(str(IpAddress.objects.first()), '10.0.0.2')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

access the ip_address attribute because str() representation may be changed and would break this test

subnet = self._create_subnet(dict(subnet="10.0.0.0/24"))
ip_address = self._create_ipaddress(dict(ip_address="10.0.0.1", subnet=subnet))
response = self.client.get(reverse('ipam:ip_address', args=(ip_address.id,)))
self.assertEqual(response.status_code, 200)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perform a basic check of the contents please

ip_address = self._create_ipaddress(dict(ip_address="10.0.0.1", subnet=subnet))
response = self.client.delete(reverse('ipam:ip_address', args=(ip_address.id,)))
self.assertEqual(response.status_code, 204)
self.assertEqual(len(IpAddress.objects.all()), 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use count as indicated in a previous comment

self._create_ipaddress(dict(ip_address="10.0.0.1", subnet=subnet))
self._create_ipaddress(dict(ip_address="10.0.0.2", subnet=subnet))
response = self.client.get(reverse('ipam:list_create_ip_address', args=(subnet.id,)))
self.assertEqual(response.status_code, 200)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please perform a basic check of the contents too

Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some minor improvements to the tests are needed, see see my comments

@@ -13,4 +14,10 @@ class Meta:
class IpAddressSerializer(serializers.ModelSerializer):
class Meta:
model = IpAddress
fields = ('ip_address', 'subnet', 'description')
fields = '__all__'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should make some fields readonly like created and modified

class SubnetSerializer(serializers.ModelSerializer):
class Meta:
model = Subnet
fields = '__all__'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should make some fields readonly like created and modified

subnet_id = self._create_subnet(subnet="fdb6:21b:a477::9f7/64").id
response = self.client.get(reverse('ipam:subnet', args=(subnet_id,)))
self.assertEqual(response.status_code, 200)
self.assertContains(response, str(subnet_id))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not good enough, you should check one of the attributes of the JSON response in response.data.

ip_address = self._create_ipaddress(ip_address="10.0.0.1", subnet=subnet)
response = self.client.get(reverse('ipam:ip_address', args=(ip_address.id,)))
self.assertEqual(response.status_code, 200)
self.assertContains(response, '10.0.0.1')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

def test_update_subnet_api(self):
data = {
'description': 'Test Subnet'
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write this as one line

response = self.client.get(reverse('ipam:list_create_ip_address', args=(subnet.id,)))
self.assertEqual(response.status_code, 200)
self.assertContains(response, '10.0.0.1')
self.assertContains(response, '10.0.0.2')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

'description': 'Test Subnet'
}
response = self.client.post(reverse('ipam:subnet_list_create'),
data=json.dumps(data),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simply use data=json.dumps({}), and remove the definition of data

Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, only docs are missing:

  • explain how to use new api methods
  • remember to explain how to authenticate
  • explain how to extend the views, take inspiration from the docs of django-netjsongraph

Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some improvements needed, see below.

README.rst Outdated

.. code-block:: text

<api-url> -H 'Cookie: csrftoken=<csrftoken>; sessionid=<session-id>'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no man, this is not good. the API must work without the CSRF mechanism, this is not a webpage.

Ensure the API works without the CSRF token

README.rst Outdated
An api enpoint to retrieve or create IP addresses under a specific subnet

GET
++++
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be +++

README.rst Outdated
@@ -168,6 +178,176 @@ Response
"description": "optional description"
}

IpAddress-Subnet List and Create View
#####################################
An api enpoint to retrieve or create IP addresses under a specific subnet
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

always leave a blank line after the title

README.rst Outdated

GET
++++
Returns the list of IP addresses under a particular subnet.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

always leave a blank line after the title

README.rst Outdated

POST
++++
Create an Ip Address record
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

always leave a blank line after the title

README.rst Outdated

DELETE
++++++
Delete a subnet instance
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leave blank line after title, add final dot, double quote Subnet (model class name).

README.rst Outdated

PUT
+++
Update details of a subnet instance
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

README.rst Outdated

GET
+++
Get details of an IP address instance
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

README.rst Outdated

DELETE
++++++
Delete an IP address instance
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

README.rst Outdated

PUT
+++
Update details of an IP address instance
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@nemesifier nemesifier merged commit 021559c into master Jul 11, 2018
[GSOC-18] openwisp-ipam automation moved this from In progress to Done Jul 11, 2018
@anurag-ks anurag-ks deleted the api branch July 11, 2018 13:24
@anurag-ks anurag-ks restored the api branch July 12, 2018 22:01
@anurag-ks anurag-ks deleted the api branch July 12, 2018 22:04
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

[api] RESTful API for django_ipam
3 participants