Browse Source

commandes checkip et checkvm

adaptation de scripts de contrôle existants
Élie Bouttier 7 years ago
parent
commit
7c9d256520
2 changed files with 160 additions and 0 deletions
  1. 75 0
      services/management/commands/checkip.py
  2. 85 0
      services/management/commands/checkvm.py

+ 75 - 0
services/management/commands/checkip.py

@@ -0,0 +1,75 @@
+from django.core.management.base import BaseCommand, CommandError
+from django.contrib.auth.models import User
+from django.contrib.contenttypes.models import ContentType
+
+import os, re, sys, socket
+
+from adhesions.models import Adhesion
+from services.models import Service, ServiceType, IPResource, Route
+from accounts.models import Profile
+
+
+check_reverse = True
+
+regex = re.compile('^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+) ([a-z.0-9]+)$')
+
+
+class Command(BaseCommand):
+    help = 'Comparaison des allocations IP dans Djadhere avec ip_ttnn.txt'
+
+    def add_arguments(self, parser):
+        parser.add_argument('file', help='Fichier ip_ttnn.txt')
+        parser.add_argument('--no-reverse', action='store_false')
+
+    def handle(self, *args, **options):
+        try:
+            f = open(options['file'])
+        except FileNotFoundError:
+            raise CommandError('Le fichier "%s" n’a pas été trouvé.' % options['file'])
+        else:
+            with f:
+                self.check_ip(f)
+
+    def check_ip(self, f):
+        i = 0
+        j = 0
+        for line in f:
+            i += 1
+            g = regex.match(line)
+            if not g:
+                self.stdout.write(self.style.ERROR("Impossible de parser la ligne n°%d: '%s'" % (i, line[:-1])))
+                continue
+            resource = IPResource.objects.get(ip=g.group(1))
+            route = g.group(2)
+            if route == 'reserved':
+                if resource.in_use:
+                    alloc = resource.allocations.get(active=True)
+                    self.stdout.write(self.style.WARNING("L’IP %s est marqué réservée dans ip_ttnn.txt mais allouée au service #%d sur Djadhere" % (resource, alloc.service.pk)))
+                if not resource.reserved:
+                    self.stdout.write(self.style.WARNING("L’IP %s est marqué réservée dans ip_ttnn.txt mais pas dans Djadhere" % resource))
+                continue
+            if route == "unused":
+                if resource.in_use:
+                    alloc = resource.allocations.get(active=True)
+                    self.stdout.write(self.style.WARNING("L’IP %s est marqué disponible dans ip_ttnn.txt mais allouée au service #%d sur Djadhere" % (resource, alloc.service.pk)))
+                continue
+            route = Route.objects.get(name=route)
+            if resource.in_use:
+                alloc = resource.allocations.get(active=True)
+                if alloc.route != route:
+                    self.stdout.write(self.style.WARNING("L’IP %s est routée sur %s dans ip_ttnn.txt mais routée sur %s pour le service #%d sur Djadhere" % (resource, route, alloc.route, alloc.service.pk)))
+                continue
+            if route.name in ['cluster', 'tls']:
+                if resource.reserved:
+                    self.stdout.write(self.style.WARNING("L’IP %s est marqué réservée dans Djadhere alors que routée via %s dans ip_ttnn.txt" % (resource, route)))
+                if check_reverse:
+                    try:
+                        reverse, _, _ = socket.gethostbyaddr(str(resource))
+                    except:
+                        reverse = '?'
+                else:
+                    reverse = '?'
+                self.stdout.write(self.style.WARNING("L’IP %s est disponible dans Djadhere alors que routée via %s dans ip_ttnn.txt (reverse : %s)" % (resource, route, reverse)))
+            else:
+                if not resource.reserved:
+                    self.stdout.write(self.style.WARNING("L’IP %s est routée via %s dans ip_ttnn.txt mais disponible dans Djadhere" % (resource, route)))

+ 85 - 0
services/management/commands/checkvm.py

