from datetime import datetime from django.core.management.base import BaseCommand from django.utils import timezone from opennebula.models import VM as VMModel from uncloud_vm.models import VMHost, VMProduct, VMNetworkCard, VMDiskImageProduct, VMDiskProduct from uncloud_pay.models import Order def convert_mac_to_int(mac_address: str): # Remove octet connecting characters mac_address = mac_address.replace(':', '') mac_address = mac_address.replace('.', '') mac_address = mac_address.replace('-', '') mac_address = mac_address.replace(' ', '') # Parse the resulting number as hexadecimal mac_address = int(mac_address, base=16) return mac_address def get_vm_price(core, ram, ssd_size, hdd_size, n_of_ipv4, n_of_ipv6): total = 3 * core + 4 * ram + (3.5 * ssd_size/10.) + (1.5 * hdd_size/100.) + 8 * n_of_ipv4 + 0 * n_of_ipv6 # TODO: Find some reason about the following magical subtraction. total -= 8 return total def create_nics(one_vm, vm_product): for nic in one_vm.nics: mac_address = convert_mac_to_int(nic.get('MAC')) ip_address = nic.get('IP', None) or nic.get('IP6_GLOBAL', None) VMNetworkCard.objects.update_or_create( mac_address=mac_address, vm=vm_product, defaults={'ip_address': ip_address} ) def create_disk_and_image(one_vm, vm_product): for disk in one_vm.disks: owner = one_vm.owner name = disk.get('image') # TODO: Fix the following hard coded values is_os_image, is_public, status = True, True, 'active' image_size_in_gb = disk.get('image_size_in_gb') disk_size_in_gb = disk.get('size_in_gb') storage_class = disk.get('pool_name') image_source = disk.get('source') image_source_type = disk.get('source_type') image, _ = VMDiskImageProduct.objects.update_or_create( name=name, defaults={ 'owner': owner, 'is_os_image': is_os_image, 'is_public': is_public, 'size_in_gb': image_size_in_gb, 'storage_class': storage_class, 'image_source': image_source, 'image_source_type': image_source_type, 'status': status } ) VMDiskProduct.objects.update_or_create( owner=owner, vm=vm_product, defaults={ 'image': image, 'size_in_gb': disk_size_in_gb } ) class Command(BaseCommand): help = 'Migrate Opennebula VM to regular (uncloud) vm' def handle(self, *args, **options): for one_vm in VMModel.objects.all(): if not one_vm.last_host: print("No VMHost for VM {} - VM might be on hold - skipping".format(one_vm.vmid)) continue try: vmhost = VMHost.objects.get(hostname=one_vm.last_host) except VMHost.DoesNotExist: print("VMHost {} does not exist, aborting".format(one_vm.last_host)) raise cores = one_vm.cores ram_in_gb = one_vm.ram_in_gb owner = one_vm.owner status = 'active' # Total Amount of SSD Storage # TODO: What would happen if the attached storage is not SSD but HDD? ssd_size = sum([ disk['size_in_gb'] for disk in one_vm.disks if disk['pool_name'] in ['ssd', 'one'] ]) hdd_size = sum([ disk['size_in_gb'] for disk in one_vm.disks if disk['pool_name'] in ['hdd'] ]) # List of IPv4 addresses and Global IPv6 addresses ipv4, ipv6 = one_vm.ips # TODO: Insert actual/real creation_date, starting_date, ending_date # instead of pseudo one we are putting currently creation_date = starting_date = datetime.now(tz=timezone.utc) # Price calculation based on datacenterlight.ch one_time_price = 0 recurring_period = 'per_month' recurring_price = get_vm_price(cores, ram_in_gb, ssd_size, hdd_size, len(ipv4), len(ipv6)) try: vm_product = VMProduct.objects.get(name=one_vm.uncloud_name) except VMProduct.DoesNotExist: order = Order.objects.create( owner=owner, creation_date=creation_date, starting_date=starting_date # one_time_price=one_time_price, # recurring_price=recurring_price, # recurring_period=recurring_period ) vm_product, _ = VMProduct.objects.update_or_create( name=one_vm.uncloud_name, defaults={ 'cores': cores, 'ram_in_gb': ram_in_gb, 'owner': owner, 'vmhost': vmhost, 'order': order, 'status': status } ) # Create VMNetworkCards create_nics(one_vm, vm_product) # Create VMDiskImageProduct and VMDiskProduct create_disk_and_image(one_vm, vm_product)