def _add_switch_port(self, port_number, port_name): assert port_name port_name = _normalize_port_name(port_name) if port_name not in self.port_name__num__map: logger.debug("Added port %s number %s" % (port_name, port_number)) self.port_name__num__map[port_name] = port_number
def resource_post_save(sender, instance, created, **kwargs): if not hasattr(sender, 'HISTORY_FIELDS'): return if created: HistoryEvent.add_create(instance) for field in sender.HISTORY_FIELDS: value = getattr(instance, field) if value: HistoryEvent.add_update(instance, field, None, value) else: for field in sender.HISTORY_FIELDS: value = getattr(instance, field) history_field = '_original_%s' % field logger.debug("POST SAVE: %s %s %s" % (instance, field, value)) if hasattr(instance, history_field): orig_value = getattr(instance, history_field) logger.debug(" original value: %s" % orig_value) if "%s" % value != "%s" % orig_value: HistoryEvent.add_update(instance, field, orig_value, value) setattr(instance, '_original_%s' % field, value)
def resource_post_init(sender, instance, **kwargs): if not issubclass(sender, Resource): return for field in RESOURCE_HISTORY_FIELDS: value = getattr(instance, field) setattr(instance, '_original_%s' % field, value) logger.debug("POST INIT: %s %s %s" % (instance, field, value))
def create_vps(self, **options): """ Create VPS using options. Parameters: vmid: ID of the VPS cpu: number of CPU cores ram: amount of RAM in Mb hdd: amount of HDD space in Gb user: user name template: template name used to create VPS. It is in form: <driver>.param1.param2..paramN (kvm.centos.6.x86_64.directadmin) driver: method of provisioning. Different drivers supports different templates and provisioning depth. Drivers can work with different virtualization technologies. Optional: node: ID of the hypervisor node. If not specified, scheduler is used to select the best node, based on template. Populated parameters: hostname: hostname of the virtual machine driver: used driver to control the VPS (got from the template string) ip, gateway, netmask, dns1, dns2: network interface config :param options: Options used to create VPS. :return: TaskTracker instance to chesk progress. """ assert 'vmid' in options assert 'cpu' in options assert 'ram' in options assert 'hdd' in options assert 'user' in options assert 'template' in options logger.debug(options) if 'node' in options and options['node'] > 0: target_node = Server.active.get(pk=options['node']) hyper_driver = target_node.get_option_value('hypervisor_driver', default='unknown') else: (hyper_driver, tpl) = options['template'].split('.', 1) target_node = self.scheduler.get_best_node( self.cloud.get_hypervisors(hypervisor_driver=hyper_driver)) ip, gateway, netmask = self.lease_ip(target_node.id) # update some options options['driver'] = hyper_driver options['hostname'] = "v%s.%s.pytin" % (options['vmid'], hyper_driver) options['dns1'] = '46.17.46.200' options['dns2'] = '46.17.40.200' options['ip'] = ip options['gateway'] = gateway options['netmask'] = netmask return self.internal_send_task(self.TASK_CREATE, target_node, **options)
def resource_post_init(sender, instance, **kwargs): if not hasattr(sender, 'HISTORY_FIELDS'): return for field in sender.HISTORY_FIELDS: value = getattr(instance, field) setattr(instance, '_original_%s' % field, value) logger.debug("POST INIT: %s %s %s" % (instance, field, value))
def create_vps(self, **options): """ Create VPS using options. Parameters: vmid: ID of the VPS cpu: number of CPU cores ram: amount of RAM in Mb hdd: amount of HDD space in Gb user: user name template: template name used to create VPS. It is in form: <driver>.param1.param2..paramN (kvm.centos.6.x86_64.directadmin) driver: method of provisioning. Different drivers supports different templates and provisioning depth. Drivers can work with different virtualization technologies. Optional: node: ID of the hypervisor node. If not specified, scheduler is used to select the best node, based on template. Populated parameters: hostname: hostname of the virtual machine driver: used driver to control the VPS (got from the template string) ip, gateway, netmask, dns1, dns2: network interface config :param options: Options used to create VPS. :return: TaskTracker instance to chesk progress. """ assert 'vmid' in options assert 'cpu' in options assert 'ram' in options assert 'hdd' in options assert 'user' in options assert 'template' in options logger.debug(options) if 'node' in options and options['node'] > 0: target_node = Server.active.get(pk=options['node']) hyper_driver = target_node.get_option_value('hypervisor_driver', default='unknown') else: (hyper_driver, tpl) = options['template'].split('.', 1) target_node = self.scheduler.get_best_node(self.cloud.get_hypervisors(hypervisor_driver=hyper_driver)) ip, gateway, netmask = self.lease_ip(target_node.id) # update some options options['driver'] = hyper_driver options['hostname'] = "v%s.%s.pytin" % (options['vmid'], hyper_driver) options['dns1'] = '46.17.46.200' options['dns2'] = '46.17.40.200' options['ip'] = ip options['gateway'] = gateway options['netmask'] = netmask return self.internal_send_task(self.TASK_CREATE, target_node, **options)
def delete(self, using=None): """ Override Model .delete() method. Instead of actual deleting object from the DB set status Deleted. """ logger.debug("Removing resource ID:%s %s" % (self.id, self)) if len(list(self)) > 0: raise ValidationError(_("Object have one or more childs.")) self.status = Resource.STATUS_DELETED self.save()
def _add_server_port_ip(self, server_port_mac, ip_address): assert server_port_mac assert ip_address logger.debug("%s <- %s" % (server_port_mac, ip_address)) server_port_mac = _normalize_mac(server_port_mac) if server_port_mac not in self.server_port__ips__map: self.server_port__ips__map[server_port_mac] = [] if ip_address not in self.server_port__ips__map[server_port_mac]: self.server_port__ips__map[server_port_mac].append(ip_address)
def _change_status(self, new_status, method_name, cascade=False): assert new_status, "new_status must be defined." assert method_name, "method_name must be defined." if cascade: for child in self: getattr(child, method_name)(cascade) if self.status != new_status: logger.debug("Setting resource ID:%s status: %s -> %s" % (self.id, self.status, new_status)) self.status = new_status self.save()
def _handle_res_list(self, *args, **options): query = self._parse_reminder_arg(options['filter']) limit = options['limit'] offset = (options['page'] - 1) * limit events_set = HistoryEvent.objects.filter(**query) if options['from_date']: events_begin_date = timezone.datetime.strptime( options['from_date'], '%d.%m.%Y %H:%M') events_set = events_set.filter(created_at__gte=events_begin_date) if options['order']: fields = options['order'].split(',') events_set = events_set.order_by(*fields) if limit > 0: events_set = events_set[offset:limit] table = PrettyTable([ 'id', 'created_at', 'type', 'resource_id', 'resource__type', 'field_name', 'field_old_value', 'field_new_value' ]) table.padding_width = 1 table.align['id'] = 'r' table.align['resource_id'] = 'r' table.align['resource_type'] = 'l' table.align['field_name'] = 'l' table.align['field_old_value'] = 'l' table.align['field_new_value'] = 'l' for event in events_set: try: table.add_row([ event.id, timezone.localtime( event.created_at).strftime('%d.%m.%Y %H:%M'), event.type, event.resource.id, event.resource.type, event.field_name, event.field_old_value, event.field_new_value ]) except ObjectDoesNotExist: logger.debug("Removing event %s with missing resource %s" % (event.id, event.resource_id)) event.delete() logger.info(unicode(table))
def get(self, request, format=None, *args, **kwargs): ip_pools = request.query_params.getlist('pool', None) ip_count = int(request.query_params.get('count', 1)) if not ip_pools: raise ParseError() logger.debug(request.query_params) logger.info("Getting %s new ip addresses from pools: %s" % (ip_count, ip_pools)) rented_ips = IPAddressPool.lease_ips(ip_pools, ip_count) serializer = self.get_serializer(rented_ips, many=True) response = {'count': len(rented_ips), 'results': serializer.data} return Response(response)
def update(self, instance, validated_data): options_list = validated_data.pop('resourceoption_set', []) logger.debug(options_list) resource, created = Resource.active.update_or_create( id=instance.id, defaults=validated_data) for option_item in options_list: ResourceOption.objects.update_or_create( name=option_item['name'], resource=resource, defaults=option_item, ) resource.refresh_from_db() return resource
def _handle_res_list(self, *args, **options): query = self._parse_reminder_arg(options['filter']) limit = options['limit'] offset = (options['page'] - 1) * limit events_set = HistoryEvent.objects.filter(**query) if options['from_date']: events_begin_date = timezone.datetime.strptime(options['from_date'], '%d.%m.%Y %H:%M') events_set = events_set.filter(created_at__gte=events_begin_date) if options['order']: fields = options['order'].split(',') events_set = events_set.order_by(*fields) if limit > 0: events_set = events_set[offset:limit] table = PrettyTable( ['id', 'created_at', 'type', 'resource_id', 'resource__type', 'field_name', 'field_old_value', 'field_new_value']) table.padding_width = 1 table.align['id'] = 'r' table.align['resource_id'] = 'r' table.align['resource_type'] = 'l' table.align['field_name'] = 'l' table.align['field_old_value'] = 'l' table.align['field_new_value'] = 'l' for event in events_set: try: table.add_row([event.id, timezone.localtime(event.created_at).strftime('%d.%m.%Y %H:%M'), event.type, event.resource.id, event.resource.type, event.field_name, event.field_old_value, event.field_new_value]) except ObjectDoesNotExist: logger.debug("Removing event %s with missing resource %s" % (event.id, event.resource_id)) event.delete() logger.info(unicode(table))
def _handle_command_search(self, *args, **options): query = self._parse_reminder_arguments(options['filter']) if options['index']: updated = 0 for resource in Resource.active.all(): resource.name = unicode(resource) resource.save() logger.debug("Updated resources: %s" % updated) return # apply status if not options['status']: resource_set = Resource.active.filter(**query) else: query['status__in'] = options['status'].split(',') resource_set = Resource.objects.filter(**query) # order by table_sort_by_field = None if options['order']: fields = options['order'].split(',') for field_name in fields: if not ModelFieldChecker.is_model_field(Resource, field_name): table_sort_by_field = field_name break if not table_sort_by_field: resource_set = resource_set.order_by(*fields) # apply limits limit = options['limit'] offset = (options['page'] - 1) * limit if limit > 0: resource_set = resource_set[offset:limit] # tabular output with column align show_fields = options['show_fields'].split(',') console_writer = ConsoleResourceWriter(resource_set) console_writer.print_table(show_fields, sort_by=table_sort_by_field)
def get(self, request, format=None, *args, **kwargs): ip_pools = request.query_params.getlist('pool', None) ip_count = int(request.query_params.get('count', 1)) if not ip_pools: raise ParseError() logger.debug(request.query_params) logger.info("Getting %s new ip addresses from pools: %s" % (ip_count, ip_pools)) rented_ips = IPAddressPool.lease_ips(ip_pools, ip_count) serializer = self.get_serializer(rented_ips, many=True) response = { 'count': len(rented_ips), 'results': serializer.data } return Response(response)
def update(self, instance, validated_data): options_list = validated_data.pop('resourceoption_set', []) logger.debug(options_list) resource, created = Resource.active.update_or_create( id=instance.id, defaults=validated_data ) for option_item in options_list: ResourceOption.objects.update_or_create( name=option_item['name'], resource=resource, defaults=option_item, ) resource.refresh_from_db() return resource
def _add_server_and_port(self, connected_mac): """ Add or get server with port. Selecting bare metal or Virtual based on Vendor code of MAC. :param connected_mac: :return: """ assert connected_mac logger.debug("Found mac: %s" % connected_mac) if connected_mac.vendor: server_port, created = ServerPort.active.get_or_create( mac=connected_mac.interface, defaults=dict(status=Resource.STATUS_INUSE)) else: server_port, created = VirtualServerPort.active.get_or_create( mac=connected_mac.interface, defaults=dict(status=Resource.STATUS_INUSE)) if created: logger.info("Added server port %s (%s)" % (server_port.id, connected_mac.interface)) if server_port.__class__ == VirtualServerPort: server = VirtualServer.objects.create(label='VPS') logger.info("Added VPS %s (%s)" % (server, connected_mac)) else: server = Server.objects.create(label=connected_mac.vendor, vendor=connected_mac.vendor) logger.info("Added metal server %s (%s)" % (server, connected_mac)) # set parent for the port server_port.parent = server server_port.save() else: server_port.use() server_port.touch() server_port.parent.touch() return server_port.typed_parent, server_port
def resource_post_save(sender, instance, created, **kwargs): if not issubclass(sender, Resource): return if created: HistoryEvent.add_create(instance) else: for field in RESOURCE_HISTORY_FIELDS: value = getattr(instance, field) history_field = '_original_%s' % field logger.debug("POST SAVE: %s %s %s" % (instance, field, value)) if hasattr(instance, history_field): orig_value = getattr(instance, history_field) logger.debug(" original value: %s" % orig_value) if unicode(value) != unicode(orig_value): HistoryEvent.add_update(instance, field, orig_value, value) setattr(instance, '_original_%s' % field, value)
def lease_ips(ip_pool_ids, count=1): """ Returns given number of IPs from different IP address pools. """ assert ip_pool_ids assert count > 0 pool_id_infinite_list = IPAddressPool.InfiniteList(ip_pool_ids) rented_ips = [] changed = False iterations = len(pool_id_infinite_list) for ip_pool_id in pool_id_infinite_list: if len(rented_ips) >= count: break if iterations <= 0 and not changed: raise Exception("There is no available IPs in pools: %s" % ip_pool_ids) iterations -= 1 ip_pool_resource = Resource.active.get(pk=ip_pool_id) if ip_pool_resource.usage >= 95: logger.warning("IP pool %s usage >95%%" % ip_pool_resource.id) try: ip = ip_pool_resource.available().next() ip.lock() ip.touch() logger.debug("Available IP found: %s" % ip) rented_ips.append(ip) changed = True except Exception, ex: logger.error("Exception %s while getting IP from IP pool: %s" % (ex.__class__.__name__, ex.message))
def _add_server_and_port(self, connected_mac): """ Add or get server with port. Selecting bare metal or Virtual based on Vendor code of MAC. :param connected_mac: :return: """ assert connected_mac logger.debug("Found mac: %s" % connected_mac) server_port, created = Resource.active.get_or_create( mac=connected_mac.interface, type__in=[ServerPort.__name__, VirtualServerPort.__name__], defaults=dict( mac=connected_mac.interface, type="assets.%s" % (ServerPort.__name__ if connected_mac.vendor else VirtualServerPort.__name__), status=Resource.STATUS_INUSE ) ) if created: logger.info("Added server port %s (%s)" % (server_port.id, connected_mac.interface)) if server_port.__class__ == VirtualServerPort: server = VirtualServer.objects.create(label='VPS') logger.info("Added VPS %s (%s)" % (server, connected_mac)) else: server = Server.objects.create(label=connected_mac.vendor, vendor=connected_mac.vendor) logger.info("Added metal server %s (%s)" % (server, connected_mac)) # set parent for the port server_port.parent = server server_port.save() else: server_port.use() server_port.touch() server_port.parent.touch() return server_port.typed_parent, server_port
def get(self, *args, **kwargs): logger.debug("%s, %s" % (args, kwargs)) return super(SubclassingQuerySet, self).get(*args, **kwargs).as_leaf_class()