mirror of
https://github.com/ansible/awx.git
synced 2026-05-07 09:27:36 -02:30
AC-1040 Removed extra model definitions used for generating migrations.
This commit is contained in:
@@ -14,43 +14,42 @@ from awx.main.models.jobs import *
|
|||||||
from awx.main.models.schedules import *
|
from awx.main.models.schedules import *
|
||||||
from awx.main.models.activity_stream 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
|
||||||
# Monkeypatch Django serializer to ignore django-taggit fields (which break
|
# the dumpdata command; see https://github.com/alex/django-taggit/issues/155).
|
||||||
# the dumpdata command; see https://github.com/alex/django-taggit/issues/155).
|
from django.core.serializers.python import Serializer as _PythonSerializer
|
||||||
from django.core.serializers.python import Serializer as _PythonSerializer
|
_original_handle_m2m_field = _PythonSerializer.handle_m2m_field
|
||||||
_original_handle_m2m_field = _PythonSerializer.handle_m2m_field
|
def _new_handle_m2m_field(self, obj, field):
|
||||||
def _new_handle_m2m_field(self, obj, field):
|
try:
|
||||||
try:
|
field.rel.through._meta
|
||||||
field.rel.through._meta
|
except AttributeError:
|
||||||
except AttributeError:
|
return
|
||||||
return
|
return _original_handle_m2m_field(self, obj, field)
|
||||||
return _original_handle_m2m_field(self, obj, field)
|
_PythonSerializer.handle_m2m_field = _new_handle_m2m_field
|
||||||
_PythonSerializer.handle_m2m_field = _new_handle_m2m_field
|
|
||||||
|
|
||||||
# Add custom methods to User model for permissions checks.
|
# Add custom methods to User model for permissions checks.
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from awx.main.access import *
|
from awx.main.access import *
|
||||||
User.add_to_class('get_queryset', get_user_queryset)
|
User.add_to_class('get_queryset', get_user_queryset)
|
||||||
User.add_to_class('can_access', check_user_access)
|
User.add_to_class('can_access', check_user_access)
|
||||||
|
|
||||||
# Import signal handlers only after models have been defined.
|
# Import signal handlers only after models have been defined.
|
||||||
import awx.main.signals
|
import awx.main.signals
|
||||||
|
|
||||||
from awx.main.registrar import activity_stream_registrar
|
from awx.main.registrar import activity_stream_registrar
|
||||||
activity_stream_registrar.connect(Organization)
|
activity_stream_registrar.connect(Organization)
|
||||||
activity_stream_registrar.connect(Inventory)
|
activity_stream_registrar.connect(Inventory)
|
||||||
activity_stream_registrar.connect(Host)
|
activity_stream_registrar.connect(Host)
|
||||||
activity_stream_registrar.connect(Group)
|
activity_stream_registrar.connect(Group)
|
||||||
activity_stream_registrar.connect(InventorySource)
|
activity_stream_registrar.connect(InventorySource)
|
||||||
#activity_stream_registrar.connect(InventoryUpdate)
|
#activity_stream_registrar.connect(InventoryUpdate)
|
||||||
activity_stream_registrar.connect(Credential)
|
activity_stream_registrar.connect(Credential)
|
||||||
activity_stream_registrar.connect(Team)
|
activity_stream_registrar.connect(Team)
|
||||||
activity_stream_registrar.connect(Project)
|
activity_stream_registrar.connect(Project)
|
||||||
#activity_stream_registrar.connect(ProjectUpdate)
|
#activity_stream_registrar.connect(ProjectUpdate)
|
||||||
activity_stream_registrar.connect(Permission)
|
activity_stream_registrar.connect(Permission)
|
||||||
activity_stream_registrar.connect(JobTemplate)
|
activity_stream_registrar.connect(JobTemplate)
|
||||||
activity_stream_registrar.connect(Job)
|
activity_stream_registrar.connect(Job)
|
||||||
# activity_stream_registrar.connect(JobHostSummary)
|
# activity_stream_registrar.connect(JobHostSummary)
|
||||||
# activity_stream_registrar.connect(JobEvent)
|
# activity_stream_registrar.connect(JobEvent)
|
||||||
#activity_stream_registrar.connect(Profile)
|
#activity_stream_registrar.connect(Profile)
|
||||||
activity_stream_registrar.connect(Schedule)
|
activity_stream_registrar.connect(Schedule)
|
||||||
|
|||||||
@@ -10,13 +10,12 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
__all__ = ['ActivityStream']
|
__all__ = ['ActivityStream']
|
||||||
|
|
||||||
|
|
||||||
class ActivityStreamBase(models.Model):
|
class ActivityStream(models.Model):
|
||||||
'''
|
'''
|
||||||
Model used to describe activity stream (audit) events
|
Model used to describe activity stream (audit) events
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
|
|
||||||
OPERATION_CHOICES = [
|
OPERATION_CHOICES = [
|
||||||
@@ -41,15 +40,17 @@ class ActivityStreamBase(models.Model):
|
|||||||
inventory = models.ManyToManyField("Inventory", blank=True)
|
inventory = models.ManyToManyField("Inventory", blank=True)
|
||||||
host = models.ManyToManyField("Host", blank=True)
|
host = models.ManyToManyField("Host", blank=True)
|
||||||
group = models.ManyToManyField("Group", blank=True)
|
group = models.ManyToManyField("Group", blank=True)
|
||||||
#inventory_source = models.ManyToManyField("InventorySource", blank=True)
|
inventory_source = models.ManyToManyField("InventorySource", blank=True)
|
||||||
#inventory_update = models.ManyToManyField("InventoryUpdate", blank=True)
|
inventory_update = models.ManyToManyField("InventoryUpdate", blank=True)
|
||||||
credential = models.ManyToManyField("Credential", blank=True)
|
credential = models.ManyToManyField("Credential", blank=True)
|
||||||
team = models.ManyToManyField("Team", blank=True)
|
team = models.ManyToManyField("Team", blank=True)
|
||||||
#project = models.ManyToManyField("Project", blank=True)
|
project = models.ManyToManyField("Project", blank=True)
|
||||||
#project_update = models.ManyToManyField("ProjectUpdate", blank=True)
|
project_update = models.ManyToManyField("ProjectUpdate", blank=True)
|
||||||
permission = models.ManyToManyField("Permission", blank=True)
|
permission = models.ManyToManyField("Permission", blank=True)
|
||||||
#job_template = models.ManyToManyField("JobTemplate", blank=True)
|
job_template = models.ManyToManyField("JobTemplate", blank=True)
|
||||||
#job = models.ManyToManyField("Job", 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)
|
schedule = models.ManyToManyField("Schedule", blank=True)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
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
|
# For compatibility with Django 1.4.x, attempt to handle any calls to
|
||||||
# save that pass update_fields.
|
# save that pass update_fields.
|
||||||
try:
|
try:
|
||||||
super(ActivityStreamBase, self).save(*args, **kwargs)
|
super(ActivityStream, self).save(*args, **kwargs)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
if 'update_fields' not in kwargs:
|
if 'update_fields' not in kwargs:
|
||||||
raise
|
raise
|
||||||
kwargs.pop('update_fields')
|
kwargs.pop('update_fields')
|
||||||
super(ActivityStreamBase, self).save(*args, **kwargs)
|
super(ActivityStream, 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)
|
|
||||||
|
|||||||
@@ -277,234 +277,7 @@ class CommonModelNameNotUnique(PrimordialModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
|
class CommonTask(PrimordialModel):
|
||||||
|
|
||||||
class CommonTask(PrimordialModel):
|
class Meta:
|
||||||
'''
|
abstract = True
|
||||||
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
|
|
||||||
|
|||||||
@@ -160,13 +160,12 @@ class Inventory(CommonModel):
|
|||||||
return self.groups.exclude(parents__pk__in=group_pks).distinct()
|
return self.groups.exclude(parents__pk__in=group_pks).distinct()
|
||||||
|
|
||||||
|
|
||||||
class HostBase(CommonModelNameNotUnique):
|
class Host(CommonModelNameNotUnique):
|
||||||
'''
|
'''
|
||||||
A managed node
|
A managed node
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
unique_together = (("name", "inventory"),) # FIXME: Add ('instance_id', 'inventory') after migration.
|
unique_together = (("name", "inventory"),) # FIXME: Add ('instance_id', 'inventory') after migration.
|
||||||
|
|
||||||
@@ -189,15 +188,14 @@ class HostBase(CommonModelNameNotUnique):
|
|||||||
default='',
|
default='',
|
||||||
help_text=_('Host variables in JSON or YAML format.'),
|
help_text=_('Host variables in JSON or YAML format.'),
|
||||||
)
|
)
|
||||||
#last_job = models.ForeignKey(
|
last_job = models.ForeignKey(
|
||||||
# 'Job',
|
'Job',
|
||||||
# related_name='hosts_as_last_job+',
|
related_name='hosts_as_last_job+',
|
||||||
# blank=True,
|
null=True,
|
||||||
# null=True,
|
default=None,
|
||||||
# default=None,
|
editable=False,
|
||||||
# editable=False,
|
on_delete=models.SET_NULL,
|
||||||
# on_delete=models.SET_NULL,
|
)
|
||||||
#)
|
|
||||||
last_job_host_summary = models.ForeignKey(
|
last_job_host_summary = models.ForeignKey(
|
||||||
'JobHostSummary',
|
'JobHostSummary',
|
||||||
related_name='hosts_as_last_job_summary+',
|
related_name='hosts_as_last_job_summary+',
|
||||||
@@ -217,13 +215,12 @@ class HostBase(CommonModelNameNotUnique):
|
|||||||
editable=False,
|
editable=False,
|
||||||
help_text=_('Flag indicating whether this host was created/updated from any external inventory sources.'),
|
help_text=_('Flag indicating whether this host was created/updated from any external inventory sources.'),
|
||||||
)
|
)
|
||||||
#inventory_sources = models.ManyToManyField(
|
inventory_sources = models.ManyToManyField(
|
||||||
# 'InventorySource',
|
'InventorySource',
|
||||||
# related_name='hosts',
|
related_name='hosts',
|
||||||
# blank=True,
|
editable=False,
|
||||||
# editable=False,
|
help_text=_('Inventory source(s) that created or modified this host.'),
|
||||||
# help_text=_('Inventory source(s) that created or modified this host.'),
|
)
|
||||||
#)
|
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@@ -236,7 +233,7 @@ class HostBase(CommonModelNameNotUnique):
|
|||||||
When marking hosts inactive, remove all associations to related
|
When marking hosts inactive, remove all associations to related
|
||||||
inventory sources.
|
inventory sources.
|
||||||
'''
|
'''
|
||||||
super(HostBase, self).mark_inactive(save=save)
|
super(Host, self).mark_inactive(save=save)
|
||||||
self.inventory_sources.clear()
|
self.inventory_sources.clear()
|
||||||
|
|
||||||
def update_computed_fields(self, update_inventory=True, update_groups=True):
|
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.
|
# Use .job_events.all() to get events affecting this host.
|
||||||
|
|
||||||
|
|
||||||
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
|
class Group(CommonModelNameNotUnique):
|
||||||
|
|
||||||
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):
|
|
||||||
'''
|
'''
|
||||||
A group containing managed hosts. A group or host may belong to multiple
|
A group containing managed hosts. A group or host may belong to multiple
|
||||||
groups.
|
groups.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
unique_together = (("name", "inventory"),)
|
unique_together = (("name", "inventory"),)
|
||||||
|
|
||||||
@@ -433,13 +345,12 @@ class GroupBase(CommonModelNameNotUnique):
|
|||||||
editable=False,
|
editable=False,
|
||||||
help_text=_('Flag indicating whether this group was created/updated from any external inventory sources.'),
|
help_text=_('Flag indicating whether this group was created/updated from any external inventory sources.'),
|
||||||
)
|
)
|
||||||
#inventory_sources = models.ManyToManyField(
|
inventory_sources = models.ManyToManyField(
|
||||||
# 'InventorySource',
|
'InventorySource',
|
||||||
# related_name='groups',
|
related_name='groups',
|
||||||
# blank=True,
|
editable=False,
|
||||||
# editable=False,
|
help_text=_('Inventory source(s) that created or modified this group.'),
|
||||||
# help_text=_('Inventory source(s) that created or modified this group.'),
|
)
|
||||||
#)
|
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@@ -453,7 +364,7 @@ class GroupBase(CommonModelNameNotUnique):
|
|||||||
groups/hosts/inventory_sources.
|
groups/hosts/inventory_sources.
|
||||||
'''
|
'''
|
||||||
def mark_actual():
|
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_source.mark_inactive(save=save)
|
||||||
self.inventory_sources.clear()
|
self.inventory_sources.clear()
|
||||||
self.parents.clear()
|
self.parents.clear()
|
||||||
@@ -560,59 +471,6 @@ class GroupBase(CommonModelNameNotUnique):
|
|||||||
return JobEvent.objects.filter(host__in=self.all_hosts)
|
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):
|
class InventorySourceOptions(BaseModel):
|
||||||
'''
|
'''
|
||||||
Common fields for InventorySource and InventoryUpdate.
|
Common fields for InventorySource and InventoryUpdate.
|
||||||
@@ -739,12 +597,27 @@ class InventorySourceOptions(BaseModel):
|
|||||||
source_vars_dict = VarsDictProperty('source_vars')
|
source_vars_dict = VarsDictProperty('source_vars')
|
||||||
|
|
||||||
|
|
||||||
class InventorySourceBase(InventorySourceOptions):
|
class InventorySource(UnifiedJobTemplate, InventorySourceOptions):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
|
||||||
app_label = 'main'
|
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(
|
update_on_launch = models.BooleanField(
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
@@ -752,9 +625,6 @@ class InventorySourceBase(InventorySourceOptions):
|
|||||||
default=0,
|
default=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class InventorySourceBaseMethods(object):
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_unified_job_class(cls):
|
def _get_unified_job_class(cls):
|
||||||
return InventoryUpdate
|
return InventoryUpdate
|
||||||
@@ -779,7 +649,7 @@ class InventorySourceBaseMethods(object):
|
|||||||
if 'name' not in update_fields:
|
if 'name' not in update_fields:
|
||||||
update_fields.append('name')
|
update_fields.append('name')
|
||||||
# Do the actual save.
|
# Do the actual save.
|
||||||
super(InventorySourceBaseMethods, self).save(*args, **kwargs)
|
super(InventorySource, self).save(*args, **kwargs)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('api:inventory_source_detail', args=(self.pk,))
|
return reverse('api:inventory_source_detail', args=(self.pk,))
|
||||||
@@ -807,142 +677,25 @@ class InventorySourceBaseMethods(object):
|
|||||||
return inventory_update
|
return inventory_update
|
||||||
|
|
||||||
|
|
||||||
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
|
class InventoryUpdate(UnifiedJob, InventorySourceOptions):
|
||||||
|
|
||||||
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):
|
|
||||||
'''
|
'''
|
||||||
Internal job for tracking inventory updates from external sources.
|
Internal job for tracking inventory updates from external sources.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
abstract = True
|
|
||||||
|
|
||||||
|
inventory_source = models.ForeignKey(
|
||||||
|
'InventorySource',
|
||||||
|
related_name='inventory_updates',
|
||||||
|
editable=False,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
)
|
||||||
license_error = models.BooleanField(
|
license_error = models.BooleanField(
|
||||||
default=False,
|
default=False,
|
||||||
editable=False,
|
editable=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class InventoryUpdateBaseMethods(object):
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_parent_field_name(cls):
|
def _get_parent_field_name(cls):
|
||||||
return 'inventory_source'
|
return 'inventory_source'
|
||||||
@@ -959,7 +712,7 @@ class InventoryUpdateBaseMethods(object):
|
|||||||
self.license_error = True
|
self.license_error = True
|
||||||
if 'license_error' not in update_fields:
|
if 'license_error' not in update_fields:
|
||||||
update_fields.append('license_error')
|
update_fields.append('license_error')
|
||||||
super(InventoryUpdateBaseMethods, self).save(*args, **kwargs)
|
super(InventoryUpdate, self).save(*args, **kwargs)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('api:inventory_update_detail', args=(self.pk,))
|
return reverse('api:inventory_update_detail', args=(self.pk,))
|
||||||
@@ -990,53 +743,3 @@ class InventoryUpdateBaseMethods(object):
|
|||||||
self.save()
|
self.save()
|
||||||
# notify_task_runner.delay(dict(task_type="inventory_update", id=self.id, metadata=kwargs))
|
# notify_task_runner.delay(dict(task_type="inventory_update", id=self.id, metadata=kwargs))
|
||||||
return True
|
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,
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ logger = logging.getLogger('awx.main.models.jobs')
|
|||||||
|
|
||||||
__all__ = ['JobTemplate', 'Job', 'JobHostSummary', 'JobEvent']
|
__all__ = ['JobTemplate', 'Job', 'JobHostSummary', 'JobEvent']
|
||||||
|
|
||||||
|
|
||||||
class JobOptions(BaseModel):
|
class JobOptions(BaseModel):
|
||||||
'''
|
'''
|
||||||
'''
|
'''
|
||||||
@@ -64,12 +65,12 @@ class JobOptions(BaseModel):
|
|||||||
null=True,
|
null=True,
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
)
|
)
|
||||||
#project = models.ForeignKey(
|
project = models.ForeignKey(
|
||||||
# 'Project',
|
'Project',
|
||||||
# related_name='%(class)ss',
|
related_name='%(class)ss',
|
||||||
# null=True,
|
null=True,
|
||||||
# on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
#)
|
)
|
||||||
playbook = models.CharField(
|
playbook = models.CharField(
|
||||||
max_length=1024,
|
max_length=1024,
|
||||||
default='',
|
default='',
|
||||||
@@ -129,14 +130,13 @@ class JobOptions(BaseModel):
|
|||||||
return cred
|
return cred
|
||||||
|
|
||||||
|
|
||||||
class JobTemplateBase(JobOptions):
|
class JobTemplate(UnifiedJobTemplate, JobOptions):
|
||||||
'''
|
'''
|
||||||
A job template is a reusable job definition for applying a project (with
|
A job template is a reusable job definition for applying a project (with
|
||||||
playbook) to an inventory source with a given credential.
|
playbook) to an inventory source with a given credential.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
|
|
||||||
host_config_key = models.CharField(
|
host_config_key = models.CharField(
|
||||||
@@ -145,8 +145,6 @@ class JobTemplateBase(JobOptions):
|
|||||||
default='',
|
default='',
|
||||||
)
|
)
|
||||||
|
|
||||||
class JobTemplateBaseMethods(object):
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_unified_job_class(cls):
|
def _get_unified_job_class(cls):
|
||||||
return Job
|
return Job
|
||||||
@@ -181,59 +179,7 @@ class JobTemplateBaseMethods(object):
|
|||||||
return bool(self.credential and not len(needed))
|
return bool(self.credential and not len(needed))
|
||||||
|
|
||||||
|
|
||||||
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
|
class Job(UnifiedJob, JobOptions):
|
||||||
|
|
||||||
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):
|
|
||||||
'''
|
'''
|
||||||
A job applies a project (with playbook) to an inventory source with a given
|
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
|
credential. It represents a single invocation of ansible-playbook with the
|
||||||
@@ -241,19 +187,23 @@ class JobBase(JobOptions):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
|
||||||
app_label = 'main'
|
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(
|
hosts = models.ManyToManyField(
|
||||||
'Host',
|
'Host',
|
||||||
related_name='%(class)ss',
|
related_name='jobs',
|
||||||
editable=False,
|
editable=False,
|
||||||
through='JobHostSummary',
|
through='JobHostSummary',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class JobBaseMethods(object):
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_parent_field_name(cls):
|
def _get_parent_field_name(cls):
|
||||||
return 'job_template'
|
return 'job_template'
|
||||||
@@ -409,111 +359,23 @@ class JobBaseMethods(object):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
|
class JobHostSummary(CreatedModifiedModel):
|
||||||
|
|
||||||
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):
|
|
||||||
'''
|
'''
|
||||||
Per-host statistics for each job.
|
Per-host statistics for each job.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
unique_together = [('job', 'host')]
|
unique_together = [('job', 'host')]
|
||||||
verbose_name_plural = _('job host summaries')
|
verbose_name_plural = _('job host summaries')
|
||||||
ordering = ('-pk',)
|
ordering = ('-pk',)
|
||||||
|
|
||||||
#job = models.ForeignKey(
|
job = models.ForeignKey(
|
||||||
# 'Job',
|
'Job',
|
||||||
# related_name='job_host_summaries',
|
related_name='job_host_summaries',
|
||||||
# on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
# editable=False,
|
editable=False,
|
||||||
#)
|
)
|
||||||
host = models.ForeignKey('Host',
|
host = models.ForeignKey('Host',
|
||||||
related_name='job_host_summaries',
|
related_name='job_host_summaries',
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
@@ -542,7 +404,7 @@ class JobHostSummaryBase(CreatedModifiedModel):
|
|||||||
update_fields = kwargs.get('update_fields', [])
|
update_fields = kwargs.get('update_fields', [])
|
||||||
self.failed = bool(self.dark or self.failures)
|
self.failed = bool(self.dark or self.failures)
|
||||||
update_fields.append('failed')
|
update_fields.append('failed')
|
||||||
super(JobHostSummaryBase, self).save(*args, **kwargs)
|
super(JobHostSummary, self).save(*args, **kwargs)
|
||||||
self.update_host_last_job_summary()
|
self.update_host_last_job_summary()
|
||||||
|
|
||||||
def update_host_last_job_summary(self):
|
def update_host_last_job_summary(self):
|
||||||
@@ -558,69 +420,7 @@ class JobHostSummaryBase(CreatedModifiedModel):
|
|||||||
#self.host.update_computed_fields()
|
#self.host.update_computed_fields()
|
||||||
|
|
||||||
|
|
||||||
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
|
class JobEvent(CreatedModifiedModel):
|
||||||
|
|
||||||
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):
|
|
||||||
'''
|
'''
|
||||||
An event/message logged from the callback when running a job.
|
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])
|
LEVEL_FOR_EVENT = dict([(x[1], x[0]) for x in EVENT_TYPES])
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
ordering = ('pk',)
|
ordering = ('pk',)
|
||||||
|
|
||||||
#job = models.ForeignKey(
|
job = models.ForeignKey(
|
||||||
# 'Job',
|
'Job',
|
||||||
# related_name='job_events',
|
related_name='job_events',
|
||||||
# on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
# editable=False,
|
editable=False,
|
||||||
#)
|
)
|
||||||
event = models.CharField(
|
event = models.CharField(
|
||||||
max_length=100,
|
max_length=100,
|
||||||
choices=EVENT_CHOICES,
|
choices=EVENT_CHOICES,
|
||||||
@@ -890,7 +689,7 @@ class JobEventBase(CreatedModifiedModel):
|
|||||||
self.parent = self._find_parent()
|
self.parent = self._find_parent()
|
||||||
if 'parent' not in update_fields:
|
if 'parent' not in update_fields:
|
||||||
update_fields.append('parent')
|
update_fields.append('parent')
|
||||||
super(JobEventBase, self).save(*args, **kwargs)
|
super(JobEvent, self).save(*args, **kwargs)
|
||||||
if post_process and not from_parent_update:
|
if post_process and not from_parent_update:
|
||||||
self.update_parent_failed_and_changed()
|
self.update_parent_failed_and_changed()
|
||||||
# FIXME: The update_hosts() call (and its queries) are the current
|
# 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)
|
host_summary.save(update_fields=update_fields)
|
||||||
job.inventory.update_computed_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,
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -37,13 +37,12 @@ __all__ = ['Organization', 'Team', 'Permission', 'Credential', 'Profile',
|
|||||||
'AuthToken']
|
'AuthToken']
|
||||||
|
|
||||||
|
|
||||||
class OrganizationBase(CommonModel):
|
class Organization(CommonModel):
|
||||||
'''
|
'''
|
||||||
An organization is the basic unit of multi-tenancy divisions
|
An organization is the basic unit of multi-tenancy divisions
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
|
|
||||||
users = models.ManyToManyField(
|
users = models.ManyToManyField(
|
||||||
@@ -56,6 +55,11 @@ class OrganizationBase(CommonModel):
|
|||||||
blank=True,
|
blank=True,
|
||||||
related_name='admin_of_organizations',
|
related_name='admin_of_organizations',
|
||||||
)
|
)
|
||||||
|
projects = models.ManyToManyField(
|
||||||
|
'Project',
|
||||||
|
blank=True,
|
||||||
|
related_name='organizations',
|
||||||
|
)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('api:organization_detail', args=(self.pk,))
|
return reverse('api:organization_detail', args=(self.pk,))
|
||||||
@@ -64,58 +68,12 @@ class OrganizationBase(CommonModel):
|
|||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
|
class Team(CommonModelNameNotUnique):
|
||||||
|
|
||||||
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):
|
|
||||||
'''
|
'''
|
||||||
A team is a group of users that work on common projects.
|
A team is a group of users that work on common projects.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
unique_together = [('organization', 'name')]
|
unique_together = [('organization', 'name')]
|
||||||
|
|
||||||
@@ -131,66 +89,22 @@ class TeamBase(CommonModelNameNotUnique):
|
|||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
related_name='teams',
|
related_name='teams',
|
||||||
)
|
)
|
||||||
|
projects = models.ManyToManyField(
|
||||||
|
'Project',
|
||||||
|
blank=True,
|
||||||
|
related_name='teams',
|
||||||
|
)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('api:team_detail', args=(self.pk,))
|
return reverse('api:team_detail', args=(self.pk,))
|
||||||
|
|
||||||
|
|
||||||
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
|
class Permission(CommonModelNameNotUnique):
|
||||||
|
|
||||||
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):
|
|
||||||
'''
|
'''
|
||||||
A permission allows a user, project, or team to be able to use an inventory source.
|
A permission allows a user, project, or team to be able to use an inventory source.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
|
|
||||||
# permissions are granted to either a user or a team:
|
# 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')
|
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):
|
# 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')
|
inventory = models.ForeignKey('Inventory', null=True, on_delete=models.SET_NULL, related_name='permissions')
|
||||||
|
|
||||||
# permission system explanation:
|
# permission system explanation:
|
||||||
@@ -229,59 +149,6 @@ class PermissionBase(CommonModelNameNotUnique):
|
|||||||
return reverse('api:permission_detail', args=(self.pk,))
|
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):
|
class Credential(CommonModelNameNotUnique):
|
||||||
'''
|
'''
|
||||||
A credential contains information about how to talk to a remote resource
|
A credential contains information about how to talk to a remote resource
|
||||||
|
|||||||
@@ -194,17 +194,13 @@ class ProjectOptions(models.Model):
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
class ProjectBase(ProjectOptions):
|
class Project(UnifiedJobTemplate, ProjectOptions):
|
||||||
'''
|
'''
|
||||||
A project represents a playbook git repo that can access a set of inventories
|
A project represents a playbook git repo that can access a set of inventories
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
app_label = 'main'
|
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(
|
scm_delete_on_next_update = models.BooleanField(
|
||||||
default=False,
|
default=False,
|
||||||
@@ -217,9 +213,6 @@ class ProjectBase(ProjectOptions):
|
|||||||
default=0,
|
default=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ProjectBaseMethods(object):
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_unified_job_class(cls):
|
def _get_unified_job_class(cls):
|
||||||
return ProjectUpdate
|
return ProjectUpdate
|
||||||
@@ -248,7 +241,7 @@ class ProjectBaseMethods(object):
|
|||||||
if 'local_path' not in update_fields:
|
if 'local_path' not in update_fields:
|
||||||
update_fields.append('local_path')
|
update_fields.append('local_path')
|
||||||
# Do the actual save.
|
# Do the actual save.
|
||||||
super(ProjectBaseMethods, self).save(*args, **kwargs)
|
super(Project, self).save(*args, **kwargs)
|
||||||
if new_instance:
|
if new_instance:
|
||||||
update_fields=[]
|
update_fields=[]
|
||||||
# Generate local_path for SCM after initial save (so we have a PK).
|
# 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,))
|
return reverse('api:project_detail', args=(self.pk,))
|
||||||
|
|
||||||
|
|
||||||
if getattr(settings, 'UNIFIED_JOBS_STEP') == 0:
|
class ProjectUpdate(UnifiedJob, ProjectOptions):
|
||||||
|
|
||||||
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):
|
|
||||||
'''
|
'''
|
||||||
Internal job for tracking project updates from SCM.
|
Internal job for tracking project updates from SCM.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
abstract = True
|
|
||||||
|
|
||||||
|
project = models.ForeignKey(
|
||||||
class ProjectUpdateBaseMethods(object):
|
'Project',
|
||||||
|
related_name='project_updates',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
editable=False,
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_parent_field_name(cls):
|
def _get_parent_field_name(cls):
|
||||||
@@ -458,53 +383,3 @@ class ProjectUpdateBaseMethods(object):
|
|||||||
'last_job',
|
'last_job',
|
||||||
'last_job_failed',
|
'last_job_failed',
|
||||||
'scm_delete_on_next_update'])
|
'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,
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -304,9 +304,6 @@ AWX_TASK_ENV = {}
|
|||||||
# Flag to enable/disable updating hosts M2M when saving job events.
|
# Flag to enable/disable updating hosts M2M when saving job events.
|
||||||
CAPTURE_JOB_EVENT_HOSTS = False
|
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
|
# Not possible to get list of regions without authenticating, so use this list
|
||||||
# instead (based on docs from:
|
# instead (based on docs from:
|
||||||
# http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/Service_Access_Endpoints-d1e517.html)
|
# http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/Service_Access_Endpoints-d1e517.html)
|
||||||
|
|||||||
Reference in New Issue
Block a user