@@ -0,0 +1,85 @@
+from django.core.management.base import BaseCommand, CommandError
+from django.contrib.contenttypes.models import ContentType
+from django.utils import timezone
+
+import re, sys, os
+from datetime import datetime
+
+from adhesions.models import Adhesion
+from services.models import Service, ServiceType, IPResource, Route
+from accounts.models import Profile
+
+
+regex = re.compile('^\| (?P<uuid>[0-9a-f-]*) \| (?P<nom>[a-z0-9.-]+)[ ]+\| vlan-routed=(?P<ip>.*)[ ]+\| (?P<created>[0-9TZ:-]+) |$')
+ipv4 = re.compile('[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
+
+
+# nova list --all-t --fields name,networks,created
+
+
+class Command(BaseCommand):
+    help = 'Comparaison des VM dans Djadhere avec OpenStack'
+
+    def add_arguments(self, parser):
+        parser.add_argument('file', help='Fichier OpenStack')
+    
+    def handle(self, *args, **options):
+        vm_st = ServiceType.objects.get(name='VM')
+        djadhere_list = Service.objects.filter(service_type=vm_st)
+        try:
+            f = open(options['file'])
+        except FileNotFoundError:
+            raise CommandError('Le fichier "%s" n’a pas été trouvé.' % options['file'])
+        else:
+            with f:
+                openstack_list = self.get_openstack_list(f)
+        self.compare(djadhere_list, openstack_list)
+
+    def get_openstack_list(self, f):
+        openstack_list = []
+        for line in f:
+            g = regex.match(line)
+            if g:
+                nom = g.group('nom')
+                ip = ipv4.findall(g.group('ip'))
+                created = datetime.strptime(g.group('created'), '%Y-%m-%dT%H:%M:%SZ')
+                openstack_list += [ (nom, ip, created) ]
+        return openstack_list
+
+    def compare(self, djadhere_list, openstack_list):
+        for vm in djadhere_list.filter(label__exact=''):
+            self.stdout.write(self.style.WARNING("> La VM n°%d n’a pas de label.\n"
+                  "Celui-ci est obligatoire pour les VM afin de les retrouver dans OpenStack.\n"
+                  "Merci d’éditer le service pour lui rajouter un label." % vm.id))
+        djadhere_name_set = set(djadhere_list.exclude(label__exact='').values_list('label', flat=True))
+        openstack_name_list, openstack_ip_list, _ = zip(*openstack_list)
+        openstack_name_set = set(openstack_name_list)
+        for vm in djadhere_name_set & openstack_name_set: # In both
+            djadhere = djadhere_list.get(label=vm)
+            if not djadhere.active:
+                self.stdout.write(self.style.WARNING("> La VM '%s' est marqué inactive dans Djadhere or elle est présente dans OpenStack.\n"
+                      "Soit c’est une erreur et elle doit être marqué active, soit elle doit être supprimé d’OpenStack suite à une demande de son propriétaire." % vm))
+            openstack_ip_set = set(openstack_ip_list[openstack_name_list.index(vm)])
+            djadhere_ip_set = set(djadhere.allocations.filter(active=True).values_list('resource__ip', flat=True))
+            for ip in openstack_ip_set & djadhere_ip_set: # In both
+                alloc = djadhere.allocations.get(resource__ip=ip)
+                if alloc.route.name != 'openstack':
+                    self.stdout.write(self.style.WARNING("> L’IP '%s' allouée à la VM '%s' a pour route '%s' dans Djadhere ; merci de modifier la route pour 'openstack'." % (ip, vm, alloc.route)))
+            for ip in djadhere_ip_set - openstack_ip_set: # Only in djadhere
+                self.stdout.write(self.style.WARNING("> L’IP '%s' est allouée à la VM '%s' dans Djadhere mais pas dans OpenStack.\n"
+                      "L’IP est soit à dés-allouer dans Djadhere, soit à rajouter à la VM dans OpenStack." % (ip, vm)))
+            for ip in openstack_ip_set - djadhere_ip_set: # Only in OpenStack
+                self.stdout.write(self.style.WARNING("> L’IP '%s' est utilisée par la VM '%s' d’après OpenStack.\n"
+                      "Il faut renseigner cette allocation dans Djadhere ou dés-allouer cette IP dans OpenStack." % (ip, vm)))
+        for vm in djadhere_name_set - openstack_name_set: # Only in djadhere
+            djadhere = djadhere_list.get(label=vm)
+            if djadhere.active:
+                self.stdout.write(self.style.WARNING("> La VM '%s' présente dans Djadhere est absente d’OpenStack.\n"
+                      "Soit il s’agit d’une VM à créer dans OpenStack, soit elle a été supprimée d’OpenStack et le service doit être marqué inactif dans Djadhere." % vm))
+        for vm in openstack_name_set - djadhere_name_set: # Only in openstack
+            self.stdout.write(self.style.WARNING("> La VM '%s' présente sur OpenStack n’a pas été trouvée dans Djadhere." % vm))
+            djadhere = djadhere_list.filter(label__icontains=vm[:vm.find('.')])
+            if djadhere.exists():
+                self.stdout.write(self.style.WARNING("Elle a peut-être été mal nommée, est-ce une des VM suivantes ?"))
+                for d in djadhere.all():
+                    self.stdout.write(self.style.WARNING("\t[%d] %s" % (d.pk, d.label)))