from django.core.management.base import BaseCommand, CommandError from django.contrib.contenttypes.models import ContentType from django.utils import timezone import re, sys, os, json 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[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)))