Commit d7f5e29b by Belákovics Ádám

Merge branch 'vm'

parents 9e46f1ed 51b00d53
Pipeline #731 failed with stage
in 38 seconds
from interface.vm.instance import InstanceInterface from interface.vm.instance import InstanceInterface
from interface.vm.resources import Instance from interface.vm.resources import Instance, Flavor
from openstack.exceptions import SDKException from openstack.exceptions import SDKException
from novaclient import client from novaclient import client
import logging import logging
...@@ -24,8 +24,8 @@ def openstackError(func): ...@@ -24,8 +24,8 @@ def openstackError(func):
try: try:
return func(*args, **kw) return func(*args, **kw)
except SDKException as e: except SDKException as e:
logging.error(e.get_error_message()) logging.error(e)
new_e = Exception(e.get_error_message()) new_e = Exception(e)
new_e.OpenStackError = True new_e.OpenStackError = True
raise new_e raise new_e
return wrap_OpenStackError return wrap_OpenStackError
...@@ -38,24 +38,27 @@ class OSVirtualMachineManager(InstanceInterface): ...@@ -38,24 +38,27 @@ class OSVirtualMachineManager(InstanceInterface):
self.openstack = cloud self.openstack = cloud
@openstackError @openstackError
def create_base_vm(self, name, resource, networks, block_dev_map): def create_base_vm(self, name, flavor, networks, block_dev_map):
flavor = self.get_flavor(resource) devices = []
new_server = self.compute.create_server(name=name, b_device = block_dev_map.__dict__
flavorRef=flavor.id, devices.append(b_device)
networks=networks, flavor = self.get_flavor(flavor)
block_device_mapping=block_dev_map new_server = self.openstack.compute.create_server(name=name,
) flavorRef=flavor.id,
return new_server networks=networks,
block_device_mapping=devices
)
return self.convert_server_to_instance(new_server)
@openstackError @openstackError
def create_vm_from_template(self, name, image, resource, networks): def create_vm_from_template(self, name, image, flavor, networks):
self.create_multiple_vm_from_template(name, image, resource, networks, 1) return self.create_multiple_vm_from_template(name, image, flavor, networks, 1)
@openstackError @openstackError
def create_multiple_vm_from_template(self, name, image, resource, networks, def create_multiple_vm_from_template(self, name, image, flavor, networks,
number, **args): number, **args):
compute = self.openstack.compute compute = self.openstack.compute
flav = compute.find_flavor(resource) flav = compute.find_flavor(flavor)
image = compute.find_image(image) image = compute.find_image(image)
if not image: if not image:
...@@ -67,76 +70,104 @@ class OSVirtualMachineManager(InstanceInterface): ...@@ -67,76 +70,104 @@ class OSVirtualMachineManager(InstanceInterface):
networks=networks, networks=networks,
min_count=number, min_count=number,
) )
return self.convert_server_to_instance(new_server)
new_server = self.openstack.compute.wait_for_server(new_server) @openstackError
def create_flavor(self, name, ram, vcpus, initial_disk):
flavor = self.openstack.compute.create_flavor(name=name,
ram=ram,
vcpus=vcpus,
disk=initial_disk)
return Flavor(flavor.name, flavor.id, flavor.ram,
flavor.vcpus, flavor.disk)
return new_server @openstackError
def get_flavor(self, flavor_id):
flavor = self.openstack.compute.find_flavor(flavor_id)
return Flavor(flavor.name, flavor.id, flavor.ram,
flavor.vcpus, flavor.disk)
@openstackError
def delete_flavor(self, flavor_id):
flavor = self.openstack.compute.find_flavor(flavor_id)
self.openstack.compute.delete_flavor(flavor)
@openstackError
def list_flavors(self):
flavors = []
for flavor in self.openstack.compute.flavors():
flavors.append(Flavor(flavor.name, flavor.id, flavor.ram,
flavor.vcpus, flavor.disk))
return flavors
@openstackError @openstackError
def get_vm(self, name_or_id=None): def get_vm(self, name_or_id=None):
if not name_or_id: if not name_or_id:
raise ValueError("Name or id doesn't given") raise ValueError("Name or id doesn't given")
server_instance = self.openstack.get_server(name_or_id) server_instance = self.openstack.compute.get_server(name_or_id)
if not server_instance: if not server_instance:
raise ValueError("Could not get the vm") raise ValueError("Could not get the vm")
return server_instance return self.convert_server_to_instance(server_instance)
@openstackError @openstackError
def start_vm(self, name_or_id=None): def start_vm(self, name_or_id=None):
if name_or_id: if name_or_id:
instance = self.get_vm(name_or_id) instance = self.openstack.compute.get_server(name_or_id)
self.openstack.compute.start_server(instance) self.openstack.compute.start_server(instance)
@openstackError @openstackError
def stop_vm(self, name_or_id=None): def stop_vm(self, name_or_id=None):
if name_or_id: if name_or_id:
instance = self.get_vm(name_or_id) instance = self.openstack.compute.get_server(name_or_id)
self.openstack.compute.stop_server(instance) self.openstack.compute.stop_server(instance)
@openstackError @openstackError
def suspend_vm(self, name_or_id=None): def suspend_vm(self, name_or_id=None):
if name_or_id: if name_or_id:
instance = self.get_vm(name_or_id) instance = self.openstack.compute.get_server(name_or_id)
self.openstack.compute.suspend_server(instance) self.openstack.compute.suspend_server(instance)
@openstackError @openstackError
def wake_up_vm(self, name_or_id=None): def wake_up_vm(self, name_or_id=None):
if name_or_id: if name_or_id:
instance = self.get_vm(name_or_id) instance = self.openstack.compute.get_server(name_or_id)
self.openstack.compute.resume_server(instance) self.openstack.compute.resume_server(instance)
@openstackError @openstackError
def reboot_vm(self, name_or_id): def reboot_vm(self, name_or_id):
if name_or_id: if name_or_id:
instance = self.get_vm(name_or_id) instance = self.openstack.compute.get_server(name_or_id)
self.openstack.compute.reboot_server(instance, reboot_type='SOFT') self.openstack.compute.reboot_server(instance, reboot_type='SOFT')
@openstackError @openstackError
def reset_vm(self, name_or_id): def reset_vm(self, name_or_id):
if name_or_id: if name_or_id:
instance = self.get_vm(name_or_id) instance = self.openstack.compute.get_server(name_or_id)
self.openstack.compute.reboot_server(instance, reboot_type='HARD') self.openstack.compute.reboot_server(instance, reboot_type='HARD')
@openstackError @openstackError
def destroy_vm(self, name_or_id): def destroy_vm(self, name_or_id):
if name_or_id: if name_or_id:
instance = self.get_vm(name_or_id) instance = self.openstack.compute.get_server(name_or_id)
self.openstack.compute.delete_server(instance) self.openstack.compute.delete_server(instance)
@openstackError @openstackError
def get_status(self, name_or_id): def get_status(self, name_or_id):
if name_or_id: if name_or_id:
instance = self.get_vm(name_or_id) instance = self.openstack.compute.get_server(name_or_id)
return instance.status return instance.status
@openstackError @openstackError
def list_all_vm(self): def list_all_vm(self):
return self.openstack.compute.servers() servers = []
for server in self.openstack.compute.servers():
servers.append(self.convert_server_to_instance(server))
return servers
@openstackError @openstackError
def resize_vm(self, name_or_id, resource): def resize_vm(self, name_or_id, resource):
if name_or_id: if name_or_id:
instance = self.get_vm(name_or_id) instance = self.openstack.get_server(name_or_id)
flavor = self.openstack.compute.find_flavor(resource['name']) flavor = self.openstack.compute.find_flavor(resource['name'])
self.openstack.compute.resize_server(instance, flavor) self.openstack.compute.resize_server(instance, flavor)
...@@ -144,28 +175,40 @@ class OSVirtualMachineManager(InstanceInterface): ...@@ -144,28 +175,40 @@ class OSVirtualMachineManager(InstanceInterface):
@openstackError @openstackError
def create_template(self, name_or_id, template_name, metadata=None): def create_template(self, name_or_id, template_name, metadata=None):
if name_or_id: if name_or_id:
instance = self.get_vm(name_or_id) instance = self.openstack.compute.get_server(name_or_id)
self.openstack.compute.create_server_image(instance, template_name, metadata) self.openstack.compute.create_server_image(instance,
template_name,
metadata)
def get_vnc_console(self, name_or_id): def get_vnc_console(self, server_id):
with client.Client("2", session=sess) as nova: with client.Client("2", session=sess) as nova:
if name_or_id: if server_id:
instance = nova.servers.get(name_or_id) instance = nova.servers.get(server_id)
return instance.get_vnc_console("novnc") return instance.get_vnc_console("novnc")
def attach_volume(self, name_or_id, amount): @openstackError
raise NotImplementedError def attach_volume(self, server_id, volume_id, device=None):
self.openstack.compute.create_volume_attachment(server_id,
{"volumeId": volume_id,
})
@openstackError
def detach_volume(self, server_id, volume_id, device=None):
self.openstack.compute.delete_volume_attachment(server_id,
{"volumeId": volume_id,
"device": device
})
def convert_server_to_instance(self, server): def convert_server_to_instance(self, server):
if not server.image: if not server.image:
image_id = None image_id = None
else: else:
image_id = server.image.id image_id = server.image_id
return Instance(id=server.id, return Instance(id=server.id,
resource=server.flavor.id, flavor=server.flavor_id,
name=server.name, name=server.name,
image_id=image_id, image_id=image_id,
disks=server.volumes, disks=server.attached_volumes,
status=server.status, status=server.status,
launched_at=server.launched_at, launched_at=server.launched_at,
terminated_at=server.terminated_at, terminated_at=server.terminated_at,
......
...@@ -7,10 +7,13 @@ It should be implemented for using other providers e. g. OpenStack ...@@ -7,10 +7,13 @@ It should be implemented for using other providers e. g. OpenStack
class InstanceInterface: class InstanceInterface:
def create_vm_from_template(self, template, resource): def create_base_vm(self, name, flavor, networks, block_device_mapping):
raise NotImplementedError raise NotImplementedError
def create_multiple_vm_from_template(self, template, resource, number): def create_vm_from_template(self, name, image, flavor, networks):
raise NotImplementedError
def create_multiple_vm_from_template(self, image, flavor, networks, number):
raise NotImplementedError raise NotImplementedError
def get_vm(self, name_or_id): def get_vm(self, name_or_id):
...@@ -40,9 +43,6 @@ class InstanceInterface: ...@@ -40,9 +43,6 @@ class InstanceInterface:
def destroy_vm(self, name_or_id): def destroy_vm(self, name_or_id):
raise NotImplementedError raise NotImplementedError
def migrate_vm(self, name_or_id, to):
raise NotImplementedError
def get_status(self, name_or_id): def get_status(self, name_or_id):
raise NotImplementedError raise NotImplementedError
...@@ -52,17 +52,14 @@ class InstanceInterface: ...@@ -52,17 +52,14 @@ class InstanceInterface:
def install_ssh_key(self, name_or_id, key): def install_ssh_key(self, name_or_id, key):
raise NotImplementedError raise NotImplementedError
def save_as_template(self, name_or_id): def get_vnc_console(self, name_or_id):
raise NotImplementedError raise NotImplementedError
def get_vnc_console(self, name_or_id): def change_password(self, name_or_id):
raise NotImplementedError raise NotImplementedError
# def change_password(self, name_or_id): def get_password(self, name_or_id):
# raise NotImplementedError raise NotImplementedError
#
# def get_password(self, name_or_id):
# raise NotImplementedError
def resize_vm(self, name_or_id): def resize_vm(self, name_or_id):
raise NotImplementedError raise NotImplementedError
......
...@@ -10,11 +10,11 @@ class Instance: ...@@ -10,11 +10,11 @@ class Instance:
ssh_keys = None ssh_keys = None
console_access_url = None console_access_url = None
def __init__(self, id, name, resource, image_id, def __init__(self, id, name, flavor, image_id, status,
status, addresses, launched_at, terminated_at, disks=None): addresses, launched_at, terminated_at, disks=None):
self.id = id self.id = id
self.name = name self.name = name
self.resource = resource self.flavor = flavor
self.image = image_id self.image = image_id
self.disks = disks self.disks = disks
self.status = status self.status = status
...@@ -34,6 +34,20 @@ class Flavor: ...@@ -34,6 +34,20 @@ class Flavor:
self.vcpus = vcpus self.vcpus = vcpus
self.initial_disk = disk self.initial_disk = disk
def JSON(self):
return json.dumps(self.__dict__)
class Volume: class BlockDeviceMapping:
pass def __init__(self, boot_index, uuid, source_type, volume_size,
destination_type, delete_on_termination, disk_bus):
self.boot_index = boot_index
self.uuid=uuid
self.source_type=source_type
self.volume_size=volume_size
self.destination_type=destination_type
self.delete_on_termination=delete_on_termination
self.disk_bus=disk_bus
def JSON(self):
return json.dumps(self.__dict__)
# This file is for testing the openstack api access # This file is for testing the openstack api access
from implementation.vm.instance import OSVirtualMachineManager from implementation.vm.instance import OSVirtualMachineManager
from interface.vm.resources import BlockDeviceMapping, Flavor
import openstack import openstack
# openstack.enable_logging(debug=True) # openstack.enable_logging(debug=True)
conn = openstack.connect(cloud='openstack') conn = openstack.connect(cloud='openstack')
block_dev_map = BlockDeviceMapping(
boot_index=0,
uuid="da51253f-867c-472d-8ce0-81e7b7126d60",
source_type="image",
volume_size=10,
destination_type="volume",
delete_on_termination=True,
disk_bus="scsi"
)
networks = [{"uuid": "c03d0d4b-413e-4cc6-9ebe-c0b5ca0dac3a"}]
interface = OSVirtualMachineManager(conn) interface = OSVirtualMachineManager(conn)
resource = {"name": "m1.tiny", "ram": 1024, "cpu": 2}
print('#'*40) print('#'*40)
print(resource)
# interface.create_vm_from_template('new_server', resource, "cirros-0.4.0-x86_64-disk") # interface.create_vm_from_template('new_server', resource, "cirros-0.4.0-x86_64-disk")
# interface.stop_vm('a6bc504f-a422-4492-b429-e5dad2df12f4') # interface.stop_vm('a6bc504f-a422-4492-b429-e5dad2df12f4')
server = interface.get_vm("New test") # server = interface.openstack.compute.get_server("8e94c162-f8ed-4872-b9e5-50bf33040b5b")
#
# print(server)
# print(interface.delete_flavor("flavorTest"))
for flavor in interface.list_flavors():
print(flavor.JSON())
for vm in interface.list_all_vm():
print(vm.JSON())
print("*" * 50)
print(interface.create_base_vm("BaseTest", "2", networks, block_dev_map).JSON())
# print(interface.convert_server_to_instance(server).JSON())
print(interface.convert_server_to_instance(server).JSON()) # print(interface.openstack.compute.get_server("8e94c162-f8ed-4872-b9e5-50bf33040b5b"))
print(interface.get_status("Uborka Test")) # print(server.JSON())
print(interface.get_vnc_console("8e94c162-f8ed-4872-b9e5-50bf33040b5b")) # print(interface.get_vnc_console("8e94c162-f8ed-4872-b9e5-50bf33040b5b"))
# print(interface.convert_server_to_instance(server)) # print(interface.convert_server_to_instance(server))
...@@ -37,4 +62,3 @@ print(interface.get_vnc_console("8e94c162-f8ed-4872-b9e5-50bf33040b5b")) ...@@ -37,4 +62,3 @@ print(interface.get_vnc_console("8e94c162-f8ed-4872-b9e5-50bf33040b5b"))
# interface.wake_up_vm(server.id) # interface.wake_up_vm(server.id)
# interface.destroy_vm(server.id) # interface.destroy_vm(server.id)
# conn.compute.change_server_password(server, "root")
import unittest
from unittest.mock import MagicMock
from implementation.vm.instance import OSVirtualMachineManager
from interface.vm.resources import Instance
servers = [
MagicMock(
id="test1",
name="test1",
flavorRef="flav1",
imageRef="image1",
networks= [{"uuid": "network1"}],
terminated_at="20200320-15-31",
launched_at="20190510-13-22",
disks=["disk1"],
status="ACTIVE",
addresses=[{"mac": "12345678AB", "ipv4": "1.1.1.1"}]
)
]
class MockOpenStackCompute(MagicMock):
def setUp(self):
self.compute = MagicMock()
self.compute.create_server = MagicMock(return_value=servers[0])
self.compute.find_flavor = MagicMock(return_value=MagicMock(id="uuid1"))
self.compute.find_image = MagicMock(return_value=MagicMock(id="uuid2"))
self.compute.wait_for_server = MagicMock(return_value=True)
self.compute.list_servers = MagicMock(return_value=servers)
class InstanceCreateTestCase(unittest.TestCase):
def setUp(self):
self.conn = MockOpenStackCompute()
self.conn.setUp()
self.manager = OSVirtualMachineManager(self.conn)
def tearDown(self):
pass
def test_create_from_template(self):
instance = self.manager.create_vm_from_template('test', 'imageid', 'flavorid',
['networkid1'])
self.conn.compute.create_server.assert_called()
def test_create_from_template_params(self):
self.manager.create_vm_from_template('test', 'imageid', 'flavorid',
['networkid1'])
self.conn.compute.create_server.assert_called_with(
name='test',
flavorRef="uuid1",
imageRef="uuid2",
networks=['networkid1'],
min_count=1)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment