AC-1040 Removed extra model definitions used for generating migrations.

This commit is contained in:
Chris Church 2014-03-25 09:38:25 -04:00
parent 871b89ab28
commit 296e87a632
8 changed files with 164 additions and 1264 deletions

View File

@ -14,43 +14,42 @@ from awx.main.models.jobs import *
from awx.main.models.schedules import *
from awx.main.models.activity_stream import *
if getattr(settings, 'UNIFIED_JOBS_STEP') in (0, 2):
# Monkeypatch Django serializer to ignore django-taggit fields (which break
# the dumpdata command; see https://github.com/alex/django-taggit/issues/155).
from django.core.serializers.python import Serializer as _PythonSerializer
_original_handle_m2m_field = _PythonSerializer.handle_m2m_field
def _new_handle_m2m_field(self, obj, field):
try:
field.rel.through._meta
except AttributeError:
return
return _original_handle_m2m_field(self, obj, field)
_PythonSerializer.handle_m2m_field = _new_handle_m2m_field
# Monkeypatch Django serializer to ignore django-taggit fields (which break
# the dumpdata command; see https://github.com/alex/django-taggit/issues/155).
from django.core.serializers.python import Serializer as _PythonSerializer
_original_handle_m2m_field = _PythonSerializer.handle_m2m_field
def _new_handle_m2m_field(self, obj, field):
try:
field.rel.through._meta
except AttributeError:
return
return _original_handle_m2m_field(self, obj, field)
_PythonSerializer.handle_m2m_field = _new_handle_m2m_field
# Add custom methods to User model for permissions checks.
from django.contrib.auth.models import User
from awx.main.access import *
User.add_to_class('get_queryset', get_user_queryset)
User.add_to_class('can_access', check_user_access)
# Add custom methods to User model for permissions checks.
from django.contrib.auth.models import User
from awx.main.access import *
User.add_to_class('get_queryset', get_user_queryset)
User.add_to_class('can_access', check_user_access)
# Import signal handlers only after models have been defined.
import awx.main.signals
# Import signal handlers only after models have been defined.
import awx.main.signals
from awx.main.registrar import activity_stream_registrar
activity_stream_registrar.connect(Organization)
activity_stream_registrar.connect(Inventory)
activity_stream_registrar.connect(Host)
activity_stream_registrar.connect(Group)
activity_stream_registrar.connect(InventorySource)
#activity_stream_registrar.connect(InventoryUpdate)
activity_stream_registrar.connect(Credential)
activity_stream_registrar.connect(Team)
activity_stream_registrar.connect(Project)
#activity_stream_registrar.connect(ProjectUpdate)
activity_stream_registrar.connect(Permission)
activity_stream_registrar.connect(JobTemplate)
activity_stream_registrar.connect(Job)
# activity_stream_registrar.connect(JobHostSummary)
# activity_stream_registrar.connect(JobEvent)
#activity_stream_registrar.connect(Profile)
activity_stream_registrar.connect(Schedule)
from awx.main.registrar import activity_stream_registrar
activity_stream_registrar.connect(Organization)
activity_stream_registrar.connect(Inventory)
activity_stream_registrar.connect(Host)
activity_stream_registrar.connect(Group)
activity_stream_registrar.connect(InventorySource)
#activity_stream_registrar.connect(InventoryUpdate)
activity_stream_registrar.connect(Credential)
activity_stream_registrar.connect(Team)
activity_stream_registrar.connect(Project)
#activity_stream_registrar.connect(ProjectUpdate)
activity_stream_registrar.connect(Permission)
activity_stream_registrar.connect(JobTemplate)
activity_stream_registrar.connect(Job)
# activity_stream_registrar.connect(JobHostSummary)
# activity_stream_registrar.connect(JobEvent)
#activity_stream_registrar.connect(Profile)
activity_stream_registrar.connect(Schedule)

View File

