Scan job templates

Implemented saving a job template as type = scan. Can add/edit these jobs. Also on inventory properties accordion you can see the list of scan job templates for the inventory.
This commit is contained in:
Jared Tabor 2015-03-18 14:08:54 -04:00
parent 3cd5cd5184
commit 0948846530
8 changed files with 179 additions and 34 deletions

View File

@ -267,6 +267,11 @@ var tower = angular.module('Tower', [
controller: JobTemplatesAdd
}).
when('/inventories/:inventory_id/job_templates/:template_id', {
templateUrl: urlPrefix + 'partials/job_templates.html',
controller: JobTemplatesEdit
}).
when('/inventories/:inventory_id/manage', {
templateUrl: urlPrefix + 'partials/inventory-manage.html',
controller: InventoriesManage

View File

@ -482,7 +482,7 @@ InventoriesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log
export function InventoriesEdit($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryForm, GenerateForm, Rest,
Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, generateList, OrganizationList, SearchInit, PaginateInit,
LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, ParseVariableString, Stream) {
LookUpInit, GetBasePath, ParseTypeChange, Wait, ToJSON, ParseVariableString, Stream, RelatedSearchInit, RelatedPaginateInit) {
ClearScope();
@ -492,17 +492,30 @@ export function InventoriesEdit($scope, $rootScope, $compile, $location, $log, $
generator = GenerateForm,
inventory_id = $routeParams.inventory_id,
master = {},
fld, json_data, data;
fld, json_data, data,
relatedSets = {};
form.well = true;
form.formLabelSize = null;
form.formFieldSize = null;
$scope.inventory_id = inventory_id;
generator.inject(form, { mode: 'edit', related: true, scope: $scope });
generator.reset();
LoadBreadCrumbs();
// After the project is loaded, retrieve each related set
if ($scope.inventoryLoadedRemove) {
$scope.inventoryLoadedRemove();
}
$scope.projectLoadedRemove = $scope.$on('inventoryLoaded', function () {
var set, opts=[];
for (set in relatedSets) {
$scope.search(relatedSets[set].iterator);
}
});
Wait('start');
Rest.setUrl(GetBasePath('inventory') + inventory_id + '/');
Rest.get()
@ -530,6 +543,19 @@ export function InventoriesEdit($scope, $rootScope, $compile, $location, $log, $
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
}
}
relatedSets = form.relatedSets(data.related);
// Initialize related search functions. Doing it here to make sure relatedSets object is populated.
RelatedSearchInit({
scope: $scope,
form: form,
relatedSets: relatedSets
});
RelatedPaginateInit({
scope: $scope,
relatedSets: relatedSets
});
Wait('stop');
$scope.parseType = 'yaml';
ParseTypeChange({
@ -546,6 +572,7 @@ export function InventoriesEdit($scope, $rootScope, $compile, $location, $log, $
field: 'organization',
input_type: 'radio'
});
$scope.$emit('inventoryLoaded');
})
.error(function (data, status) {
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
@ -627,11 +654,19 @@ export function InventoriesEdit($scope, $rootScope, $compile, $location, $log, $
$scope.addScanJob = function(){
$location.path($location.path()+'/job_templates/add');
};
$scope.editScanJob = function(){
$location.path($location.path()+'/job_templates/'+this.scan_job_template.id);
};
$scope.deleteScanJob = function(){
$location.path($location.path()+'/job_templates/add');
};
}
InventoriesEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'InventoryForm', 'GenerateForm',
'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'generateList', 'OrganizationList', 'SearchInit',
'PaginateInit', 'LookUpInit', 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', 'ParseVariableString', 'Stream'
'PaginateInit', 'LookUpInit', 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', 'ParseVariableString', 'Stream', 'RelatedSearchInit', 'RelatedPaginateInit'
];

View File

@ -302,12 +302,13 @@ export function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $
LookUpInit({
scope: $scope,
form: form,
current_item: null,
current_item: ($routeParams.inventory_id !== undefined) ? $routeParams.inventory_id : null,
list: InventoryList,
field: 'inventory',
input_type: "radio"
});
// Clone the CredentialList object for use with cloud_credential. Cloning
// and changing properties to avoid collision.
jQuery.extend(true, CloudCredentialList, CredentialList);
@ -341,14 +342,62 @@ export function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $
parent_scope: $scope
});
// $scope.jobTypeChange = function(){
//
// };
$scope.jobTypeChange = function(){
if($scope.job_type){
if($scope.job_type.value === 'scan'){
$scope.default_scan = true;
$scope.project_name = 'Default';
$scope.project = null;
}
else{
$scope.default_scan = false;
$scope.project_name = null;
$scope.project = null;
$scope.playbook_options = [];
$scope.playbook = 'null';
}
}
};
$scope.toggleScanInfo = function() {
if($scope.default_scan){
$scope.project_name = 'Default';
$scope.project = null;
}
if(!$scope.default_scan){
$scope.project_name = null;
$scope.playbook_options = [];
$scope.playbook = 'null';
}
};
if ($routeParams.inventory_id) {
// This means that the job template form was accessed via inventory prop's
// This also means the job is a scan job.
$scope.job_type.value = 'scan';
$scope.jobTypeChange();
$scope.inventory = $routeParams.inventory_id;
Rest.setUrl(GetBasePath('inventory') + $routeParams.inventory_id + '/');
Rest.get()
.success(function (data) {
$scope.inventory_name = data.name;
})
.error(function (data, status) {
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
msg: 'Failed to lookup inventory: ' + data.id + '. GET returned status: ' + status });
});
}
// Update playbook select whenever project value changes
selectPlaybook = function (oldValue, newValue) {
var url;
if (oldValue !== newValue) {
if($scope.job_type.value === 'scan' && $scope.default_scan === true){
$scope.playbook_options = ['Default'];
$scope.playbook = 'Default';
Wait('stop');
}
else if (oldValue !== newValue) {
if ($scope.project) {
Wait('start');
url = GetBasePath('projects') + $scope.project + '/playbooks/';
@ -477,7 +526,10 @@ export function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $
}
}
data.extra_vars = ToJSON($scope.parseType, $scope.variables, true);
if(data.job_type === 'scan' && $scope.default_scan === true){
data.project = "";
data.playbook = "";
}
Rest.setUrl(defaultUrl);
Rest.post(data)
.success(function(data) {
@ -621,9 +673,42 @@ export function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log,
$scope.playbook = null;
generator.reset();
$scope.jobTypeChange = function(){
if($scope.job_type){
if($scope.job_type.value === 'scan'){
$scope.default_scan = true;
$scope.project_name = 'Default';
$scope.project = null;
}
else{
$scope.default_scan = false;
$scope.project_name = null;
$scope.playbook_options = [];
$scope.playbook = 'null';
}
}
};
$scope.toggleScanInfo = function() {
if($scope.default_scan){
$scope.project_name = 'Default';
$scope.project = null;
}
if(!$scope.default_scan){
$scope.project_name = null;
$scope.playbook_options = [];
$scope.playbook = 'null';
}
};
getPlaybooks = function (project) {
var url;
if (!Empty(project)) {
if($scope.job_type.value === 'scan' && $scope.default_scan === true){
$scope.playbook_options = ['Default'];
$scope.playbook = 'Default';
Wait('stop');
}
else if (!Empty(project)) {
url = GetBasePath('projects') + project + '/playbooks/';
Wait('start');
Rest.setUrl(url);

View File

@ -97,10 +97,10 @@ export default
},
related: {
scan_jobs: {
scan_job_templates: {
type: 'collection',
title: 'Scan Jobs',
iterator: 'scan_job',
iterator: 'scan_job_template',
index: false,
open: false,
@ -109,14 +109,15 @@ export default
ngClick: "addScanJob(inventory_id)",
icon: 'icon-plus',
label: 'Add',
awToolTip: 'Add a scan job'
awToolTip: 'Add a scan job template'
}
},
fields: {
name: {
key: true,
label: 'Name'
label: 'Name',
linkTo: '/#/inventories/{{inventory_id}}/job_templates/{{scan_job_template.id}}'
},
description: {
label: 'Description'
@ -126,17 +127,17 @@ export default
fieldActions: {
edit: {
label: 'Edit',
ngClick: "edit('organizations', organization.id, organization.name)",
ngClick: "editScanJob(inventory_id)",
icon: 'icon-edit',
awToolTip: 'Edit the organization',
awToolTip: 'Edit the scan job template',
'class': 'btn btn-default'
},
"delete": {
label: 'Delete',
ngClick: "delete('organizations', organization.id, organization.name, 'organizations')",
ngClick: "deleteScanJob(inventory_id)",
icon: 'icon-trash',
"class": 'btn-danger',
awToolTip: 'Delete the organization'
awToolTip: 'Delete the scan job template'
}
}
}
@ -144,14 +145,10 @@ export default
relatedSets: function(urls) {
return {
scan_jobs: {
iterator: 'scan_job',
url: urls.organizations
},
// schedules: {
// iterator: 'schedule',
// url: urls.schedules
// }
scan_job_templates: {
iterator: 'scan_job_template',
url: urls.scan_job_templates
}
};
}

View File

@ -102,7 +102,9 @@ export default
awPopOver: "<p>Select the project containing the playbook you want this job to execute.</p>",
dataTitle: 'Project',
dataPlacement: 'right',
dataContainer: "body"
dataContainer: "body",
ngDisabled: 'default_scan === true',
ngRequired: 'default_scan === false'
},
playbook: {
label: 'Playbook',
@ -114,7 +116,20 @@ export default
awPopOver: "<p>Select the playbook to be executed by this job.</p>",
dataTitle: 'Playbook',
dataPlacement: 'right',
dataContainer: "body"
dataContainer: "body",
ngDisabled: 'default_scan === true',
ngRequired: 'default_scan === false'
},
default_scan: {
label: "Use default scan job project and playbook",
type: 'checkbox',
ngChange: 'toggleScanInfo()',
ngShow: 'job_type.value === "scan"',
column: 1,
awPopOver: "<p>Scan jobs templates use a default project and default playbook. Uncheck this box to override these defaults.</p>",
dataTitle: 'Scan jobs',
dataPlacement: 'right',
dataContainer: "body"
},
credential: {
label: 'Machine Credential',

View File

@ -171,6 +171,12 @@ angular.module('JobTemplatesHelper', ['Utilities'])
input_type: "radio"
});
if(scope.project === "" && scope.playbook === ""){
scope.default_scan = true;
scope.toggleScanInfo();
}
RelatedSearchInit({
scope: scope,
form: form,
@ -193,7 +199,4 @@ angular.module('JobTemplatesHelper', ['Utilities'])
};
};
}]);

View File

@ -15,8 +15,8 @@ export default
angular.module('ScanJobsListDefinition', [])
.value( 'ScanJobsList', {
name: 'scan_jobs',
iterator: 'scan_job',
name: 'scan_job_templates',
iterator: 'scan_job_template',
editTitle: 'Scan Jobs',
'class': 'table-condensed',
index: false,

View File

@ -1107,6 +1107,8 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
html += "\" ";
html += this.attr(field, 'ngOptions');
html += (field.ngChange) ? this.attr(field, 'ngChange') : "";
html += (field.ngDisabled) ? this.attr(field, 'ngDisabled'): "";
html += (field.ngRequired) ? this.attr(field, 'ngRequired') : "";
html += buildId(field, fld, this.form);
html += (options.mode === 'edit' && field.editRequired) ? "required " : "";
html += (options.mode === 'add' && field.addRequired) ? "required " : "";
@ -1331,6 +1333,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
html += "<span class=\"input-group-btn\">\n";
html += "<button type=\"button\" class=\"lookup-btn btn btn-default\" " + this.attr(field, 'ngClick');
html += (field.readonly || field.showonly) ? " disabled " : "";
html += (field.ngDisabled) ? this.attr(field, "ngDisabled"): "";
html += "id=\"" + fld + "-lookup-btn\"><i class=\"fa fa-search\"></i></button>\n";
html += "</span>\n";
html += "<input type=\"text\" class=\"form-control input-medium lookup\" ";
@ -1338,6 +1341,8 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
html += "name=\"" + field.sourceModel + '_' + field.sourceField + "\" ";
html += "class=\"form-control\" ";
html += (field.ngChange) ? this.attr(field, 'ngChange') : "";
html += (field.ngDisabled) ? this.attr(field, 'ngDisabled') : "" ;
html += (field.ngRequired) ? this.attr(field, 'ngRequired') : "";
html += (field.id) ? this.attr(field, 'id') : "";
html += (field.placeholder) ? this.attr(field, 'placeholder') : "";
html += (options.mode === 'edit' && field.editRequired) ? "required " : "";