From fc376318c70848bfbf5879b01a87e128f75e21c1 Mon Sep 17 00:00:00 2001
From: Helge Jung <hej@c3pb.de>
Date: Sat, 26 Dec 2020 04:06:48 +0100
Subject: [PATCH] hangar creation management command

---
 .../management/commands/hangar_creation.py    | 63 +++++++++++++++++++
 src/core/models/assemblies.py                 |  6 ++
 2 files changed, 69 insertions(+)
 create mode 100644 src/core/management/commands/hangar_creation.py

diff --git a/src/core/management/commands/hangar_creation.py b/src/core/management/commands/hangar_creation.py
new file mode 100644
index 000000000..cf5256c10
--- /dev/null
+++ b/src/core/management/commands/hangar_creation.py
@@ -0,0 +1,63 @@
+import logging
+import subprocess
+
+from django.conf import settings
+from django.core.management.base import BaseCommand, CommandError
+from django.utils import timezone
+
+from core.models.rooms import Room
+
+
+def create_hangar(room: Room):
+    username = room.assembly.slug
+    cmd = ['ssh', settings.HANGAR_HOST, settings.HANGAR_CMD, username]
+
+    result = subprocess.run(cmd, capture_output=True, timeout=42, encoding='utf-8', stderr=subprocess.STDOUT)
+    if result.returncode == 0:
+        password = result.stdout
+        room.backend_link = settings.BACKEND_URL.format(username=username, password=password)
+        room.backend_status = Room.BackendStatus.ACTIVE
+
+        all_contacts = room.assembly.get_all_managing_contacts()
+        room.backend_data = {
+            'timestamp': timezone.now(),
+            'contacts': all_contacts,
+        }
+        room.save()
+
+    else:
+        room.backend_data = {
+            'timestamp': timezone.now(),
+            '_error': result.stdout,
+        }
+        room.backend_status = Room.BackendStatus.ERROR
+        room.save()
+
+        raise Exception('Backend creation failed.')
+
+
+class Command(BaseCommand):
+    def handle(self, *args, **options):
+        for x in ['URL', 'BACKEND_URL', 'HOST', 'CMD']:
+            if not hasattr(settings, 'HANGAR_' + x) or getattr(settings, 'HANGAR_' + x) in [None, '']:
+                raise CommandError(f'No HANGAR_{x} configured.')
+
+        if settings.HANGAR_BACKEND_URL is None or settings.HANGAR_BACKEND_URL == '':
+            raise CommandError('No HANGAR_BACKEND_URL configured.')
+
+        rooms = Room.objects.filter(room_type=Room.RoomType.HANGAR, backend_status=Room.BackendStatus.NEW)
+        for room in rooms:
+            room.backend_status = Room.BackendStatus.SETUP
+            room.save()
+
+            try:
+                create_hangar(room)
+
+            except Exception as err:
+                logging.error('Got error on creating hangar for %s: %s', room, err)
+                room.backend_status = Room.BackendStatus.ERROR
+                room.backend_data = {
+                    'timestamp': timezone.now(),
+                    '_exception': str(err),
+                }
+                room.save()
diff --git a/src/core/models/assemblies.py b/src/core/models/assemblies.py
index 9637928f1..a7f4466bb 100644
--- a/src/core/models/assemblies.py
+++ b/src/core/models/assemblies.py
@@ -293,6 +293,12 @@ class Assembly(TaggedItemMixin, models.Model):
     def sorted_tags(self):
         return sorted(t['slug'] for t in self.tags)
 
+    def get_all_managing_contacts(self):
+        result = {}
+        for member in self.members.filter(role__in=AssemblyMember.MANAGEMENT_ROLES):
+            result[member.member.username] = member.member.get_verified_contacts()
+        return result
+
     def create_technical_user_if_necessary(self):
         if self.technical_user is not None:
             return self.technical_user
-- 
GitLab