Make migrate-one-vm-to-regular command idempotent
This commit is contained in:
parent
88c10e2e4a
commit
a662b1fe29
4 changed files with 80 additions and 45 deletions
|
@ -8,6 +8,19 @@ from uncloud_vm.models import VMHost, VMProduct, VMNetworkCard, VMDiskImageProdu
|
||||||
from uncloud_pay.models import Order
|
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):
|
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
|
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
|
total = 3 * core + 4 * ram + 3.5 * storage + 8 * n_of_ipv4 + 0 * n_of_ipv6
|
||||||
|
@ -20,20 +33,11 @@ def get_vm_price(core, ram, storage, n_of_ipv4, n_of_ipv6):
|
||||||
|
|
||||||
def create_nics(one_vm, vm_product):
|
def create_nics(one_vm, vm_product):
|
||||||
for nic in one_vm.nics:
|
for nic in one_vm.nics:
|
||||||
mac_address = nic.get('MAC')
|
mac_address = convert_mac_to_int(nic.get('MAC'))
|
||||||
ip_address = nic.get('IP', None) or nic.get('IP6_GLOBAL', None)
|
ip_address = nic.get('IP', None) or nic.get('IP6_GLOBAL', None)
|
||||||
|
|
||||||
# Remove octet connecting characters
|
VMNetworkCard.objects.update_or_create(
|
||||||
mac_address = mac_address.replace(':', '')
|
mac_address=mac_address, vm=vm_product, defaults={'ip_address': ip_address}
|
||||||
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)
|
|
||||||
|
|
||||||
VMNetworkCard.objects.create(
|
|
||||||
mac_address=mac_address, vm=vm_product, ip_address=ip_address
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,9 +47,7 @@ def create_disk_and_image(one_vm, vm_product):
|
||||||
name = disk.get('image')
|
name = disk.get('image')
|
||||||
|
|
||||||
# TODO: Fix the following hard coded values
|
# TODO: Fix the following hard coded values
|
||||||
is_os_image = True
|
is_os_image, is_public, status = True, True, 'active'
|
||||||
is_public = True
|
|
||||||
status = 'active'
|
|
||||||
|
|
||||||
image_size_in_gb = disk.get('image_size_in_gb')
|
image_size_in_gb = disk.get('image_size_in_gb')
|
||||||
disk_size_in_gb = disk.get('size_in_gb')
|
disk_size_in_gb = disk.get('size_in_gb')
|
||||||
|
@ -53,22 +55,31 @@ def create_disk_and_image(one_vm, vm_product):
|
||||||
image_source = disk.get('source')
|
image_source = disk.get('source')
|
||||||
image_source_type = disk.get('source_type')
|
image_source_type = disk.get('source_type')
|
||||||
|
|
||||||
image = VMDiskImageProduct.objects.create(
|
image, _ = VMDiskImageProduct.objects.update_or_create(
|
||||||
owner=owner, name=name, is_os_image=is_os_image, is_public=is_public,
|
name=name,
|
||||||
size_in_gb=image_size_in_gb, storage_class=storage_class,
|
defaults={
|
||||||
image_source=image_source, image_source_type=image_source_type, status=status
|
'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
|
||||||
|
}
|
||||||
)
|
)
|
||||||
vm_disk = VMDiskProduct.objects.create(
|
VMDiskProduct.objects.update_or_create(
|
||||||
owner=owner, vm=vm_product, image=image, size_in_gb=disk_size_in_gb
|
owner=owner, vm=vm_product,
|
||||||
|
defaults={
|
||||||
|
'image': image,
|
||||||
|
'size_in_gb': disk_size_in_gb
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Migrate Opennebula VM to regular (uncloud) vm'
|
help = 'Migrate Opennebula VM to regular (uncloud) vm'
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
for one_vm in VMModel.objects.all():
|
for one_vm in VMModel.objects.all():
|
||||||
# Host on which the VM is currently residing
|
# Host on which the VM is currently residing
|
||||||
|
@ -76,7 +87,8 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
# VCPU, RAM, Owner, Status
|
# VCPU, RAM, Owner, Status
|
||||||
# TODO: Set actual status instead of hard coded 'active'
|
# TODO: Set actual status instead of hard coded 'active'
|
||||||
cores, ram_in_gb, owner, status = one_vm.cores, one_vm.ram_in_gb, one_vm.owner, '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
|
# Total Amount of SSD Storage
|
||||||
# TODO: What would happen if the attached storage is not SSD but HDD?
|
# TODO: What would happen if the attached storage is not SSD but HDD?
|
||||||
|
@ -96,7 +108,9 @@ class Command(BaseCommand):
|
||||||
recurring_period = 'per_month'
|
recurring_period = 'per_month'
|
||||||
|
|
||||||
recurring_price = get_vm_price(cores, ram_in_gb, total_storage_in_gb, len(ipv4), len(ipv6))
|
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(
|
order = Order.objects.create(
|
||||||
owner=one_vm.owner,
|
owner=one_vm.owner,
|
||||||
creation_date=creation_date,
|
creation_date=creation_date,
|
||||||
|
@ -106,14 +120,16 @@ class Command(BaseCommand):
|
||||||
recurring_price=recurring_price,
|
recurring_price=recurring_price,
|
||||||
recurring_period=recurring_period
|
recurring_period=recurring_period
|
||||||
)
|
)
|
||||||
|
vm_product, _ = VMProduct.objects.update_or_create(
|
||||||
vm_product = VMProduct.objects.create(
|
vmid=vm_id,
|
||||||
cores=cores,
|
defaults={
|
||||||
ram_in_gb=ram_in_gb,
|
'cores': cores,
|
||||||
owner=one_vm.owner,
|
'ram_in_gb': ram_in_gb,
|
||||||
vmhost=host,
|
'owner': owner,
|
||||||
order=order,
|
'vmhost': host,
|
||||||
status=status
|
'order': order,
|
||||||
|
'status': status
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create VMNetworkCards
|
# Create VMNetworkCards
|
||||||
|
|
|
@ -19,7 +19,7 @@ class VM(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ram_in_gb(self):
|
def ram_in_gb(self):
|
||||||
return (int(self.data['TEMPLATE']['MEMORY'])/1024.)
|
return int(self.data['TEMPLATE']['MEMORY'])/1024.0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def disks(self):
|
def disks(self):
|
||||||
|
|
18
uncloud/uncloud_vm/migrations/0014_vmproduct_vmid.py
Normal file
18
uncloud/uncloud_vm/migrations/0014_vmproduct_vmid.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.0.3 on 2020-03-04 07:52
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('uncloud_vm', '0013_auto_20200303_1845'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='vmproduct',
|
||||||
|
name='vmid',
|
||||||
|
field=models.IntegerField(null=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -53,6 +53,7 @@ class VMProduct(Product):
|
||||||
|
|
||||||
cores = models.IntegerField()
|
cores = models.IntegerField()
|
||||||
ram_in_gb = models.FloatField()
|
ram_in_gb = models.FloatField()
|
||||||
|
vmid = models.IntegerField(null=True)
|
||||||
|
|
||||||
|
|
||||||
class VMWithOSProduct(VMProduct):
|
class VMWithOSProduct(VMProduct):
|
||||||
|
|
Loading…
Reference in a new issue