def activity_stream_delete(sender, instance, **kwargs): if not activity_stream_enabled: return # Inventory delete happens in the task system rather than request-response-cycle. # If we trigger this handler there we may fall into db-integrity-related race conditions. # So we add flag verification to prevent normal signal handling. This funciton will be # explicitly called with flag on in Inventory.schedule_deletion. changes = {} if isinstance(instance, Inventory): if not kwargs.get('inventory_delete_flag', False): return # Add additional data about child hosts / groups that will be deleted changes['coalesced_data'] = { 'hosts_deleted': instance.hosts.count(), 'groups_deleted': instance.groups.count() } elif isinstance(instance, (Host, Group)) and instance.inventory.pending_deletion: return # accounted for by inventory entry, above _type = type(instance) if getattr(_type, '_deferred', False): return changes.update(model_to_dict(instance, model_serializer_mapping())) object1 = camelcase_to_underscore(instance.__class__.__name__) if type(instance) == OAuth2AccessToken: changes['token'] = CENSOR_VALUE activity_entry = get_activity_stream_class()( operation='delete', changes=json.dumps(changes), object1=object1, actor=get_current_user_or_none()) activity_entry.save() connection.on_commit(lambda: emit_activity_stream_change(activity_entry))
def activity_stream_create(sender, instance, created, **kwargs): if created and activity_stream_enabled: # TODO: remove deprecated_group conditional in 3.3 # Skip recording any inventory source directly associated with a group. if isinstance(instance, InventorySource) and instance.deprecated_group: return _type = type(instance) if getattr(_type, '_deferred', False): return object1 = camelcase_to_underscore(instance.__class__.__name__) changes = model_to_dict(instance, model_serializer_mapping) # Special case where Job survey password variables need to be hidden if type(instance) == Job: if 'extra_vars' in changes: changes['extra_vars'] = instance.display_extra_vars() if type(instance) == OAuth2AccessToken: changes['token'] = '*************' activity_entry = ActivityStream(operation='create', object1=object1, changes=json.dumps(changes), actor=get_current_user_or_none()) #TODO: Weird situation where cascade SETNULL doesn't work # it might actually be a good idea to remove all of these FK references since # we don't really use them anyway. if instance._meta.model_name != 'setting': # Is not conf.Setting instance activity_entry.save() getattr(activity_entry, object1).add(instance) else: activity_entry.setting = conf_to_dict(instance) activity_entry.save()
def activity_stream_create(sender, instance, created, **kwargs): if created and activity_stream_enabled: _type = type(instance) if getattr(_type, '_deferred', False): return object1 = camelcase_to_underscore(instance.__class__.__name__) changes = model_to_dict(instance, model_serializer_mapping()) # Special case where Job survey password variables need to be hidden if type(instance) == Job: changes['credentials'] = ['{} ({})'.format(c.name, c.id) for c in instance.credentials.iterator()] changes['labels'] = [label.name for label in instance.labels.iterator()] if 'extra_vars' in changes: changes['extra_vars'] = instance.display_extra_vars() if type(instance) == OAuth2AccessToken: changes['token'] = CENSOR_VALUE activity_entry = get_activity_stream_class()(operation='create', object1=object1, changes=json.dumps(changes), actor=get_current_user_or_none()) # TODO: Weird situation where cascade SETNULL doesn't work # it might actually be a good idea to remove all of these FK references since # we don't really use them anyway. if instance._meta.model_name != 'setting': # Is not conf.Setting instance activity_entry.save() getattr(activity_entry, object1).add(instance.pk) else: activity_entry.setting = conf_to_dict(instance) activity_entry.save() connection.on_commit(lambda: emit_activity_stream_change(activity_entry))
def activity_stream_delete(sender, instance, **kwargs): if not activity_stream_enabled: return # TODO: remove deprecated_group conditional in 3.3 # Skip recording any inventory source directly associated with a group. if isinstance(instance, InventorySource) and instance.deprecated_group: return # Inventory delete happens in the task system rather than request-response-cycle. # If we trigger this handler there we may fall into db-integrity-related race conditions. # So we add flag verification to prevent normal signal handling. This funciton will be # explicitly called with flag on in Inventory.schedule_deletion. if isinstance(instance, Inventory) and not kwargs.get( 'inventory_delete_flag', False): return _type = type(instance) if getattr(_type, '_deferred', False): return changes = model_to_dict(instance) object1 = camelcase_to_underscore(instance.__class__.__name__) if type(instance) == OAuth2AccessToken: changes['token'] = TOKEN_CENSOR activity_entry = ActivityStream(operation='delete', changes=json.dumps(changes), object1=object1, actor=get_current_user_or_none()) activity_entry.save()
def test_missing_related_on_delete(inventory_source): old_is = InventorySource.objects.get(name=inventory_source.name) inventory_source.inventory.delete() d = model_to_dict(old_is, serializer_mapping=model_serializer_mapping) assert d['inventory'] == '<missing inventory source>-{}'.format( old_is.inventory_id)