mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 08:21:15 +03:00
Merge pull request #3061 from jakemcdermott/inventory-scm-job-linkage
add linked status indicator for scm inventory project updates Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
This commit is contained in:
commit
2a86c5b944
@ -2209,6 +2209,44 @@ class InventoryUpdateSerializer(UnifiedJobSerializer, InventorySourceOptionsSeri
|
||||
return res
|
||||
|
||||
|
||||
class InventoryUpdateDetailSerializer(InventoryUpdateSerializer):
|
||||
|
||||
source_project = serializers.SerializerMethodField(
|
||||
help_text=_('The project used for this job.'),
|
||||
method_name='get_source_project_id'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = InventoryUpdate
|
||||
fields = ('*', 'source_project',)
|
||||
|
||||
def get_source_project(self, obj):
|
||||
return getattrd(obj, 'source_project_update.unified_job_template', None)
|
||||
|
||||
def get_source_project_id(self, obj):
|
||||
return getattrd(obj, 'source_project_update.unified_job_template.id', None)
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(InventoryUpdateDetailSerializer, self).get_related(obj)
|
||||
source_project_id = self.get_source_project_id(obj)
|
||||
|
||||
if source_project_id:
|
||||
res['source_project'] = self.reverse('api:project_detail', kwargs={'pk': source_project_id})
|
||||
return res
|
||||
|
||||
def get_summary_fields(self, obj):
|
||||
summary_fields = super(InventoryUpdateDetailSerializer, self).get_summary_fields(obj)
|
||||
summary_obj = self.get_source_project(obj)
|
||||
|
||||
if summary_obj:
|
||||
summary_fields['source_project'] = {}
|
||||
for field in SUMMARIZABLE_FK_FIELDS['project']:
|
||||
value = getattr(summary_obj, field, None)
|
||||
if value is not None:
|
||||
summary_fields['source_project'][field] = value
|
||||
return summary_fields
|
||||
|
||||
|
||||
class InventoryUpdateListSerializer(InventoryUpdateSerializer, UnifiedJobListSerializer):
|
||||
|
||||
class Meta:
|
||||
|
@ -1972,7 +1972,7 @@ class InventoryInventorySourcesUpdate(RetrieveAPIView):
|
||||
details['status'] = None
|
||||
if inventory_source.can_update:
|
||||
update = inventory_source.update()
|
||||
details.update(InventoryUpdateSerializer(update, context=self.get_serializer_context()).to_representation(update))
|
||||
details.update(InventoryUpdateDetailSerializer(update, context=self.get_serializer_context()).to_representation(update))
|
||||
details['status'] = 'started'
|
||||
details['inventory_update'] = update.id
|
||||
successes += 1
|
||||
@ -2135,7 +2135,7 @@ class InventorySourceUpdateView(RetrieveAPIView):
|
||||
headers = {'Location': update.get_absolute_url(request=request)}
|
||||
data = OrderedDict()
|
||||
data['inventory_update'] = update.id
|
||||
data.update(InventoryUpdateSerializer(update, context=self.get_serializer_context()).to_representation(update))
|
||||
data.update(InventoryUpdateDetailSerializer(update, context=self.get_serializer_context()).to_representation(update))
|
||||
return Response(data, status=status.HTTP_202_ACCEPTED, headers=headers)
|
||||
else:
|
||||
return self.http_method_not_allowed(request, *args, **kwargs)
|
||||
@ -2150,7 +2150,7 @@ class InventoryUpdateList(ListAPIView):
|
||||
class InventoryUpdateDetail(UnifiedJobDeletionMixin, RetrieveDestroyAPIView):
|
||||
|
||||
model = InventoryUpdate
|
||||
serializer_class = InventoryUpdateSerializer
|
||||
serializer_class = InventoryUpdateDetailSerializer
|
||||
|
||||
|
||||
class InventoryUpdateCredentialsList(SubListAPIView):
|
||||
|
@ -113,7 +113,7 @@ class TestInventoryInventorySourcesUpdate:
|
||||
|
||||
with mocker.patch.object(InventoryInventorySourcesUpdate, 'get_object', return_value=obj):
|
||||
with mocker.patch.object(InventoryInventorySourcesUpdate, 'get_serializer_context', return_value=None):
|
||||
with mocker.patch('awx.api.views.InventoryUpdateSerializer') as serializer_class:
|
||||
with mocker.patch('awx.api.views.InventoryUpdateDetailSerializer') as serializer_class:
|
||||
serializer = serializer_class.return_value
|
||||
serializer.to_representation.return_value = {}
|
||||
|
||||
|
@ -187,6 +187,12 @@ function getInventorySourceDetails () {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (resource.model.get('summary_fields.inventory_source.source') === 'scm') {
|
||||
// we already show a SOURCE PROJECT item for scm inventory updates, so we
|
||||
// skip the display of the standard source details item.
|
||||
return null;
|
||||
}
|
||||
|
||||
const { source } = resource.model.get('summary_fields.inventory_source');
|
||||
const choices = mapChoices(resource.model.options('actions.GET.source.choices'));
|
||||
|
||||
@ -324,6 +330,33 @@ function getProjectUpdateDetails (updateId) {
|
||||
return { link, tooltip };
|
||||
}
|
||||
|
||||
function getInventoryScmDetails (updateId, updateStatus) {
|
||||
const projectId = resource.model.get('summary_fields.source_project.id');
|
||||
const projectName = resource.model.get('summary_fields.source_project.name');
|
||||
const jobId = updateId || resource.model.get('source_project_update');
|
||||
const status = updateStatus || resource.model.get('summary_fields.inventory_source.status');
|
||||
|
||||
if (!projectId || !projectName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = strings.get('labels.INVENTORY_SCM');
|
||||
const jobLink = `/#/jobs/project/${jobId}`;
|
||||
const link = `/#/projects/${projectId}`;
|
||||
const jobTooltip = strings.get('tooltips.INVENTORY_SCM_JOB');
|
||||
const tooltip = strings.get('tooltips.INVENTORY_SCM');
|
||||
|
||||
let icon;
|
||||
|
||||
if (status === 'unknown') {
|
||||
icon = 'fa icon-job-pending';
|
||||
} else {
|
||||
icon = `fa icon-job-${status}`;
|
||||
}
|
||||
|
||||
return { label, link, icon, jobLink, jobTooltip, tooltip, value: projectName };
|
||||
}
|
||||
|
||||
function getSCMRevisionDetails () {
|
||||
const label = strings.get('labels.SCM_REVISION');
|
||||
const value = resource.model.get('scm_revision');
|
||||
@ -718,6 +751,7 @@ function JobDetailsController (
|
||||
vm.projectUpdate = getProjectUpdateDetails();
|
||||
vm.projectStatus = getProjectStatusDetails();
|
||||
vm.scmRevision = getSCMRevisionDetails();
|
||||
vm.inventoryScm = getInventoryScmDetails();
|
||||
vm.playbook = getPlaybookDetails();
|
||||
vm.resultTraceback = getResultTracebackDetails();
|
||||
vm.launchedBy = getLaunchedByDetails();
|
||||
@ -748,12 +782,13 @@ function JobDetailsController (
|
||||
vm.toggleLabels = toggleLabels;
|
||||
vm.showLabels = showLabels;
|
||||
|
||||
unsubscribe = subscribe(({ status, started, finished, scm, environment }) => {
|
||||
unsubscribe = subscribe(({ status, started, finished, scm, inventoryScm, environment }) => {
|
||||
vm.started = getStartDetails(started);
|
||||
vm.finished = getFinishDetails(finished);
|
||||
vm.projectUpdate = getProjectUpdateDetails(scm.id);
|
||||
vm.projectStatus = getProjectStatusDetails(scm.status);
|
||||
vm.environment = getEnvironmentDetails(environment);
|
||||
vm.inventoryScm = getInventoryScmDetails(inventoryScm.id, inventoryScm.status);
|
||||
vm.status = getStatusDetails(status);
|
||||
vm.job.status = status;
|
||||
});
|
||||
|
@ -198,6 +198,27 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- INVENTORY SCM DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="!vm.project && vm.inventoryScm">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.inventoryScm.label }}</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
<span>
|
||||
<a href="{{ vm.inventoryScm.jobLink }}"
|
||||
aw-tool-tip="{{ vm.inventoryScm.jobTooltip }}"
|
||||
data-placement="top">
|
||||
<i class="JobResults-statusResultIcon {{ vm.inventoryScm.icon }}"></i>
|
||||
</a>
|
||||
</span>
|
||||
<span>
|
||||
<a href="{{ vm.inventoryScm.link }}"
|
||||
aw-tool-tip="{{ vm.inventoryScm.tooltip }}"
|
||||
data-placement="top">
|
||||
{{ vm.inventoryScm.value }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- REVISION DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.scmRevision">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.scmRevision.label }}</label>
|
||||
|
@ -22,6 +22,8 @@ function OutputStrings (BaseString) {
|
||||
EXPAND_OUTPUT: t.s('Expand Output'),
|
||||
EXTRA_VARS: t.s('Read-only view of extra variables added to the job template'),
|
||||
INVENTORY: t.s('View the Inventory'),
|
||||
INVENTORY_SCM: t.s('View the Project'),
|
||||
INVENTORY_SCM_JOB: t.s('View Project checkout results'),
|
||||
JOB_TEMPLATE: t.s('View the Job Template'),
|
||||
SLICE_JOB_DETAILS: t.s('Job is one of several from a JT that slices on inventory'),
|
||||
PROJECT: t.s('View the Project'),
|
||||
@ -54,6 +56,7 @@ function OutputStrings (BaseString) {
|
||||
FORKS: t.s('Forks'),
|
||||
INSTANCE_GROUP: t.s('Instance Group'),
|
||||
INVENTORY: t.s('Inventory'),
|
||||
INVENTORY_SCM: t.s('Source Project'),
|
||||
JOB_EXPLANATION: t.s('Explanation'),
|
||||
JOB_TAGS: t.s('Job Tags'),
|
||||
JOB_TEMPLATE: t.s('Job Template'),
|
||||
|
@ -44,6 +44,10 @@ function JobStatusService (moment, message) {
|
||||
id: model.get('summary_fields.project_update.id'),
|
||||
status: model.get('summary_fields.project_update.status')
|
||||
},
|
||||
inventoryScm: {
|
||||
id: model.get('source_project_update'),
|
||||
status: model.get('summary_fields.inventory_source.status')
|
||||
}
|
||||
};
|
||||
|
||||
this.initHostStatusCounts({ model });
|
||||
@ -86,6 +90,7 @@ function JobStatusService (moment, message) {
|
||||
this.pushStatusEvent = data => {
|
||||
const isJobStatusEvent = (this.job === data.unified_job_id);
|
||||
const isProjectStatusEvent = (this.project && (this.project === data.project_id));
|
||||
const isInventoryScmStatus = (this.model.get('source_project_update') === data.unified_job_id);
|
||||
|
||||
if (isJobStatusEvent) {
|
||||
this.setJobStatus(data.status);
|
||||
@ -94,6 +99,10 @@ function JobStatusService (moment, message) {
|
||||
this.setProjectStatus(data.status);
|
||||
this.setProjectUpdateId(data.unified_job_id);
|
||||
this.dispatch();
|
||||
} else if (isInventoryScmStatus) {
|
||||
this.setInventoryScmStatus(data.status);
|
||||
this.setInventoryScmId(data.unified_job_id);
|
||||
this.dispatch();
|
||||
}
|
||||
};
|
||||
|
||||
@ -249,6 +258,14 @@ function JobStatusService (moment, message) {
|
||||
this.state.scm.id = id;
|
||||
};
|
||||
|
||||
this.setInventoryScmStatus = status => {
|
||||
this.state.inventoryScm.status = status;
|
||||
};
|
||||
|
||||
this.setInventoryScmId = id => {
|
||||
this.state.inventoryScm.id = id;
|
||||
};
|
||||
|
||||
this.setFinished = time => {
|
||||
if (!time) return;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user