mirror of
https://github.com/ansible/awx.git
synced 2026-02-22 13:36:02 -03:30
AC-503 cloud inventory- first attempt at summary information on Inventory-> Groups page. Fixed compilation bugs.
This commit is contained in:
@@ -32,6 +32,7 @@ angular.module('ansible', [
|
|||||||
'InventoryHelper',
|
'InventoryHelper',
|
||||||
'InventoryHostsFormDefinition',
|
'InventoryHostsFormDefinition',
|
||||||
'InventoryGroupsFormDefinition',
|
'InventoryGroupsFormDefinition',
|
||||||
|
'InventorySummaryDefinition',
|
||||||
'AWFilters',
|
'AWFilters',
|
||||||
'HostFormDefinition',
|
'HostFormDefinition',
|
||||||
'HostListDefinition',
|
'HostListDefinition',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryGroupsForm,
|
function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryGroupsForm,
|
||||||
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, Prompt,
|
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, Prompt,
|
||||||
TreeInit, GetBasePath, GroupsList, GroupsAdd, GroupsEdit, LoadInventory,
|
TreeInit, GetBasePath, GroupsList, GroupsAdd, GroupsEdit, LoadInventory,
|
||||||
GroupsDelete, RefreshGroupName, EditInventory, SetShowGroupHelp)
|
GroupsDelete, RefreshGroupName, EditInventory, SetShowGroupHelp, InventoryStatus)
|
||||||
{
|
{
|
||||||
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||||
//scope.
|
//scope.
|
||||||
@@ -155,7 +155,6 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP
|
|||||||
$('input:first').focus();
|
$('input:first').focus();
|
||||||
}
|
}
|
||||||
else if (type == 'inventory') {
|
else if (type == 'inventory') {
|
||||||
$('#tree-form').hide().empty();
|
|
||||||
url = node.attr('hosts');
|
url = node.attr('hosts');
|
||||||
scope.groupAddHide = true;
|
scope.groupAddHide = true;
|
||||||
scope.groupCreateHide = false;
|
scope.groupCreateHide = false;
|
||||||
@@ -164,6 +163,8 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP
|
|||||||
scope.groupDeleteHide = true;
|
scope.groupDeleteHide = true;
|
||||||
scope.createButtonShow = false;
|
scope.createButtonShow = false;
|
||||||
scope.group_id = null;
|
scope.group_id = null;
|
||||||
|
InventoryStatus();
|
||||||
|
$('#tree-form').show();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scope.$$phase) {
|
if (!scope.$$phase) {
|
||||||
@@ -221,6 +222,6 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP
|
|||||||
InventoryGroups.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'InventoryGroupsForm',
|
InventoryGroups.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'InventoryGroupsForm',
|
||||||
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'Prompt',
|
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'Prompt',
|
||||||
'TreeInit', 'GetBasePath', 'GroupsList', 'GroupsAdd', 'GroupsEdit', 'LoadInventory',
|
'TreeInit', 'GetBasePath', 'GroupsList', 'GroupsAdd', 'GroupsEdit', 'LoadInventory',
|
||||||
'GroupsDelete', 'RefreshGroupName', 'EditInventory', 'SetShowGroupHelp'
|
'GroupsDelete', 'RefreshGroupName', 'EditInventory', 'SetShowGroupHelp', 'InventoryStatus'
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ function OrganizationsAdd ($scope, $rootScope, $compile, $location, $log, $route
|
|||||||
|
|
||||||
// Save
|
// Save
|
||||||
scope.formSave = function() {
|
scope.formSave = function() {
|
||||||
form.clearApiErrors();s
|
form.clearApiErrors();
|
||||||
var url = GetBasePath(base);
|
var url = GetBasePath(base);
|
||||||
url += (base != 'organizations') ? $routeParams['project_id'] + '/organizations/' : '';
|
url += (base != 'organizations') ? $routeParams['project_id'] + '/organizations/' : '';
|
||||||
Rest.setUrl(url);
|
Rest.setUrl(url);
|
||||||
|
|||||||
@@ -232,7 +232,6 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
|||||||
}
|
}
|
||||||
}])
|
}])
|
||||||
|
|
||||||
|
|
||||||
.factory('GroupsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm',
|
.factory('GroupsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm',
|
||||||
'Prompt', 'ProcessErrors', 'GetBasePath', 'RefreshGroupName', 'ParseTypeChange', 'getSourceTypeOptions',
|
'Prompt', 'ProcessErrors', 'GetBasePath', 'RefreshGroupName', 'ParseTypeChange', 'getSourceTypeOptions',
|
||||||
function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors,
|
function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors,
|
||||||
@@ -488,6 +487,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
|||||||
{ hdr: 'Error!', msg: 'Failed to update group varaibles. PUT status: ' + status });
|
{ hdr: 'Error!', msg: 'Failed to update group varaibles. PUT status: ' + status });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
RefreshGroupName(scope['selectedNode'], data.name, data.description);
|
||||||
scope.$emit('formSaveSuccess', data.id);
|
scope.$emit('formSaveSuccess', data.id);
|
||||||
})
|
})
|
||||||
.error( function(data, status, headers, config) {
|
.error( function(data, status, headers, config) {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationListDefinition',
|
angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationListDefinition',
|
||||||
'SearchHelper', 'PaginateHelper', 'ListGenerator', 'AuthService',
|
'SearchHelper', 'PaginateHelper', 'ListGenerator', 'AuthService',
|
||||||
'InventoryHelper', 'RelatedSearchHelper', 'RelatedPaginateHelper',
|
'InventoryHelper', 'RelatedSearchHelper', 'RelatedPaginateHelper',
|
||||||
'InventoryFormDefinition', 'ParseHelper'
|
'InventoryFormDefinition', 'ParseHelper', 'InventorySummaryDefinition'
|
||||||
])
|
])
|
||||||
|
|
||||||
.factory('LoadTreeData', ['Alert', 'Rest', 'Authorization', '$http', 'Wait', 'SortNodes',
|
.factory('LoadTreeData', ['Alert', 'Rest', 'Authorization', '$http', 'Wait', 'SortNodes',
|
||||||
@@ -160,6 +160,7 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi
|
|||||||
$(tree_id).bind("loaded.jstree", function () {
|
$(tree_id).bind("loaded.jstree", function () {
|
||||||
scope['treeLoading'] = false;
|
scope['treeLoading'] = false;
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
|
$(tree_id).prepend('<div class=\"title\"><i class=\"icon-sitemap\"></i> Group Selector</div>');
|
||||||
scope.$emit('treeLoaded');
|
scope.$emit('treeLoaded');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -666,5 +667,65 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi
|
|||||||
}
|
}
|
||||||
return newData;
|
return newData;
|
||||||
}
|
}
|
||||||
|
}])
|
||||||
|
|
||||||
|
.factory('InventoryStatus', [ 'Rest', 'Alert', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'InventorySummary', 'GenerateList',
|
||||||
|
function(Rest, Aler, ProcessErrors, GetBasePath, FormatDate, InventorySummary, GenerateList) {
|
||||||
|
return function(params) {
|
||||||
|
//Build a summary of a given inventory
|
||||||
|
|
||||||
|
$('#tree-form').hide().empty();
|
||||||
|
var view = GenerateList;
|
||||||
|
var scope = view.inject(InventorySummary, { mode: 'summary', id: 'tree-form', breadCrumbs: false });
|
||||||
|
scope['groups'] = [];
|
||||||
|
|
||||||
|
function checkSource(url) {
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
//console.log(data);
|
||||||
|
var last_update = (data.last_updated == null) ? 'n/a' : FormatDate(new Date(data.last_updated));
|
||||||
|
var source = 'Manual';
|
||||||
|
switch(data.source) {
|
||||||
|
case 'file':
|
||||||
|
source = 'File';
|
||||||
|
break;
|
||||||
|
case 'ec2':
|
||||||
|
source = 'Amazon EC2';
|
||||||
|
break;
|
||||||
|
case 'rackspace':
|
||||||
|
source = 'Rackspace';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
scope['groups'].push({
|
||||||
|
name: data.summary_fields.group.name,
|
||||||
|
description: data.summary_fields.group.description,
|
||||||
|
failures: data.summary_fields.group.hosts_with_active_failures,
|
||||||
|
source: source,
|
||||||
|
last_update: last_update,
|
||||||
|
status: data.status
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST status: ' + status });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = GetBasePath('inventory') + scope['inventory_id'] + '/groups/';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
for (var i=0; i < data.results.length; i++) {
|
||||||
|
if (data.results[i].related.inventory_source) {
|
||||||
|
checkSource(data.results[i].related.inventory_source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST status: ' + status });
|
||||||
|
});
|
||||||
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
|||||||
44
awx/ui/static/js/lists/InventorySummary.js
Normal file
44
awx/ui/static/js/lists/InventorySummary.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*********************************************
|
||||||
|
* Copyright (c) 2013 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
* InventorySummary.js
|
||||||
|
*
|
||||||
|
* Summary of groups contained within an inventory
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
angular.module('InventorySummaryDefinition', [])
|
||||||
|
.value(
|
||||||
|
'InventorySummary', {
|
||||||
|
|
||||||
|
name: 'groups',
|
||||||
|
iterator: 'group',
|
||||||
|
editTitle: 'Inventory Summary',
|
||||||
|
index: false,
|
||||||
|
hover: true,
|
||||||
|
|
||||||
|
fields: {
|
||||||
|
name: {
|
||||||
|
key: true,
|
||||||
|
label: 'Name'
|
||||||
|
},
|
||||||
|
failures: {
|
||||||
|
label: 'Hosts Failures'
|
||||||
|
},
|
||||||
|
source: {
|
||||||
|
label: 'Source'
|
||||||
|
},
|
||||||
|
last_update: {
|
||||||
|
label: 'Last Update'
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
label: 'Update Status'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
},
|
||||||
|
|
||||||
|
fieldActions: {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
@@ -771,8 +771,15 @@ select.field-mini-height {
|
|||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background-color: #e3e3e3;
|
background-color: #e3e3e3;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
margin-top: 10px;
|
padding-left: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #888;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -792,13 +799,13 @@ select.field-mini-height {
|
|||||||
#tree-form {
|
#tree-form {
|
||||||
display: none;
|
display: none;
|
||||||
padding: 15px 10px 0 10px;
|
padding: 15px 10px 0 10px;
|
||||||
margin-top: 10px;
|
margin-top: 5px;
|
||||||
border: 1px solid #e3e3e3;
|
border: 1px solid #e3e3e3;
|
||||||
background-color: #e3e3e3;
|
background-color: #e3e3e3;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
|
||||||
.form-title {
|
.form-title {
|
||||||
color: #999;
|
color: #888;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1102,7 +1109,7 @@ tr td button i {
|
|||||||
|
|
||||||
#tree-view {
|
#tree-view {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-top: 10px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-text {
|
.label-text {
|
||||||
|
|||||||
@@ -1230,7 +1230,9 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
|
|||||||
html += "</div><!-- tree controls -->\n";
|
html += "</div><!-- tree controls -->\n";
|
||||||
html += "<hr class=\"tree-control-divider\">\n";
|
html += "<hr class=\"tree-control-divider\">\n";
|
||||||
html += "<div class=\"row\">\n";
|
html += "<div class=\"row\">\n";
|
||||||
html += "<div class=\"col-lg-4\"><div id=\"tree-view\"></div></div>\n";
|
html += "<div class=\"col-lg-4\">\n" +
|
||||||
|
"<div id=\"tree-view\"></div>\n" +
|
||||||
|
"</div>\n";
|
||||||
html += "<div class=\"col-lg-8 tree-form-container\">\n<div id=\"tree-form\">\n</div>\n</div>\n";
|
html += "<div class=\"col-lg-8 tree-form-container\">\n<div id=\"tree-form\">\n</div>\n</div>\n";
|
||||||
html += "</div>\n";
|
html += "</div>\n";
|
||||||
html += "</div><!-- well -->\n";
|
html += "</div><!-- well -->\n";
|
||||||
|
|||||||
@@ -169,56 +169,59 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
|
|||||||
if (options.mode != 'lookup' && (list.well == undefined || list.well == 'true')) {
|
if (options.mode != 'lookup' && (list.well == undefined || list.well == 'true')) {
|
||||||
html += "<div class=\"well\">\n";
|
html += "<div class=\"well\">\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.mode == 'lookup' || options.id != undefined) {
|
|
||||||
html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: 'col-lg-8' });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
html += SearchWidget({ iterator: list.iterator, template: list, mini: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.mode != 'lookup') {
|
if (options.mode !== 'summary') {
|
||||||
//actions
|
|
||||||
var base = $location.path().replace(/^\//,'').split('/')[0];
|
|
||||||
html += "<div class=\"list-actions ";
|
|
||||||
html += (options.id != undefined) ? "col-lg-3" : "col-lg-7 col-md-5";
|
|
||||||
html += "\">\n";
|
|
||||||
for (action in list.actions) {
|
|
||||||
if (list.actions[action].mode == 'all' || list.actions[action].mode == options.mode) {
|
|
||||||
if ( (list.actions[action].basePaths == undefined) ||
|
|
||||||
(list.actions[action].basePaths && list.actions[action].basePaths.indexOf(base) > -1) ) {
|
|
||||||
html += this.button(list.actions[action], action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list.name == 'inventories' && options.mode !== 'select') {
|
if ( options.mode == 'lookup' || options.id != undefined ) {
|
||||||
html += "<label class=\"checkbox-inline pull-right\"><input type=\"checkbox\" ng-model=\"inventoryFailureFilter\" " +
|
html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: 'col-lg-8' });
|
||||||
"ng-change=\"search('inventory')\" id=\"failed_jobs_chbox\"> Show only inventories with failed jobs</label>\n";
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
//select instructions
|
html += SearchWidget({ iterator: list.iterator, template: list, mini: true });
|
||||||
if (options.mode == 'select' && list.selectInstructions) {
|
|
||||||
var btn = {
|
|
||||||
awPopOver: list.selectInstructions,
|
|
||||||
dataPlacement: 'left',
|
|
||||||
dataContainer: 'body',
|
|
||||||
icon: "icon-question-sign",
|
|
||||||
'class': 'btn-sm btn-help btn-info',
|
|
||||||
awToolTip: 'Click for help',
|
|
||||||
dataTitle: 'Help',
|
|
||||||
iconSize: 'large'
|
|
||||||
};
|
|
||||||
html += this.button(btn, 'select');
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
html += "<div class=\"col-lg-7\"></div>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
html += "</div>\n";
|
if (options.mode != 'lookup') {
|
||||||
html += "</div><!-- row -->\n";
|
//actions
|
||||||
|
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||||
|
html += "<div class=\"list-actions ";
|
||||||
|
html += (options.id != undefined) ? "col-lg-3" : "col-lg-7 col-md-5";
|
||||||
|
html += "\">\n";
|
||||||
|
for (action in list.actions) {
|
||||||
|
if (list.actions[action].mode == 'all' || list.actions[action].mode == options.mode) {
|
||||||
|
if ( (list.actions[action].basePaths == undefined) ||
|
||||||
|
(list.actions[action].basePaths && list.actions[action].basePaths.indexOf(base) > -1) ) {
|
||||||
|
html += this.button(list.actions[action], action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.name == 'inventories' && options.mode !== 'select') {
|
||||||
|
html += "<label class=\"checkbox-inline pull-right\"><input type=\"checkbox\" ng-model=\"inventoryFailureFilter\" " +
|
||||||
|
"ng-change=\"search('inventory')\" id=\"failed_jobs_chbox\"> Show only inventories with failed jobs</label>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//select instructions
|
||||||
|
if (options.mode == 'select' && list.selectInstructions) {
|
||||||
|
var btn = {
|
||||||
|
awPopOver: list.selectInstructions,
|
||||||
|
dataPlacement: 'left',
|
||||||
|
dataContainer: 'body',
|
||||||
|
icon: "icon-question-sign",
|
||||||
|
'class': 'btn-sm btn-help btn-info',
|
||||||
|
awToolTip: 'Click for help',
|
||||||
|
dataTitle: 'Help',
|
||||||
|
iconSize: 'large'
|
||||||
|
};
|
||||||
|
html += this.button(btn, 'select');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
html += "<div class=\"col-lg-7\"></div>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
html += "</div>\n";
|
||||||
|
html += "</div><!-- row -->\n";
|
||||||
|
}
|
||||||
|
|
||||||
// table header row
|
// table header row
|
||||||
html += "<table id=\"" + list.name + "_table\" ";
|
html += "<table id=\"" + list.name + "_table\" ";
|
||||||
html += "class=\"table"
|
html += "class=\"table"
|
||||||
|
|||||||
@@ -76,6 +76,7 @@
|
|||||||
<script src="{{ STATIC_URL }}js/lists/Inventories.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Inventories.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/Teams.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Teams.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/Hosts.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Hosts.js"></script>
|
||||||
|
<script src="{{ STATIC_URL }}js/lists/InventorySummary.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/Groups.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Groups.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/Credentials.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Credentials.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/JobTemplates.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/JobTemplates.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user