121 lines
5.3 KiB
Python
121 lines
5.3 KiB
Python
# Copyright (c) 2015 Ansible, Inc.
|
|
# All Rights Reserved.
|
|
|
|
# Tower
|
|
from awx.api.versioning import reverse
|
|
from awx.main.fields import JSONField
|
|
from awx.main.models.base import accepts_json
|
|
|
|
# Django
|
|
from django.db import models
|
|
from django.conf import settings
|
|
from django.utils.encoding import smart_str
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
__all__ = ['ActivityStream']
|
|
|
|
|
|
class ActivityStream(models.Model):
|
|
'''
|
|
Model used to describe activity stream (audit) events
|
|
'''
|
|
|
|
class Meta:
|
|
app_label = 'main'
|
|
ordering = ('pk',)
|
|
|
|
OPERATION_CHOICES = [
|
|
('create', _('Entity Created')),
|
|
('update', _("Entity Updated")),
|
|
('delete', _("Entity Deleted")),
|
|
('associate', _("Entity Associated with another Entity")),
|
|
('disassociate', _("Entity was Disassociated with another Entity"))
|
|
]
|
|
|
|
actor = models.ForeignKey('auth.User', null=True, on_delete=models.SET_NULL, related_name='activity_stream')
|
|
operation = models.CharField(max_length=13, choices=OPERATION_CHOICES)
|
|
timestamp = models.DateTimeField(auto_now_add=True)
|
|
changes = accepts_json(models.TextField(blank=True))
|
|
deleted_actor = JSONField(null=True)
|
|
action_node = models.CharField(
|
|
blank=True,
|
|
default='',
|
|
editable=False,
|
|
max_length=512,
|
|
help_text=_("The cluster node the activity took place on."),
|
|
)
|
|
|
|
object_relationship_type = models.TextField(blank=True)
|
|
object1 = models.TextField()
|
|
object2 = models.TextField()
|
|
|
|
user = models.ManyToManyField("auth.User", blank=True)
|
|
organization = models.ManyToManyField("Organization", blank=True)
|
|
inventory = models.ManyToManyField("Inventory", blank=True)
|
|
host = models.ManyToManyField("Host", blank=True)
|
|
group = models.ManyToManyField("Group", blank=True)
|
|
inventory_source = models.ManyToManyField("InventorySource", blank=True)
|
|
inventory_update = models.ManyToManyField("InventoryUpdate", blank=True)
|
|
credential = models.ManyToManyField("Credential", blank=True)
|
|
credential_type = models.ManyToManyField("CredentialType", blank=True)
|
|
team = models.ManyToManyField("Team", blank=True)
|
|
project = models.ManyToManyField("Project", blank=True)
|
|
project_update = models.ManyToManyField("ProjectUpdate", blank=True)
|
|
job_template = models.ManyToManyField("JobTemplate", blank=True)
|
|
job = models.ManyToManyField("Job", blank=True)
|
|
workflow_job_template_node = models.ManyToManyField("WorkflowJobTemplateNode", blank=True)
|
|
workflow_job_node = models.ManyToManyField("WorkflowJobNode", blank=True)
|
|
workflow_job_template = models.ManyToManyField("WorkflowJobTemplate", blank=True)
|
|
workflow_job = models.ManyToManyField("WorkflowJob", blank=True)
|
|
workflow_approval_template = models.ManyToManyField("WorkflowApprovalTemplate", blank=True)
|
|
workflow_approval = models.ManyToManyField("WorkflowApproval", blank=True)
|
|
unified_job_template = models.ManyToManyField("UnifiedJobTemplate", blank=True, related_name='activity_stream_as_unified_job_template+')
|
|
unified_job = models.ManyToManyField("UnifiedJob", blank=True, related_name='activity_stream_as_unified_job+')
|
|
ad_hoc_command = models.ManyToManyField("AdHocCommand", blank=True)
|
|
schedule = models.ManyToManyField("Schedule", blank=True)
|
|
custom_inventory_script = models.ManyToManyField("CustomInventoryScript", blank=True)
|
|
notification_template = models.ManyToManyField("NotificationTemplate", blank=True)
|
|
notification = models.ManyToManyField("Notification", blank=True)
|
|
label = models.ManyToManyField("Label", blank=True)
|
|
role = models.ManyToManyField("Role", blank=True)
|
|
instance = models.ManyToManyField("Instance", blank=True)
|
|
instance_group = models.ManyToManyField("InstanceGroup", blank=True)
|
|
o_auth2_application = models.ManyToManyField("OAuth2Application", blank=True)
|
|
o_auth2_access_token = models.ManyToManyField("OAuth2AccessToken", blank=True)
|
|
|
|
|
|
|
|
setting = JSONField(blank=True)
|
|
|
|
def __str__(self):
|
|
operation = self.operation if 'operation' in self.__dict__ else '_delayed_'
|
|
if 'timestamp' in self.__dict__:
|
|
if self.timestamp:
|
|
timestamp = self.timestamp.isoformat()
|
|
else:
|
|
timestamp = self.timestamp
|
|
else:
|
|
timestamp = '_delayed_'
|
|
return u'%s-%s-pk=%s' % (operation, timestamp, self.pk)
|
|
|
|
def get_absolute_url(self, request=None):
|
|
return reverse('api:activity_stream_detail', kwargs={'pk': self.pk}, request=request)
|
|
|
|
def save(self, *args, **kwargs):
|
|
# Store denormalized actor metadata so that we retain it for accounting
|
|
# purposes when the User row is deleted.
|
|
if self.actor:
|
|
self.deleted_actor = {
|
|
'id': self.actor_id,
|
|
'username': smart_str(self.actor.username),
|
|
'first_name': smart_str(self.actor.first_name),
|
|
'last_name': smart_str(self.actor.last_name),
|
|
}
|
|
if 'update_fields' in kwargs and 'deleted_actor' not in kwargs['update_fields']:
|
|
kwargs['update_fields'].append('deleted_actor')
|
|
|
|
hostname_char_limit = self._meta.get_field('action_node').max_length
|
|
self.action_node = settings.CLUSTER_HOST_ID[:hostname_char_limit]
|
|
|
|
super(ActivityStream, self).save(*args, **kwargs)
|