from django.core.management.base import BaseCommand, CommandError from django.contrib.contenttypes.models import ContentType import re, sys, os, json from adhesions.models import Adhesion from services.models import Service, ServiceType, IPResource, Route from accounts.models import Profile regex = re.compile('^\| (?P[0-9a-f-]*) \| (?P[a-z0-9.-]+)[ ]+\| vlan-routed=(?P.*)[ ]+\| (?P[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') parser.add_argument('--absent-ok', help='Ne pas afficher de message d’erreur si la VM est absente d’OpenStack', action='append', default=[]) 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 = json.load(f) openstack_list = { vm['name']: vm for vm in openstack_list } self.compare(djadhere_list, openstack_list, absent_ok=options['absent_ok']) def compare(self, djadhere_list, openstack_list, absent_ok): for vm in djadhere_list.filter(label__exact=''): if not vm.is_active(): continue 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_list = djadhere_list.exclude(label__exact='') djadhere_name_set = set(djadhere_list.values_list('label', flat=True)) openstack_name_set = set(openstack_list.keys()) for vm in djadhere_name_set & openstack_name_set: # In both djadhere = djadhere_list.get(label=vm) if not djadhere.is_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(map(lambda vlan_routed: vlan_routed['addr'], openstack_list[vm]['addresses']['vlan-routed'])) 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 if not ip.startswith('fe80::'): 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.is_active() and vm not in absent_ok: 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 l’IP doit être déallouée 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)))