def mon_vm_delete(task_id, sender, vm_uuid=None, vm_hostname=None, vm_alias=None, dc_id=None, zabbix_sync=None, external_zabbix_sync=None, log=LOG, **kwargs): """ Remove host from zabbix. """ assert vm_uuid assert dc_id assert zabbix_sync is not None assert external_zabbix_sync is not None # Create dummy VM object - used just to get zabbix_id and log things vm = Vm(uuid=vm_uuid, hostname=vm_hostname, alias=vm_alias) log.obj = vm.log_list if zabbix_sync or external_zabbix_sync: dc = Dc.objects.get_by_id(dc_id) return get_monitoring(dc).vm_delete(Vm(uuid=vm_uuid, hostname=vm_hostname), internal=zabbix_sync, external=external_zabbix_sync, task_log=log) else: logger.info('Zabbix synchronization completely disabled for VM %s', vm_uuid) return None
def mon_vm_sync(task_id, sender, vm_uuid=None, log=LOG, **kwargs): """ Create or synchronize zabbix host according to VM. """ assert vm_uuid vm = log.obj = Vm.objects.select_related('dc', 'slavevm').get(uuid=vm_uuid) log.dc_id = vm.dc.id if vm.is_slave_vm(): logger.info('Ignoring VM %s zabbix sync, because it is a slave VM', vm) return None if vm.is_deploying(): logger.warn( 'Ignoring VM %s zabbix sync, because it is currently being deployed', vm) return None # This can be also called via vm_zoneid_changed signal, where VM's DC is not available and # monitoring can be disabled in that DC if not vm.dc.settings.MON_ZABBIX_ENABLED: logger.info( 'Skipping VM %s zabbix sync, because zabbix module is completely disabled in DC %s', vm, vm.dc) return None zx = get_monitoring(vm.dc) force_update = kwargs.get('force_update', False) return zx.vm_sync(vm, force_update=force_update, task_log=log)
def mon_template_list(task_id, dc_id, full=False, extended=False, **kwargs): """ Return list of templates available in Zabbix. """ dc = Dc.objects.get_by_id(int(dc_id)) return get_monitoring(dc).template_list(full=full, extended=extended)
def mon_node_status_sync(task_id, sender, node_uuid=None, log=LOG, **kwargs): """ Switch host status in zabbix according to node status. """ assert node_uuid node = log.obj = Node.objects.get(uuid=node_uuid) return get_monitoring(DefaultDc()).node_status_sync(node, task_log=log)
def mon_node_sync(task_id, sender, node_uuid=None, log=LOG, **kwargs): """ Create or synchronize zabbix node host according to compute node. """ assert node_uuid node = log.obj = Node.objects.get(uuid=node_uuid) return get_monitoring(DefaultDc()).node_sync(node, task_log=log)
def mon_action_get(task_id, dc_id, action_name, **kwargs): dc = Dc.objects.get_by_id(int(dc_id)) mon = get_monitoring(dc) try: return mon.action_detail(action_name) except RemoteObjectDoesNotExist as exc: raise MgmtTaskException(exc.detail)
def mon_hostgroup_get(task_id, dc_id, hostgroup_name, dc_bound=True, **kwargs): dc = Dc.objects.get_by_id(int(dc_id)) mon = get_monitoring(dc) try: return mon.hostgroup_detail(hostgroup_name, dc_bound=dc_bound) except RemoteObjectDoesNotExist as exc: raise MgmtTaskException(exc.detail)
def set_mon_zabbix_server_login_error(self): if self._changed_data and 'MON_ZABBIX_SERVER' in self._changed_data: return # Do not set error if setting has changed zx = get_monitoring(self._request.dc) zx_error = zx.ezx.login_error if zx_error: self.set_error('MON_ZABBIX_SERVER', zx_error)
def mon_node_delete(task_id, sender, node_uuid=None, node_hostname=None, log=LOG, **kwargs): """ Remove host from zabbix. """ assert node_uuid # Create dummy node object - used just to get zabbix_id and log things node = Node(uuid=node_uuid, hostname=node_hostname) log.obj = node.log_list return get_monitoring(DefaultDc()).node_delete(node, task_log=log)
def _synchronize_user_on_monitoring_server(dc_name, user): dc = Dc.objects.get_by_name(dc_name) mon = get_monitoring(dc) if not mon.enabled: logger.info('Monitoring is disabled in DC %s', dc) return logger.info('Going to create/update user %s in zabbix %s for dc %s.', user.username, mon, dc) mon.user_sync(user=user)
def _remove_user_from_monitoring_server(dc_name, user_name): dc = Dc.objects.get_by_name(dc_name) mon = get_monitoring(dc) if not mon.enabled: logger.info('Monitoring is disabled in DC %s', dc) return logger.info('Going to delete user with name %s in zabbix %s for dc %s.', user_name, mon, dc) mon.user_delete(name=user_name)
def mon_vm_disable(task_id, sender, vm_uuid=None, log=LOG, **kwargs): """ Switch host status in zabbix to not monitored. """ assert vm_uuid vm = log.obj = Vm.objects.select_related('dc').get(uuid=vm_uuid) if vm.is_zabbix_sync_active() or vm.is_external_zabbix_sync_active(): return get_monitoring(vm.dc).vm_disable(vm, task_log=log) else: logger.info('Zabbix synchronization completely disabled for VM %s', vm) return None
def mon_node_history(task_id, node_uuid, items, zhistory, result, items_search, **kwargs): """ Return node's historical data for selected graph and period. """ try: history = get_monitoring(DefaultDc()).node_history(node_uuid, items, zhistory, result['since'], result['until'], items_search=items_search) except MonitoringError as exc: raise MgmtTaskException(text_type(exc)) result.update(history) return result
def mon_hostgroup_list(task_id, dc_id, dc_bound=True, full=False, extended=False, **kwargs): """ Return list of hostgroups available in Zabbix. """ dc = Dc.objects.get_by_id(int(dc_id)) return get_monitoring(dc).hostgroup_list(dc_bound=dc_bound, full=full, extended=extended)
def mon_node_sla(task_id, node_hostname, yyyymm, since, until, **kwargs): """ Return SLA (%) for compute node / month. """ try: sla = get_monitoring(DefaultDc()).node_sla(node_hostname, since, until) except MonitoringError as exc: raise MgmtTaskException(text_type(exc)) return { 'hostname': node_hostname, 'since': since, 'until': until, 'sla': round(sla, 4), }
def mon_sync_all(task_id, dc_id, clear_cache=True, sync_groups=True, sync_nodes=True, sync_vms=True, **kwargs): """ Clear Zabbix cache and sync everything in Zabbix. Related to a specific DC. Triggered by dc_settings_changed signal. """ dc = Dc.objects.get_by_id(int(dc_id)) if clear_cache: logger.info('Clearing zabbix cache in DC %s', dc) mon_clear_zabbix_cache(dc) get_monitoring(dc) # Cache new Zabbix instance for tasks below if sync_groups: logger.info( 'Running monitoring group synchronization for all user groups in DC %s', dc) mon_all_groups_sync.call(task_id, dc_name=dc.name) if sync_nodes: logger.info( 'Running monitoring host synchronization for all compute nodes') for node in Node.all(): mon_node_sync.call(task_id, node_uuid=node.uuid) if sync_vms: logger.info( 'Running monitoring host synchronization for all VMs in DC %s', dc) for vm_uuid in dc.vm_set.values_list('uuid', flat=True): mon_vm_sync.call(task_id, vm_uuid=vm_uuid)
def mon_action_delete(task_id, dc_id, action_name, action_data=None, **kwargs): dc = Dc.objects.get_by_id(int(dc_id)) mon = get_monitoring(dc) try: result = mon.action_delete(action_name) # Fail loudly if doesnt exist except RemoteObjectDoesNotExist as exc: raise MgmtTaskException(exc.detail) result = mon.action_delete(action_name) # Fail loudly if doesnt exist detail = get_mon_action_detail(MON_OBJ_ACTION, MON_OBJ_DELETED, action_name) mon.task_log_success(task_id, detail=detail, **kwargs['meta']) return result
def mon_node_vm_history(task_id, node_uuid, items, zhistory, result, items_search, **kwargs): """ Return node's historical data for selected graph and period. """ vm_uuids = [vm.uuid for vm in get_mon_vms(node__uuid=node_uuid)] try: history = get_monitoring(DefaultDc()).vms_history(vm_uuids, items, zhistory, result['since'], result['until'], items_search=items_search, skip_nonexistent_items=True) except MonitoringError as exc: raise MgmtTaskException(text_type(exc)) result.update(history) return result
def mon_hostgroup_list(task_id, dc_id, **kwargs): """ Return list of hostgroups available in Zabbix. """ dc = Dc.objects.get_by_id(int(dc_id)) try: zabbix_hostgroups = get_monitoring(dc).hostgroup_list() except MonitoringError as exc: raise MgmtTaskException(text_type(exc)) return [{ 'name': t['name'], 'id': t['groupid'], } for t in zabbix_hostgroups]
def mon_template_list(task_id, dc_id, **kwargs): """ Return list of templates available in Zabbix. """ dc = Dc.objects.get_by_id(int(dc_id)) try: zabbix_templates = get_monitoring(dc).template_list() except MonitoringError as exc: raise MgmtTaskException(text_type(exc)) return [{ 'name': t['host'], 'visible_name': t['name'], 'desc': t['description'], 'id': t['templateid'], } for t in zabbix_templates]
def mon_clear_zabbix_cache(dc, full=True): """ Clear Zabbix instance from global zabbix cache used by get_monitoring() if full==True. Reset internal zabbix instance cache if full==False and the zabbix instance exists in global zabbix cache. Should be reviewed with every new backend implemented. """ if full: if del_monitoring(dc): logger.info( 'Zabbix instance for DC "%s" was successfully removed from global cache', dc) else: logger.info( 'Zabbix instance for DC "%s" was not found in global cache', dc) else: zx = get_monitoring(dc) zx.reset_cache() logger.info('Cleared cache for zabbix instance %s in DC "%s"', zx, dc)
def mon_action_update(task_id, dc_id, action_name, action_data=None, **kwargs): assert action_data is not None dc = Dc.objects.get_by_id(int(dc_id)) mon = get_monitoring(dc) try: result = mon.action_update(action_name, action_data) except RemoteObjectDoesNotExist as exc: raise MgmtTaskException(exc.detail) detail = get_mon_action_detail(MON_OBJ_ACTION, MON_OBJ_UPDATED, action_name) mon.task_log_success(task_id, detail=detail, **kwargs['meta']) for hostgroup_name in result.get('hostgroups_created', []): _log_hostgroup_created(mon, task_id, hostgroup_name) return result
def mon_vm_sla(task_id, vm_hostname, yyyymm, vm_node_history, **kwargs): """ Return SLA (%) for VM / month. """ dc = Dc.objects.get_by_id(int(dc_id_from_task_id(task_id))) try: sla = get_monitoring(dc).vm_sla(vm_node_history) except MonitoringError as exc: raise MgmtTaskException(text_type(exc)) result = { 'hostname': vm_hostname, 'since': vm_node_history[0]['since'], 'until': vm_node_history[-1]['till'], 'sla': round(sla, 4), } return result
def mon_hostgroup_create(task_id, dc_id, hostgroup_name, dc_bound=True, **kwargs): dc = Dc.objects.get_by_id(int(dc_id)) mon = get_monitoring(dc) try: result = mon.hostgroup_create(hostgroup_name, dc_bound=dc_bound) except RemoteObjectAlreadyExists as exc: raise MgmtTaskException(exc.detail) detail = 'Monitoring hostgroup "%s" was successfully created' % hostgroup_name mon.task_log_success(task_id, obj=mon.server_class(dc), detail=detail, **kwargs['meta']) return result
def mon_vm_history(task_id, vm_uuid, items, zhistory, result, items_search, **kwargs): """ Return server history data for selected graph and period. """ dc = Dc.objects.get_by_id(int(dc_id_from_task_id(task_id))) try: history = get_monitoring(dc).vm_history(vm_uuid, items, zhistory, result['since'], result['until'], items_search=items_search) except MonitoringError as exc: raise MgmtTaskException(text_type(exc)) result.update(history) return result
def _synchronize_user_on_group_related_monitoring_servers(task_id, user, affected_groups): logger.info('Going to create/update user %s in zabbixes related to groups %s.', user.username, affected_groups) for dc in Dc.objects.filter(roles__in=affected_groups): mon = get_monitoring(dc) if not mon.enabled: logger.info('Monitoring is disabled in DC %s', dc) continue try: res = mon.user_sync(user=user) except MonitoringError as exc: logger.exception(exc) # we will let it try again in a separate task and not crash this one logger.error('Creating a separate task for dc %s and user %s because it crashed.', dc.name, user.username) mon_user_changed.call(task_id, user_name=user.username, dc_name=dc.name) else: _log_mon_user_action(res, mon, task_id, user.username, dc.name)
def _remove_user_from_all_monitoring_servers(task_id, user_name): logger.info('As we don\'t know where does the user %s belonged to, ' 'we are trying to delete it from all available zabbixes.', user_name) for dc in Dc.objects.all(): # Nasty mon = get_monitoring(dc) if not mon.enabled: logger.info('Monitoring is disabled in DC %s', dc) continue try: res = mon.user_delete(name=user_name) except MonitoringError as exc: logger.exception(exc) # we will let it try again in a separate task and not crash this one logger.error('Creating a separate task for dc %s and user %s because it crashed.', dc.name, user_name) mon_user_changed.call(task_id, user_name=user_name, dc_name=dc.name) else: _log_mon_user_action(res, mon, task_id, user_name, dc.name)
def mon_vm_sync(task_id, sender, vm_uuid=None, log=LOG, **kwargs): """ Create or synchronize zabbix host according to VM. """ assert vm_uuid vm = log.obj = Vm.objects.select_related('dc', 'slavevm').get(uuid=vm_uuid) log.dc_id = vm.dc.id if vm.is_slave_vm(): logger.info('Ignoring VM %s zabbix sync, because it is a slave VM', vm) return None if vm.is_deploying(): logger.warn( 'Ignoring VM %s zabbix sync, because it is currently being deployed', vm) return None zx = get_monitoring(vm.dc) force_update = kwargs.get('force_update', False) return zx.vm_sync(vm, force_update=force_update, task_log=log)
def _user_changed(user_name, dc_name, affected_groups): try: user = User.objects.get(username=user_name) except User.DoesNotExist: if dc_name: dc = Dc.objects.get_by_name(dc_name) zabbix = get_monitoring(dc) logger.debug( 'Going to delete user with name %s in zabbix %s for dc %s.', user_name, zabbix, dc) zabbix.delete_user(name=user_name) elif affected_groups: logger.debug( 'Going to delete user with name %s ' 'from zabbixes related to groups %s.', user_name, affected_groups) for dc in Dc.objects.filter(roles__in=affected_groups): zabbix = get_monitoring(dc) try: zabbix.delete_user(name=user_name) except (ZabbixAPIException, MonitoringError): # we will let it try again in a separate task and not crash this one logger.exception( "Creating a separate task for dc %s and user %s because it crashed.", dc.name, user_name) mon_user_changed.call(sender='parent mon_user_changed', user_name=user_name, dc_name=dc.name) else: logger.debug( 'As we don\'t know where does the user %s belonged to, ' 'we are trying to delete it from all available zabbixes.', user_name) for dc in Dc.objects.all(): # Nasty zabbix = get_monitoring(dc) try: zabbix.delete_user(name=user_name) except (ZabbixAPIException, MonitoringError): # we will let it try again in a separate task and not crash this one logger.exception( "Creating a separate task for dc %s and user %s because it crashed.", dc.name, user_name) mon_user_changed.call(sender='parent mon_user_changed', user_name=user_name, dc_name=dc.name) else: if dc_name: dc = Dc.objects.get_by_name(dc_name) zabbix = get_monitoring(dc) logger.debug( 'Going to create/update user %s in zabbix %s for dc %s.', user_name, zabbix, dc) zabbix.synchronize_user(user=user) elif affected_groups: logger.debug( 'Going to create/update user %s in zabbixes related to groups %s.', user_name, affected_groups) for dc in Dc.objects.filter(roles__in=affected_groups): zabbix = get_monitoring(dc) try: zabbix.synchronize_user(user=user) except (ZabbixAPIException, MonitoringError): # we will let it try again in a separate task and not crash this one logger.exception( "Creating a separate task for dc %s and user %s because it crashed.", dc.name, user_name) mon_user_changed.call(sender='parent mon_user_changed', user_name=user_name, dc_name=dc.name) else: logger.debug( 'Going to create/update user %s ' 'in zabbixes related to all groups to which the user is related to.', user_name) for dc in Dc.objects.filter(roles__user=user): zabbix = get_monitoring(dc) try: zabbix.synchronize_user(user=user) except (ZabbixAPIException, MonitoringError): # we will let it try again in a separate task and not crash this one logger.exception( "Creating a separate task for dc %s and user %s because it crashed.", dc.name, user_name) mon_user_changed.call(sender='parent mon_user_changed', user_name=user_name, dc_name=dc.name)
def _user_group_changed(group_name, dc_name): if dc_name and group_name: # Particular group under dc changed dc = Dc.objects.get_by_name(dc_name) zabbix = get_monitoring(dc) try: group = Role.objects.get(dc=dc, name=group_name) except Role.DoesNotExist: logger.debug('Going to delete %s from %s.', group_name, dc.name) zabbix.delete_user_group(name=group_name) else: logger.debug('Going to update %s from %s.', group.name, dc.name) zabbix.synchronize_user_group(group=group) elif dc_name: # Something about dc changed try: dc = Dc.objects.get_by_name(dc_name) except Dc.DoesNotExist: raise NotImplementedError( 'TODO DC deletion hook is not implemented') # When DC is deleted, we lose the access to the zabbix and therefore we don't know what to do # We have to provide information about zabbix connection so that we can delete related information in zabbix else: zabbix = get_monitoring(dc) zabbix.synchronize_user_group( dc_as_group=True) # DC name is implied by the zabbix instance elif group_name: # A group under unknown dc changed # This is an expensive operation, but not called often try: group = Role.objects.get(name=group_name) except Role.DoesNotExist: # group does not exist-> remove from all dcs as we don't know where it was for dc in Dc.objects.all(): logger.debug('Going to delete %s from %s.', group_name, dc.name) zabbix = get_monitoring(dc) try: zabbix.delete_user_group(name=group_name) except (ZabbixAPIException, MonitoringError): # we will let it try again in a separate task and not crash this one logger.exception( "Creating a separate task for dc %s and group %s because it crashed.", dc.name, group_name) mon_user_group_changed.call( sender='parent mon_user_group_changed', group_name=group_name, dc_name=dc.name) else: related_dcs = Dc.objects.filter(roles=group) unrelated_dcs = Dc.objects.exclude(id__in=related_dcs) for dc in related_dcs: logger.debug('Going to update %s from %s.', group.name, dc.name) zabbix = get_monitoring(dc) try: zabbix.synchronize_user_group(group=group) except (ZabbixAPIException, MonitoringError): # we will let it try again in a separate task and not crash this one logger.exception( "Creating a separate task for dc %s and group %s because it crashed.", dc.name, group_name) mon_user_group_changed.call( sender='parent mon_user_group_changed', group_name=group_name, dc_name=dc.name) for dc in unrelated_dcs: # TODO this is quite expensive and I would like to avoid this somehow logger.debug('Going to delete %s from %s.', group.name, dc.name) zabbix = get_monitoring(dc) try: zabbix.delete_user_group(name=group_name) except (ZabbixAPIException, MonitoringError): # we will let it try again in a separate task and not crash this one logger.exception( "Creating a separate task for dc %s and group %s because it crashed.", dc.name, group_name) mon_user_group_changed.call( sender='parent mon_user_group_changed', group_name=group_name, dc_name=dc.name) else: raise AssertionError('Either group name or dc name has to be defined.')