@ -10,13 +10,12 @@ from django.utils.translation import ugettext_lazy as _
__all__ = ['ActivityStream']
class ActivityStreamBase(models.Model):
class ActivityStream(models.Model):
'''
Model used to describe activity stream (audit) events
'''
class Meta:
abstract = True
app_label = 'main'
OPERATION_CHOICES = [
@ -41,15 +40,17 @@ class ActivityStreamBase(models.Model):
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)
inventory_source = models.ManyToManyField("InventorySource", blank=True)
inventory_update = models.ManyToManyField("InventoryUpdate", blank=True)
credential = models.ManyToManyField("Credential", blank=True)
team = models.ManyToManyField("Team", blank=True)
#project = models.ManyToManyField("Project", blank=True)
#project_update = models.ManyToManyField("ProjectUpdate", blank=True)
project = models.ManyToManyField("Project", blank=True)
project_update = models.ManyToManyField("ProjectUpdate", blank=True)
permission = models.ManyToManyField("Permission", blank=True)
#job_template = models.ManyToManyField("JobTemplate", blank=True)
#job = models.ManyToManyField("Job", blank=True)
job_template = models.ManyToManyField("JobTemplate", blank=True)
job = models.ManyToManyField("Job", 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+')
schedule = models.ManyToManyField("Schedule", blank=True)
def get_absolute_url(self):
@ -59,68 +60,9 @@ class ActivityStreamBase(models.Model):
# For compatibility with Django 1.4.x, attempt to handle any calls to
# save that pass update_fields.
try:
super(ActivityStreamBase, self).save(*args, **kwargs)
super(ActivityStream, self).save(*args, **kwargs)
except TypeError:
if 'update_fields' not in kwargs:
raise
kwargs.pop('update_fields')
super(ActivityStreamBase, self).save(*args, **kwargs)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class ActivityStream(ActivityStreamBase):
class Meta:
app_label = 'main'
inventory_source = models.ManyToManyField("InventorySource", blank=True)
inventory_update = models.ManyToManyField("InventoryUpdate", 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)
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+')
new_inventory_source = models.ManyToManyField("InventorySourceNew", blank=True)
new_inventory_update = models.ManyToManyField("InventoryUpdateNew", blank=True)
new_project = models.ManyToManyField("ProjectNew", blank=True)
new_project_update = models.ManyToManyField("ProjectUpdateNew", blank=True)
new_job_template = models.ManyToManyField("JobTemplateNew", blank=True)
new_job = models.ManyToManyField("JobNew", blank=True)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class ActivityStream(ActivityStreamBase):
class Meta:
app_label = 'main'
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+')
new_inventory_source = models.ManyToManyField("InventorySourceNew", blank=True)
new_inventory_update = models.ManyToManyField("InventoryUpdateNew", blank=True)
new_project = models.ManyToManyField("ProjectNew", blank=True)
new_project_update = models.ManyToManyField("ProjectUpdateNew", blank=True)
new_job_template = models.ManyToManyField("JobTemplateNew", blank=True)
new_job = models.ManyToManyField("JobNew", blank=True)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class ActivityStream(ActivityStreamBase):
class Meta:
app_label = 'main'
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+')
inventory_source = models.ManyToManyField("InventorySource", blank=True)
inventory_update = models.ManyToManyField("InventoryUpdate", 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)
super(ActivityStream, self).save(*args, **kwargs)

View File

@ -277,234 +277,7 @@ class CommonModelNameNotUnique(PrimordialModel):
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class CommonTask(PrimordialModel):
class CommonTask(PrimordialModel):
'''
Common fields for models run by the task engine.
'''
class Meta:
app_label = 'main'
abstract = True
cancel_flag = models.BooleanField(
blank=True,
default=False,
editable=False,
)
status = models.CharField(
max_length=20,
choices=TASK_STATUS_CHOICES,
default='new',
editable=False,
)
failed = models.BooleanField(
default=False,
editable=False,
)
job_args = models.TextField(
blank=True,
default='',
editable=False,
)
job_cwd = models.CharField(
max_length=1024,
blank=True,
default='',
editable=False,
)
job_env = JSONField(
blank=True,
default={},
editable=False,
)
start_args = models.TextField(
blank=True,
default='',
editable=False,
)
_result_stdout = models.TextField(
blank=True,
default='',
editable=False,
db_column="result_stdout",
)
result_stdout_file = models.TextField(
blank=True,
default='',
editable=False,
)
result_traceback = models.TextField(
blank=True,
default='',
editable=False,
)
celery_task_id = models.CharField(
max_length=100,
blank=True,
default='',
editable=False,
)
def __unicode__(self):
return u'%s-%s-%s' % (self.created, self.id, self.status)
def _get_parent_instance(self):
return None
def _update_parent_instance(self):
parent_instance = self._get_parent_instance()
if parent_instance:
if self.status in ('pending', 'waiting', 'running'):
if parent_instance.current_update != self:
parent_instance.current_update = self
parent_instance.save(update_fields=['current_update'])
elif self.status in ('successful', 'failed', 'error', 'canceled'):
if parent_instance.current_update == self:
parent_instance.current_update = None
parent_instance.last_update = self
parent_instance.last_update_failed = self.failed
parent_instance.save(update_fields=['current_update',
'last_update',
'last_update_failed'])
def save(self, *args, **kwargs):
# Get status before save...
status_before = self.status or 'new'
if self.pk:
self_before = self.__class__.objects.get(pk=self.pk)
if self_before.status != self.status:
status_before = self_before.status
self.failed = bool(self.status in ('failed', 'error', 'canceled'))
super(CommonTask, self).save(*args, **kwargs)
# If status changed, update parent instance....
if self.status != status_before:
self._update_parent_instance()
def delete(self):
if self.result_stdout_file != "":
try:
os.remove(self.result_stdout_file)
except Exception, e:
pass
super(CommonTask, self).delete()
@property
def result_stdout(self):
if self.result_stdout_file != "":
if not os.path.exists(self.result_stdout_file):
return "stdout capture is missing"
stdout_fd = open(self.result_stdout_file, "r")
output = stdout_fd.read()
stdout_fd.close()
return output
return self._result_stdout
@property
def celery_task(self):
try:
if self.celery_task_id:
return TaskMeta.objects.get(task_id=self.celery_task_id)
except TaskMeta.DoesNotExist:
pass
@property
def can_start(self):
return bool(self.status in ('new', 'waiting'))
@property
def task_impact(self):
raise NotImplementedError
def _get_task_class(self):
raise NotImplementedError
def _get_passwords_needed_to_start(self):
return []
def is_blocked_by(self, task_object):
''' Given another task object determine if this task would be blocked by it '''
raise NotImplementedError
def generate_dependencies(self, active_tasks):
''' Generate any tasks that the current task might be dependent on given a list of active
tasks that might preclude creating one'''
return []
def signal_start(self):
''' Notify the task runner system to begin work on this task '''
raise NotImplementedError
def start(self, error_callback, **kwargs):
task_class = self._get_task_class()
if not self.status == 'waiting':
return False
needed = self._get_passwords_needed_to_start()
try:
stored_args = json.loads(decrypt_field(self, 'start_args'))
except Exception, e:
stored_args = None
if stored_args is None or stored_args == '':
opts = dict([(field, kwargs.get(field, '')) for field in needed])
else:
opts = dict([(field, stored_args.get(field, '')) for field in needed])
if not all(opts.values()):
return False
task_class().apply_async((self.pk,), opts, link_error=error_callback)
return True
@property
def can_cancel(self):
return bool(self.status in ('pending', 'waiting', 'running'))
def _force_cancel(self):
# Update the status to 'canceled' if we can detect that the job
# really isn't running (i.e. celery has crashed or forcefully
# killed the worker).
task_statuses = ('STARTED', 'SUCCESS', 'FAILED', 'RETRY', 'REVOKED')
try:
taskmeta = self.celery_task
if not taskmeta or taskmeta.status not in task_statuses:
return
from celery import current_app
i = current_app.control.inspect()
for v in (i.active() or {}).values():
if taskmeta.task_id in [x['id'] for x in v]:
return
for v in (i.reserved() or {}).values():
if taskmeta.task_id in [x['id'] for x in v]:
return
for v in (i.revoked() or {}).values():
if taskmeta.task_id in [x['id'] for x in v]:
return
for v in (i.scheduled() or {}).values():
if taskmeta.task_id in [x['id'] for x in v]:
return
instance = self.__class__.objects.get(pk=self.pk)
if instance.can_cancel:
instance.status = 'canceled'
update_fields = ['status']
if not instance.result_traceback:
instance.result_traceback = 'Forced cancel'
update_fields.append('result_traceback')
instance.save(update_fields=update_fields)
except: # FIXME: Log this exception!
if settings.DEBUG:
raise
def cancel(self):
if self.can_cancel:
if not self.cancel_flag:
self.cancel_flag = True
self.save(update_fields=['cancel_flag'])
if settings.BROKER_URL.startswith('amqp://'):
self._force_cancel()
return self.cancel_flag
else:
class CommonTask(PrimordialModel):
class Meta:
abstract = True
class Meta:
abstract = True

View File

@ -160,13 +160,12 @@ class Inventory(CommonModel):
return self.groups.exclude(parents__pk__in=group_pks).distinct()
class HostBase(CommonModelNameNotUnique):
class Host(CommonModelNameNotUnique):
'''
A managed node
'''
class Meta:
abstract = True
app_label = 'main'
unique_together = (("name", "inventory"),) # FIXME: Add ('instance_id', 'inventory') after migration.
@ -189,15 +188,14 @@ class HostBase(CommonModelNameNotUnique):
default='',
help_text=_('Host variables in JSON or YAML format.'),
)
#last_job = models.ForeignKey(
# 'Job',
# related_name='hosts_as_last_job+',
# blank=True,
# null=True,
# default=None,
# editable=False,
# on_delete=models.SET_NULL,
#)
last_job = models.ForeignKey(
'Job',
related_name='hosts_as_last_job+',
null=True,
default=None,
editable=False,
on_delete=models.SET_NULL,
)
last_job_host_summary = models.ForeignKey(
'JobHostSummary',
related_name='hosts_as_last_job_summary+',
@ -217,13 +215,12 @@ class HostBase(CommonModelNameNotUnique):
editable=False,
help_text=_('Flag indicating whether this host was created/updated from any external inventory sources.'),
)
#inventory_sources = models.ManyToManyField(
# 'InventorySource',
# related_name='hosts',
# blank=True,
# editable=False,
# help_text=_('Inventory source(s) that created or modified this host.'),
#)
inventory_sources = models.ManyToManyField(
'InventorySource',
related_name='hosts',
editable=False,
help_text=_('Inventory source(s) that created or modified this host.'),
)
def __unicode__(self):
return self.name
@ -236,7 +233,7 @@ class HostBase(CommonModelNameNotUnique):
When marking hosts inactive, remove all associations to related
inventory sources.
'''
super(HostBase, self).mark_inactive(save=save)
super(Host, self).mark_inactive(save=save)
self.inventory_sources.clear()
def update_computed_fields(self, update_inventory=True, update_groups=True):
@ -285,98 +282,13 @@ class HostBase(CommonModelNameNotUnique):
# Use .job_events.all() to get events affecting this host.
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class Host(HostBase):
class Meta:
app_label = 'main'
unique_together = (("name", "inventory"),)
last_job = models.ForeignKey(
'Job',
related_name='hosts_as_last_job+',
null=True,
default=None,
editable=False,
on_delete=models.SET_NULL,
)
new_last_job = models.ForeignKey(
'JobNew',
related_name='hosts_as_last_job+',
null=True,
default=None,
editable=False,
on_delete=models.SET_NULL,
)
inventory_sources = models.ManyToManyField(
'InventorySource',
related_name='hosts',
editable=False,
help_text=_('Inventory source(s) that created or modified this host.'),
)
new_inventory_sources = models.ManyToManyField(
'InventorySourceNew',
related_name='hosts',
editable=False,
help_text=_('Inventory source(s) that created or modified this host.'),
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class Host(HostBase):
class Meta:
app_label = 'main'
unique_together = (("name", "inventory"),)
new_last_job = models.ForeignKey(
'JobNew',
related_name='hosts_as_last_job+',
null=True,
default=None,
editable=False,
on_delete=models.SET_NULL,
)
new_inventory_sources = models.ManyToManyField(
'InventorySourceNew',
related_name='hosts',
editable=False,
help_text=_('Inventory source(s) that created or modified this host.'),
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class Host(HostBase):
class Meta:
app_label = 'main'
unique_together = (("name", "inventory"),)
last_job = models.ForeignKey(
'Job',
related_name='hosts_as_last_job+',
null=True,
default=None,
editable=False,
on_delete=models.SET_NULL,
)
inventory_sources = models.ManyToManyField(
'InventorySource',
related_name='hosts',
editable=False,
help_text=_('Inventory source(s) that created or modified this host.'),
)
class GroupBase(CommonModelNameNotUnique):
class Group(CommonModelNameNotUnique):
'''
A group containing managed hosts. A group or host may belong to multiple
groups.
'''
class Meta:
abstract = True
app_label = 'main'
unique_together = (("name", "inventory"),)
@ -433,13 +345,12 @@ class GroupBase(CommonModelNameNotUnique):
editable=False,
help_text=_('Flag indicating whether this group was created/updated from any external inventory sources.'),
)
#inventory_sources = models.ManyToManyField(
# 'InventorySource',
# related_name='groups',
# blank=True,
# editable=False,
# help_text=_('Inventory source(s) that created or modified this group.'),
#)
inventory_sources = models.ManyToManyField(
'InventorySource',
related_name='groups',
editable=False,
help_text=_('Inventory source(s) that created or modified this group.'),
)
def __unicode__(self):
return self.name
@ -453,7 +364,7 @@ class GroupBase(CommonModelNameNotUnique):
groups/hosts/inventory_sources.
'''
def mark_actual():
super(GroupBase, self).mark_inactive(save=save)
super(Group, self).mark_inactive(save=save)
self.inventory_source.mark_inactive(save=save)
self.inventory_sources.clear()
self.parents.clear()
@ -560,59 +471,6 @@ class GroupBase(CommonModelNameNotUnique):
return JobEvent.objects.filter(host__in=self.all_hosts)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class Group(GroupBase):
class Meta:
app_label = 'main'
unique_together = (("name", "inventory"),)
inventory_sources = models.ManyToManyField(
'InventorySource',
related_name='groups',
editable=False,
help_text=_('Inventory source(s) that created or modified this group.'),
)
new_inventory_sources = models.ManyToManyField(
'InventorySourceNew',
related_name='groups',
editable=False,
help_text=_('Inventory source(s) that created or modified this group.'),
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class Group(GroupBase):
class Meta:
app_label = 'main'
unique_together = (("name", "inventory"),)
new_inventory_sources = models.ManyToManyField(
'InventorySourceNew',
related_name='groups',
editable=False,
help_text=_('Inventory source(s) that created or modified this group.'),
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class Group(GroupBase):
class Meta:
app_label = 'main'
unique_together = (("name", "inventory"),)
inventory_sources = models.ManyToManyField(
'InventorySource',
related_name='groups',
editable=False,
help_text=_('Inventory source(s) that created or modified this group.'),
)
class InventorySourceOptions(BaseModel):
'''
Common fields for InventorySource and InventoryUpdate.
@ -739,12 +597,27 @@ class InventorySourceOptions(BaseModel):
source_vars_dict = VarsDictProperty('source_vars')
class InventorySourceBase(InventorySourceOptions):
class InventorySource(UnifiedJobTemplate, InventorySourceOptions):
class Meta:
abstract = True
app_label = 'main'
inventory = models.ForeignKey(
'Inventory',
related_name='inventory_sources',
null=True,
default=None,
editable=False,
on_delete=models.CASCADE,
)
group = AutoOneToOneField(
'Group',
related_name='inventory_source',
null=True,
default=None,
editable=False,
on_delete=models.CASCADE,
)
update_on_launch = models.BooleanField(
default=False,
)
@ -752,9 +625,6 @@ class InventorySourceBase(InventorySourceOptions):
default=0,
)
class InventorySourceBaseMethods(object):
@classmethod
def _get_unified_job_class(cls):
return InventoryUpdate
@ -779,7 +649,7 @@ class InventorySourceBaseMethods(object):
if 'name' not in update_fields:
update_fields.append('name')
# Do the actual save.
super(InventorySourceBaseMethods, self).save(*args, **kwargs)
super(InventorySource, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('api:inventory_source_detail', args=(self.pk,))
@ -807,142 +677,25 @@ class InventorySourceBaseMethods(object):
return inventory_update
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class InventorySource(InventorySourceBaseMethods, PrimordialModel, InventorySourceBase):
INVENTORY_SOURCE_STATUS_CHOICES = [
('none', _('No External Source')),
('never updated', _('Never Updated')),
('updating', _('Updating')),
('failed', _('Failed')),
('successful', _('Successful')),
]
class Meta:
app_label = 'main'
inventory = models.ForeignKey(
'Inventory',
related_name='inventory_sources',
null=True,
default=None,
editable=False,
on_delete=models.CASCADE,
)
group = AutoOneToOneField(
'Group',
related_name='inventory_source',
null=True,
default=None,
editable=False,
on_delete=models.CASCADE,
)
current_update = models.ForeignKey(
'InventoryUpdate',
null=True,
default=None,
editable=False,
related_name='inventory_source_as_current_update+',
on_delete=models.SET_NULL,
)
last_update = models.ForeignKey(
'InventoryUpdate',
null=True,
default=None,
editable=False,
related_name='inventory_source_as_last_update+',
on_delete=models.SET_NULL,
)
last_update_failed = models.BooleanField(
default=False,
editable=False,
)
last_updated = models.DateTimeField(
null=True,
default=None,
editable=False,
)
status = models.CharField(
max_length=32,
choices=INVENTORY_SOURCE_STATUS_CHOICES,
default='none',
editable=False,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') in (0, 1):
class InventorySourceNew(InventorySourceBaseMethods, UnifiedJobTemplate, InventorySourceBase):
class Meta:
app_label = 'main'
inventory = models.ForeignKey(
'Inventory',
related_name='new_inventory_sources',
null=True,
default=None,
editable=False,
on_delete=models.CASCADE,
)
group = AutoOneToOneField(
'Group',
related_name='new_inventory_source',
null=True,
default=None,
editable=False,
on_delete=models.CASCADE,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class InventorySource(InventorySourceNew):
class Meta:
proxy = True
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class InventorySource(InventorySourceBaseMethods, UnifiedJobTemplate, InventorySourceBase):
class Meta:
app_label = 'main'
inventory = models.ForeignKey(
'Inventory',
related_name='inventory_sources',
null=True,
default=None,
editable=False,
on_delete=models.CASCADE,
)
group = AutoOneToOneField(
'Group',
related_name='inventory_source',
null=True,
default=None,
editable=False,
on_delete=models.CASCADE,
)
class InventoryUpdateBase(InventorySourceOptions):
class InventoryUpdate(UnifiedJob, InventorySourceOptions):
'''
Internal job for tracking inventory updates from external sources.
'''
class Meta:
app_label = 'main'
abstract = True
inventory_source = models.ForeignKey(
'InventorySource',
related_name='inventory_updates',
editable=False,
on_delete=models.CASCADE,
)
license_error = models.BooleanField(
default=False,
editable=False,
)
class InventoryUpdateBaseMethods(object):
@classmethod
def _get_parent_field_name(cls):
return 'inventory_source'
@ -959,7 +712,7 @@ class InventoryUpdateBaseMethods(object):
self.license_error = True
if 'license_error' not in update_fields:
update_fields.append('license_error')
super(InventoryUpdateBaseMethods, self).save(*args, **kwargs)
super(InventoryUpdate, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('api:inventory_update_detail', args=(self.pk,))
@ -990,53 +743,3 @@ class InventoryUpdateBaseMethods(object):
self.save()
# notify_task_runner.delay(dict(task_type="inventory_update", id=self.id, metadata=kwargs))
return True
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class InventoryUpdate(InventoryUpdateBaseMethods, CommonTask, InventoryUpdateBase):
class Meta:
app_label = 'main'
inventory_source = models.ForeignKey(
'InventorySource',
related_name='inventory_updates',
editable=False,
on_delete=models.CASCADE,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') in (0, 1):
class InventoryUpdateNew(InventoryUpdateBaseMethods, UnifiedJob, InventoryUpdateBase):
class Meta:
app_label = 'main'
inventory_source = models.ForeignKey(
'InventorySourceNew',
related_name='inventory_updates',
editable=False,
on_delete=models.CASCADE,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class InventoryUpdate(InventoryUpdateNew):
class Meta:
proxy = True
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class InventoryUpdate(InventoryUpdateBaseMethods, UnifiedJob, InventoryUpdateBase):
class Meta:
app_label = 'main'
inventory_source = models.ForeignKey(
'InventorySource',
related_name='inventory_updates',
editable=False,
on_delete=models.CASCADE,
)

View File

@ -47,6 +47,7 @@ logger = logging.getLogger('awx.main.models.jobs')
__all__ = ['JobTemplate', 'Job', 'JobHostSummary', 'JobEvent']
class JobOptions(BaseModel):
'''
'''
@ -64,12 +65,12 @@ class JobOptions(BaseModel):
null=True,
on_delete=models.SET_NULL,
)
#project = models.ForeignKey(
# 'Project',
# related_name='%(class)ss',
# null=True,
# on_delete=models.SET_NULL,
#)
project = models.ForeignKey(
'Project',
related_name='%(class)ss',
null=True,
on_delete=models.SET_NULL,
)
playbook = models.CharField(
max_length=1024,
default='',
@ -129,14 +130,13 @@ class JobOptions(BaseModel):
return cred
class JobTemplateBase(JobOptions):
class JobTemplate(UnifiedJobTemplate, JobOptions):
'''
A job template is a reusable job definition for applying a project (with
playbook) to an inventory source with a given credential.
'''
class Meta:
abstract = True
app_label = 'main'
host_config_key = models.CharField(
@ -145,8 +145,6 @@ class JobTemplateBase(JobOptions):
default='',
)
class JobTemplateBaseMethods(object):
@classmethod
def _get_unified_job_class(cls):
return Job
@ -181,59 +179,7 @@ class JobTemplateBaseMethods(object):
return bool(self.credential and not len(needed))
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class JobTemplate(JobTemplateBaseMethods, CommonModel, JobTemplateBase):
class Meta:
app_label = 'main'
project = models.ForeignKey(
'Project',
related_name='job_templates',
null=True,
on_delete=models.SET_NULL,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') in (0, 1):
class JobTemplateNew(JobTemplateBaseMethods, UnifiedJobTemplate, JobTemplateBase):
class Meta:
app_label = 'main'
db_table = 'main_jobtemplatenew'
project = models.ForeignKey(
'ProjectNew',
related_name='job_templates',
null=True,
on_delete=models.SET_NULL,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class JobTemplate(JobTemplateNew):
class Meta:
proxy = True
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
#class JobTemplate(JobTemplateBase, UnifiedJobTemplate):
class JobTemplate(JobTemplateBaseMethods, UnifiedJobTemplate, JobTemplateBase):
class Meta:
app_label = 'main'
project = models.ForeignKey(
'Project',
related_name='job_templates',
null=True,
on_delete=models.SET_NULL,
)
class JobBase(JobOptions):
class Job(UnifiedJob, JobOptions):
'''
A job applies a project (with playbook) to an inventory source with a given
credential. It represents a single invocation of ansible-playbook with the
@ -241,19 +187,23 @@ class JobBase(JobOptions):
'''
class Meta:
abstract = True
app_label = 'main'
job_template = models.ForeignKey(
'JobTemplate',
related_name='jobs',
blank=True,
null=True,
default=None,
on_delete=models.SET_NULL,
)
hosts = models.ManyToManyField(
'Host',
related_name='%(class)ss',
related_name='jobs',
editable=False,
through='JobHostSummary',
)
class JobBaseMethods(object):
@classmethod
def _get_parent_field_name(cls):
return 'job_template'
@ -409,111 +359,23 @@ class JobBaseMethods(object):
return True
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class Job(JobBaseMethods, CommonTask, JobBase):
LAUNCH_TYPE_CHOICES = [
('manual', _('Manual')),
('callback', _('Callback')),
('scheduled', _('Scheduled')),
]
class Meta:
app_label = 'main'
job_template = models.ForeignKey(
'JobTemplate',
related_name='jobs',
blank=True,
null=True,
default=None,
on_delete=models.SET_NULL,
)
project = models.ForeignKey(
'Project',
related_name='jobs',
null=True,
on_delete=models.SET_NULL,
)
launch_type = models.CharField(
max_length=20,
choices=LAUNCH_TYPE_CHOICES,
default='manual',
editable=False,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') in (0, 1):
class JobNew(JobBaseMethods, UnifiedJob, JobBase):
class Meta:
app_label = 'main'
job_template = models.ForeignKey(
'JobTemplateNew',
related_name='jobs',
blank=True,
null=True,
default=None,
on_delete=models.SET_NULL,
)
project = models.ForeignKey(
'ProjectNew',
related_name='jobs',
null=True,
on_delete=models.SET_NULL,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class Job(JobNew):
class Meta:
proxy = True
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
#class Job(JobBase, UnifiedJob):
class Job(JobBaseMethods, UnifiedJob, JobBase):
class Meta:
app_label = 'main'
job_template = models.ForeignKey(
'JobTemplate',
related_name='jobs',
blank=True,
null=True,
default=None,
on_delete=models.SET_NULL,
)
project = models.ForeignKey(
'Project',
related_name='jobs',
null=True,
on_delete=models.SET_NULL,
)
class JobHostSummaryBase(CreatedModifiedModel):
class JobHostSummary(CreatedModifiedModel):
'''
Per-host statistics for each job.
'''
class Meta:
abstract = True
app_label = 'main'
unique_together = [('job', 'host')]
verbose_name_plural = _('job host summaries')
ordering = ('-pk',)
#job = models.ForeignKey(
# 'Job',
# related_name='job_host_summaries',
# on_delete=models.CASCADE,
# editable=False,
#)
job = models.ForeignKey(
'Job',
related_name='job_host_summaries',
on_delete=models.CASCADE,
editable=False,
)
host = models.ForeignKey('Host',
related_name='job_host_summaries',
on_delete=models.CASCADE,
@ -542,7 +404,7 @@ class JobHostSummaryBase(CreatedModifiedModel):
update_fields = kwargs.get('update_fields', [])
self.failed = bool(self.dark or self.failures)
update_fields.append('failed')
super(JobHostSummaryBase, self).save(*args, **kwargs)
super(JobHostSummary, self).save(*args, **kwargs)
self.update_host_last_job_summary()
def update_host_last_job_summary(self):
@ -558,69 +420,7 @@ class JobHostSummaryBase(CreatedModifiedModel):
#self.host.update_computed_fields()
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class JobHostSummary(JobHostSummaryBase):
class Meta:
app_label = 'main'
unique_together = [('job', 'host'), ('new_job', 'host')]
verbose_name_plural = _('job host summaries')
ordering = ('-pk',)
job = models.ForeignKey(
'Job',
related_name='job_host_summaries',
on_delete=models.CASCADE,
null=True,
default=None,
editable=False,
)
new_job = models.ForeignKey(
'JobNew',
related_name='new_job_host_summaries',
on_delete=models.CASCADE,
null=True,
default=None,
editable=False,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class JobHostSummary(JobHostSummaryBase):
class Meta:
app_label = 'main'
unique_together = [('new_job', 'host')]
verbose_name_plural = _('job host summaries')
ordering = ('-pk',)
new_job = models.ForeignKey(
'JobNew',
related_name='new_job_host_summaries',
on_delete=models.CASCADE,
editable=False,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class JobHostSummary(JobHostSummaryBase):
class Meta:
app_label = 'main'
unique_together = [('job', 'host')]
verbose_name_plural = _('job host summaries')
ordering = ('-pk',)
job = models.ForeignKey(
'Job',
related_name='job_host_summaries',
on_delete=models.CASCADE,
editable=False,
)
class JobEventBase(CreatedModifiedModel):
class JobEvent(CreatedModifiedModel):
'''
An event/message logged from the callback when running a job.
'''
@ -683,16 +483,15 @@ class JobEventBase(CreatedModifiedModel):
LEVEL_FOR_EVENT = dict([(x[1], x[0]) for x in EVENT_TYPES])
class Meta:
abstract = True
app_label = 'main'
ordering = ('pk',)
#job = models.ForeignKey(
# 'Job',
# related_name='job_events',
# on_delete=models.CASCADE,
# editable=False,
#)
job = models.ForeignKey(
'Job',
related_name='job_events',
on_delete=models.CASCADE,
editable=False,
)
event = models.CharField(
max_length=100,
choices=EVENT_CHOICES,
@ -890,7 +689,7 @@ class JobEventBase(CreatedModifiedModel):
self.parent = self._find_parent()
if 'parent' not in update_fields:
update_fields.append('parent')
super(JobEventBase, self).save(*args, **kwargs)
super(JobEvent, self).save(*args, **kwargs)
if post_process and not from_parent_update:
self.update_parent_failed_and_changed()
# FIXME: The update_hosts() call (and its queries) are the current
@ -967,58 +766,3 @@ class JobEventBase(CreatedModifiedModel):
host_summary.save(update_fields=update_fields)
job.inventory.update_computed_fields()
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class JobEvent(JobEventBase):
class Meta:
app_label = 'main'
ordering = ('pk',)
job = models.ForeignKey(
'Job',
related_name='job_events',
on_delete=models.CASCADE,
null=True,
default=None,
editable=False,
)
new_job = models.ForeignKey(
'JobNew',
related_name='new_job_events',
on_delete=models.CASCADE,
null=True,
default=None,
editable=False,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class JobEvent(JobEventBase):
class Meta:
app_label = 'main'
ordering = ('pk',)
new_job = models.ForeignKey(
'JobNew',
related_name='new_job_events',
on_delete=models.CASCADE,
editable=False,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class JobEvent(JobEventBase):
class Meta:
app_label = 'main'
ordering = ('pk',)
job = models.ForeignKey(
'Job',
related_name='job_events',
on_delete=models.CASCADE,
editable=False,
)

View File

@ -37,13 +37,12 @@ __all__ = ['Organization', 'Team', 'Permission', 'Credential', 'Profile',
'AuthToken']
class OrganizationBase(CommonModel):
class Organization(CommonModel):
'''
An organization is the basic unit of multi-tenancy divisions
'''
class Meta:
abstract = True
app_label = 'main'
users = models.ManyToManyField(
@ -56,6 +55,11 @@ class OrganizationBase(CommonModel):
blank=True,
related_name='admin_of_organizations',
)
projects = models.ManyToManyField(
'Project',
blank=True,
related_name='organizations',
)
def get_absolute_url(self):
return reverse('api:organization_detail', args=(self.pk,))
@ -64,58 +68,12 @@ class OrganizationBase(CommonModel):
return self.name
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class Organization(OrganizationBase):
class Meta:
app_label = 'main'
projects = models.ManyToManyField(
'Project',
blank=True,
related_name='organizations',
)
new_projects = models.ManyToManyField(
'ProjectNew',
blank=True,
related_name='organizations',
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class Organization(OrganizationBase):
class Meta:
app_label = 'main'
new_projects = models.ManyToManyField(
'ProjectNew',
blank=True,
related_name='organizations',
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class Organization(OrganizationBase):
class Meta:
app_label = 'main'
projects = models.ManyToManyField(
'Project',
blank=True,
related_name='organizations',
)
class TeamBase(CommonModelNameNotUnique):
class Team(CommonModelNameNotUnique):
'''
A team is a group of users that work on common projects.
'''
class Meta:
abstract = True
app_label = 'main'
unique_together = [('organization', 'name')]
@ -131,66 +89,22 @@ class TeamBase(CommonModelNameNotUnique):
on_delete=models.SET_NULL,
related_name='teams',
)
projects = models.ManyToManyField(
'Project',
blank=True,
related_name='teams',
)
def get_absolute_url(self):
return reverse('api:team_detail', args=(self.pk,))
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class Team(TeamBase):
class Meta:
app_label = 'main'
unique_together = [('organization', 'name')]
projects = models.ManyToManyField(
'Project',
blank=True,
related_name='teams',
)
new_projects = models.ManyToManyField(
'ProjectNew',
blank=True,
related_name='teams',
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class Team(TeamBase):
class Meta:
app_label = 'main'
unique_together = [('organization', 'name')]
new_projects = models.ManyToManyField(
'ProjectNew',
blank=True,
related_name='teams',
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class Team(TeamBase):
class Meta:
app_label = 'main'
unique_together = [('organization', 'name')]
projects = models.ManyToManyField(
'Project',
blank=True,
related_name='teams',
)
class PermissionBase(CommonModelNameNotUnique):
class Permission(CommonModelNameNotUnique):
'''
A permission allows a user, project, or team to be able to use an inventory source.
'''
class Meta:
abstract = True
app_label = 'main'
# permissions are granted to either a user or a team:
@ -198,7 +112,13 @@ class PermissionBase(CommonModelNameNotUnique):
team = models.ForeignKey('Team', null=True, on_delete=models.SET_NULL, blank=True, related_name='permissions')
# to be used against a project or inventory (or a project and inventory in conjunction):
#project = models.ForeignKey('Project', null=True, on_delete=models.SET_NULL, blank=True, related_name='permissions')
project = models.ForeignKey(
'Project',
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name='permissions',
)
inventory = models.ForeignKey('Inventory', null=True, on_delete=models.SET_NULL, related_name='permissions')
# permission system explanation:
@ -229,59 +149,6 @@ class PermissionBase(CommonModelNameNotUnique):
return reverse('api:permission_detail', args=(self.pk,))
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class Permission(PermissionBase):
class Meta:
app_label = 'main'
project = models.ForeignKey(
'Project',
null=True,
on_delete=models.SET_NULL,
blank=True,
related_name='permissions',
)
new_project = models.ForeignKey(
'ProjectNew',
null=True,
on_delete=models.SET_NULL,
blank=True,
related_name='permissions',
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class Permission(PermissionBase):
class Meta:
app_label = 'main'
new_project = models.ForeignKey(
'ProjectNew',
null=True,
on_delete=models.SET_NULL,
blank=True,
related_name='permissions',
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class Permission(PermissionBase):
class Meta:
app_label = 'main'
project = models.ForeignKey(
'Project',
null=True,
on_delete=models.SET_NULL,
blank=True,
related_name='permissions',
)
class Credential(CommonModelNameNotUnique):
'''
A credential contains information about how to talk to a remote resource

View File

@ -194,17 +194,13 @@ class ProjectOptions(models.Model):
return results
class ProjectBase(ProjectOptions):
class Project(UnifiedJobTemplate, ProjectOptions):
'''
A project represents a playbook git repo that can access a set of inventories
'''
class Meta:
app_label = 'main'
abstract = True
# this is not part of the project, but managed with perms
# inventories = models.ManyToManyField('Inventory', blank=True, related_name='projects')
scm_delete_on_next_update = models.BooleanField(
default=False,
@ -217,9 +213,6 @@ class ProjectBase(ProjectOptions):
default=0,
)
class ProjectBaseMethods(object):
@classmethod
def _get_unified_job_class(cls):
return ProjectUpdate
@ -248,7 +241,7 @@ class ProjectBaseMethods(object):
if 'local_path' not in update_fields:
update_fields.append('local_path')
# Do the actual save.
super(ProjectBaseMethods, self).save(*args, **kwargs)
super(Project, self).save(*args, **kwargs)
if new_instance:
update_fields=[]
# Generate local_path for SCM after initial save (so we have a PK).
@ -318,88 +311,20 @@ class ProjectBaseMethods(object):
return reverse('api:project_detail', args=(self.pk,))
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class Project(ProjectBaseMethods, CommonModel, ProjectBase):
PROJECT_STATUS_CHOICES = [
('ok', 'OK'),
('missing', 'Missing'),
('never updated', 'Never Updated'),
('updating', 'Updating'),
('failed', 'Failed'),
('successful', 'Successful'),
]
class Meta:
app_label = 'main'
current_update = models.ForeignKey(
'ProjectUpdate',
null=True,
default=None,
editable=False,
related_name='project_as_current_update+',
on_delete=models.SET_NULL,
)
last_update = models.ForeignKey(
'ProjectUpdate',
null=True,
default=None,
editable=False,
related_name='project_as_last_update+',
on_delete=models.SET_NULL,
)
last_update_failed = models.BooleanField(
default=False,
editable=False,
)
last_updated = models.DateTimeField(
null=True,
default=None,
editable=False,
)
status = models.CharField(
max_length=32,
choices=PROJECT_STATUS_CHOICES,
default='ok',
editable=False,
null=True, # FIXME: Remove
)
if getattr(settings, 'UNIFIED_JOBS_STEP') in (0, 1):
class ProjectNew(ProjectBaseMethods, UnifiedJobTemplate, ProjectBase):
class Meta:
app_label = 'main'
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class Project(ProjectNew):
class Meta:
proxy = True
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class Project(ProjectBaseMethods, UnifiedJobTemplate, ProjectBase):
class Meta:
app_label = 'main'
class ProjectUpdateBase(ProjectOptions):
class ProjectUpdate(UnifiedJob, ProjectOptions):
'''
Internal job for tracking project updates from SCM.
'''
class Meta:
app_label = 'main'
abstract = True
class ProjectUpdateBaseMethods(object):
project = models.ForeignKey(
'Project',
related_name='project_updates',
on_delete=models.CASCADE,
editable=False,
)
@classmethod
def _get_parent_field_name(cls):
@ -458,53 +383,3 @@ class ProjectUpdateBaseMethods(object):
'last_job',
'last_job_failed',
'scm_delete_on_next_update'])
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
class ProjectUpdate(ProjectUpdateBaseMethods, CommonTask, ProjectUpdateBase):
class Meta:
app_label = 'main'
project = models.ForeignKey(
'Project',
related_name='project_updates',
on_delete=models.CASCADE,
editable=False,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') in (0, 1):
class ProjectUpdateNew(ProjectUpdateBaseMethods, UnifiedJob, ProjectUpdateBase):
class Meta:
app_label = 'main'
project = models.ForeignKey(
'ProjectNew',
related_name='project_updates',
on_delete=models.CASCADE,
editable=False,
)
if getattr(settings, 'UNIFIED_JOBS_STEP') == 1:
class ProjectUpdate(ProjectUpdateNew):
class Meta:
proxy = True
if getattr(settings, 'UNIFIED_JOBS_STEP') == 2:
class ProjectUpdate(ProjectUpdateBaseMethods, UnifiedJob, ProjectUpdateBase):
class Meta:
app_label = 'main'
project = models.ForeignKey(
'Project',
related_name='project_updates',
on_delete=models.CASCADE,
editable=False,
)

View File

@ -304,9 +304,6 @@ AWX_TASK_ENV = {}
# Flag to enable/disable updating hosts M2M when saving job events.
CAPTURE_JOB_EVENT_HOSTS = False
# Flag to indicate which version of unified jobs model to use.
UNIFIED_JOBS_STEP = 2
# Not possible to get list of regions without authenticating, so use this list
# instead (based on docs from:
# http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/Service_Access_Endpoints-d1e517.html)