| 
									
										
										
										
											2017-05-19 16:39:56 +02:00
										 |  |  | import ipaddress | 
					
						
							| 
									
										
										
										
											2017-05-11 04:05:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-19 02:28:48 +05:30
										 |  |  | from builtins import hasattr | 
					
						
							| 
									
										
										
										
											2017-05-11 04:05:58 +02:00
										 |  |  | from rest_framework import serializers | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from oca import OpenNebulaException | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  | from .models import OpenNebulaManager | 
					
						
							| 
									
										
										
										
											2017-05-11 04:05:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  | class VirtualMachineTemplateSerializer(serializers.Serializer): | 
					
						
							| 
									
										
										
										
											2017-05-11 04:05:58 +02:00
										 |  |  |     """Serializer to map the virtual machine template instance into JSON format.""" | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  |     id = serializers.IntegerField(read_only=True) | 
					
						
							|  |  |  |     name = serializers.SerializerMethodField() | 
					
						
							|  |  |  |     cores = serializers.SerializerMethodField() | 
					
						
							|  |  |  |     disk_size = serializers.SerializerMethodField() | 
					
						
							|  |  |  |     memory = serializers.SerializerMethodField() | 
					
						
							| 
									
										
										
										
											2017-05-11 04:05:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 22:01:26 -05:00
										 |  |  |     def get_cores(self, obj): | 
					
						
							|  |  |  |         if hasattr(obj.template, 'vcpu'): | 
					
						
							|  |  |  |             return obj.template.vcpu | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return '' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  |     def get_disk_size(self, obj): | 
					
						
							|  |  |  |         template = obj.template | 
					
						
							|  |  |  |         disk_size = 0 | 
					
						
							| 
									
										
										
										
											2017-05-14 01:02:22 +02:00
										 |  |  |         try: | 
					
						
							|  |  |  |             for disk in template.disks: | 
					
						
							|  |  |  |                 disk_size += int(disk.size) | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  |             return disk_size / 1024 | 
					
						
							| 
									
										
										
										
											2017-05-14 01:02:22 +02:00
										 |  |  |         except: | 
					
						
							|  |  |  |             return 0 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_memory(self, obj): | 
					
						
							| 
									
										
										
										
											2017-08-19 02:28:48 +05:30
										 |  |  |         return int(obj.template.memory) / 1024 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-13 13:47:53 +02:00
										 |  |  |     def get_name(self, obj): | 
					
						
							| 
									
										
										
										
											2018-08-08 00:10:03 +02:00
										 |  |  |         if obj.name.startswith('public-'): | 
					
						
							|  |  |  |             return obj.name.lstrip('public-') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return obj.name | 
					
						
							| 
									
										
										
										
											2017-05-13 13:47:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 00:49:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  | class VirtualMachineSerializer(serializers.Serializer): | 
					
						
							| 
									
										
										
										
											2017-05-11 05:51:30 +02:00
										 |  |  |     """Serializer to map the virtual machine instance into JSON format.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:23:39 +02:00
										 |  |  |     name = serializers.SerializerMethodField() | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  |     cores = serializers.IntegerField(source='template.vcpu') | 
					
						
							|  |  |  |     disk = serializers.IntegerField(write_only=True) | 
					
						
							|  |  |  |     set_memory = serializers.IntegerField(write_only=True, label='Memory') | 
					
						
							|  |  |  |     memory = serializers.SerializerMethodField() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     disk_size = serializers.SerializerMethodField() | 
					
						
							| 
									
										
										
										
											2018-01-03 08:43:57 +01:00
										 |  |  |     hdd_size = serializers.SerializerMethodField() | 
					
						
							| 
									
										
										
										
											2018-02-23 20:05:24 +05:30
										 |  |  |     ssd_size = serializers.SerializerMethodField() | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  |     ipv4 = serializers.SerializerMethodField() | 
					
						
							|  |  |  |     ipv6 = serializers.SerializerMethodField() | 
					
						
							|  |  |  |     vm_id = serializers.IntegerField(read_only=True, source='id') | 
					
						
							|  |  |  |     state = serializers.CharField(read_only=True, source='str_state') | 
					
						
							|  |  |  |     price = serializers.SerializerMethodField() | 
					
						
							|  |  |  |     ssh_key = serializers.CharField(write_only=True) | 
					
						
							| 
									
										
										
										
											2017-05-14 03:41:30 +02:00
										 |  |  |     configuration = serializers.SerializerMethodField() | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     template_id = serializers.ChoiceField( | 
					
						
							| 
									
										
										
										
											2017-08-19 02:28:48 +05:30
										 |  |  |         choices=[(key.id, key.name) for key in | 
					
						
							|  |  |  |                  OpenNebulaManager().try_get_templates() | 
					
						
							|  |  |  |                  ], | 
					
						
							|  |  |  |         source='template.template_id', | 
					
						
							|  |  |  |         write_only=True, | 
					
						
							|  |  |  |         default=[] | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-05-11 05:51:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  |     def create(self, validated_data): | 
					
						
							|  |  |  |         owner = validated_data['owner'] | 
					
						
							| 
									
										
										
										
											2017-05-13 15:50:00 +02:00
										 |  |  |         ssh_key = validated_data['ssh_key'] | 
					
						
							|  |  |  |         cores = validated_data['template']['vcpu'] | 
					
						
							| 
									
										
										
										
											2017-05-13 17:32:55 +02:00
										 |  |  |         memory = validated_data['set_memory'] | 
					
						
							| 
									
										
										
										
											2017-05-13 15:50:00 +02:00
										 |  |  |         disk = validated_data['disk'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  |         template_id = validated_data['template']['template_id'] | 
					
						
							| 
									
										
										
										
											2017-05-13 15:50:00 +02:00
										 |  |  |         specs = { | 
					
						
							| 
									
										
										
										
											2017-08-19 02:28:48 +05:30
										 |  |  |             'cpu': cores, | 
					
						
							|  |  |  |             'disk_size': disk, | 
					
						
							|  |  |  |             'memory': memory, | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-05-13 15:50:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-11 05:51:30 +02:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2017-05-11 12:45:09 +02:00
										 |  |  |             manager = OpenNebulaManager(email=owner.email, | 
					
						
							| 
									
										
										
										
											2017-05-12 12:13:18 -05:00
										 |  |  |                                         password=owner.password, | 
					
						
							| 
									
										
										
										
											2017-05-13 06:59:57 +02:00
										 |  |  |                                         ) | 
					
						
							| 
									
										
										
										
											2017-05-13 15:50:00 +02:00
										 |  |  |             opennebula_id = manager.create_vm(template_id=template_id, | 
					
						
							|  |  |  |                                               ssh_key=ssh_key, | 
					
						
							|  |  |  |                                               specs=specs) | 
					
						
							| 
									
										
										
										
											2017-05-11 05:51:30 +02:00
										 |  |  |         except OpenNebulaException as err: | 
					
						
							| 
									
										
										
										
											2018-02-23 20:05:24 +05:30
										 |  |  |             raise serializers.ValidationError( | 
					
						
							|  |  |  |                 "OpenNebulaException occured. {0}".format(err) | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  |         return manager.get_vm(opennebula_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_memory(self, obj): | 
					
						
							| 
									
										
										
										
											2017-08-19 02:28:48 +05:30
										 |  |  |         return int(obj.template.memory) / 1024 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_disk_size(self, obj): | 
					
						
							|  |  |  |         template = obj.template | 
					
						
							|  |  |  |         disk_size = 0 | 
					
						
							|  |  |  |         for disk in template.disks: | 
					
						
							|  |  |  |             disk_size += int(disk.size) | 
					
						
							|  |  |  |         return disk_size / 1024 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 11:46:33 +01:00
										 |  |  |     def get_ssd_size(self, obj): | 
					
						
							| 
									
										
										
										
											2018-01-03 08:43:57 +01:00
										 |  |  |         template = obj.template | 
					
						
							|  |  |  |         disk_size = 0 | 
					
						
							|  |  |  |         for disk in template.disks: | 
					
						
							|  |  |  |             if disk.datastore == 'cephds': | 
					
						
							|  |  |  |                 disk_size += int(disk.size) | 
					
						
							|  |  |  |         return disk_size / 1024 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_hdd_size(self, obj): | 
					
						
							|  |  |  |         template = obj.template | 
					
						
							|  |  |  |         disk_size = 0 | 
					
						
							|  |  |  |         for disk in template.disks: | 
					
						
							|  |  |  |             if disk.datastore == 'ceph_hdd_ds': | 
					
						
							|  |  |  |                 disk_size += int(disk.size) | 
					
						
							|  |  |  |         return disk_size / 1024 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  |     def get_price(self, obj): | 
					
						
							|  |  |  |         template = obj.template | 
					
						
							| 
									
										
										
										
											2017-05-14 02:17:48 +02:00
										 |  |  |         price = float(template.vcpu) * 5.0 | 
					
						
							| 
									
										
										
										
											2017-08-19 02:28:48 +05:30
										 |  |  |         price += (int(template.memory) / 1024 * 2.0) | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  |         for disk in template.disks: | 
					
						
							| 
									
										
										
										
											2017-08-19 02:28:48 +05:30
										 |  |  |             price += int(disk.size) / 1024 * 0.6 | 
					
						
							| 
									
										
										
										
											2017-05-12 12:07:05 +02:00
										 |  |  |         return price | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-14 03:41:30 +02:00
										 |  |  |     def get_configuration(self, obj): | 
					
						
							|  |  |  |         template_id = obj.template.template_id | 
					
						
							|  |  |  |         template = OpenNebulaManager().get_template(template_id) | 
					
						
							| 
									
										
										
										
											2018-08-08 00:10:03 +02:00
										 |  |  |         if template.name.startswith('public-'): | 
					
						
							|  |  |  |             return template.name.lstrip('public-') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return template.name | 
					
						
							| 
									
										
										
										
											2017-05-19 16:39:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-23 11:30:10 +02:00
										 |  |  |     def get_ipv4(self, obj): | 
					
						
							| 
									
										
										
										
											2017-08-19 02:28:48 +05:30
										 |  |  |         """
 | 
					
						
							|  |  |  |         Get the IPv4s from the given VM | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         :param obj: The VM in contention | 
					
						
							|  |  |  |         :return: Returns csv string of all IPv4s added to this VM otherwise returns "-" if no IPv4 is available | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         ipv4 = [] | 
					
						
							|  |  |  |         for nic in obj.template.nics: | 
					
						
							|  |  |  |             if hasattr(nic, 'ip'): | 
					
						
							|  |  |  |                 ipv4.append(nic.ip) | 
					
						
							|  |  |  |         if len(ipv4) > 0: | 
					
						
							|  |  |  |             return ', '.join(ipv4) | 
					
						
							| 
									
										
										
										
											2017-05-19 16:39:56 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             return '-' | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-23 11:30:10 +02:00
										 |  |  |     def get_ipv6(self, obj): | 
					
						
							| 
									
										
										
										
											2017-08-19 02:28:48 +05:30
										 |  |  |         ipv6 = [] | 
					
						
							|  |  |  |         for nic in obj.template.nics: | 
					
						
							|  |  |  |             if hasattr(nic, 'ip6_global'): | 
					
						
							|  |  |  |                 ipv6.append(nic.ip6_global) | 
					
						
							|  |  |  |         if len(ipv6) > 0: | 
					
						
							|  |  |  |             return ', '.join(ipv6) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return '-' | 
					
						
							| 
									
										
										
										
											2017-05-19 16:39:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:23:39 +02:00
										 |  |  |     def get_name(self, obj): | 
					
						
							| 
									
										
										
										
											2018-08-04 08:46:00 +02:00
										 |  |  |         if obj.name.startswith('public-'): | 
					
						
							|  |  |  |             return obj.name.lstrip('public-') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return obj.name | 
					
						
							| 
									
										
										
										
											2017-05-19 16:39:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-27 12:05:01 +05:30
										 |  |  | class VMTemplateSerializer(serializers.Serializer): | 
					
						
							|  |  |  |     """Serializer to map the VMTemplate instance into JSON format.""" | 
					
						
							| 
									
										
										
										
											2018-02-23 20:05:24 +05:30
										 |  |  |     id = serializers.IntegerField( | 
					
						
							|  |  |  |         read_only=True, source='opennebula_vm_template_id' | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-07-27 12:05:01 +05:30
										 |  |  |     name = serializers.CharField(read_only=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 16:39:56 +02:00
										 |  |  | def hexstr2int(string): | 
					
						
							|  |  |  |     return int(string.replace(':', ''), 16) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 16:39:56 +02:00
										 |  |  | FIRST_MAC = hexstr2int('02:00:b3:39:79:4d') | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | FIRST_V4 = ipaddress.ip_address('185.203.112.2') | 
					
						
							|  |  |  | COUNT = 1000 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 16:39:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | def v4_from_mac(mac): | 
					
						
							|  |  |  |     """Calculates the IPv4 address from a MAC address.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mac: string (the colon-separated representation) | 
					
						
							|  |  |  |     returns: ipaddress.ip_address object with the v4 address | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     return FIRST_V4 + (hexstr2int(mac) - FIRST_MAC) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 17:34:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 16:39:56 +02:00
										 |  |  | def is_in_v4_range(mac): | 
					
						
							|  |  |  |     return FIRST_MAC <= hexstr2int(mac) < FIRST_MAC + 1000 |