Commit efe0ed67 by Barnabás Czémán

ADD REST API for network client

parent eff32210
...@@ -357,6 +357,7 @@ THIRD_PARTY_APPS = ( ...@@ -357,6 +357,7 @@ THIRD_PARTY_APPS = (
'statici18n', 'statici18n',
'django_sshkey', 'django_sshkey',
'pipeline', 'pipeline',
'rest_framework',
) )
...@@ -528,6 +529,8 @@ if get_env_variable('DJANGO_SAML', 'FALSE') == 'TRUE': ...@@ -528,6 +529,8 @@ if get_env_variable('DJANGO_SAML', 'FALSE') == 'TRUE':
LOGIN_REDIRECT_URL = "/" LOGIN_REDIRECT_URL = "/"
# CSRF_USE_SESSIONS = True
AGENT_DIR = get_env_variable( AGENT_DIR = get_env_variable(
'DJANGO_AGENT_DIR', join(unicode(expanduser("~")), 'agent')) 'DJANGO_AGENT_DIR', join(unicode(expanduser("~")), 'agent'))
# AGENT_DIR is the root directory for the agent. # AGENT_DIR is the root directory for the agent.
...@@ -587,3 +590,19 @@ REQUEST_HOOK_URL = get_env_variable("REQUEST_HOOK_URL", "") ...@@ -587,3 +590,19 @@ REQUEST_HOOK_URL = get_env_variable("REQUEST_HOOK_URL", "")
SSHKEY_EMAIL_ADD_KEY = False SSHKEY_EMAIL_ADD_KEY = False
TWO_FACTOR_ISSUER = get_env_variable("TWO_FACTOR_ISSUER", "CIRCLE") TWO_FACTOR_ISSUER = get_env_variable("TWO_FACTOR_ISSUER", "CIRCLE")
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'common.pagination.RelativePageNumberPagination',
'PAGE_SIZE': 2,
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAdminUser',
),
}
...@@ -88,3 +88,20 @@ for i in LOCAL_APPS: ...@@ -88,3 +88,20 @@ for i in LOCAL_APPS:
LOGGING['loggers'][i] = {'handlers': ['syslog'], 'level': level} LOGGING['loggers'][i] = {'handlers': ['syslog'], 'level': level}
LOGGING['loggers']['djangosaml2'] = {'handlers': ['syslog'], 'level': level} LOGGING['loggers']['djangosaml2'] = {'handlers': ['syslog'], 'level': level}
LOGGING['loggers']['django'] = {'handlers': ['syslog'], 'level': level} LOGGING['loggers']['django'] = {'handlers': ['syslog'], 'level': level}
############ REST FRAMEWORK CONFIGURATION
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'common.pagination.RelativePageNumberPagination',
'PAGE_SIZE': 25,
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAdminUser',
),
}
...@@ -34,6 +34,7 @@ from dashboard.views import ( ...@@ -34,6 +34,7 @@ from dashboard.views import (
from dashboard.forms import CirclePasswordResetForm, CircleSetPasswordForm from dashboard.forms import CirclePasswordResetForm, CircleSetPasswordForm
from firewall.views import add_blacklist_item from firewall.views import add_blacklist_item
admin.autodiscover() admin.autodiscover()
urlpatterns = [ urlpatterns = [
...@@ -73,6 +74,10 @@ urlpatterns = [ ...@@ -73,6 +74,10 @@ urlpatterns = [
name="info.support"), name="info.support"),
url(r'^info/resize-how-to/$', ResizeHelpView.as_view(), url(r'^info/resize-how-to/$', ResizeHelpView.as_view(),
name="info.resize"), name="info.resize"),
# API urls
url(r'api/v1/network/', include('network.api_urls')),
url(r'api/v1/dashboard/', include('dashboard.api_urls')),
] ]
......
from rest_framework.pagination import PageNumberPagination, _positive_int
from rest_framework.utils.urls import remove_query_param, replace_query_param
class RelativePageNumberPagination(PageNumberPagination):
page_size_query_param = 'page_size'
def get_next_link(self):
if not self.page.has_next():
return None
url = self.request.path
page_number = self.page.next_page_number()
return replace_query_param(url, self.page_query_param, page_number)
def get_previous_link(self):
if not self.page.has_previous():
return None
url = self.request.path
page_number = self.page.previous_page_number()
if page_number == 1:
return remove_query_param(url, self.page_query_param)
return replace_query_param(url, self.page_query_param, page_number)
def get_page_size(self, request):
if self.page_size_query_param:
try:
return _positive_int(
request.query_params[self.page_size_query_param],
strict=True,
cutoff=self.max_page_size
)
except (KeyError, ValueError):
pass
return None
from rest_framework import routers
from . import api_views
router = routers.DefaultRouter()
router.register('user', api_views.UserViewSet)
urlpatterns = router.urls
from rest_framework import viewsets
from django.contrib.auth.models import User
from . import serializers
class UserViewSet(viewsets.ReadOnlyModelViewSet):
queryset = User.objects.all()
serializer_class = serializers.UserSerializer
pagination_class = None
from rest_framework import serializers
from django.contrib.auth.models import User
class UserSerializer(serializers.HyperlinkedModelSerializer):
full_name = serializers.SerializerMethodField()
class Meta:
model = User
fields = ('url', 'full_name', 'email')
def get_full_name(self, obj):
return obj.get_full_name()
from rest_framework import routers
from . import api_views
router = routers.DefaultRouter()
router.register('blacklist', api_views.BlacklistViewSet)
router.register('domains', api_views.DomainViewSet)
router.register('firewalls', api_views.FirewallViewSet)
router.register('groups', api_views.GroupViewSet)
router.register('hosts', api_views.HostViewSet)
router.register('records', api_views.RecordViewSet)
router.register('rules', api_views.RuleViewSet)
router.register('switchports', api_views.SwitchPortViewSet)
router.register('vlans', api_views.VlanViewSet)
router.register('vlangroups', api_views.VlanGroupViewSet)
urlpatterns = router.urls
from rest_framework import viewsets
from . import serializers
from firewall import models
class RelativeURLFieldMixin(object):
def get_serializer_context(self):
context = super(RelativeURLFieldMixin, self).get_serializer_context()
context['request'] = None
return context
class BlacklistViewSet(RelativeURLFieldMixin, viewsets.ModelViewSet):
queryset = models.BlacklistItem.objects.all()
serializer_class = serializers.BlacklistItemSerializer
class DomainViewSet(RelativeURLFieldMixin, viewsets.ModelViewSet):
queryset = models.Domain.objects.all()
serializer_class = serializers.DomainSerializer
class FirewallViewSet(RelativeURLFieldMixin, viewsets.ModelViewSet):
queryset = models.Firewall.objects.all()
serializer_class = serializers.FirewallSerializer
class GroupViewSet(RelativeURLFieldMixin, viewsets.ModelViewSet):
queryset = models.Group.objects.all()
serializer_class = serializers.GroupSerializer
class HostViewSet(RelativeURLFieldMixin, viewsets.ModelViewSet):
queryset = models.Host.objects.all()
serializer_class = serializers.HostSerializer
class RecordViewSet(RelativeURLFieldMixin, viewsets.ModelViewSet):
queryset = models.Record.objects.all()
serializer_class = serializers.RecordSerializer
class RuleViewSet(RelativeURLFieldMixin, viewsets.ModelViewSet):
queryset = models.Rule.objects.all()
serializer_class = serializers.RuleSerializer
class SwitchPortViewSet(RelativeURLFieldMixin, viewsets.ModelViewSet):
queryset = models.SwitchPort.objects.all()
serializer_class = serializers.SwitchPortSerializer
class VlanViewSet(RelativeURLFieldMixin, viewsets.ModelViewSet):
queryset = models.Vlan.objects.all()
serializer_class = serializers.VlanSerializer
class VlanGroupViewSet(RelativeURLFieldMixin, viewsets.ModelViewSet):
queryset = models.VlanGroup.objects.all()
serializer_class = serializers.VlanGroupSerializer
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from rest_framework import serializers
from firewall import models
class BlacklistItemSerializer(serializers.HyperlinkedModelSerializer):
host_name = serializers.SerializerMethodField()
class Meta:
model = models.BlacklistItem
fields = (
"url", "ipv4", "host", "host_name", "expires_at", "whitelisted",
"reason", "snort_message", "created_at",
)
def get_host_name(self, obj):
if obj.host is None:
return ''
return obj.host.hostname
class DomainSerializer(serializers.HyperlinkedModelSerializer):
owner_name = serializers.SerializerMethodField()
class Meta:
model = models.Domain
fields = ("url", "name", "ttl", "owner", "owner_name")
def get_owner_name(self, obj):
return obj.owner.get_full_name()
class FirewallSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Firewall
fields = ("url", "name", )
class GroupSerializer(serializers.HyperlinkedModelSerializer):
owner_name = serializers.SerializerMethodField()
class Meta:
model = models.Group
fields = ("url", "name", "description", "owner", "owner_name")
def get_owner_name(self, obj):
if obj.owner is None:
return ''
return obj.owner.get_full_name()
class HostSerializer(serializers.HyperlinkedModelSerializer):
owner_name = serializers.SerializerMethodField()
vlan_name = serializers.SerializerMethodField()
class Meta:
model = models.Host
fields = (
"url",
"hostname", "reverse", "mac", "vlan", "vlan_name",
"shared_ip", "ipv4", "ipv6", "external_ipv4",
"description", "location", "comment", "owner",
"owner_name", "created_at",
)
def get_owner_name(self, obj):
return obj.owner.get_full_name()
def get_vlan_name(self, obj):
return obj.vlan.name
class RecordSerializer(serializers.HyperlinkedModelSerializer):
owner_name = serializers.SerializerMethodField()
host_name = serializers.SerializerMethodField()
class Meta:
model = models.Record
fields = (
"url",
"type", "host", "host_name", "name", "domain", "address", "ttl",
"description", "owner", "owner_name", "fqdn",
)
def get_owner_name(self, obj):
return obj.owner.get_full_name()
def get_host_name(self, obj):
return obj.host.hostname
class RuleSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Rule
fields = (
"url",
"direction", "description", "foreign_network", "dport",
"sport", "weight", "proto", "extra", "action", "owner",
"nat", "nat_external_port", "nat_external_ipv4", "vlan",
"vlangroup", "host", "hostgroup", "firewall",
)
class SwitchPortSerializer(serializers.HyperlinkedModelSerializer):
untagged_vlan_info = serializers.SerializerMethodField()
tagged_vlans_name = serializers.SerializerMethodField()
class Meta:
model = models.SwitchPort
fields = ("url", "untagged_vlan", "tagged_vlans", "description", "untagged_vlan_info", "tagged_vlans_name")
def get_untagged_vlan_info(self, obj):
return '{}'.format(obj.untagged_vlan)
def get_tagged_vlans_name(self, obj):
return obj.tagged_vlans.name
class VlanSerializer(serializers.HyperlinkedModelSerializer):
domain_name = serializers.SerializerMethodField()
class Meta:
model = models.Vlan
fields = (
"url",
"name", "vid", "network_type", "managed", "network4",
"snat_to", "snat_ip", "dhcp_pool", "network6",
"ipv6_template", "host_ipv6_prefixlen", "domain", "domain_name",
"reverse_domain", "description", "comment", "owner",
)
def get_domain_name(self, obj):
return obj.domain.name
class VlanGroupSerializer(serializers.HyperlinkedModelSerializer):
owner_name = serializers.SerializerMethodField()
class Meta:
model = models.VlanGroup
fields = ("url", "name", "vlans", "description", "owner", "owner_name")
def get_owner_name(self, obj):
if obj.owner is None:
return ''
return obj.owner.get_full_name()
...@@ -16,122 +16,115 @@ ...@@ -16,122 +16,115 @@
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>. # with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.conf.urls import url from django.conf.urls import url
from .views import ( from rest_framework import routers
IndexView,
HostList, HostDetail, HostCreate, HostDelete, from . import views
VlanList, VlanDetail, VlanDelete, VlanCreate, from . import api_views
DomainList, DomainDetail, DomainDelete, DomainCreate,
GroupList, GroupDetail, GroupDelete, GroupCreate, router = routers.DefaultRouter()
RecordList, RecordDetail, RecordCreate, RecordDelete, router.register(r'blacklist', api_views.BlacklistViewSet)
BlacklistList, BlacklistDetail, BlacklistDelete, BlacklistCreate,
RuleList, RuleDetail, RuleDelete, RuleCreate,
SwitchPortList, SwitchPortDetail, SwitchPortCreate, SwitchPortDelete,
VlanGroupList, VlanGroupDetail, VlanGroupDelete, VlanGroupCreate,
FirewallList, FirewallDetail, FirewallCreate, FirewallDelete,
remove_host_group, add_host_group,
remove_switch_port_device, add_switch_port_device,
VlanAclUpdateView
)
urlpatterns = [ urlpatterns = [
url('^$', IndexView.as_view(), name='network.index'), url('^$', views.IndexView.as_view(), name='network.index'),
# blacklist # blacklist
url('^blacklist/$', BlacklistList.as_view(), url('^blacklist/$', views.BlacklistList.as_view(),
name='network.blacklist_list'), name='network.blacklist_list'),
url('^blacklist/create$', BlacklistCreate.as_view(), url('^blacklist/create$', views.BlacklistCreate.as_view(),
name='network.blacklist_create'), name='network.blacklist_create'),
url('^blacklist/(?P<pk>\d+)/$', BlacklistDetail.as_view(), url('^blacklist/(?P<pk>\d+)/$', views.BlacklistDetail.as_view(),
name='network.blacklist'), name='network.blacklist'),
url('^blacklist/delete/(?P<pk>\d+)/$', BlacklistDelete.as_view(), url('^blacklist/delete/(?P<pk>\d+)/$', views.BlacklistDelete.as_view(),
name="network.blacklist_delete"), name="network.blacklist_delete"),
# domain # domain
url('^domains/$', DomainList.as_view(), name='network.domain_list'), url('^domains/$', views.DomainList.as_view(), name='network.domain_list'),
url('^domains/create$', DomainCreate.as_view(), url('^domains/create$', views.DomainCreate.as_view(),
name='network.domain_create'), name='network.domain_create'),
url('^domains/(?P<pk>\d+)/$', DomainDetail.as_view(), url('^domains/(?P<pk>\d+)/$', views.DomainDetail.as_view(),
name='network.domain'), name='network.domain'),
url('^domains/delete/(?P<pk>\d+)/$', DomainDelete.as_view(), url('^domains/delete/(?P<pk>\d+)/$', views.DomainDelete.as_view(),
name="network.domain_delete"), name="network.domain_delete"),
# firewall # firewall
url('^firewalls/$', FirewallList.as_view(), url('^firewalls/$', views.FirewallList.as_view(),
name='network.firewall_list'), name='network.firewall_list'),
url('^firewalls/create$', FirewallCreate.as_view(), url('^firewalls/create$', views.FirewallCreate.as_view(),
name='network.firewall_create'), name='network.firewall_create'),
url('^firewalls/(?P<pk>\d+)/$', FirewallDetail.as_view(), url('^firewalls/(?P<pk>\d+)/$', views.FirewallDetail.as_view(),
name='network.firewall'), name='network.firewall'),
url('^firewalls/delete/(?P<pk>\d+)/$', FirewallDelete.as_view(), url('^firewalls/delete/(?P<pk>\d+)/$', views.FirewallDelete.as_view(),
name="network.firewall_delete"), name="network.firewall_delete"),
# group (host) # group (host)
url('^groups/$', GroupList.as_view(), name='network.group_list'), url('^groups/$', views.GroupList.as_view(), name='network.group_list'),
url('^groups/create$', GroupCreate.as_view(), url('^groups/create$', views.GroupCreate.as_view(),
name='network.group_create'), name='network.group_create'),
url('^groups/(?P<pk>\d+)/$', GroupDetail.as_view(), name='network.group'), url('^groups/(?P<pk>\d+)/$', views.GroupDetail.as_view(), name='network.group'),
url('^groups/delete/(?P<pk>\d+)/$', GroupDelete.as_view(), url('^groups/delete/(?P<pk>\d+)/$', views.GroupDelete.as_view(),
name="network.group_delete"), name="network.group_delete"),
# host # host
url('^hosts/$', HostList.as_view(), name='network.host_list'), url('^hosts/$', views.HostList.as_view(), name='network.host_list'),
url('^hosts/create$', HostCreate.as_view(), name='network.host_create'), url('^hosts/create$', views.HostCreate.as_view(), name='network.host_create'),
url('^hosts/(?P<pk>\d+)/$', HostDetail.as_view(), name='network.host'), url('^hosts/(?P<pk>\d+)/$', views.HostDetail.as_view(), name='network.host'),
url('^hosts/delete/(?P<pk>\d+)/$', HostDelete.as_view(), url('^hosts/delete/(?P<pk>\d+)/$', views.HostDelete.as_view(),
name="network.host_delete"), name="network.host_delete"),
# record # record
url('^records/$', RecordList.as_view(), name='network.record_list'), url('^records/$', views.RecordList.as_view(), name='network.record_list'),
url('^records/create$', RecordCreate.as_view(), url('^records/create$', views.RecordCreate.as_view(),
name='network.record_create'), name='network.record_create'),
url('^records/(?P<pk>\d+)/$', RecordDetail.as_view(), url('^records/(?P<pk>\d+)/$', views.RecordDetail.as_view(),
name='network.record'), name='network.record'),
url('^records/delete/(?P<pk>\d+)/$', RecordDelete.as_view(), url('^records/delete/(?P<pk>\d+)/$', views.RecordDelete.as_view(),
name="network.record_delete"), name="network.record_delete"),
# rule # rule
url('^rules/$', RuleList.as_view(), name='network.rule_list'), url('^rules/$', views.RuleList.as_view(), name='network.rule_list'),
url('^rules/create$', RuleCreate.as_view(), name='network.rule_create'), url('^rules/create$', views.RuleCreate.as_view(), name='network.rule_create'),
url('^rules/(?P<pk>\d+)/$', RuleDetail.as_view(), url('^rules/(?P<pk>\d+)/$', views.RuleDetail.as_view(),
name='network.rule'), name='network.rule'),
# switchport # switchport
url('^switchports/$', SwitchPortList.as_view(), url('^switchports/$', views.SwitchPortList.as_view(),
name='network.switch_port_list'), name='network.switch_port_list'),
url('^switchports/create$', SwitchPortCreate.as_view(), url('^switchports/create$', views.SwitchPortCreate.as_view(),
name='network.switch_port_create'), name='network.switch_port_create'),
url('^switchports/(?P<pk>\d+)/$', SwitchPortDetail.as_view(), url('^switchports/(?P<pk>\d+)/$', views.SwitchPortDetail.as_view(),
name='network.switch_port'), name='network.switch_port'),
url('^switchports/delete/(?P<pk>\d+)/$', SwitchPortDelete.as_view(), url('^switchports/delete/(?P<pk>\d+)/$', views.SwitchPortDelete.as_view(),
name="network.switch_port_delete"), name="network.switch_port_delete"),
# vlan # vlan
url('^vlans/$', VlanList.as_view(), name='network.vlan_list'), url('^vlans/$', views.VlanList.as_view(), name='network.vlan_list'),
url('^vlans/create$', VlanCreate.as_view(), name='network.vlan_create'), url('^vlans/create$', views.VlanCreate.as_view(), name='network.vlan_create'),
url('^vlans/(?P<vid>\d+)/$', VlanDetail.as_view(), name='network.vlan'), url('^vlans/(?P<vid>\d+)/$', views.VlanDetail.as_view(), name='network.vlan'),
url('^vlans/(?P<pk>\d+)/acl/$', VlanAclUpdateView.as_view(), url('^vlans/(?P<pk>\d+)/acl/$', views.VlanAclUpdateView.as_view(),
name='network.vlan-acl'), name='network.vlan-acl'),
url('^vlans/delete/(?P<vid>\d+)/$', VlanDelete.as_view(), url('^vlans/delete/(?P<vid>\d+)/$', views.VlanDelete.as_view(),
name="network.vlan_delete"), name="network.vlan_delete"),
# vlangroup # vlangroup
url('^vlangroups/$', VlanGroupList.as_view(), url('^vlangroups/$', views.VlanGroupList.as_view(),
name='network.vlan_group_list'), name='network.vlan_group_list'),
url('^vlangroups/create$', VlanGroupCreate.as_view(), url('^vlangroups/create$', views.VlanGroupCreate.as_view(),
name='network.vlan_group_create'), name='network.vlan_group_create'),
url('^vlangroups/(?P<pk>\d+)/$', VlanGroupDetail.as_view(), url('^vlangroups/(?P<pk>\d+)/$', views.VlanGroupDetail.as_view(),
name='network.vlan_group'), name='network.vlan_group'),
url('^vlangroups/delete/(?P<pk>\d+)/$', VlanGroupDelete.as_view(), url('^vlangroups/delete/(?P<pk>\d+)/$', views.VlanGroupDelete.as_view(),
name="network.vlan_group_delete"), name="network.vlan_group_delete"),
url('^rules/delete/(?P<pk>\d+)/$', RuleDelete.as_view(), url('^rules/delete/(?P<pk>\d+)/$', views.RuleDelete.as_view(),
name="network.rule_delete"), name="network.rule_delete"),
# non class based views # non class based views
url('^hosts/(?P<pk>\d+)/remove/(?P<group_pk>\d+)/$', remove_host_group, url('^hosts/(?P<pk>\d+)/remove/(?P<group_pk>\d+)/$', views.remove_host_group,
name='network.remove_host_group'), name='network.remove_host_group'),
url('^hosts/(?P<pk>\d+)/add/$', add_host_group, url('^hosts/(?P<pk>\d+)/add/$', views.add_host_group,
name='network.add_host_group'), name='network.add_host_group'),
url('^switchports/(?P<pk>\d+)/remove/(?P<device_pk>\d+)/$', url('^switchports/(?P<pk>\d+)/remove/(?P<device_pk>\d+)/$',
remove_switch_port_device, name='network.remove_switch_port_device'), views.remove_switch_port_device, name='network.remove_switch_port_device'),
url('^switchports/(?P<pk>\d+)/add/$', add_switch_port_device, url('^switchports/(?P<pk>\d+)/add/$', views.add_switch_port_device,
name='network.add_switch_port_device'), name='network.add_switch_port_device'),
] ]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment