diff --git a/awx/ui/static/js/app.js b/awx/ui/static/js/app.js
index 22e3455789..d3a09f6013 100644
--- a/awx/ui/static/js/app.js
+++ b/awx/ui/static/js/app.js
@@ -85,7 +85,8 @@ angular.module('ansible', [
'StreamListDefinition',
'HomeGroupListDefinition',
'HomeHostListDefinition',
- 'ActivityDetailDefinition'
+ 'ActivityDetailDefinition',
+ 'VariablesHelper'
])
.config(['$routeProvider',
function ($routeProvider) {
diff --git a/awx/ui/static/js/controllers/JobTemplates.js b/awx/ui/static/js/controllers/JobTemplates.js
index 147a8bcbd9..4a684d5276 100644
--- a/awx/ui/static/js/controllers/JobTemplates.js
+++ b/awx/ui/static/js/controllers/JobTemplates.js
@@ -108,7 +108,7 @@ JobTemplatesList.$inject = ['$scope', '$rootScope', '$location', '$log', '$route
function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm,
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, GetBasePath,
- InventoryList, CredentialList, ProjectList, LookUpInit, md5Setup, ParseTypeChange, Wait, Empty) {
+ InventoryList, CredentialList, ProjectList, LookUpInit, md5Setup, ParseTypeChange, Wait, Empty, ToJSON) {
ClearScope();
@@ -286,20 +286,8 @@ function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $routePa
$scope.formSave = function () {
generator.clearApiErrors();
Wait('start');
- var data = {}, json_data, fld;
+ var data = {}, fld;
try {
- // Make sure we have valid variable data
- if ($scope.parseType === 'json') {
- json_data = JSON.parse($scope.variables); //make sure JSON parses
- } else {
- json_data = jsyaml.load($scope.variables); //parse yaml
- }
-
- // Make sure our JSON is actually an object
- if (typeof json_data !== 'object') {
- throw "failed to return an object!";
- }
-
for (fld in form.fields) {
if (form.fields[fld].type === 'select' && fld !== 'playbook') {
data[fld] = $scope[fld].value;
@@ -309,11 +297,7 @@ function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $routePa
}
}
}
-
- data.extra_vars = JSON.stringify(json_data, undefined, '\t');
- if (Empty(data.extra_vars)) {
- data.extra_vars = "";
- }
+ data.extra_vars = ToJSON($scope.parseType, $scope.variables, true);
Rest.setUrl(defaultUrl);
Rest.post(data)
@@ -346,14 +330,14 @@ function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $routePa
JobTemplatesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm',
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope',
'GetBasePath', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit',
- 'md5Setup', 'ParseTypeChange', 'Wait', 'Empty'
+ 'md5Setup', 'ParseTypeChange', 'Wait', 'Empty', 'ToJSON'
];
function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, GenerateForm, Rest,
Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, InventoryList,
CredentialList, ProjectList, LookUpInit, PromptPasswords, GetBasePath, md5Setup, ParseTypeChange, JobStatusToolTip, FormatDate,
- Wait, Stream, Empty, Prompt) {
+ Wait, Stream, Empty, Prompt, ParseVariableString, ToJSON) {
ClearScope();
@@ -569,7 +553,7 @@ function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, $routeP
Rest.setUrl(defaultUrl + ':id/');
Rest.get({ params: { id: id } })
.success(function (data) {
- var fld, i, json_obj, related, set;
+ var fld, i, related, set;
LoadBreadCrumbs({ path: '/job_templates/' + id, title: data.name });
for (fld in form.fields) {
if (fld !== 'variables' && data[fld] !== null && data[fld] !== undefined) {
@@ -589,28 +573,8 @@ function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, $routeP
master[fld] = $scope[fld];
}
if (fld === 'variables') {
- // Parse extra_vars, converting to YAML.
- if ($.isEmptyObject(data.extra_vars) || data.extra_vars === "{}" || data.extra_vars === "null" ||
- data.extra_vars === "" || data.extra_vars === null) {
- $scope.variables = "---";
- } else {
- $scope.variables = '---';
- try {
- json_obj = JSON.parse(data.extra_vars);
- $scope.variables = jsyaml.safeDump(json_obj);
- }
- catch (e) {
- $log.info('Attempt to parse extra_vars as JSON faild. Attempting to parse as YAML');
- try {
- json_obj = jsyaml.safeLoad(data.extra_vars);
- $scope.variables = jsyaml.safeDump(json_obj);
- }
- catch(e2) {
- ProcessErrors($scope, data.extra_vars, e2.message, null, { hdr: 'Error!',
- msg: 'Attempts to parse variables as JSON and YAML failed. Last attempt returned: ' + e2.message });
- }
- }
- }
+ // Parse extra_vars, converting to YAML.
+ $scope.variables = ParseVariableString(data.extra_vars);
master.variables = $scope.variables;
}
if (form.fields[fld].type === 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) {
@@ -702,20 +666,10 @@ function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, $routeP
$scope.formSave = function () {
generator.clearApiErrors();
Wait('start');
- var data = {}, json_data, fld;
+ var data = {}, fld;
try {
// Make sure we have valid variable data
- if ($scope.parseType === 'json') {
- json_data = JSON.parse($scope.variables); //make sure JSON parses
- } else {
- json_data = jsyaml.load($scope.variables); //parse yaml
- }
-
- // Make sure our JSON is actually an object
- if (typeof json_data !== 'object') {
- throw "failed to return an object!";
- }
-
+ data.extra_vars = ToJSON($scope.parseType, $scope.variables, true);
for (fld in form.fields) {
if (form.fields[fld].type === 'select' && fld !== 'playbook') {
data[fld] = $scope[fld].value;
@@ -725,12 +679,6 @@ function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, $routeP
}
}
}
-
- data.extra_vars = JSON.stringify(json_data, undefined, '\t');
- if (data.extra_vars === "null" || data.extra_vars === null) {
- data.extra_vars = "";
- }
-
Rest.setUrl(defaultUrl + id + '/');
Rest.put(data)
.success(function (data) {
@@ -810,5 +758,6 @@ function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log, $routeP
JobTemplatesEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm',
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit',
'ReturnToCaller', 'ClearScope', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit', 'PromptPasswords',
- 'GetBasePath', 'md5Setup', 'ParseTypeChange', 'JobStatusToolTip', 'FormatDate', 'Wait', 'Stream', 'Empty', 'Prompt'
+ 'GetBasePath', 'md5Setup', 'ParseTypeChange', 'JobStatusToolTip', 'FormatDate', 'Wait', 'Stream', 'Empty', 'Prompt',
+ 'ParseVariableString', 'ToJSON'
];
\ No newline at end of file
diff --git a/awx/ui/static/js/controllers/Jobs.js b/awx/ui/static/js/controllers/Jobs.js
index 2f71835c75..4aa2c3c2c7 100644
--- a/awx/ui/static/js/controllers/Jobs.js
+++ b/awx/ui/static/js/controllers/Jobs.js
@@ -8,8 +8,6 @@
*
*/
-/* global jsyaml:false */
-
'use strict';
function JobsListCtrl($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobList, GenerateList, LoadBreadCrumbs, Prompt,
@@ -189,7 +187,8 @@ JobsListCtrl.$inject = ['$scope', '$rootScope', '$location', '$log', '$routePara
function JobsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, JobForm, JobTemplateForm, GenerateForm, Rest,
Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, InventoryList,
- CredentialList, ProjectList, LookUpInit, PromptPasswords, GetBasePath, md5Setup, FormatDate, JobStatusToolTip, Wait, Empty) {
+ CredentialList, ProjectList, LookUpInit, PromptPasswords, GetBasePath, md5Setup, FormatDate, JobStatusToolTip, Wait, Empty,
+ ParseVariableString) {
ClearScope();
@@ -374,28 +373,7 @@ function JobsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, J
}
}
if (fld === 'variables') {
- // Parse extra_vars, converting to YAML.
- if ($.isEmptyObject(data.extra_vars) || data.extra_vars === "{}" || data.extra_vars === "null" ||
- data.extra_vars === "" || data.extra_vars === null) {
- $scope.variables = "---";
- } else {
- $scope.variables = '---';
- try {
- json_obj = JSON.parse(data.extra_vars);
- $scope.variables = jsyaml.safeDump(json_obj);
- }
- catch (e) {
- $log.info('Attempt to parse extra_vars as JSON faild. Attempting to parse as YAML');
- try {
- json_obj = jsyaml.safeLoad(data.extra_vars);
- $scope.variables = jsyaml.safeDump(json_obj);
- }
- catch(e2) {
- ProcessErrors($scope, data.extra_vars, e2.message, null, { hdr: 'Error!',
- msg: 'Attempts to parse variables as JSON and YAML failed. Last attempt returned: ' + e2.message });
- }
- }
- }
+ $scope.variables = ParseVariableString(data.extra_vars);
}
if (JobTemplateForm.fields[fld].type === 'lookup' && data.summary_fields[JobTemplateForm.fields[fld].sourceModel]) {
$scope[JobTemplateForm.fields[fld].sourceModel + '_' + JobTemplateForm.fields[fld].sourceField] =
@@ -446,5 +424,5 @@ function JobsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, J
JobsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobForm', 'JobTemplateForm',
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit',
'ReturnToCaller', 'ClearScope', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit', 'PromptPasswords',
- 'GetBasePath', 'md5Setup', 'FormatDate', 'JobStatusToolTip', 'Wait', 'Empty'
+ 'GetBasePath', 'md5Setup', 'FormatDate', 'JobStatusToolTip', 'Wait', 'Empty', 'ParseVariableString'
];
diff --git a/awx/ui/static/js/helpers/Groups.js b/awx/ui/static/js/helpers/Groups.js
index 8a3526974d..3684935e31 100644
--- a/awx/ui/static/js/helpers/Groups.js
+++ b/awx/ui/static/js/helpers/Groups.js
@@ -12,8 +12,7 @@
angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'GroupListDefinition', 'SearchHelper',
'PaginationHelpers', 'ListGenerator', 'AuthService', 'GroupsHelper', 'InventoryHelper', 'SelectionHelper',
'JobSubmissionHelper', 'RefreshHelper', 'PromptDialog', 'CredentialsListDefinition', 'InventoryTree',
- 'InventoryStatusDefinition'
-])
+ 'InventoryStatusDefinition', 'VariablesHelper'])
.factory('GetSourceTypeOptions', ['Rest', 'ProcessErrors', 'GetBasePath',
function (Rest, ProcessErrors, GetBasePath) {
@@ -322,10 +321,10 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
.factory('GroupsAdd', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm',
'Prompt', 'ProcessErrors', 'GetBasePath', 'ParseTypeChange', 'Wait', 'GetChoices',
- 'GetSourceTypeOptions', 'LookUpInit', 'BuildTree', 'SourceChange', 'WatchInventoryWindowResize',
+ 'GetSourceTypeOptions', 'LookUpInit', 'BuildTree', 'SourceChange', 'WatchInventoryWindowResize', 'ToJSON',
function ($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors,
GetBasePath, ParseTypeChange, Wait, GetChoices, GetSourceTypeOptions, LookUpInit, BuildTree,
- SourceChange, WatchInventoryWindowResize) {
+ SourceChange, WatchInventoryWindowResize, ToJSON) {
return function (params) {
var inventory_id = params.inventory_id,
@@ -403,8 +402,7 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
var parseError = false,
data = {},
- regions, r, i,
- json_data;
+ regions, r, i;
// Update the selector tree with new group name, descr
//SetNodeName({ scope: scope['selectedNode'], group_id: group_id,
@@ -428,30 +426,7 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
data.source_regions = r.join();
if (scope.source.value === 'ec2') {
- // for ec2, validate variable data
- try {
- if (scope.envParseType === 'json') {
- json_data = JSON.parse(scope.source_vars); //make sure JSON parses
- } else {
- json_data = jsyaml.load(scope.source_vars); //parse yaml
- }
-
- // Make sure our JSON is actually an object
- if (typeof json_data !== 'object') {
- throw "failed to return an object!";
- }
-
- // Send JSON as a string
- if ($.isEmptyObject(json_data)) {
- data.source_vars = "";
- } else {
- data.source_vars = JSON.stringify(json_data, undefined, '\t');
- }
- } catch (err) {
- parseError = true;
- scope.$emit('SaveComplete', true);
- Alert("Error", "Error parsing extra variables. Parser returned: " + err);
- }
+ data.source_vars = ToJSON(scope.envParseType, scope.source_vars, true);
}
if (!parseError) {
@@ -484,54 +459,28 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
// Save
scope.formModalAction = function () {
- var json_data, data;
+ var data;
Wait('start');
- try {
- scope.formModalActionDisabled = true;
-
- // Make sure we have valid variable data
- if (scope.parseType === 'json') {
- json_data = JSON.parse(scope.variables); //make sure JSON parses
- } else {
- json_data = jsyaml.load(scope.variables); //parse yaml
- }
-
- // Make sure our JSON is actually an object
- if (typeof json_data !== 'object') {
- throw "failed to return an object!";
- }
-
- data = {
- name: scope.name,
- description: scope.description
- };
-
- if (inventory_id) {
- data.inventory = inventory_id;
- }
-
- if ($.isEmptyObject(json_data)) {
- data.variables = "";
- } else {
- data.variables = JSON.stringify(json_data, undefined, '\t');
- }
-
- Rest.setUrl(defaultUrl);
- Rest.post(data)
- .success(function (data) {
- scope.$emit('formSaveSuccess', data.id, GetBasePath('inventory_sources') + data.id + '/');
- })
- .error(function (data, status) {
- Wait('stop');
- scope.formModalActionDisabled = false;
- ProcessErrors(scope, data, status, form, { hdr: 'Error!',
- msg: 'Failed to add new group. POST returned status: ' + status });
- });
- } catch (err) {
- Wait('stop');
- scope.formModalActionDisabled = false;
- Alert("Error", "Error parsing group variables. Parser returned: " + err);
+ scope.formModalActionDisabled = true;
+ data = {
+ name: scope.name,
+ description: scope.description
+ };
+ if (inventory_id) {
+ data.inventory = inventory_id;
}
+ data.variables = ToJSON(scope.parseType, scope.variables, true);
+ Rest.setUrl(defaultUrl);
+ Rest.post(data)
+ .success(function (data) {
+ scope.$emit('formSaveSuccess', data.id, GetBasePath('inventory_sources') + data.id + '/');
+ })
+ .error(function (data, status) {
+ Wait('stop');
+ scope.formModalActionDisabled = false;
+ ProcessErrors(scope, data, status, form, { hdr: 'Error!',
+ msg: 'Failed to add new group. POST returned status: ' + status });
+ });
};
scope.sourceChange = function () {
@@ -584,9 +533,12 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
.factory('GroupsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm',
'Prompt', 'ProcessErrors', 'GetBasePath', 'SetNodeName', 'ParseTypeChange', 'GetSourceTypeOptions', 'InventoryUpdate',
'LookUpInit', 'Empty', 'Wait', 'GetChoices', 'UpdateGroup', 'SourceChange', 'Find','WatchInventoryWindowResize',
+ 'ParseVariableString', 'ToJSON',
function ($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors,
GetBasePath, SetNodeName, ParseTypeChange, GetSourceTypeOptions, InventoryUpdate, LookUpInit, Empty, Wait,
- GetChoices, UpdateGroup, SourceChange, Find, WatchInventoryWindowResize) {
+ GetChoices, UpdateGroup, SourceChange, Find, WatchInventoryWindowResize,
+ ParseVariableString, ToJSON) {
+
return function (params) {
var parent_scope = params.scope,
@@ -647,11 +599,7 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
Rest.setUrl(scope.variable_url);
Rest.get()
.success(function (data) {
- if ($.isEmptyObject(data)) {
- scope.variables = "---";
- } else {
- scope.variables = jsyaml.safeDump(data);
- }
+ scope.variables = ParseVariableString(data);
scope.$emit('groupVariablesLoaded');
})
.error(function (data, status) {
@@ -670,7 +618,7 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
Rest.setUrl(scope.source_url);
Rest.get()
.success(function (data) {
- var fld, i, j, flag, found, json_obj, set, opts, list;
+ var fld, i, j, flag, found, set, opts, list;
for (fld in form.fields) {
if (fld === 'checkbox_group') {
for (i = 0; i < form.fields[fld].fields.length; i++) {
@@ -706,13 +654,7 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
}
} else if (fld === 'source_vars') {
// Parse source_vars, converting to YAML.
- if ($.isEmptyObject(data.source_vars) || data.source_vars === "{}" ||
- data.source_vars === "null" || data.source_vars === "") {
- scope.source_vars = "---";
- } else {
- json_obj = JSON.parse(data.source_vars);
- scope.source_vars = jsyaml.safeDump(json_obj);
- }
+ scope.source_vars = ParseVariableString(data.source_vars);
master.source_vars = scope.variables;
} else if (data[fld]) {
scope[fld] = data[fld];
@@ -882,7 +824,7 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
// related fields, then call SaveComplete to wrap things up.
var parseError = false,
- regions, r, i, json_data,
+ regions, r, i,
data = {
group: group_id,
source: ((scope.source && scope.source.value) ? scope.source.value : ''),
@@ -903,29 +845,7 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
if (scope.source && scope.source.value === 'ec2') {
// for ec2, validate variable data
- try {
- if (scope.envParseType === 'json') {
- json_data = JSON.parse(scope.source_vars); //make sure JSON parses
- } else {
- json_data = jsyaml.load(scope.source_vars); //parse yaml
- }
-
- // Make sure our JSON is actually an object
- if (typeof json_data !== 'object') {
- throw "failed to return an object!";
- }
-
- // Send JSON as a string
- if ($.isEmptyObject(json_data)) {
- data.source_vars = "";
- } else {
- data.source_vars = JSON.stringify(json_data);
- }
- } catch (err) {
- parseError = true;
- scope.$emit('SaveComplete', true);
- Alert("Error", "Error parsing extra variables. Parser returned: " + err);
- }
+ data.source_vars = ToJSON(scope.envParseType, scope.source_vars, true);
}
if (!parseError) {
@@ -953,57 +873,42 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
// Save
scope.formModalAction = function () {
Wait('start');
- try {
- var fld, data, json_data;
+ var fld, data, json_data;
- // Make sure we have valid variable data
- if (scope.parseType === 'json') {
- json_data = JSON.parse(scope.variables); //make sure JSON parses
- } else {
- json_data = jsyaml.load(scope.variables); //parse yaml
- }
+ json_data = ToJSON(scope.parseType, scope.variables);
- // Make sure our JSON is actually an object
- if (typeof json_data !== 'object') {
- throw "failed to return an object!";
- }
-
- data = {};
- for (fld in form.fields) {
- data[fld] = scope[fld];
- }
-
- data.inventory = inventory_id;
-
- Rest.setUrl(defaultUrl);
- Rest.put(data)
- .success(function () {
- if (scope.variables) {
- //update group variables
- Rest.setUrl(scope.variable_url);
- Rest.put(json_data)
- .success(function () {
- scope.$emit('formSaveSuccess');
- })
- .error(function (data, status) {
- ProcessErrors(scope, data, status, form, { hdr: 'Error!',
- msg: 'Failed to update group variables. PUT status: ' + status });
- });
- } else {
- scope.$emit('formSaveSuccess');
- }
- })
- .error(function (data, status) {
- Wait('stop');
- ProcessErrors(scope, data, status, form, {
- hdr: 'Error!',
- msg: 'Failed to update group: ' + group_id + '. PUT status: ' + status
- });
- });
- } catch (err) {
- Wait('stop');
- Alert("Error", "Error parsing group variables. Parser returned: " + err);
+ data = {};
+ for (fld in form.fields) {
+ data[fld] = scope[fld];
}
+
+ data.inventory = inventory_id;
+
+ Rest.setUrl(defaultUrl);
+ Rest.put(data)
+ .success(function () {
+ if (scope.variables) {
+ //update group variables
+ Rest.setUrl(scope.variable_url);
+ Rest.put(json_data)
+ .success(function () {
+ scope.$emit('formSaveSuccess');
+ })
+ .error(function (data, status) {
+ ProcessErrors(scope, data, status, form, { hdr: 'Error!',
+ msg: 'Failed to update group variables. PUT status: ' + status });
+ });
+ } else {
+ scope.$emit('formSaveSuccess');
+ }
+ })
+ .error(function (data, status) {
+ Wait('stop');
+ ProcessErrors(scope, data, status, form, {
+ hdr: 'Error!',
+ msg: 'Failed to update group: ' + group_id + '. PUT status: ' + status
+ });
+ });
};
// Start the update process
diff --git a/awx/ui/static/js/helpers/Hosts.js b/awx/ui/static/js/helpers/Hosts.js
index 9cbf93eee1..2489dee95e 100644
--- a/awx/ui/static/js/helpers/Hosts.js
+++ b/awx/ui/static/js/helpers/Hosts.js
@@ -14,7 +14,7 @@
angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'HostListDefinition',
'SearchHelper', 'PaginationHelpers', 'ListGenerator', 'AuthService', 'HostsHelper',
'InventoryHelper', 'RelatedSearchHelper', 'InventoryFormDefinition', 'SelectionHelper',
- 'HostGroupsFormDefinition'
+ 'HostGroupsFormDefinition', 'VariablesHelper'
])
.factory('SetEnabledMsg', [ function() {
@@ -320,8 +320,9 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostList, Gener
.factory('HostsCreate', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'HostForm', 'GenerateForm',
'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', 'WatchInventoryWindowResize',
+ 'ToJSON',
function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, GenerateForm, Prompt, ProcessErrors,
- GetBasePath, HostsReload, ParseTypeChange, Wait, WatchInventoryWindowResize) {
+ GetBasePath, HostsReload, ParseTypeChange, Wait, WatchInventoryWindowResize, ToJSON) {
return function(params) {
var parent_scope = params.scope,
@@ -380,55 +381,27 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, Gener
Wait('start');
- try {
- var fld, json_data, data={};
- scope.formModalActionDisabled = true;
-
- // Make sure we have valid variable data
- if (scope.parseType === 'json') {
- json_data = JSON.parse(scope.variables); //make sure JSON parses
+ var fld, data={};
+ scope.formModalActionDisabled = true;
+ data.variables = ToJSON(scope.parseType, scope.variables, true);
+ for (fld in form.fields) {
+ if (fld !== 'variables') {
+ data[fld] = scope[fld];
}
- else {
- json_data = jsyaml.load(scope.variables); //parse yaml
- }
-
- // Make sure our JSON is actually an object
- if (typeof json_data !== 'object') {
- throw "failed to return an object!";
- }
-
- for (fld in form.fields) {
- if (fld !== 'variables') {
- data[fld] = scope[fld];
- }
- }
-
- data.inventory = inventory_id;
-
- if ($.isEmptyObject(json_data)) {
- data.variables = "";
- }
- else {
- data.variables = JSON.stringify(json_data, undefined, '\t');
- }
-
- Rest.setUrl(defaultUrl);
- Rest.post(data)
- .success( function() {
- scope.$emit('HostSaveComplete');
- })
- .error( function(data, status) {
- Wait('stop');
- scope.formModalActionDisabled = false;
- ProcessErrors(scope, data, status, form,
- { hdr: 'Error!', msg: 'Failed to add new host. POST returned status: ' + status });
- });
- }
- catch(err) {
- Wait('stop');
- scope.formModalActionDisabled = false;
- Alert("Error", "Error parsing host variables. Parser returned: " + err);
}
+ data.inventory = inventory_id;
+
+ Rest.setUrl(defaultUrl);
+ Rest.post(data)
+ .success( function() {
+ scope.$emit('HostSaveComplete');
+ })
+ .error( function(data, status) {
+ Wait('stop');
+ scope.formModalActionDisabled = false;
+ ProcessErrors(scope, data, status, form,
+ { hdr: 'Error!', msg: 'Failed to add new host. POST returned status: ' + status });
+ });
};
// Cancel
@@ -447,9 +420,10 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, Gener
.factory('HostsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'HostForm', 'GenerateForm',
'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', 'Find', 'SetStatus', 'ApplyEllipsis',
- 'WatchInventoryWindowResize',
+ 'WatchInventoryWindowResize', 'ToJSON', 'ParseVariableString',
function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, GenerateForm, Prompt, ProcessErrors,
- GetBasePath, HostsReload, ParseTypeChange, Wait, Find, SetStatus, ApplyEllipsis, WatchInventoryWindowResize) {
+ GetBasePath, HostsReload, ParseTypeChange, Wait, Find, SetStatus, ApplyEllipsis, WatchInventoryWindowResize, ToJSON,
+ ParseVariableString) {
return function(params) {
var parent_scope = params.scope,
@@ -486,12 +460,7 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, Gener
Rest.setUrl(scope.variable_url);
Rest.get()
.success( function(data) {
- if ($.isEmptyObject(data)) {
- scope.variables = "---";
- }
- else {
- scope.variables = jsyaml.safeDump(data);
- }
+ scope.variables = ParseVariableString(data);
scope.$emit('hostVariablesLoaded');
})
.error( function(data, status) {
@@ -570,49 +539,23 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, Gener
scope.formModalAction = function() {
Wait('start');
-
- try {
- // Make sure we have valid variable data
- var fld, json_data, data={};
- if (scope.parseType === 'json') {
- json_data = JSON.parse(scope.variables); //make sure JSON parses
- }
- else {
- json_data = jsyaml.load(scope.variables); //parse yaml
- }
-
- // Make sure our JSON is actually an object
- if (typeof json_data !== 'object') {
- throw "failed to return an object!";
- }
-
- for (fld in form.fields) {
- data[fld] = scope[fld];
- }
- data.inventory = inventory_id;
-
- if ($.isEmptyObject(json_data)) {
- data.variables = "";
- }
- else {
- data.variables = JSON.stringify(json_data, undefined, '\t');
- }
-
- Rest.setUrl(defaultUrl);
- Rest.put(data)
- .success( function() {
- scope.$emit('saveCompleted');
- })
- .error( function(data, status) {
- Wait('stop');
- ProcessErrors(scope, data, status, form,
- { hdr: 'Error!', msg: 'Failed to update host: ' + host_id + '. PUT returned status: ' + status });
- });
- }
- catch(err) {
- Wait('stop');
- Alert("Error", "Error parsing host variables. Parser returned: " + err);
+ var fld, data={};
+
+ data.variables = ToJSON(scope.parseType, scope.variables, true);
+ for (fld in form.fields) {
+ data[fld] = scope[fld];
}
+ data.inventory = inventory_id;
+ Rest.setUrl(defaultUrl);
+ Rest.put(data)
+ .success( function() {
+ scope.$emit('saveCompleted');
+ })
+ .error( function(data, status) {
+ Wait('stop');
+ ProcessErrors(scope, data, status, form,
+ { hdr: 'Error!', msg: 'Failed to update host: ' + host_id + '. PUT returned status: ' + status });
+ });
};
// Cancel
diff --git a/awx/ui/static/js/helpers/Variables.js b/awx/ui/static/js/helpers/Variables.js
new file mode 100644
index 0000000000..31e3bd7cc5
--- /dev/null
+++ b/awx/ui/static/js/helpers/Variables.js
@@ -0,0 +1,109 @@
+/*********************************************
+ * Copyright (c) 2014 AnsibleWorks, Inc.
+ *
+ * VariablesHelper
+ *
+ * Show the CodeMirror variable editor and allow
+ * toggle between JSON and YAML
+ *
+ */
+
+'use strict';
+
+angular.module('VariablesHelper', ['Utilities'])
+
+ /**
+ variables: string containing YAML or JSON | a JSON object.
+
+ If JSON string, convert to JSON object and run through jsyaml.safeDump() to create a YAML document. If YAML,
+ will attempt to load via jsyaml.safeLoad() and return a YAML document using jsyaml.safeDump(). In all cases
+ a YAML document is returned.
+ **/
+ .factory('ParseVariableString', ['$log', 'ProcessErrors', function ($log, ProcessErrors) {
+ return function (variables) {
+ var result = "---", json_obj;
+ if (typeof variables === 'string') {
+ if ($.isEmptyObject(variables) || variables === "{}" || variables === "null" ||
+ variables === "" || variables === null) {
+ // String is empty, return ---
+ } else {
+ try {
+ json_obj = JSON.parse(variables);
+ result = jsyaml.safeDump(json_obj);
+ }
+ catch (e) {
+ $log.info('Attempt to parse extra_vars as JSON faild. Attempting to parse as YAML');
+ try {
+ json_obj = jsyaml.safeLoad(variables);
+ result = jsyaml.safeDump(json_obj);
+ }
+ catch(e2) {
+ ProcessErrors(null, variables, e2.message, null, { hdr: 'Error!',
+ msg: 'Attempts to parse variables as JSON and YAML failed. Last attempt returned: ' + e2.message });
+ }
+ }
+ }
+ }
+ else {
+ // an object was passed in. just convert to yaml
+ try {
+ result = jsyaml.safeDump(variables);
+ }
+ catch(e3) {
+ ProcessErrors(null, variables, e3.message, null, { hdr: 'Error!',
+ msg: 'Attempt to convert JSON object to YAML document failed: ' + e3.message });
+ }
+ }
+ return result;
+ };
+ }])
+
+ /**
+ parseType: 'json' | 'yaml'
+ variables: string containing JSON or YAML
+ stringify: optional, boolean
+
+ Parse the given string according to the parseType to a JSON object. If stringify true,
+ stringify the object and return the string. Otherwise, return the JSON object.
+
+ **/
+ .factory('ToJSON', ['$log', 'ProcessErrors', function($log, ProcessErrors) {
+ return function(parseType, variables, stringify) {
+ var json_data, result;
+ if (parseType === 'json') {
+ try {
+ json_data = JSON.parse(variables); //make sure JSON parses
+ }
+ catch(e) {
+ json_data = {};
+ $log.error('Failed to parse JSON string. Parser returned: ' + e.message);
+ ProcessErrors(null, variables, e.message, null, { hdr: 'Error!',
+ msg: 'Failed to parse JSON string. Parser returned: ' + e.message });
+ }
+ } else {
+ try {
+ json_data = jsyaml.load(variables);
+ }
+ catch(e) {
+ json_data = {};
+ $log.error('Failed to parse YAML string. Parser returned: ' + e.message);
+ ProcessErrors(null, variables, e.message, null, { hdr: 'Error!',
+ msg: 'Failed to parse YAML string. Parser returned: ' + e.message });
+ }
+ }
+ // Make sure our JSON is actually an object
+ if (typeof json_data !== 'object') {
+ ProcessErrors(null, variables, null, null, { hdr: 'Error!',
+ msg: 'Failed to parse variables. Attempted to parse ' + parseType + ' Parser did not return an object.' });
+ }
+ result = json_data;
+ if (stringify) {
+ if ($.isEmptyObject(json_data)) {
+ result = "";
+ } else {
+ result = JSON.stringify(json_data, undefined, '\t');
+ }
+ }
+ return result;
+ };
+ }]);
\ No newline at end of file
diff --git a/awx/ui/static/js/helpers/inventory.js b/awx/ui/static/js/helpers/inventory.js
index 0a9f618a55..b060f1e756 100644
--- a/awx/ui/static/js/helpers/inventory.js
+++ b/awx/ui/static/js/helpers/inventory.js
@@ -11,7 +11,7 @@
'use strict';
angular.module('InventoryHelper', ['RestServices', 'Utilities', 'OrganizationListDefinition', 'ListGenerator', 'AuthService',
- 'InventoryHelper', 'InventoryFormDefinition', 'ParseHelper', 'SearchHelper'
+ 'InventoryHelper', 'InventoryFormDefinition', 'ParseHelper', 'SearchHelper', 'VariablesHelper',
])
.factory('WatchInventoryWindowResize', ['ApplyEllipsis',
@@ -40,8 +40,9 @@ angular.module('InventoryHelper', ['RestServices', 'Utilities', 'OrganizationLis
])
.factory('SaveInventory', ['InventoryForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList',
- 'GetBasePath', 'ParseTypeChange', 'Wait',
- function (InventoryForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange, Wait) {
+ 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON',
+ function (InventoryForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange, Wait,
+ ToJSON) {
return function (params) {
// Save inventory property modifications
@@ -52,67 +53,58 @@ angular.module('InventoryHelper', ['RestServices', 'Utilities', 'OrganizationLis
fld, json_data, data;
Wait('start');
+
+ // Make sure we have valid variable data
+ json_data = ToJSON(scope.inventoryParseType, scope.inventory_variables);
+
+ // Make sure our JSON is actually an object
+ if (typeof json_data !== 'object') {
+ throw "failed to return an object!";
+ }
- try {
- // Make sure we have valid variable data
- if (scope.inventoryParseType === 'json') {
- json_data = JSON.parse(scope.inventory_variables); //make sure JSON parses
- } else {
- json_data = jsyaml.load(scope.inventory_variables); //parse yaml
- }
-
- // Make sure our JSON is actually an object
- if (typeof json_data !== 'object') {
- throw "failed to return an object!";
- }
-
- data = {};
- for (fld in form.fields) {
- if (fld !== 'inventory_variables') {
- if (form.fields[fld].realName) {
- data[form.fields[fld].realName] = scope[fld];
- } else {
- data[fld] = scope[fld];
- }
+ data = {};
+ for (fld in form.fields) {
+ if (fld !== 'inventory_variables') {
+ if (form.fields[fld].realName) {
+ data[form.fields[fld].realName] = scope[fld];
+ } else {
+ data[fld] = scope[fld];
}
}
-
- Rest.setUrl(defaultUrl + scope.inventory_id + '/');
- Rest.put(data)
- .success(function (data) {
- if (scope.inventory_variables) {
- Rest.setUrl(data.related.variable_data);
- Rest.put(json_data)
- .success(function () {
- Wait('stop');
- scope.$emit('InventorySaved');
- })
- .error(function (data, status) {
- ProcessErrors(scope, data, status, form, { hdr: 'Error!',
- msg: 'Failed to update inventory varaibles. PUT returned status: ' + status
- });
- });
- } else {
- scope.$emit('InventorySaved');
- }
- })
- .error(function (data, status) {
- ProcessErrors(scope, data, status, form, { hdr: 'Error!',
- msg: 'Failed to update inventory. POST returned status: ' + status });
- });
- } catch (err) {
- Wait('stop');
- Alert("Error", "Error parsing inventory variables. Parser returned: " + err);
}
+
+ Rest.setUrl(defaultUrl + scope.inventory_id + '/');
+ Rest.put(data)
+ .success(function (data) {
+ if (scope.inventory_variables) {
+ Rest.setUrl(data.related.variable_data);
+ Rest.put(json_data)
+ .success(function () {
+ Wait('stop');
+ scope.$emit('InventorySaved');
+ })
+ .error(function (data, status) {
+ ProcessErrors(scope, data, status, form, { hdr: 'Error!',
+ msg: 'Failed to update inventory varaibles. PUT returned status: ' + status
+ });
+ });
+ } else {
+ scope.$emit('InventorySaved');
+ }
+ })
+ .error(function (data, status) {
+ ProcessErrors(scope, data, status, form, { hdr: 'Error!',
+ msg: 'Failed to update inventory. POST returned status: ' + status });
+ });
};
}
])
.factory('EditInventoryProperties', ['InventoryForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList',
- 'GetBasePath', 'ParseTypeChange', 'SaveInventory', 'Wait', 'Store', 'SearchInit',
+ 'GetBasePath', 'ParseTypeChange', 'SaveInventory', 'Wait', 'Store', 'SearchInit', 'ParseVariableString',
function (InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange, SaveInventory,
- Wait, Store, SearchInit) {
+ Wait, Store, SearchInit, ParseVariableString) {
return function (params) {
var parent_scope = params.scope,
@@ -146,23 +138,10 @@ angular.module('InventoryHelper', ['RestServices', 'Utilities', 'OrganizationLis
Rest.setUrl(GetBasePath('inventory') + inventory_id + '/');
Rest.get()
.success(function (data) {
- var fld, json_obj;
+ var fld;
for (fld in form.fields) {
if (fld === 'inventory_variables') {
- // Parse variables, converting to YAML.
- if ($.isEmptyObject(data.variables) || data.variables === "{}" ||
- data.variables === "null" || data.variables === "") {
- scope.inventory_variables = "---";
- } else {
- try {
- json_obj = JSON.parse(data.variables);
- scope.inventory_variables = jsyaml.safeDump(json_obj);
- } catch (err) {
- Alert('Variable Parse Error', 'Attempted to parse variables for inventory: ' + inventory_id +
- '. Parse returned: ' + err);
- scope.inventory_variables = '---';
- }
- }
+ scope.inventory_variables = ParseVariableString(data.variables);
master.inventory_variables = scope.variables;
} else if (fld === 'inventory_name') {
scope[fld] = data.name;
@@ -174,7 +153,6 @@ angular.module('InventoryHelper', ['RestServices', 'Utilities', 'OrganizationLis
scope[fld] = data[fld];
master[fld] = scope[fld];
}
-
if (form.fields[fld].sourceModel && data.summary_fields &&
data.summary_fields[form.fields[fld].sourceModel]) {
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
diff --git a/awx/ui/templates/ui/index.html b/awx/ui/templates/ui/index.html
index 1a634e1611..b1498e1e52 100644
--- a/awx/ui/templates/ui/index.html
+++ b/awx/ui/templates/ui/index.html
@@ -127,6 +127,7 @@
+