mirror of
https://github.com/ansible/awx.git
synced 2026-02-27 07:56:06 -03:30
Merge branch 'devel' of github.com:ansible/ansible-tower into 11th-hour
This commit is contained in:
@@ -463,9 +463,10 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, ResourceMixin):
|
|||||||
success_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_success__in=[self, self.project]))
|
success_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_success__in=[self, self.project]))
|
||||||
any_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_any__in=[self, self.project]))
|
any_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_any__in=[self, self.project]))
|
||||||
# Get Organization Notifiers
|
# Get Organization Notifiers
|
||||||
error_notifiers = set(error_notifiers + list(base_notifiers.filter(organization_notifiers_for_errors=self.project.organization)))
|
if self.project is not None and self.project.organization is not None:
|
||||||
success_notifiers = set(success_notifiers + list(base_notifiers.filter(organization_notifiers_for_success=self.project.organization)))
|
error_notifiers = set(error_notifiers + list(base_notifiers.filter(organization_notifiers_for_errors=self.project.organization)))
|
||||||
any_notifiers = set(any_notifiers + list(base_notifiers.filter(organization_notifiers_for_any=self.project.organization)))
|
success_notifiers = set(success_notifiers + list(base_notifiers.filter(organization_notifiers_for_success=self.project.organization)))
|
||||||
|
any_notifiers = set(any_notifiers + list(base_notifiers.filter(organization_notifiers_for_any=self.project.organization)))
|
||||||
return dict(error=list(error_notifiers), success=list(success_notifiers), any=list(any_notifiers))
|
return dict(error=list(error_notifiers), success=list(success_notifiers), any=list(any_notifiers))
|
||||||
|
|
||||||
class Job(UnifiedJob, JobOptions):
|
class Job(UnifiedJob, JobOptions):
|
||||||
@@ -533,14 +534,13 @@ class Job(UnifiedJob, JobOptions):
|
|||||||
def is_blocked_by(self, obj):
|
def is_blocked_by(self, obj):
|
||||||
from awx.main.models import InventoryUpdate, ProjectUpdate
|
from awx.main.models import InventoryUpdate, ProjectUpdate
|
||||||
if type(obj) == Job:
|
if type(obj) == Job:
|
||||||
if obj.job_template is not None and obj.job_template == self.job_template:
|
if obj.job_template is not None and obj.inventory is not None:
|
||||||
if obj.launch_type == 'callback' and self.launch_type == 'callback':
|
if obj.job_template == self.job_template and \
|
||||||
if obj.limit != self.limit:
|
obj.inventory == self.inventory:
|
||||||
# NOTE: This is overriden by api/views.py.JobTemplateCallback.post() check
|
if obj.launch_type == 'callback' and self.launch_type == 'callback' and \
|
||||||
# which limits job runs on a JT to one per host in a callback scenario
|
obj.limit != self.limit:
|
||||||
# I'm leaving this here in case we change that
|
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
if type(obj) == InventoryUpdate:
|
if type(obj) == InventoryUpdate:
|
||||||
if self.inventory == obj.inventory_source.inventory:
|
if self.inventory == obj.inventory_source.inventory:
|
||||||
|
|||||||
@@ -362,9 +362,10 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin):
|
|||||||
success_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_success=self))
|
success_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_success=self))
|
||||||
any_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_any=self))
|
any_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_any=self))
|
||||||
# Get Organization Notifiers
|
# Get Organization Notifiers
|
||||||
error_notifiers = set(error_notifiers + list(base_notifiers.filter(organization_notifiers_for_errors=self.organization)))
|
if self.organization is not None:
|
||||||
success_notifiers = set(success_notifiers + list(base_notifiers.filter(organization_notifiers_for_success=self.organization)))
|
error_notifiers = set(error_notifiers + list(base_notifiers.filter(organization_notifiers_for_errors=self.organization)))
|
||||||
any_notifiers = set(any_notifiers + list(base_notifiers.filter(organization_notifiers_for_any=self.organization)))
|
success_notifiers = set(success_notifiers + list(base_notifiers.filter(organization_notifiers_for_success=self.organization)))
|
||||||
|
any_notifiers = set(any_notifiers + list(base_notifiers.filter(organization_notifiers_for_any=self.organization)))
|
||||||
return dict(error=list(error_notifiers), success=list(success_notifiers), any=list(any_notifiers))
|
return dict(error=list(error_notifiers), success=list(success_notifiers), any=list(any_notifiers))
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ from awx.main.models.credential import Credential
|
|||||||
from awx.main.models.jobs import JobTemplate
|
from awx.main.models.jobs import JobTemplate
|
||||||
from awx.main.models.inventory import (
|
from awx.main.models.inventory import (
|
||||||
Group,
|
Group,
|
||||||
|
Inventory,
|
||||||
)
|
)
|
||||||
from awx.main.models.organization import (
|
from awx.main.models.organization import (
|
||||||
Organization,
|
Organization,
|
||||||
@@ -175,6 +176,16 @@ def machine_credential():
|
|||||||
def inventory(organization):
|
def inventory(organization):
|
||||||
return organization.inventories.create(name="test-inv")
|
return organization.inventories.create(name="test-inv")
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def inventory_factory(organization):
|
||||||
|
def factory(name, org=organization):
|
||||||
|
try:
|
||||||
|
inv = Inventory.objects.get(name=name, organization=org)
|
||||||
|
except Inventory.DoesNotExist:
|
||||||
|
inv = Inventory.objects.create(name=name, organization=org)
|
||||||
|
return inv
|
||||||
|
return factory
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def label(organization):
|
def label(organization):
|
||||||
return organization.labels.create(name="test-label", description="test-label-desc")
|
return organization.labels.create(name="test-label", description="test-label-desc")
|
||||||
|
|||||||
24
awx/main/tests/functional/test_jobs.py
Normal file
24
awx/main/tests/functional/test_jobs.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
from awx.main.models import Job
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_job_blocking(get, post, job_template, inventory, inventory_factory):
|
||||||
|
j1 = Job.objects.create(job_template=job_template,
|
||||||
|
inventory=inventory)
|
||||||
|
j2 = Job.objects.create(job_template=job_template,
|
||||||
|
inventory=inventory)
|
||||||
|
assert j1.is_blocked_by(j2)
|
||||||
|
j2.inventory = inventory_factory(name='test-different-inventory')
|
||||||
|
assert not j1.is_blocked_by(j2)
|
||||||
|
j_callback_1 = Job.objects.create(job_template=job_template,
|
||||||
|
inventory=inventory,
|
||||||
|
launch_type='callback',
|
||||||
|
limit='a')
|
||||||
|
j_callback_2 = Job.objects.create(job_template=job_template,
|
||||||
|
inventory=inventory,
|
||||||
|
launch_type='callback',
|
||||||
|
limit='a')
|
||||||
|
assert j_callback_1.is_blocked_by(j_callback_2)
|
||||||
|
j_callback_2.limit = 'b'
|
||||||
|
assert not j_callback_1.is_blocked_by(j_callback_2)
|
||||||
@@ -49,7 +49,6 @@
|
|||||||
padding: 1em 12px;
|
padding: 1em 12px;
|
||||||
color: @default-as-detail-txt;
|
color: @default-as-detail-txt;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-column {
|
&-column {
|
||||||
|
|||||||
@@ -1,31 +1,3 @@
|
|||||||
// /** @define FactModulePickers */
|
|
||||||
//
|
|
||||||
// .FactModulePickers {
|
|
||||||
// //width: 100%;
|
|
||||||
// display: flex;
|
|
||||||
// margin-bottom: 15px;
|
|
||||||
//
|
|
||||||
// &-dateContainer {
|
|
||||||
// flex: 1 0 auto;
|
|
||||||
// display: flex;
|
|
||||||
// flex-direction: column
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// &-dateContainer--left {
|
|
||||||
// margin-right: 7px;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// &-dateContainer--right {
|
|
||||||
// margin-left: 7px;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// &-label {
|
|
||||||
// flex: 1 0 auto;
|
|
||||||
// font-weight: 700;
|
|
||||||
// padding-bottom: 5px;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@import "../../shared/branding/colors.default.less";
|
@import "../../shared/branding/colors.default.less";
|
||||||
|
|
||||||
.FactModulePickers-label {
|
.FactModulePickers-label {
|
||||||
@@ -36,3 +8,11 @@
|
|||||||
color: @default-interface-txt;
|
color: @default-interface-txt;
|
||||||
line-height: 17px;
|
line-height: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.FactModulePickers-warning {
|
||||||
|
float: right;
|
||||||
|
clear: both;
|
||||||
|
font-size: 12px;
|
||||||
|
width: 75%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ export default {
|
|||||||
templateUrl: templateUrl('system-tracking/system-tracking'),
|
templateUrl: templateUrl('system-tracking/system-tracking'),
|
||||||
params: {hosts: null, inventory: null},
|
params: {hosts: null, inventory: null},
|
||||||
reloadOnSearch: false,
|
reloadOnSearch: false,
|
||||||
|
ncyBreadcrumb: {
|
||||||
|
label: "SYSTEM TRACKING"
|
||||||
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
moduleOptions:
|
moduleOptions:
|
||||||
[ 'getModuleOptions',
|
[ 'getModuleOptions',
|
||||||
|
|||||||
Reference in New Issue
Block a user