split Node in job and job template node

This commit is contained in:
Chris Meyers
2016-09-12 11:04:20 -04:00
parent e4025a7eff
commit cea5ebadb7
9 changed files with 232 additions and 111 deletions
+37 -4
View File
@@ -1133,11 +1133,43 @@ class SystemJobAccess(BaseAccess):
model = SystemJob
# TODO:
class WorkflowNodeAccess(BaseAccess):
class WorkflowJobTemplateNodeAccess(BaseAccess):
'''
I can see/use a WorkflowNode if I have permission to associated Workflow Job Template
I can see/use a WorkflowJobTemplateNode if I have permission to associated Workflow Job Template
'''
model = WorkflowNode
model = WorkflowJobTemplateNode
def get_queryset(self):
if self.user.is_superuser or self.user.is_system_auditor:
return self.model.objects.all()
@check_superuser
def can_read(self, obj):
return True
@check_superuser
def can_add(self, data):
if not data: # So the browseable API will work
return True
return True
@check_superuser
def can_change(self, obj, data):
if self.can_add(data) is False:
return False
return True
def can_delete(self, obj):
return self.can_change(obj, None)
# TODO:
class WorkflowJobNodeAccess(BaseAccess):
'''
I can see/use a WorkflowJobNode if I have permission to associated Workflow Job
'''
model = WorkflowJobNode
def get_queryset(self):
if self.user.is_superuser or self.user.is_system_auditor:
@@ -1863,6 +1895,7 @@ register_access(Role, RoleAccess)
register_access(NotificationTemplate, NotificationTemplateAccess)
register_access(Notification, NotificationAccess)
register_access(Label, LabelAccess)
register_access(WorkflowNode, WorkflowNodeAccess)
register_access(WorkflowJobTemplateNode, WorkflowJobTemplateNodeAccess)
register_access(WorkflowJobNode, WorkflowJobNodeAccess)
register_access(WorkflowJobTemplate, WorkflowJobTemplateAccess)
register_access(WorkflowJob, WorkflowJobAccess)
+41 -10
View File
@@ -26,6 +26,21 @@ class Migration(migrations.Migration):
},
bases=('main.unifiedjob', models.Model, awx.main.models.notifications.JobNotificationMixin, awx.main.models.workflow.WorkflowJobInheritNodesMixin),
),
migrations.CreateModel(
name='WorkflowJobNode',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('created', models.DateTimeField(default=None, editable=False)),
('modified', models.DateTimeField(default=None, editable=False)),
('always_nodes', models.ManyToManyField(related_name='workflowjobnodes_always', to='main.WorkflowJobNode', blank=True)),
('failure_nodes', models.ManyToManyField(related_name='workflowjobnodes_failure', to='main.WorkflowJobNode', blank=True)),
('job', models.ForeignKey(related_name='unified_job_nodes', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to='main.UnifiedJob', null=True)),
('success_nodes', models.ManyToManyField(related_name='workflowjobnodes_success', to='main.WorkflowJobNode', blank=True)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='WorkflowJobTemplate',
fields=[
@@ -36,19 +51,30 @@ class Migration(migrations.Migration):
bases=('main.unifiedjobtemplate', models.Model),
),
migrations.CreateModel(
name='WorkflowNode',
name='WorkflowJobTemplateNode',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('created', models.DateTimeField(default=None, editable=False)),
('modified', models.DateTimeField(default=None, editable=False)),
('always_nodes', models.ManyToManyField(related_name='parent_always_nodes', to='main.WorkflowNode', blank=True)),
('failure_nodes', models.ManyToManyField(related_name='parent_failure_nodes', to='main.WorkflowNode', blank=True)),
('job', models.ForeignKey(related_name='unified_job_nodes', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to='main.UnifiedJob', null=True)),
('success_nodes', models.ManyToManyField(related_name='parent_success_nodes', to='main.WorkflowNode', blank=True)),
('unified_job_template', models.ForeignKey(related_name='unified_jt_workflow_nodes', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to='main.UnifiedJobTemplate', null=True)),
('workflow_job', models.ForeignKey(related_name='workflow_job_nodes', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to='main.WorkflowJob', null=True)),
('workflow_job_template', models.ForeignKey(related_name='workflow_nodes', default=None, blank=True, to='main.WorkflowJobTemplate', null=True)),
('always_nodes', models.ManyToManyField(related_name='workflowjobtemplatenodes_always', to='main.WorkflowJobTemplateNode', blank=True)),
('failure_nodes', models.ManyToManyField(related_name='workflowjobtemplatenodes_failure', to='main.WorkflowJobTemplateNode', blank=True)),
('success_nodes', models.ManyToManyField(related_name='workflowjobtemplatenodes_success', to='main.WorkflowJobTemplateNode', blank=True)),
('unified_job_template', models.ForeignKey(related_name='workflowjobtemplatenodes', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to='main.UnifiedJobTemplate', null=True)),
('workflow_job_template', models.ForeignKey(related_name='workflow_job_template_nodes', default=None, blank=True, to='main.WorkflowJobTemplate', null=True)),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='workflowjobnode',
name='unified_job_template',
field=models.ForeignKey(related_name='workflowjobnodes', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to='main.UnifiedJobTemplate', null=True),
),
migrations.AddField(
model_name='workflowjobnode',
name='workflow_job',
field=models.ForeignKey(related_name='workflow_job_nodes', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to='main.WorkflowJob', null=True),
),
migrations.AddField(
model_name='workflowjob',
@@ -60,6 +86,11 @@ class Migration(migrations.Migration):
name='workflow_job',
field=models.ManyToManyField(to='main.WorkflowJob', blank=True),
),
migrations.AddField(
model_name='activitystream',
name='workflow_job_node',
field=models.ManyToManyField(to='main.WorkflowJobNode', blank=True),
),
migrations.AddField(
model_name='activitystream',
name='workflow_job_template',
@@ -67,7 +98,7 @@ class Migration(migrations.Migration):
),
migrations.AddField(
model_name='activitystream',
name='workflow_node',
field=models.ManyToManyField(to='main.WorkflowNode', blank=True),
name='workflow_job_template_node',
field=models.ManyToManyField(to='main.WorkflowJobTemplateNode', blank=True),
),
]
+2 -1
View File
@@ -49,7 +49,8 @@ class ActivityStream(models.Model):
permission = models.ManyToManyField("Permission", blank=True)
job_template = models.ManyToManyField("JobTemplate", blank=True)
job = models.ManyToManyField("Job", blank=True)
workflow_node = models.ManyToManyField("WorkflowNode", blank=True)
workflow_job_template_node = models.ManyToManyField("WorkflowJobTemplateNode", blank=True)
workflow_job_node = models.ManyToManyField("WorkflowJobNode", blank=True)
workflow_job_template = models.ManyToManyField("WorkflowJobTemplate", blank=True)
workflow_job = models.ManyToManyField("WorkflowJob", blank=True)
unified_job_template = models.ManyToManyField("UnifiedJobTemplate", blank=True, related_name='activity_stream_as_unified_job_template+')
+44 -43
View File
@@ -18,11 +18,11 @@ from awx.main.models.rbac import (
)
from awx.main.fields import ImplicitRoleField
__all__ = ['WorkflowJobTemplate', 'WorkflowJob', 'WorkflowJobOptions', 'WorkflowNode']
class WorkflowNode(CreatedModifiedModel):
__all__ = ['WorkflowJobTemplate', 'WorkflowJob', 'WorkflowJobOptions', 'WorkflowJobNode', 'WorkflowJobTemplateNode',]
class WorkflowNodeBase(CreatedModifiedModel):
class Meta:
abstract = True
app_label = 'main'
# TODO: RBAC
@@ -31,41 +31,55 @@ class WorkflowNode(CreatedModifiedModel):
parent_role='workflow_job_template.admin_role',
)
'''
# TODO: Ensure the API forces workflow_job_template being set
workflow_job_template = models.ForeignKey(
'WorkflowJobTemplate',
related_name='workflow_nodes',
success_nodes = models.ManyToManyField(
'self',
blank=True,
null=True,
default=None,
on_delete=models.CASCADE,
symmetrical=False,
related_name='%(class)ss_success',
)
failure_nodes = models.ManyToManyField(
'self',
blank=True,
symmetrical=False,
related_name='%(class)ss_failure',
)
always_nodes = models.ManyToManyField(
'self',
blank=True,
symmetrical=False,
related_name='%(class)ss_always',
)
unified_job_template = models.ForeignKey(
'UnifiedJobTemplate',
related_name='unified_jt_workflow_nodes',
related_name='%(class)ss',
blank=True,
null=True,
default=None,
on_delete=models.SET_NULL,
)
success_nodes = models.ManyToManyField(
'self',
related_name='parent_success_nodes',
class WorkflowJobTemplateNode(WorkflowNodeBase):
# TODO: Ensure the API forces workflow_job_template being set
workflow_job_template = models.ForeignKey(
'WorkflowJobTemplate',
related_name='workflow_job_template_nodes',
blank=True,
symmetrical=False,
null=True,
default=None,
on_delete=models.CASCADE,
)
failure_nodes = models.ManyToManyField(
'self',
related_name='parent_failure_nodes',
def get_absolute_url(self):
return reverse('api:workflow_job_template_node_detail', args=(self.pk,))
class WorkflowJobNode(WorkflowNodeBase):
job = models.ForeignKey(
'UnifiedJob',
related_name='unified_job_nodes',
blank=True,
symmetrical=False,
)
always_nodes = models.ManyToManyField(
'self',
related_name='parent_always_nodes',
blank=True,
symmetrical=False,
null=True,
default=None,
on_delete=models.SET_NULL,
)
workflow_job = models.ForeignKey(
'WorkflowJob',
@@ -75,17 +89,9 @@ class WorkflowNode(CreatedModifiedModel):
default=None,
on_delete=models.SET_NULL,
)
job = models.ForeignKey(
'UnifiedJob',
related_name='unified_job_nodes',
blank=True,
null=True,
default=None,
on_delete=models.SET_NULL,
)
def get_absolute_url(self):
return reverse('api:workflow_node_detail', args=(self.pk,))
return reverse('api:workflow_job_node_detail', args=(self.pk,))
class WorkflowJobOptions(BaseModel):
class Meta:
@@ -147,22 +153,17 @@ class WorkflowJobInheritNodesMixin(object):
for old_related_node in old_related_nodes:
new_related_node_id = node_ids_map[old_related_node.id]
new_related_node = WorkflowNode.objects.get(id=new_related_node_id)
new_related_node = WorkflowJobNode.objects.get(id=new_related_node_id)
new_node_type_mgr.add(new_related_node)
def inherit_jt_workflow_nodes(self):
new_nodes = []
old_nodes = self.workflow_job_template.workflow_nodes.all()
old_nodes = self.workflow_job_template.workflow_job_template_nodes.all()
node_ids_map = {}
for old_node in old_nodes:
new_node = WorkflowNode.objects.get(id=old_node.pk)
new_node.workflow_job = self
new_node.job = None
new_node.workflow_job_template = None
new_node.pk = None
new_node.save()
new_node = WorkflowJobNode.objects.create(workflow_job=self, unified_job_template=old_node.unified_job_template)
new_nodes.append(new_node)
node_ids_map[old_node.id] = new_node.id
+8 -8
View File
@@ -1,6 +1,6 @@
# AWX
from awx.main.models import (
WorkflowNode,
WorkflowJobTemplateNode,
WorkflowJobTemplate,
)
from awx.main.models.jobs import JobTemplate
@@ -10,16 +10,16 @@ def do_init_workflow(job_template_success, job_template_fail, job_template_never
wfjt.delete()
wfjt, created = WorkflowJobTemplate.objects.get_or_create(name="linear workflow")
print(wfjt.id)
WorkflowNode.objects.all().delete()
WorkflowJobTemplateNode.objects.all().delete()
if created:
nodes_success = []
nodes_fail = []
nodes_never = []
for i in range(0, 2):
nodes_success.append(WorkflowNode.objects.create(workflow_job_template=wfjt, unified_job_template=job_template_success))
nodes_fail.append(WorkflowNode.objects.create(workflow_job_template=wfjt, unified_job_template=job_template_fail))
nodes_never.append(WorkflowNode.objects.create(workflow_job_template=wfjt, unified_job_template=job_template_never))
nodes_never.append(WorkflowNode.objects.create(workflow_job_template=wfjt, unified_job_template=job_template_never))
nodes_success.append(WorkflowJobTemplateNode.objects.create(workflow_job_template=wfjt, unified_job_template=job_template_success))
nodes_fail.append(WorkflowJobTemplateNode.objects.create(workflow_job_template=wfjt, unified_job_template=job_template_fail))
nodes_never.append(WorkflowJobTemplateNode.objects.create(workflow_job_template=wfjt, unified_job_template=job_template_never))
nodes_never.append(WorkflowJobTemplateNode.objects.create(workflow_job_template=wfjt, unified_job_template=job_template_never))
nodes_fail[1].delete()
nodes_success[0].success_nodes.add(nodes_fail[0])
@@ -32,8 +32,8 @@ def do_init_workflow(job_template_success, job_template_fail, job_template_never
def do_init():
jt_success = JobTemplate.objects.get(id=5)
jt_fail= JobTemplate.objects.get(id=9)
jt_never= JobTemplate.objects.get(id=11)
jt_fail= JobTemplate.objects.get(id=6)
jt_never= JobTemplate.objects.get(id=7)
do_init_workflow(jt_success, jt_fail, jt_never)
if __name__ == "__main__":
+2 -2
View File
@@ -32,8 +32,8 @@ def do_init_workflow(job_template_success, job_template_fail, job_template_never
def do_init():
jt_success = JobTemplate.objects.get(id=5)
jt_fail= JobTemplate.objects.get(id=9)
jt_never= JobTemplate.objects.get(id=11)
jt_fail= JobTemplate.objects.get(id=6)
jt_never= JobTemplate.objects.get(id=7)
jt_parallel = []
jt_parallel.append(JobTemplate.objects.get(id=16))