diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js
index ac431c2dd8..ead6518963 100644
--- a/awx/ui/client/src/app.js
+++ b/awx/ui/client/src/app.js
@@ -125,11 +125,6 @@ var tower = angular.module('Tower', [
'templates',
'PromptDialog',
'AWDirectives',
- 'InventoryFormDefinition',
- 'HostFormDefinition',
- 'GroupFormDefinition',
- 'JobTemplateFormDefinition',
- 'HostGroupsFormDefinition',
'lrInfiniteScroll',
'features',
'pendolytics',
diff --git a/awx/ui/client/src/forms.js b/awx/ui/client/src/forms.js
deleted file mode 100644
index b1be9928dc..0000000000
--- a/awx/ui/client/src/forms.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*************************************************
- * Copyright (c) 2015 Ansible, Inc.
- *
- * All Rights Reserved
-*************************************************/
-
-import Groups from "./forms/Groups";
-import HostGroups from "./forms/HostGroups";
-import Hosts from "./forms/Hosts";
-import Inventories from "./forms/Inventories";
-import InventoryStatus from "./forms/InventoryStatus";
-import JobTemplates from "./forms/JobTemplates";
-
-export {
- Groups,
- HostGroups,
- Hosts,
- Inventories,
- InventoryStatus,
- JobTemplates
-};
diff --git a/awx/ui/client/src/forms/Groups.js b/awx/ui/client/src/forms/Groups.js
deleted file mode 100644
index 506d66d1b2..0000000000
--- a/awx/ui/client/src/forms/Groups.js
+++ /dev/null
@@ -1,362 +0,0 @@
-/*************************************************
- * Copyright (c) 2015 Ansible, Inc.
- *
- * All Rights Reserved
- *************************************************/
-
- /**
- * @ngdoc function
- * @name forms.function:Groups
- * @description This form is for adding/editing a Group on the inventory page
-*/
-
-export default
- angular.module('GroupFormDefinition', [])
- .value('GroupFormObject', {
-
- addTitle: 'CREATE GROUP',
- editTitle: '{{ name }}',
- showTitle: true,
- name: 'group',
- basePath: 'groups',
- // the parent node this generated state definition tree expects to attach to
- stateTree: 'inventoryManage',
- // form generator inspects the current state name to determine whether or not to set an active (.is-selected) class on a form tab
- // this setting is optional on most forms, except where the form's edit state name is not parentStateName.edit
- activeEditState: 'inventoryManage.editGroup',
- detailsClick: "$state.go('inventoryManage.editGroup')",
- well: false,
- fields: {
- name: {
- label: 'Name',
- type: 'text',
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
- required: true,
- tab: 'properties'
- },
- description: {
- label: 'Description',
- type: 'text',
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
- tab: 'properties'
- },
- variables: {
- label: 'Variables',
- type: 'textarea',
- class: 'Form-textAreaLabel Form-formGroup--fullWidth',
- rows: 6,
- 'default': '---',
- dataTitle: 'Group Variables',
- dataPlacement: 'right',
- parseTypeName: 'parseType',
- awPopOver: "
Variables defined here apply to all child groups and hosts.
" +
- "Enter variables using either JSON or YAML syntax. Use the " +
- "radio button to toggle between the two.
" +
- "JSON: \n" +
- "{ \"somevar\": \"somevalue\", \"password\": \"magic\" } \n" +
- "YAML: \n" +
- "--- somevar: somevalue password: magic \n" +
- 'View JSON examples at www.json.org
' +
- 'View YAML examples at docs.ansible.com
',
- dataContainer: 'body',
- tab: 'properties'
- },
- source: {
- label: 'Source',
- type: 'select',
- ngOptions: 'source.label for source in source_type_options track by source.value',
- ngChange: 'sourceChange(source)',
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
- ngModel: 'source'
- },
- credential: {
- // initializes a default value for this search param
- // search params with default values set will not generate user-interactable search tags
- search: {
- kind: null
- },
- label: 'Cloud Credential',
- type: 'lookup',
- list: 'CredentialList',
- basePath: 'credentials',
- ngShow: "source && source.value !== '' && source.value !== 'custom'",
- sourceModel: 'credential',
- sourceField: 'name',
- ngClick: 'lookupCredential()',
- awRequiredWhen: {
- reqExpression: "cloudCredentialRequired",
- init: "false"
- },
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
- watchBasePath: "credentialBasePath"
- },
- source_regions: {
- label: 'Regions',
- type: 'select',
- ngOptions: 'source.label for source in source_region_choices track by source.value',
- multiSelect: true,
- ngShow: "source && (source.value == 'rax' || source.value == 'ec2' || source.value == 'gce' || source.value == 'azure' || source.value == 'azure_rm')",
-
-
- dataTitle: 'Source Regions',
- dataPlacement: 'right',
- awPopOver: "Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, " +
- "or choose All to include all regions. Tower will only be updated with Hosts associated with the selected regions." +
- "
",
- dataContainer: 'body',
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
- },
- instance_filters: {
- label: 'Instance Filters',
- type: 'text',
- ngShow: "source && source.value == 'ec2'",
- dataTitle: 'Instance Filters',
- dataPlacement: 'right',
- awPopOver: "Provide a comma-separated list of filter expressions. " +
- "Hosts are imported to Tower when ANY of the filters match.
" +
- "Limit to hosts having a tag: \n" +
- "tag-key=TowerManaged \n" +
- "Limit to hosts using either key pair: \n" +
- "key-name=staging, key-name=production \n" +
- "Limit to hosts where the Name tag begins with test : \n" +
- "tag:Name=test* \n" +
- "View the Describe Instances documentation " +
- "for a complete list of supported filters.
",
- dataContainer: 'body',
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
- },
- group_by: {
- label: 'Only Group By',
- type: 'select',
- ngShow: "source && source.value == 'ec2'",
- ngOptions: 'source.label for source in group_by_choices track by source.value',
- multiSelect: true,
- dataTitle: 'Only Group By',
- dataPlacement: 'right',
- awPopOver: "Select which groups to create automatically. " +
- "Tower will create group names similar to the following examples based on the options selected:
" +
- "Availability Zone: zones » us-east-1b " +
- "Image ID: images » ami-b007ab1e " +
- "Instance ID: instances » i-ca11ab1e " +
- "Instance Type: types » type_m1_medium " +
- "Key Name: keys » key_testing " +
- "Region: regions » us-east-1 " +
- "Security Group: security_groups » security_group_default " +
- "Tags: tags » tag_Name » tag_Name_host1 " +
- "VPC ID: vpcs » vpc-5ca1ab1e " +
- "Tag None: tags » tag_none " +
- " If blank, all groups above are created except Instance ID .
",
- dataContainer: 'body',
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
- },
- inventory_script: {
- label : "Custom Inventory Script",
- type: 'lookup',
- basePath: 'inventory_scripts',
- list: 'InventoryScriptsList',
- ngShow: "source && source.value === 'custom'",
- sourceModel: 'inventory_script',
- sourceField: 'name',
- awRequiredWhen: {
- reqExpression: "source && source.value === 'custom'",
- init: "false"
- },
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
- },
- custom_variables: {
- id: 'custom_variables',
- label: 'Environment Variables', //"{{vars_label}}" ,
- ngShow: "source && source.value=='custom' ",
- type: 'textarea',
- class: 'Form-textAreaLabel Form-formGroup--fullWidth',
- rows: 6,
- 'default': '---',
- parseTypeName: 'envParseType',
- dataTitle: "Environment Variables",
- dataPlacement: 'right',
- awPopOver: "Provide environment variables to pass to the custom inventory script.
" +
- "Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.
" +
- "JSON: \n" +
- "{ \"somevar\": \"somevalue\", \"password\": \"magic\" } \n" +
- "YAML: \n" +
- "--- somevar: somevalue password: magic \n" +
- 'View JSON examples at www.json.org
' +
- 'View YAML examples at docs.ansible.com
',
- dataContainer: 'body'
- },
- ec2_variables: {
- id: 'ec2_variables',
- label: 'Source Variables', //"{{vars_label}}" ,
- ngShow: "source && source.value == 'ec2'",
- type: 'textarea',
- class: 'Form-textAreaLabel Form-formGroup--fullWidth',
- rows: 6,
- 'default': '---',
- parseTypeName: 'envParseType',
- dataTitle: "Source Variables",
- dataPlacement: 'right',
- awPopOver: "Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables " +
- "" +
- "view ec2.ini in the Ansible github repo.
" +
- "Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.
" +
- "JSON: \n" +
- "{ \"somevar\": \"somevalue\", \"password\": \"magic\" } \n" +
- "YAML: \n" +
- "--- somevar: somevalue password: magic \n" +
- 'View JSON examples at www.json.org
' +
- 'View YAML examples at docs.ansible.com
',
- dataContainer: 'body'
- },
- vmware_variables: {
- id: 'vmware_variables',
- label: 'Source Variables', //"{{vars_label}}" ,
- ngShow: "source && source.value == 'vmware'",
- type: 'textarea',
- class: 'Form-textAreaLabel Form-formGroup--fullWidth',
- rows: 6,
- 'default': '---',
- parseTypeName: 'envParseType',
- dataTitle: "Source Variables",
- dataPlacement: 'right',
- awPopOver: "Override variables found in vmware.ini and used by the inventory update script. For a detailed description of these variables " +
- "" +
- "view vmware_inventory.ini in the Ansible github repo.
" +
- "Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.
" +
- "JSON: \n" +
- "{ \"somevar\": \"somevalue\", \"password\": \"magic\" } \n" +
- "YAML: \n" +
- "--- somevar: somevalue password: magic \n" +
- 'View JSON examples at www.json.org
' +
- 'View YAML examples at docs.ansible.com
',
- dataContainer: 'body'
- },
- openstack_variables: {
- id: 'openstack_variables',
- label: 'Source Variables', //"{{vars_label}}" ,
- ngShow: "source && source.value == 'openstack'",
- type: 'textarea',
- class: 'Form-textAreaLabel Form-formGroup--fullWidth',
- rows: 6,
- 'default': '---',
- parseTypeName: 'envParseType',
- dataTitle: "Source Variables",
- dataPlacement: 'right',
- awPopOver: "Override variables found in openstack.yml and used by the inventory update script. For an example variable configuration " +
- "" +
- "view openstack.yml in the Ansible github repo.
" +
- "Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.
" +
- "JSON: \n" +
- "{ \"somevar\": \"somevalue\", \"password\": \"magic\" } \n" +
- "YAML: \n" +
- "--- somevar: somevalue password: magic \n" +
- 'View JSON examples at www.json.org
' +
- 'View YAML examples at docs.ansible.com
',
- dataContainer: 'body'
- },
- checkbox_group: {
- label: 'Update Options',
- type: 'checkbox_group',
- ngShow: "source && (source.value !== '' && source.value !== null)",
- class: 'Form-checkbox--stacked',
- fields: [{
- name: 'overwrite',
- label: 'Overwrite',
- type: 'checkbox',
- ngShow: "source.value !== '' && source.value !== null",
-
-
- awPopOver: 'If checked, all child groups and hosts not found on the external source will be deleted from ' +
- 'the local inventory.
When not checked, local child hosts and groups not found on the external source will ' +
- 'remain untouched by the inventory update process.
',
- dataTitle: 'Overwrite',
- dataContainer: 'body',
- dataPlacement: 'right',
- labelClass: 'checkbox-options',
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
- }, {
- name: 'overwrite_vars',
- label: 'Overwrite Variables',
- type: 'checkbox',
- ngShow: "source.value !== '' && source.value !== null",
-
-
- awPopOver: 'If checked, all variables for child groups and hosts will be removed and replaced by those ' +
- 'found on the external source.
When not checked, a merge will be performed, combining local variables with ' +
- 'those found on the external source.
',
- dataTitle: 'Overwrite Variables',
- dataContainer: 'body',
- dataPlacement: 'right',
- labelClass: 'checkbox-options',
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
- }, {
- name: 'update_on_launch',
- label: 'Update on Launch',
- type: 'checkbox',
- ngShow: "source.value !== '' && source.value !== null",
- awPopOver: 'Each time a job runs using this inventory, refresh the inventory from the selected source before ' +
- 'executing job tasks.
',
- dataTitle: 'Update on Launch',
- dataContainer: 'body',
- dataPlacement: 'right',
- labelClass: 'checkbox-options',
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
- }]
- },
- update_cache_timeout: {
- label: "Cache Timeout (seconds) ",
- id: 'source-cache-timeout',
- type: 'number',
- ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
- integer: true,
- min: 0,
- ngShow: "source && source.value !== '' && update_on_launch",
- spinner: true,
- "default": 0,
- awPopOver: 'Time in seconds to consider an inventory sync to be current. During job runs and callbacks the task system will ' +
- 'evaluate the timestamp of the latest sync. If it is older than Cache Timeout, it is not considered current, ' +
- 'and a new inventory sync will be performed.
',
- dataTitle: 'Cache Timeout',
- dataPlacement: 'right',
- dataContainer: "body"
- }
- },
-
- buttons: {
- cancel: {
- ngClick: 'formCancel()',
- ngShow: '(group_obj.summary_fields.user_capabilities.edit || canAdd)'
- },
- close: {
- ngClick: 'formCancel()',
- ngShow: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
- },
- save: {
- ngClick: 'formSave()',
- ngDisabled: true,
- ngShow: '(group_obj.summary_fields.user_capabilities.edit || canAdd)'
- }
- },
-
- related: {
- "notifications": {
- include: "NotificationsList"
- }
- }
-
- })
- .factory('GroupForm', ['GroupFormObject', 'NotificationsList',
- function(GroupFormObject, NotificationsList) {
- return function() {
- var itm;
-
- for (itm in GroupFormObject.related) {
- if (GroupFormObject.related[itm].include === "NotificationsList") {
- GroupFormObject.related[itm] = angular.copy(NotificationsList);
- GroupFormObject.related[itm].generateList = true;
- GroupFormObject.related[itm].disabled = "source === undefined || source.value === ''";
- GroupFormObject.related[itm].ngClick = "$state.go('inventoryManage.editGroup.notifications')";
- }
- }
- return GroupFormObject;
- };
- }]);
diff --git a/awx/ui/client/src/forms/HostGroups.js b/awx/ui/client/src/forms/HostGroups.js
deleted file mode 100644
index 16479fee2b..0000000000
--- a/awx/ui/client/src/forms/HostGroups.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/*************************************************
- * Copyright (c) 2015 Ansible, Inc.
- *
- * All Rights Reserved
- *************************************************/
-
- /**
- * @ngdoc function
- * @name forms.function:HostGroups
- * @description This form is for groups of hosts on the inventory page
-*/
-
-export default
- angular.module('HostGroupsFormDefinition', [])
- .value('HostGroupsForm', {
-
- editTitle: 'HOST GROUPS',
- name: 'host',
- well: false,
- formLabelSize: 'col-lg-3',
- formFieldSize: 'col-lg-9',
-
- fields: {
- groups: {
- label: 'Groups',
- type: 'select',
- multiple: true,
- ngOptions: 'group.name for group in inventory_groups track by group.value',
- required: true,
- awPopOver: "Provide a host name, ip address, or ip address:port. Examples include:
" +
- "myserver.domain.com " +
- "127.0.0.1 " +
- "10.1.0.140:25 " +
- "server.example.com:25" +
- " ",
- dataTitle: 'Host Name',
- dataPlacement: 'right',
- dataContainer: '#form-modal .modal-content'
- }
- },
-
- buttons: { //for now always generates tags
- reset: {
- ngClick: 'formReset()',
- ngDisabled: true
- },
- save: {
- ngClick: 'formSave()',
- ngDisabled: true
- }
- },
-
- related: { }
-
- }); //UserForm
diff --git a/awx/ui/client/src/forms/InventoryStatus.js b/awx/ui/client/src/forms/InventoryStatus.js
deleted file mode 100644
index 274c96a4d0..0000000000
--- a/awx/ui/client/src/forms/InventoryStatus.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*************************************************
- * Copyright (c) 2015 Ansible, Inc.
- *
- * All Rights Reserved
- *************************************************/
-
- /**
- * @ngdoc function
- * @name forms.function:InventoryStatus
- * @description This form is for adding/editing an InventoryStatus
-*/
-export default
- angular.module('InventoryStatusDefinition', [])
- .value('InventoryStatusForm', {
-
- name: 'inventory_update',
- editTitle: 'INVENTORY STATUS',
- well: false,
- 'class': 'horizontal-narrow',
-
- fields: {
- license_error: {
- type: 'alertblock',
- 'class': 'alert-info',
- alertTxt: 'The invenvtory update process exceeded the available number of licensed hosts. ' +
- 'View your license ' +
- 'for more information.',
- ngShow: 'license_error',
- closeable: true
- },
- created: {
- label: 'Created',
- type: 'text',
- readonly: true
- },
- status: {
- label: 'Status',
- type: 'text',
- readonly: true,
- 'class': 'nowrap mono-space resizable',
- rows: '{{ status_rows }}'
- },
- result_stdout: {
- label: 'Std Out',
- type: 'textarea',
- ngShow: 'result_stdout',
- 'class': 'nowrap mono-space resizable',
- readonly: true,
- rows: '{{ stdout_rows }}'
- },
- result_traceback: {
- label: 'Traceback',
- type: 'textarea',
- ngShow: 'result_traceback',
- 'class': 'nowrap mono-space resizable',
- readonly: true,
- rows: '{{ traceback_rows }}'
- }
- }
- }); //Form
diff --git a/awx/ui/client/src/forms/Inventories.js b/awx/ui/client/src/inventories/inventory.form.js
similarity index 97%
rename from awx/ui/client/src/forms/Inventories.js
rename to awx/ui/client/src/inventories/inventory.form.js
index 08f29d5872..3164d47b5a 100644
--- a/awx/ui/client/src/forms/Inventories.js
+++ b/awx/ui/client/src/inventories/inventory.form.js
@@ -10,9 +10,7 @@
* @description This form is for adding/editing an inventory
*/
-export default
-angular.module('InventoryFormDefinition', [])
- .factory('InventoryForm', ['i18n', function(i18n) {
+export default ['i18n', function(i18n) {
return {
addTitle: i18n._('NEW INVENTORY'),
@@ -134,4 +132,4 @@ angular.module('InventoryFormDefinition', [])
}
}
- };}]);
+ };}];
diff --git a/awx/ui/client/src/inventories/main.js b/awx/ui/client/src/inventories/main.js
index 1d9aa75804..45207bcf7e 100644
--- a/awx/ui/client/src/inventories/main.js
+++ b/awx/ui/client/src/inventories/main.js
@@ -16,6 +16,7 @@ import { N_ } from '../i18n';
// actual inventory list config object
import InventoryList from './inventory.list';
+import InventoryForm from './inventory.form';
export default
angular.module('inventory', [
@@ -25,6 +26,7 @@ angular.module('inventory', [
inventoryManage.name,
])
.factory('InventoryList', InventoryList)
+ .factory('InventoryForm', InventoryForm)
.config(['$stateProvider', '$stateExtenderProvider', 'stateDefinitionsProvider',
function($stateProvider, $stateExtenderProvider, stateDefinitionsProvider) {
// When stateDefinition.lazyLoad() resolves, states matching name.** or /url** will be de-registered and replaced with resolved states
diff --git a/awx/ui/client/src/inventories/manage/groups/groups.form.js b/awx/ui/client/src/inventories/manage/groups/groups.form.js
new file mode 100644
index 0000000000..16fee6017d
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/groups/groups.form.js
@@ -0,0 +1,360 @@
+/*************************************************
+ * Copyright (c) 2015 Ansible, Inc.
+ *
+ * All Rights Reserved
+ *************************************************/
+
+ /**
+ * @ngdoc function
+ * @name forms.function:Groups
+ * @description This form is for adding/editing a Group on the inventory page
+*/
+
+export default ['NotificationsList',
+ function(NotificationsList) {
+ return function() {
+ var GroupFormObject = {
+
+ addTitle: 'CREATE GROUP',
+ editTitle: '{{ name }}',
+ showTitle: true,
+ name: 'group',
+ basePath: 'groups',
+ // the parent node this generated state definition tree expects to attach to
+ stateTree: 'inventoryManage',
+ // form generator inspects the current state name to determine whether or not to set an active (.is-selected) class on a form tab
+ // this setting is optional on most forms, except where the form's edit state name is not parentStateName.edit
+ activeEditState: 'inventoryManage.editGroup',
+ detailsClick: "$state.go('inventoryManage.editGroup')",
+ well: false,
+ fields: {
+ name: {
+ label: 'Name',
+ type: 'text',
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
+ required: true,
+ tab: 'properties'
+ },
+ description: {
+ label: 'Description',
+ type: 'text',
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
+ tab: 'properties'
+ },
+ variables: {
+ label: 'Variables',
+ type: 'textarea',
+ class: 'Form-textAreaLabel Form-formGroup--fullWidth',
+ rows: 6,
+ 'default': '---',
+ dataTitle: 'Group Variables',
+ dataPlacement: 'right',
+ parseTypeName: 'parseType',
+ awPopOver: "Variables defined here apply to all child groups and hosts.
" +
+ "Enter variables using either JSON or YAML syntax. Use the " +
+ "radio button to toggle between the two.
" +
+ "JSON: \n" +
+ "{ \"somevar\": \"somevalue\", \"password\": \"magic\" } \n" +
+ "YAML: \n" +
+ "--- somevar: somevalue password: magic \n" +
+ 'View JSON examples at www.json.org
' +
+ 'View YAML examples at docs.ansible.com
',
+ dataContainer: 'body',
+ tab: 'properties'
+ },
+ source: {
+ label: 'Source',
+ type: 'select',
+ ngOptions: 'source.label for source in source_type_options track by source.value',
+ ngChange: 'sourceChange(source)',
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
+ ngModel: 'source'
+ },
+ credential: {
+ // initializes a default value for this search param
+ // search params with default values set will not generate user-interactable search tags
+ search: {
+ kind: null
+ },
+ label: 'Cloud Credential',
+ type: 'lookup',
+ list: 'CredentialList',
+ basePath: 'credentials',
+ ngShow: "source && source.value !== '' && source.value !== 'custom'",
+ sourceModel: 'credential',
+ sourceField: 'name',
+ ngClick: 'lookupCredential()',
+ awRequiredWhen: {
+ reqExpression: "cloudCredentialRequired",
+ init: "false"
+ },
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
+ watchBasePath: "credentialBasePath"
+ },
+ source_regions: {
+ label: 'Regions',
+ type: 'select',
+ ngOptions: 'source.label for source in source_region_choices track by source.value',
+ multiSelect: true,
+ ngShow: "source && (source.value == 'rax' || source.value == 'ec2' || source.value == 'gce' || source.value == 'azure' || source.value == 'azure_rm')",
+
+
+ dataTitle: 'Source Regions',
+ dataPlacement: 'right',
+ awPopOver: "Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, " +
+ "or choose All to include all regions. Tower will only be updated with Hosts associated with the selected regions." +
+ "
",
+ dataContainer: 'body',
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
+ },
+ instance_filters: {
+ label: 'Instance Filters',
+ type: 'text',
+ ngShow: "source && source.value == 'ec2'",
+ dataTitle: 'Instance Filters',
+ dataPlacement: 'right',
+ awPopOver: "Provide a comma-separated list of filter expressions. " +
+ "Hosts are imported to Tower when ANY of the filters match.
" +
+ "Limit to hosts having a tag: \n" +
+ "tag-key=TowerManaged \n" +
+ "Limit to hosts using either key pair: \n" +
+ "key-name=staging, key-name=production \n" +
+ "Limit to hosts where the Name tag begins with test : \n" +
+ "tag:Name=test* \n" +
+ "View the Describe Instances documentation " +
+ "for a complete list of supported filters.
",
+ dataContainer: 'body',
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
+ },
+ group_by: {
+ label: 'Only Group By',
+ type: 'select',
+ ngShow: "source && source.value == 'ec2'",
+ ngOptions: 'source.label for source in group_by_choices track by source.value',
+ multiSelect: true,
+ dataTitle: 'Only Group By',
+ dataPlacement: 'right',
+ awPopOver: "Select which groups to create automatically. " +
+ "Tower will create group names similar to the following examples based on the options selected:
" +
+ "Availability Zone: zones » us-east-1b " +
+ "Image ID: images » ami-b007ab1e " +
+ "Instance ID: instances » i-ca11ab1e " +
+ "Instance Type: types » type_m1_medium " +
+ "Key Name: keys » key_testing " +
+ "Region: regions » us-east-1 " +
+ "Security Group: security_groups » security_group_default " +
+ "Tags: tags » tag_Name » tag_Name_host1 " +
+ "VPC ID: vpcs » vpc-5ca1ab1e " +
+ "Tag None: tags » tag_none " +
+ " If blank, all groups above are created except Instance ID .
",
+ dataContainer: 'body',
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
+ },
+ inventory_script: {
+ label : "Custom Inventory Script",
+ type: 'lookup',
+ basePath: 'inventory_scripts',
+ list: 'InventoryScriptsList',
+ ngShow: "source && source.value === 'custom'",
+ sourceModel: 'inventory_script',
+ sourceField: 'name',
+ awRequiredWhen: {
+ reqExpression: "source && source.value === 'custom'",
+ init: "false"
+ },
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
+ },
+ custom_variables: {
+ id: 'custom_variables',
+ label: 'Environment Variables', //"{{vars_label}}" ,
+ ngShow: "source && source.value=='custom' ",
+ type: 'textarea',
+ class: 'Form-textAreaLabel Form-formGroup--fullWidth',
+ rows: 6,
+ 'default': '---',
+ parseTypeName: 'envParseType',
+ dataTitle: "Environment Variables",
+ dataPlacement: 'right',
+ awPopOver: "Provide environment variables to pass to the custom inventory script.
" +
+ "Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.
" +
+ "JSON: \n" +
+ "{ \"somevar\": \"somevalue\", \"password\": \"magic\" } \n" +
+ "YAML: \n" +
+ "--- somevar: somevalue password: magic \n" +
+ 'View JSON examples at www.json.org
' +
+ 'View YAML examples at docs.ansible.com
',
+ dataContainer: 'body'
+ },
+ ec2_variables: {
+ id: 'ec2_variables',
+ label: 'Source Variables', //"{{vars_label}}" ,
+ ngShow: "source && source.value == 'ec2'",
+ type: 'textarea',
+ class: 'Form-textAreaLabel Form-formGroup--fullWidth',
+ rows: 6,
+ 'default': '---',
+ parseTypeName: 'envParseType',
+ dataTitle: "Source Variables",
+ dataPlacement: 'right',
+ awPopOver: "Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables " +
+ "" +
+ "view ec2.ini in the Ansible github repo.
" +
+ "Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.
" +
+ "JSON: \n" +
+ "{ \"somevar\": \"somevalue\", \"password\": \"magic\" } \n" +
+ "YAML: \n" +
+ "--- somevar: somevalue password: magic \n" +
+ 'View JSON examples at www.json.org
' +
+ 'View YAML examples at docs.ansible.com
',
+ dataContainer: 'body'
+ },
+ vmware_variables: {
+ id: 'vmware_variables',
+ label: 'Source Variables', //"{{vars_label}}" ,
+ ngShow: "source && source.value == 'vmware'",
+ type: 'textarea',
+ class: 'Form-textAreaLabel Form-formGroup--fullWidth',
+ rows: 6,
+ 'default': '---',
+ parseTypeName: 'envParseType',
+ dataTitle: "Source Variables",
+ dataPlacement: 'right',
+ awPopOver: "Override variables found in vmware.ini and used by the inventory update script. For a detailed description of these variables " +
+ "" +
+ "view vmware_inventory.ini in the Ansible github repo.
" +
+ "Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.
" +
+ "JSON: \n" +
+ "{ \"somevar\": \"somevalue\", \"password\": \"magic\" } \n" +
+ "YAML: \n" +
+ "--- somevar: somevalue password: magic \n" +
+ 'View JSON examples at www.json.org
' +
+ 'View YAML examples at docs.ansible.com
',
+ dataContainer: 'body'
+ },
+ openstack_variables: {
+ id: 'openstack_variables',
+ label: 'Source Variables', //"{{vars_label}}" ,
+ ngShow: "source && source.value == 'openstack'",
+ type: 'textarea',
+ class: 'Form-textAreaLabel Form-formGroup--fullWidth',
+ rows: 6,
+ 'default': '---',
+ parseTypeName: 'envParseType',
+ dataTitle: "Source Variables",
+ dataPlacement: 'right',
+ awPopOver: "Override variables found in openstack.yml and used by the inventory update script. For an example variable configuration " +
+ "" +
+ "view openstack.yml in the Ansible github repo.
" +
+ "Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.
" +
+ "JSON: \n" +
+ "{ \"somevar\": \"somevalue\", \"password\": \"magic\" } \n" +
+ "YAML: \n" +
+ "--- somevar: somevalue password: magic \n" +
+ 'View JSON examples at www.json.org
' +
+ 'View YAML examples at docs.ansible.com
',
+ dataContainer: 'body'
+ },
+ checkbox_group: {
+ label: 'Update Options',
+ type: 'checkbox_group',
+ ngShow: "source && (source.value !== '' && source.value !== null)",
+ class: 'Form-checkbox--stacked',
+ fields: [{
+ name: 'overwrite',
+ label: 'Overwrite',
+ type: 'checkbox',
+ ngShow: "source.value !== '' && source.value !== null",
+
+
+ awPopOver: 'If checked, all child groups and hosts not found on the external source will be deleted from ' +
+ 'the local inventory.
When not checked, local child hosts and groups not found on the external source will ' +
+ 'remain untouched by the inventory update process.
',
+ dataTitle: 'Overwrite',
+ dataContainer: 'body',
+ dataPlacement: 'right',
+ labelClass: 'checkbox-options',
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
+ }, {
+ name: 'overwrite_vars',
+ label: 'Overwrite Variables',
+ type: 'checkbox',
+ ngShow: "source.value !== '' && source.value !== null",
+
+
+ awPopOver: 'If checked, all variables for child groups and hosts will be removed and replaced by those ' +
+ 'found on the external source.
When not checked, a merge will be performed, combining local variables with ' +
+ 'those found on the external source.
',
+ dataTitle: 'Overwrite Variables',
+ dataContainer: 'body',
+ dataPlacement: 'right',
+ labelClass: 'checkbox-options',
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
+ }, {
+ name: 'update_on_launch',
+ label: 'Update on Launch',
+ type: 'checkbox',
+ ngShow: "source.value !== '' && source.value !== null",
+ awPopOver: 'Each time a job runs using this inventory, refresh the inventory from the selected source before ' +
+ 'executing job tasks.
',
+ dataTitle: 'Update on Launch',
+ dataContainer: 'body',
+ dataPlacement: 'right',
+ labelClass: 'checkbox-options',
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
+ }]
+ },
+ update_cache_timeout: {
+ label: "Cache Timeout (seconds) ",
+ id: 'source-cache-timeout',
+ type: 'number',
+ ngDisabled: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)',
+ integer: true,
+ min: 0,
+ ngShow: "source && source.value !== '' && update_on_launch",
+ spinner: true,
+ "default": 0,
+ awPopOver: 'Time in seconds to consider an inventory sync to be current. During job runs and callbacks the task system will ' +
+ 'evaluate the timestamp of the latest sync. If it is older than Cache Timeout, it is not considered current, ' +
+ 'and a new inventory sync will be performed.
',
+ dataTitle: 'Cache Timeout',
+ dataPlacement: 'right',
+ dataContainer: "body"
+ }
+ },
+
+ buttons: {
+ cancel: {
+ ngClick: 'formCancel()',
+ ngShow: '(group_obj.summary_fields.user_capabilities.edit || canAdd)'
+ },
+ close: {
+ ngClick: 'formCancel()',
+ ngShow: '!(group_obj.summary_fields.user_capabilities.edit || canAdd)'
+ },
+ save: {
+ ngClick: 'formSave()',
+ ngDisabled: true,
+ ngShow: '(group_obj.summary_fields.user_capabilities.edit || canAdd)'
+ }
+ },
+
+ related: {
+ "notifications": {
+ include: "NotificationsList"
+ }
+ }
+
+ };
+ var itm;
+
+ for (itm in GroupFormObject.related) {
+ if (GroupFormObject.related[itm].include === "NotificationsList") {
+ GroupFormObject.related[itm] = angular.copy(NotificationsList);
+ GroupFormObject.related[itm].generateList = true;
+ GroupFormObject.related[itm].disabled = "source === undefined || source.value === ''";
+ GroupFormObject.related[itm].ngClick = "$state.go('inventoryManage.editGroup.notifications')";
+ }
+ }
+ return GroupFormObject;
+ };
+ }];
diff --git a/awx/ui/client/src/inventories/manage/groups/main.js b/awx/ui/client/src/inventories/manage/groups/main.js
index b5d467445f..9423ed0c81 100644
--- a/awx/ui/client/src/inventories/manage/groups/main.js
+++ b/awx/ui/client/src/inventories/manage/groups/main.js
@@ -12,6 +12,7 @@ import GetSyncStatusMsg from './factories/get-sync-status-msg.factory';
import GroupsCancelUpdate from './factories/groups-cancel-update.factory';
import ViewUpdateStatus from './factories/view-update-status.factory';
import InventoryGroups from './inventory-groups.list';
+import GroupForm from './groups.form';
export default
angular.module('manageGroups', [])
@@ -20,6 +21,7 @@ angular.module('manageGroups', [])
.factory('GetSyncStatusMsg', GetSyncStatusMsg)
.factory('GroupsCancelUpdate', GroupsCancelUpdate)
.factory('ViewUpdateStatus', ViewUpdateStatus)
+ .factory('GroupForm', GroupForm)
.value('InventoryGroups', InventoryGroups)
.controller('GroupAddController', GroupAddController)
.controller('GroupEditController', GroupEditController);
diff --git a/awx/ui/client/src/forms/Hosts.js b/awx/ui/client/src/inventories/manage/hosts/hosts.form.js
similarity index 97%
rename from awx/ui/client/src/forms/Hosts.js
rename to awx/ui/client/src/inventories/manage/hosts/hosts.form.js
index 55c7da509e..efb64a4785 100644
--- a/awx/ui/client/src/forms/Hosts.js
+++ b/awx/ui/client/src/inventories/manage/hosts/hosts.form.js
@@ -10,9 +10,7 @@
* @description This form is for adding/editing a host on the inventory page
*/
-export default
- angular.module('HostFormDefinition', [])
- .factory('HostForm', ['i18n', function(i18n) {
+export default ['i18n', function(i18n) {
return {
addTitle: i18n._('CREATE HOST'),
@@ -102,4 +100,4 @@ export default
}
},
};
- }]);
+ }];
diff --git a/awx/ui/client/src/inventories/manage/hosts/main.js b/awx/ui/client/src/inventories/manage/hosts/main.js
index 7afed80efb..b3d514a4f4 100644
--- a/awx/ui/client/src/inventories/manage/hosts/main.js
+++ b/awx/ui/client/src/inventories/manage/hosts/main.js
@@ -9,11 +9,13 @@ import HostsEditController from './hosts-edit.controller';
import SetStatus from './factories/set-status.factory';
import SetEnabledMsg from './factories/set-enabled-msg.factory';
import InventoryHosts from './inventory-hosts.list';
+import HostForm from './hosts.form';
export default
angular.module('manageHosts', [])
.factory('SetStatus', SetStatus)
.factory('SetEnabledMsg', SetEnabledMsg)
+ .factory('HostForm', HostForm)
.value('InventoryHosts', InventoryHosts)
.controller('HostsAddController', HostsAddController)
.controller('HostEditController', HostsEditController);
diff --git a/awx/ui/client/src/forms/JobTemplates.js b/awx/ui/client/src/templates/job-template.form.js
similarity index 94%
rename from awx/ui/client/src/forms/JobTemplates.js
rename to awx/ui/client/src/templates/job-template.form.js
index a6c2eb0dfe..f5b8f59502 100644
--- a/awx/ui/client/src/forms/JobTemplates.js
+++ b/awx/ui/client/src/templates/job-template.form.js
@@ -11,11 +11,10 @@
*/
-export default
- angular.module('JobTemplateFormDefinition', [])
-
- .factory('JobTemplateFormObject', ['i18n', function(i18n) {
- return {
+export default ['NotificationsList', 'CompletedJobsList',
+function(NotificationsList, CompletedJobsList) {
+ return function() {
+ var JobTemplateFormObject = {
addTitle: i18n._('NEW JOB TEMPLATE'),
editTitle: '{{ name }}',
@@ -487,26 +486,22 @@ export default
class: 'Form-primaryButton'
}
}
- };}])
+ };
+ var itm;
- .factory('JobTemplateForm', ['JobTemplateFormObject', 'NotificationsList', 'CompletedJobsList',
- function(JobTemplateFormObject, NotificationsList, CompletedJobsList) {
- return function() {
- var itm;
+ for (itm in JobTemplateFormObject.related) {
+ if (JobTemplateFormObject.related[itm].include === "NotificationsList") {
+ JobTemplateFormObject.related[itm] = _.clone(NotificationsList);
+ JobTemplateFormObject.related[itm].ngClick = "$state.go('templates.editJobTemplate.notifications')";
+ JobTemplateFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
+ }
+ if (JobTemplateFormObject.related[itm].include === "CompletedJobsList") {
+ JobTemplateFormObject.related[itm] = CompletedJobsList;
+ JobTemplateFormObject.related[itm].ngClick = "$state.go('templates.editJobTemplate.completed_jobs')";
+ JobTemplateFormObject.related[itm].generateList = true;
+ }
+ }
- for (itm in JobTemplateFormObject.related) {
- if (JobTemplateFormObject.related[itm].include === "NotificationsList") {
- JobTemplateFormObject.related[itm] = _.clone(NotificationsList);
- JobTemplateFormObject.related[itm].ngClick = "$state.go('templates.editJobTemplate.notifications')";
- JobTemplateFormObject.related[itm].generateList = true; // tell form generator to call list generator and inject a list
- }
- if (JobTemplateFormObject.related[itm].include === "CompletedJobsList") {
- JobTemplateFormObject.related[itm] = CompletedJobsList;
- JobTemplateFormObject.related[itm].ngClick = "$state.go('templates.editJobTemplate.completed_jobs')";
- JobTemplateFormObject.related[itm].generateList = true;
- }
- }
-
- return JobTemplateFormObject;
- };
- }]);
+ return JobTemplateFormObject;
+ };
+}];
diff --git a/awx/ui/client/src/templates/main.js b/awx/ui/client/src/templates/main.js
index 3c80ab2b6c..c733507f05 100644
--- a/awx/ui/client/src/templates/main.js
+++ b/awx/ui/client/src/templates/main.js
@@ -24,6 +24,7 @@ import WorkflowForm from './workflows.form';
import CompletedJobsList from './completed-jobs.list';
import InventorySourcesList from './inventory-sources.list';
import TemplateList from './templates.list';
+import JobTemplateForm from './job-template.form';
export default
angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesAdd.name,
@@ -38,6 +39,7 @@ angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesA
.factory('WorkflowForm', WorkflowForm)
.factory('CompletedJobsList', CompletedJobsList)
.factory('TemplateList', TemplateList)
+ .factory('JobTemplateForm', JobTemplateForm)
.value('InventorySourcesList', InventorySourcesList)
.config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider',
function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) {