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, storage, n_of_ipv4, n_of_ipv6): storage = storage / 10 # Division by 10 because our base storage unit is 10 GB total = 3 * core + 4 * ram + 3.5 * storage + 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(): # Host on which the VM is currently residing host = VMHost.objects.filter(vms__icontains=one_vm.vmid).first() # VCPU, RAM, Owner, Status # TODO: Set actual status instead of hard coded 'active' vm_id, cores, ram_in_gb = one_vm.vmid, one_vm.cores, one_vm.ram_in_gb owner, status = one_vm.owner, 'active' # Total Amount of SSD Storage # TODO: What would happen if the attached storage is not SSD but HDD? total_storage_in_gb = sum([disk['size_in_gb'] for disk in one_vm.disks]) # 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 = ending_date = datetime.now(tz=timezone.utc) # Price calculation # TODO: Make the following non-hardcoded one_time_price = 0 recurring_period = 'per_month' recurring_price = get_vm_price(cores, ram_in_gb, total_storage_in_gb, len(ipv4), len(ipv6)) try: vm_product = VMProduct.objects.get(vmid=vm_id) except VMProduct.DoesNotExist: order = Order.objects.create( owner=one_vm.owner, creation_date=creation_date, starting_date=starting_date, ending_date=ending_date, one_time_price=one_time_price, recurring_price=recurring_price, recurring_period=recurring_period ) vm_product, _ = VMProduct.objects.update_or_create( vmid=vm_id, defaults={ 'cores': cores, 'ram_in_gb': ram_in_gb, 'owner': owner, 'vmhost': host, 'order': order, 'status': status } ) # Create VMNetworkCards create_nics(one_vm, vm_product) # Create VMDiskImageProduct and VMDiskProduct create_disk_and_image(one_vm, vm_product)