Commit e54ae328 authored by Lukas Burgey's avatar Lukas Burgey
Browse files

Add deployments

parent 1a270c0b
from django.contrib.auth.models import AbstractUser, Group from django.contrib.auth.models import AbstractUser, Group
from django.db import models from django.db import models
from django.forms import ValidationError
class User(AbstractUser): class User(AbstractUser):
...@@ -30,9 +31,12 @@ class Service(models.Model): ...@@ -30,9 +31,12 @@ class Service(models.Model):
name = models.CharField(max_length=150, unique=True) name = models.CharField(max_length=150, unique=True)
description = models.TextField(max_length=300, blank=True) description = models.TextField(max_length=300, blank=True)
site = models.ForeignKey( site = models.ForeignKey(
Site, related_name='services') Site,
related_name='services')
groups = models.ManyToManyField( groups = models.ManyToManyField(
Group, related_name='services', blank=True) Group,
related_name='services',
blank=True)
def __str__(self): def __str__(self):
return self.name + '@' + self.site.name return self.name + '@' + self.site.name
...@@ -42,7 +46,8 @@ class SSHPublicKey(models.Model): ...@@ -42,7 +46,8 @@ class SSHPublicKey(models.Model):
name = models.CharField(max_length=150, unique=True) name = models.CharField(max_length=150, unique=True)
key = models.TextField(max_length=1000) key = models.TextField(max_length=1000)
user = models.ForeignKey( user = models.ForeignKey(
User, related_name='ssh_keys') User,
related_name='ssh_keys')
def __str__(self): def __str__(self):
return self.name return self.name
...@@ -57,3 +62,25 @@ class State(object): ...@@ -57,3 +62,25 @@ class State(object):
) )
else: else:
self.services = [] self.services = []
class Deployment(models.Model):
user = models.ForeignKey(
User,
related_name='deployments',
on_delete=models.CASCADE,
)
service = models.ForeignKey(
Service,
related_name='deployments',
on_delete=models.CASCADE,
)
# SET_NULL: we allow credentials to be deleted after deployment
ssh_keys = models.ManyToManyField(
SSHPublicKey,
related_name='deployments',
blank=True,
)
def __str__(self):
return str(self.user) + '@' + str(self.service)
...@@ -58,28 +58,68 @@ class ServiceViewSet(viewsets.ModelViewSet): ...@@ -58,28 +58,68 @@ class ServiceViewSet(viewsets.ModelViewSet):
class SSHPublicKeyView(views.APIView): class SSHPublicKeyView(views.APIView):
def get(self, request, format=None):
pass
def post(self, request, format=None): def post(self, request, format=None):
if 'type' in request.data: if 'type' not in request.data:
request_type = request.data['type'] return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST)
request_type = request.data['type']
if request_type == 'remove':
if 'name' in request.data:
key = get_object_or_404(
models.SSHPublicKey,
name=request.data['name'])
key.delete()
return redirect('/backend/api/state/')
elif request_type == 'add':
if 'key' in request.data:
key = models.SSHPublicKey(
user=request.user,
name=request.data['key']['name'],
key=request.data['key']['key'],
)
key.save()
return redirect('/backend/api/state/')
return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST)
class DeploymentView(views.APIView):
def post(self, request, format=None):
if (
'type' not in request.data or
'key' not in request.data or
'service' not in request.data
):
return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST)
request_type = request.data['type']
request_service = get_object_or_404(
models.Service, name=request.data['service'])
request_key = get_object_or_404(
models.SSHPublicKey,
name=request.data['key'])
# check if there is already an deployment
try:
deployment = request.user.deployments.get(service=request_service)
except Exception:
if request_type == 'remove': if request_type == 'remove':
if 'name' in request.data: return Response({'ok': False},
key = get_object_or_404( status=status.HTTP_400_BAD_REQUEST)
models.SSHPublicKey,
name=request.data['name']) deployment = models.Deployment(
key.delete() user=request.user,
return redirect('/backend/api/state/') service=request_service)
elif request_type == 'add': deployment.save()
if 'key' in request.data:
key = models.SSHPublicKey() if request_type == 'add':
key.user = request.user deployment.ssh_keys.add(request_key)
key.name = request.data['key']['name'] deployment.save()
key.key = request.data['key']['key'] return redirect('/backend/api/state/')
key.save() elif request_type == 'remove':
return Response({'ok': True}, deployment.ssh_keys.remove(request_key)
status=status.HTTP_201_CREATED) deployment.save()
return redirect('/backend/api/state/')
return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST) return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST)
...@@ -30,13 +30,32 @@ class SSHPublicKeySerializer(serializers.ModelSerializer): ...@@ -30,13 +30,32 @@ class SSHPublicKeySerializer(serializers.ModelSerializer):
fields = ['name', 'key'] fields = ['name', 'key']
class DeploymentSerializer(serializers.Serializer):
service = ServiceSerializer()
ssh_keys = SSHPublicKeySerializer(many=True)
class Meta:
model = models.Deployment
exclude = ['user']
class DeploymentSerializerB(serializers.Serializer):
service = ServiceSerializer()
class Meta:
model = models.Deployment
class UserSerializer(serializers.ModelSerializer): class UserSerializer(serializers.ModelSerializer):
groups = GroupSerializer(many=True) groups = GroupSerializer(many=True)
ssh_keys = SSHPublicKeySerializer(many=True) ssh_keys = SSHPublicKeySerializer(many=True)
deployments = DeploymentSerializer(many=True)
class Meta: class Meta:
model = models.User model = models.User
fields = ['sub', 'email', 'username', 'ssh_keys', 'groups'] fields = [
'sub', 'email', 'username', 'ssh_keys', 'groups', 'deployments'
]
class StateSerializer(serializers.Serializer): class StateSerializer(serializers.Serializer):
......
...@@ -15,6 +15,7 @@ urlpatterns = [ ...@@ -15,6 +15,7 @@ urlpatterns = [
url(r'^backend/api/state/', rest_views.StateView.as_view()), url(r'^backend/api/state/', rest_views.StateView.as_view()),
url(r'^backend/api/sshkey/', rest_views.SSHPublicKeyView.as_view()), url(r'^backend/api/sshkey/', rest_views.SSHPublicKeyView.as_view()),
url(r'^backend/api/operational/', rest_views.OperationalView.as_view()), url(r'^backend/api/operational/', rest_views.OperationalView.as_view()),
url(r'^backend/api/deployments/', rest_views.DeploymentView.as_view()),
url(r'^backend/auth/', auth_views.Auth.as_view()), url(r'^backend/auth/', auth_views.Auth.as_view()),
url(r'^backend/auth_callback/', auth_views.AuthCallback.as_view()), url(r'^backend/auth_callback/', auth_views.AuthCallback.as_view()),
url(r'^backend/auth_logout', rest_views.LogoutView.as_view()), url(r'^backend/auth_logout', rest_views.LogoutView.as_view()),
......
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 to comment