forked from uncloud/uncloud
148 lines
5.2 KiB
Python
148 lines
5.2 KiB
Python
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)
|