mirror of
https://github.com/ansible/awx.git
synced 2026-01-17 04:31:21 -03:30
Merge pull request #6334 from mabashian/5815-inventory-sync
Inventory sync fixes
This commit is contained in:
commit
606a47c324
3
awx/ui/client/src/inventories/inventories.block.less
Normal file
3
awx/ui/client/src/inventories/inventories.block.less
Normal file
@ -0,0 +1,3 @@
|
||||
.Inventories-hostStatus {
|
||||
margin-left: 5px;
|
||||
}
|
||||
@ -22,16 +22,22 @@ export default ['i18n', function(i18n) {
|
||||
fields: {
|
||||
status: {
|
||||
label: '',
|
||||
columnClass: 'col-md-1 col-sm-2 col-xs-2 List-staticColumn--smallStatus',
|
||||
columnClass: 'List-staticColumn--mediumStatus',
|
||||
nosort: true,
|
||||
ngClick: "null",
|
||||
iconOnly: true,
|
||||
excludeModal: true,
|
||||
icons: [{
|
||||
icon: "{{ 'icon-cloud-' + inventory.syncStatus }}",
|
||||
awToolTip: "{{ inventory.syncTip }}",
|
||||
awTipPlacement: "right",
|
||||
ngClick: "showSourceSummary($event, inventory.id)",
|
||||
ngClass: "inventory.launch_class"
|
||||
},{
|
||||
icon: "{{ 'icon-job-' + inventory.hostsStatus }}",
|
||||
awToolTip: false,
|
||||
ngClick: "showHostSummary($event, inventory.id)",
|
||||
ngClass: ""
|
||||
ngClass: "inventory.host_status_class"
|
||||
}]
|
||||
},
|
||||
name: {
|
||||
@ -87,6 +93,13 @@ export default ['i18n', function(i18n) {
|
||||
|
||||
columnClass: 'col-md-2 col-sm-3 col-xs-4',
|
||||
|
||||
inventory_update: {
|
||||
mode: 'all',
|
||||
ngClick: 'syncInventory(inventory)',
|
||||
awToolTip: i18n._('Sync all inventory sources'),
|
||||
ngShow: "inventory.kind === '' && inventory.has_inventory_sources",
|
||||
dataPlacement: "top",
|
||||
},
|
||||
edit: {
|
||||
label: i18n._('Edit'),
|
||||
ngClick: 'editInventory(inventory)',
|
||||
|
||||
@ -12,7 +12,8 @@
|
||||
|
||||
function InventoriesList($scope, $rootScope, $location,
|
||||
$compile, $filter, Rest, InventoryList, Prompt,
|
||||
ProcessErrors, GetBasePath, Wait, Find, Empty, $state, rbacUiControlService, Dataset) {
|
||||
ProcessErrors, GetBasePath, Wait, Find, Empty, $state,
|
||||
rbacUiControlService, Dataset, InventoryUpdate) {
|
||||
|
||||
let list = InventoryList,
|
||||
defaultUrl = GetBasePath('inventory');
|
||||
@ -37,7 +38,6 @@ function InventoriesList($scope, $rootScope, $location,
|
||||
$scope[list.name] = $scope[`${list.iterator}_dataset`].results;
|
||||
|
||||
$rootScope.flashMessage = null;
|
||||
|
||||
}
|
||||
|
||||
function processInventoryRow(inventory) {
|
||||
@ -47,10 +47,12 @@ function InventoriesList($scope, $rootScope, $location,
|
||||
|
||||
function buildStatusIndicators(inventory){
|
||||
inventory.launch_class = "";
|
||||
inventory.host_status_class = "Inventories-hostStatus";
|
||||
|
||||
if (inventory.has_inventory_sources) {
|
||||
if (inventory.inventory_sources_with_failures > 0) {
|
||||
inventory.syncStatus = 'error';
|
||||
inventory.syncTip = inventory.inventory_sources_with_failures + ' groups with sync failures. Click for details';
|
||||
inventory.syncTip = inventory.inventory_sources_with_failures + ' sources with sync failures. Click for details';
|
||||
}
|
||||
else {
|
||||
inventory.syncStatus = 'successful';
|
||||
@ -62,6 +64,7 @@ function InventoriesList($scope, $rootScope, $location,
|
||||
inventory.syncTip = 'Not configured for inventory sync.';
|
||||
inventory.launch_class = "btn-disabled";
|
||||
}
|
||||
|
||||
if (inventory.has_active_failures) {
|
||||
inventory.hostsStatus = 'error';
|
||||
inventory.hostsTip = inventory.hosts_with_active_failures + ' hosts with failures. Click for details.';
|
||||
@ -148,10 +151,10 @@ function InventoriesList($scope, $rootScope, $location,
|
||||
attachElem(event, html, title);
|
||||
});
|
||||
|
||||
if ($scope.removeGroupSummaryReady) {
|
||||
$scope.removeGroupSummaryReady();
|
||||
if ($scope.removeSourceSummaryReady) {
|
||||
$scope.removeSourceSummaryReady();
|
||||
}
|
||||
$scope.removeGroupSummaryReady = $scope.$on('GroupSummaryReady', function(e, event, inventory, data) {
|
||||
$scope.removeSourceSummaryReady = $scope.$on('SourceSummaryReady', function(e, event, inventory, data) {
|
||||
var html, title;
|
||||
|
||||
Wait('stop');
|
||||
@ -162,7 +165,7 @@ function InventoriesList($scope, $rootScope, $location,
|
||||
html += "<tr>";
|
||||
html += "<th>Status</th>";
|
||||
html += "<th>Last Sync</th>";
|
||||
html += "<th>Group</th>";
|
||||
html += "<th>Source</th>";
|
||||
html += "</tr>";
|
||||
html += "</thead>\n";
|
||||
html += "<tbody>\n";
|
||||
@ -171,14 +174,14 @@ function InventoriesList($scope, $rootScope, $location,
|
||||
html += "<tr>";
|
||||
html += `<td><a href="" ng-click="viewJob('${row.related.last_update}')" aw-tool-tip="${row.status.charAt(0).toUpperCase() + row.status.slice(1)}. Click for details" aw-tip-placement="top"><i class="SmartStatus-tooltip--${row.status} fa icon-job-${row.status}"></i></a></td>`;
|
||||
html += "<td>" + ($filter('longDate')(row.last_updated)).replace(/ /,'<br />') + "</td>";
|
||||
html += "<td><a href=\"\" ng-click=\"viewJob('" + row.related.last_update + "')\">" + $filter('sanitize')(ellipsis(row.summary_fields.group.name)) + "</a></td>";
|
||||
html += "<td><a href=\"\" ng-click=\"viewJob('" + row.related.last_update + "')\">" + $filter('sanitize')(ellipsis(row.name)) + "</a></td>";
|
||||
html += "</tr>\n";
|
||||
}
|
||||
else {
|
||||
html += "<tr>";
|
||||
html += "<td><a href=\"\" aw-tool-tip=\"No sync data\" aw-tip-placement=\"top\"><i class=\"fa icon-job-none\"></i></a></td>";
|
||||
html += "<td>NA</td>";
|
||||
html += "<td><a href=\"\">" + $filter('sanitize')(ellipsis(row.summary_fields.group.name)) + "</a></td>";
|
||||
html += "<td><a href=\"\">" + $filter('sanitize')(ellipsis(row.name)) + "</a></td>";
|
||||
html += "</tr>\n";
|
||||
}
|
||||
});
|
||||
@ -188,7 +191,7 @@ function InventoriesList($scope, $rootScope, $location,
|
||||
attachElem(event, html, title);
|
||||
});
|
||||
|
||||
$scope.showGroupSummary = function(event, id) {
|
||||
$scope.showSourceSummary = function(event, id) {
|
||||
try{
|
||||
var elem = $(event.target).parent();
|
||||
// if the popover is visible already, then exit the function here
|
||||
@ -202,10 +205,10 @@ function InventoriesList($scope, $rootScope, $location,
|
||||
inventory = Find({ list: $scope.inventories, key: 'id', val: id });
|
||||
if (inventory.syncStatus !== 'na') {
|
||||
Wait('start');
|
||||
Rest.setUrl(inventory.related.inventory_sources + '?or__source=ec2&or__source=rax&order_by=-last_job_run&page_size=5');
|
||||
Rest.setUrl(inventory.related.inventory_sources + '?order_by=-last_job_run&page_size=5');
|
||||
Rest.get()
|
||||
.success(function(data) {
|
||||
$scope.$emit('GroupSummaryReady', event, inventory, data);
|
||||
$scope.$emit('SourceSummaryReady', event, inventory, data);
|
||||
})
|
||||
.error(function(data, status) {
|
||||
ProcessErrors( $scope, data, status, null, { hdr: 'Error!',
|
||||
@ -310,9 +313,18 @@ function InventoriesList($scope, $rootScope, $location,
|
||||
$scope.viewFailedJobs = function (id) {
|
||||
$location.url('/jobs/?inventory__int=' + id + '&status=failed');
|
||||
};
|
||||
|
||||
$scope.syncInventory = function(inventory) {
|
||||
InventoryUpdate({
|
||||
scope: $scope,
|
||||
url: inventory.related.update_inventory_sources,
|
||||
updateAllSources: true
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default ['$scope', '$rootScope', '$location',
|
||||
'$compile', '$filter', 'Rest', 'InventoryList',
|
||||
'Prompt', 'ProcessErrors', 'GetBasePath', 'Wait', 'Find', 'Empty', '$state', 'rbacUiControlService', 'Dataset', InventoriesList
|
||||
'$compile', '$filter', 'Rest', 'InventoryList', 'Prompt',
|
||||
'ProcessErrors', 'GetBasePath', 'Wait', 'Find', 'Empty',
|
||||
'$state', 'rbacUiControlService', 'Dataset', 'InventoryUpdate', InventoriesList
|
||||
];
|
||||
|
||||
@ -8,12 +8,12 @@
|
||||
'InventoryUpdate', 'GroupManageService', 'CancelSourceUpdate',
|
||||
'ViewUpdateStatus', 'rbacUiControlService', 'GetBasePath',
|
||||
'GetSyncStatusMsg', 'Dataset', 'Find', 'QuerySet',
|
||||
'inventoryData', '$filter', 'Prompt', 'Wait', 'SourcesService',
|
||||
'inventoryData', '$filter', 'Prompt', 'Wait', 'SourcesService', 'inventorySourceOptions',
|
||||
function($scope, $rootScope, $state, $stateParams, SourcesListDefinition,
|
||||
InventoryUpdate, GroupManageService, CancelSourceUpdate,
|
||||
ViewUpdateStatus, rbacUiControlService, GetBasePath, GetSyncStatusMsg,
|
||||
Dataset, Find, qs, inventoryData, $filter, Prompt,
|
||||
Wait, SourcesService){
|
||||
Wait, SourcesService, inventorySourceOptions){
|
||||
|
||||
let list = SourcesListDefinition;
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
|
||||
$scope.inventory_id = $stateParams.inventory_id;
|
||||
_.forEach($scope[list.name], buildStatusIndicators);
|
||||
optionsRequestDataProcessing();
|
||||
|
||||
$scope.$on(`ws-jobs`, function(e, data){
|
||||
var inventory_source = Find({ list: $scope.inventory_sources, key: 'id', val: data.inventory_source_id });
|
||||
@ -52,6 +53,7 @@
|
||||
$scope[`${list.iterator}_dataset`] = searchResponse.data;
|
||||
$scope[list.name] = $scope[`${list.iterator}_dataset`].results;
|
||||
_.forEach($scope[list.name], buildStatusIndicators);
|
||||
optionsRequestDataProcessing();
|
||||
});
|
||||
} else {
|
||||
var status = GetSyncStatusMsg({
|
||||
@ -64,6 +66,28 @@
|
||||
inventory_source.launch_class = status.launch_class;
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watchCollection(`${$scope.list.name}`, function() {
|
||||
_.forEach($scope[list.name], buildStatusIndicators);
|
||||
optionsRequestDataProcessing();
|
||||
});
|
||||
}
|
||||
|
||||
function optionsRequestDataProcessing(){
|
||||
if ($scope[list.name] !== undefined) {
|
||||
$scope[list.name].forEach(function(item, item_idx) {
|
||||
var itm = $scope[list.name][item_idx];
|
||||
|
||||
// Set the item source label
|
||||
if (list.fields.source && inventorySourceOptions && inventorySourceOptions.hasOwnProperty('source')) {
|
||||
inventorySourceOptions.source.choices.forEach(function(choice) {
|
||||
if (choice[0] === item.source) {
|
||||
itm.source_label = choice[1];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function buildStatusIndicators(inventory_source){
|
||||
|
||||
@ -42,6 +42,9 @@ export default {
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
inventorySourceOptions: ['SourcesService', (SourcesService) => {
|
||||
return SourcesService.options().then(res => res.data.actions.GET);
|
||||
}],
|
||||
Dataset: ['SourcesListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', '$interpolate', '$rootScope',
|
||||
(list, qs, $stateParams, GetBasePath, $interpolate, $rootScope) => {
|
||||
// allow related list definitions to use interpolated $rootScope / $stateParams in basePath field
|
||||
|
||||
@ -33,8 +33,13 @@ export default {
|
||||
label: 'Sources',
|
||||
key: true,
|
||||
ngClick: "editSource(inventory_source.id)",
|
||||
columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6',
|
||||
columnClass: 'col-lg-4 col-md-4 col-sm-4 col-xs-4',
|
||||
class: 'InventoryManage-breakWord',
|
||||
},
|
||||
source: {
|
||||
label: 'Type',
|
||||
ngBind: 'inventory_source.source_label',
|
||||
columnClass: 'col-lg-4 col-md-4 col-sm-4 col-xs-4'
|
||||
}
|
||||
},
|
||||
|
||||
@ -60,7 +65,7 @@ export default {
|
||||
|
||||
fieldActions: {
|
||||
|
||||
columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6 text-right',
|
||||
columnClass: 'col-lg-4 col-md-4 col-sm-4 col-xs-4 text-right',
|
||||
|
||||
group_update: {
|
||||
//label: 'Sync',
|
||||
|
||||
@ -54,6 +54,13 @@ export default
|
||||
.error(this.error.bind(this))
|
||||
.finally(Wait('stop'));
|
||||
},
|
||||
options: function(){
|
||||
this.url = GetBasePath('inventory_sources');
|
||||
Rest.setUrl(this.url);
|
||||
return Rest.options()
|
||||
.success(this.success.bind(this))
|
||||
.error(this.error.bind(this));
|
||||
},
|
||||
getCredential: function(id){
|
||||
Wait('start');
|
||||
this.url = GetBasePath('credentials') + id;
|
||||
|
||||
@ -43,19 +43,33 @@ export default
|
||||
Rest.setUrl(url);
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
inventory_source = data;
|
||||
if (data.can_update) {
|
||||
if (data.passwords_needed_to_update) {
|
||||
Wait('stop');
|
||||
scope.$emit('PromptForPasswords');
|
||||
}
|
||||
else {
|
||||
if(params.updateAllSources) {
|
||||
let userCanUpdateAllSources = true;
|
||||
_.forEach(data, function(inventory_source){
|
||||
if (!inventory_source.can_update) {
|
||||
userCanUpdateAllSources = false;
|
||||
}
|
||||
});
|
||||
|
||||
if(userCanUpdateAllSources) {
|
||||
scope.$emit('StartTheUpdate', {});
|
||||
}
|
||||
} else {
|
||||
Wait('stop');
|
||||
Alert('Permission Denied', 'You do not have access to run the inventory sync. Please contact your system administrator.',
|
||||
'alert-danger');
|
||||
}
|
||||
else {
|
||||
inventory_source = data;
|
||||
if (data.can_update) {
|
||||
if (data.passwords_needed_to_update) {
|
||||
Wait('stop');
|
||||
scope.$emit('PromptForPasswords');
|
||||
}
|
||||
else {
|
||||
scope.$emit('StartTheUpdate', {});
|
||||
}
|
||||
} else {
|
||||
Wait('stop');
|
||||
Alert('Permission Denied', 'You do not have access to run the inventory sync. Please contact your system administrator.',
|
||||
'alert-danger');
|
||||
}
|
||||
}
|
||||
})
|
||||
.error(function (data, status) {
|
||||
|
||||
@ -134,6 +134,9 @@ angular.module('GeneratorHelpers', [systemStatus.name])
|
||||
case 'group_update':
|
||||
icon = 'fa-refresh';
|
||||
break;
|
||||
case 'inventory_update':
|
||||
icon = 'fa-refresh';
|
||||
break;
|
||||
case 'scm_update':
|
||||
icon = 'fa-cloud-download';
|
||||
break;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user