Commit 924ba8d3 authored by Lukas Burgey's avatar Lukas Burgey
Browse files

Implement deployment and withdrawal of keys

parent 45d578f0
...@@ -18,10 +18,12 @@ class UserSerializer(serializers.ModelSerializer): ...@@ -18,10 +18,12 @@ class UserSerializer(serializers.ModelSerializer):
class DeploymentSerializer(serializers.ModelSerializer): class DeploymentSerializer(serializers.ModelSerializer):
user = UserSerializer() user = UserSerializer()
ssh_keys = frontend_serializers.SSHPublicKeySerializer(many=True) ssh_keys = frontend_serializers.SSHPublicKeySerializer(many=True)
ssh_keys_to_withdraw = frontend_serializers.SSHPublicKeySerializer(
many=True)
class Meta: class Meta:
model = models.Deployment model = models.Deployment
fields = ['user', 'ssh_keys'] fields = ['user', 'ssh_keys', 'ssh_keys_to_withdraw']
class DeploymentsSerializer(serializers.Serializer): class DeploymentsSerializer(serializers.Serializer):
......
...@@ -76,6 +76,9 @@ class SSHPublicKeyView(views.APIView): ...@@ -76,6 +76,9 @@ class SSHPublicKeyView(views.APIView):
name=request.data['name']) name=request.data['name'])
# we do not delete ssh keys directly, as we need to keep track # we do not delete ssh keys directly, as we need to keep track
# of them until all clients have also deleted them # of them until all clients have also deleted them
# key state: -> (1), if there are no deployments
# key state: -> (5), if there are deployments
key.deleted = True key.deleted = True
key.save() key.save()
return state_response(request) return state_response(request)
...@@ -86,6 +89,7 @@ class SSHPublicKeyView(views.APIView): ...@@ -86,6 +89,7 @@ class SSHPublicKeyView(views.APIView):
name=request.data['key']['name'], name=request.data['key']['name'],
key=request.data['key']['key'], key=request.data['key']['key'],
) )
# key state: -> (2)
key.save() key.save()
return state_response(request) return state_response(request)
...@@ -122,15 +126,14 @@ class DeploymentView(views.APIView): ...@@ -122,15 +126,14 @@ class DeploymentView(views.APIView):
deployment.save() deployment.save()
if request_type == 'add': if request_type == 'add':
deployment.ssh_keys.add(request_key) deployment.deploy_key(request_key)
deployment.save()
return state_response(request)
elif request_type == 'remove': elif request_type == 'remove':
deployment.ssh_keys.remove(request_key) deployment.withdraw_key(request_key)
deployment.save() else:
return state_response(request) return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST)
return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST) deployment.save()
return state_response(request)
class ClientViewSet(viewsets.ModelViewSet): class ClientViewSet(viewsets.ModelViewSet):
......
...@@ -65,14 +65,16 @@ class Site(models.Model): ...@@ -65,14 +65,16 @@ class Site(models.Model):
for service in self.services.all(): for service in self.services.all():
ds = ( ds = (
service.deployments service.deployments
.filter(user__user_type='oidcuser') .filter(user__user_type='oidcuser')
.exclude(ssh_keys=None) # we do not exclude deployments without ssh_keys, as the
) # ssh_keys_to_withdraw still need to be propagated
# .exclude(ssh_keys=None)
)
if not all: if not all:
ds = ds.filter(last_change__gt=self.last_fetch) ds = ds.filter(last_change__gt=self.last_fetch)
# deployments with ssh keys # deployments for this site
services[service.name] = ds services[service.name] = ds
self.last_fetch = datetime.now() self.last_fetch = datetime.now()
...@@ -176,13 +178,6 @@ class SSHPublicKey(models.Model): ...@@ -176,13 +178,6 @@ class SSHPublicKey(models.Model):
User, User,
related_name='_ssh_keys') related_name='_ssh_keys')
# at which sites is this ssh key deployed?
deployements = models.ManyToManyField(
Site,
related_name='deployed_ssh_keys',
blank=True,
editable=False,
)
# has the user triggered the deletion of this key # has the user triggered the deletion of this key
deleted = models.BooleanField( deleted = models.BooleanField(
default=False, default=False,
...@@ -220,9 +215,39 @@ class Deployment(models.Model): ...@@ -220,9 +215,39 @@ class Deployment(models.Model):
related_name='deployments', related_name='deployments',
blank=True, blank=True,
) )
# these ssh keys are to be withdrawn by the clients
ssh_keys_to_withdraw = models.ManyToManyField(
SSHPublicKey,
related_name='withdrawn_deployments',
blank=True,
)
last_change = models.DateTimeField( last_change = models.DateTimeField(
auto_now=True auto_now=True
) )
def deploy_key(self, key):
# key state: -> (2.5)
self.ssh_keys.add(key)
if key in self.ssh_keys_to_withdraw.all():
self.ssh_keys_to_withdraw.remove(key)
self.save()
def withdraw_key(self, key):
# key state: -> (4)
self.ssh_keys.remove(key)
# keys which are to be withdrawn by the clients
self.ssh_keys_to_withdraw.add(key)
self.save()
def client_got_deployment(self):
# the client has withdrawn the keys so we can empty the list
self.ssh_keys_to_withdraw.clear()
# TODO: does the deletion of the ssh_keys actually occur?
self.save()
def __str__(self): def __str__(self):
return str(self.user) + '@' + str(self.service) return '{}@{}'.format(self.user, self.service)
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