Skip to content
Snippets Groups Projects
Commit 278ac10c authored by Stauros Kroustouris's avatar Stauros Kroustouris
Browse files

fod rest api

parent 7dc37a14
No related branches found
No related tags found
No related merge requests found
......@@ -37,6 +37,50 @@ You can find the installation instructions for Debian Wheezy (64)
with Django 1.4.x at [Flowspy documentation](http://flowspy.readthedocs.org).
If upgrading from a previous version bear in mind the changes introduced in Django 1.4.
##Rest Api##
FoD provides a rest api. It uses token as authentication method.
### Generating Tokens
A user can generate a token for his account on "my profile" page from FoD's
UI. Then by using this token in the header of the request he can list, retrieve,
modify and create rules.
### Example Usage
Here are some examples:
#### GET items
- List all the rules your user has created (admin users can see all the rules)
curl -X GET https://fod.example.com/api/routes/ -H 'Authorization: Token <Your users token>'
- Retrieve a specific rule:
curl -X GET https:/fod.example.com/api/routes/<rule_id>/ -H 'Authorization: Token <Your users token>'
- In order to create or modify a rule you have to use POST/PUT methods.
#### POST/PUT items
##### Foreign Keys
In order to create/modify a rule you have to connect the rule with:
###### Ports, Fragmentypes, protocols, thenactions
When creating a rule, one can specify:
- source port
- destination port
- port (if source = destination)
That can be done by getting the url of the desired port instance from `/api/ports/<port_id>/`
Same with Fragmentypes in `/api/fragmenttypes/<fragmenttype_id>/`, protocols in `/api/matchprotocol/<protocol_id>/` and then actions in `/api/thenactions/<action_id>/`.
Since we have the urls we want to connect with the rule we want to create, we can make a POST request like the following:
curl -X POST -H 'Authorization: Token <Your users token>' -F "name=Example" -F "comments=Description" -F "source=0.0.0.0/0" -F "sourceport=https://fod.example.com/api/ports/7/" -F "destination=203.0.113.12" https://fod.example.com/api/routes/
##Contact##
You can find more about FoD or raise your issues at GRNET FoD
......
......@@ -175,6 +175,12 @@ class Route(models.Model):
comments = models.TextField(null=True, blank=True, verbose_name=_("Comments"))
requesters_address = models.CharField(max_length=255, blank=True, null=True)
@property
def applier_username(self):
if self.applier:
return self.applier.username
else:
return None
def __unicode__(self):
return self.name
......
from rest_framework import serializers
from flowspec.models import (
Route,
MatchPort,
ThenAction,
FragmentType,
MatchProtocol
)
# Serializers define the API representation.
class RouteSerializer(serializers.HyperlinkedModelSerializer):
applier = serializers.CharField(source='applier_username', read_only=True)
class Meta:
model = Route
fields = (
'name',
'id',
'comments',
'applier',
'source',
'sourceport',
'destination',
'destinationport',
'port',
'dscp',
'fragmenttype',
'icmpcode',
'packetlength',
'protocol',
'tcpflag',
'then',
'filed',
'last_updated',
'status',
'expires',
'response',
'comments',
'requesters_address'
)
read_only_fields = ('status', 'expires', 'requesters_address', 'response')
class PortSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = MatchPort
fields = ('port', )
class ThenActionSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ThenAction
fields = ('action', 'action_value')
class FragmentTypeSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = FragmentType
fields = ('fragmenttype', )
class MatchProtocolSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = MatchProtocol
fields = ('protocol', )
from django.shortcuts import get_object_or_404
from rest_framework import status
from rest_framework import viewsets
from flowspec.models import (
Route,
MatchPort,
ThenAction,
FragmentType,
MatchProtocol
)
from flowspec.serializers import (
RouteSerializer,
PortSerializer,
ThenActionSerializer,
FragmentTypeSerializer,
MatchProtocolSerializer,
)
from rest_framework.response import Response
from django.contrib.auth.models import User
class RouteViewSet(viewsets.ModelViewSet):
queryset = Route.objects.all()
serializer_class = RouteSerializer
def get_queryset(self):
if self.request.user.is_anonymous or self.request.user.is_superuser:
return Route.objects.all()
else:
return Route.objects.filter(applier=self.request.user)
def list(self, request):
serializer = RouteSerializer(self.get_queryset(), many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
route = get_object_or_404(self.get_queryset(), pk=pk)
serializer = RouteSerializer(route)
return Response(serializer.data)
def pre_save(self, obj):
if self.request.user.is_anonymous:
obj.applier = User.objects.all()[0]
else:
obj.applier = self.request.user
class PortViewSet(viewsets.ModelViewSet):
queryset = MatchPort.objects.all()
serializer_class = PortSerializer
class ThenActionViewSet(viewsets.ModelViewSet):
queryset = ThenAction.objects.all()
serializer_class = ThenActionSerializer
class FragmentTypeViewSet(viewsets.ModelViewSet):
queryset = FragmentType.objects.all()
serializer_class = FragmentTypeSerializer
class MatchProtocolViewSet(viewsets.ModelViewSet):
queryset = MatchProtocol.objects.all()
serializer_class = MatchProtocolSerializer
......@@ -316,3 +316,19 @@ BRANDING = {
'logo': 'fodlogo2.png',
'favicon': 'favicon.ico',
}
# Django Rest Framework configuration.
# You should leave this intact.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissions',
'rest_framework.permissions.IsAuthenticated'
]
}
......@@ -14,4 +14,4 @@ pycrypto==2.6
pyparsing==1.5.6
python-dateutil==1.5
python-memcached==1.48
djangorestframework==3.1.2
djangorestframework==2.3.14
{% load url from future %}
{% load rest_framework %}
{% load staticfiles %}
<html>
<head>
{% block style %}
{% block bootstrap_theme %}
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/bootstrap.min.css" %}"/>
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/bootstrap-tweaks.css" %}"/>
{% endblock %}
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/default.css" %}"/>
{% endblock %}
</head>
<body class="container">
<div class="container-fluid" style="margin-top: 30px">
<div class="row-fluid">
<div class="well" style="width: 320px; margin-left: auto; margin-right: auto">
<div class="row-fluid">
<div>
{% block branding %}<h3 style="margin: 0 0 20px;">Django REST framework</h3>{% endblock %}
</div>
</div><!-- /row fluid -->
<div class="row-fluid">
<div>
<form action="{% url 'rest_framework:login' %}" class=" form-inline" method="post">
{% csrf_token %}
<div id="div_id_username" class="clearfix control-group">
<div class="controls">
<Label class="span4">Username:</label>
<input style="height: 25px" type="text" name="username" maxlength="100" autocapitalize="off" autocorrect="off" class="textinput textInput" id="id_username">
</div>
</div>
<div id="div_id_password" class="clearfix control-group">
<div class="controls">
<Label class="span4">Password:</label>
<input style="height: 25px" type="password" name="password" maxlength="100" autocapitalize="off" autocorrect="off" class="textinput textInput" id="id_password">
</div>
</div>
<input type="hidden" name="next" value="{{ next }}" />
<div class="form-actions-no-box">
<input type="submit" name="submit" value="Log in" class="btn btn-primary" id="submit-id-submit">
</div>
</form>
</div>
</div><!-- /.row-fluid -->
</div><!--/.well-->
</div><!-- /.row-fluid -->
</div><!-- /.container-fluid -->
</body>
</html>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment