({
privilegeEscalation: t`If enabled, run this playbook as an administrator.`,
enableWebhook: t`Enable webhook for this template.`,
concurrentJobs: t`If enabled, simultaneous runs of this job template will be allowed.`,
+ preventInstanceGroupFallback: t`If enabled, the job template will prevent adding any inventory or organization instance groups to the list of preferred instances groups to run on.
+ Note: If this setting is enabled and you provided an empty list, the global instance groups will be applied.`,
enableFactStorage: t`If enabled, this will store gathered facts so they can be viewed at the host level. Facts are persisted and injected into the fact cache at runtime.`,
enabledOptions: (
<>
@@ -38,6 +40,7 @@ const jtHelpTextStrings = () => ({
{t`Privilege escalation: If enabled, run this playbook as an administrator.`}
{t`Provisioning callbacks: Enables creation of a provisioning callback URL. Using the URL a host can contact Ansible AWX and request a configuration update using this job template.`}
{t`Webhooks: Enable webhook for this template.`}
+ {t`Prevent Instance Group Fallback: If enabled, the job template will prevent adding any inventory or organization instance groups to the list of preferred instances groups to run on.`}
>
),
forks: (
diff --git a/awx/ui/src/screens/Template/shared/JobTemplateForm.js b/awx/ui/src/screens/Template/shared/JobTemplateForm.js
index a82aaa8ad361..7621601e9e6e 100644
--- a/awx/ui/src/screens/Template/shared/JobTemplateForm.js
+++ b/awx/ui/src/screens/Template/shared/JobTemplateForm.js
@@ -597,6 +597,12 @@ function JobTemplateForm({
label={t`Enable Fact Storage`}
tooltip={helpText.enableFactStorage}
/>
+
@@ -731,6 +737,8 @@ const FormikApp = withFormik({
limit: template.limit || '',
name: template.name || '',
playbook: template.playbook || '',
+ prevent_instance_group_fallback:
+ template.prevent_instance_group_fallback || false,
project: summary_fields?.project || projectValues || null,
scm_branch: template.scm_branch || '',
skip_tags: template.skip_tags || '',
diff --git a/awx/ui/src/screens/Template/shared/data.job_template.json b/awx/ui/src/screens/Template/shared/data.job_template.json
index 4d4eb77af102..3c57d0143c81 100644
--- a/awx/ui/src/screens/Template/shared/data.job_template.json
+++ b/awx/ui/src/screens/Template/shared/data.job_template.json
@@ -1,194 +1,199 @@
{
- "id": 7,
- "type": "job_template",
- "url": "/api/v2/job_templates/7/",
- "related": {
- "named_url": "/api/v2/job_templates/Mike's JT/",
- "created_by": "/api/v2/users/1/",
- "modified_by": "/api/v2/users/1/",
- "labels": "/api/v2/job_templates/7/labels/",
- "inventory": "/api/v2/inventories/1/",
- "project": "/api/v2/projects/6/",
- "credentials": "/api/v2/job_templates/7/credentials/",
- "last_job": "/api/v2/jobs/12/",
- "jobs": "/api/v2/job_templates/7/jobs/",
- "schedules": "/api/v2/job_templates/7/schedules/",
- "activity_stream": "/api/v2/job_templates/7/activity_stream/",
- "launch": "/api/v2/job_templates/7/launch/",
- "notification_templates_started": "/api/v2/job_templates/7/notification_templates_started/",
- "notification_templates_success": "/api/v2/job_templates/7/notification_templates_success/",
- "notification_templates_error": "/api/v2/job_templates/7/notification_templates_error/",
- "access_list": "/api/v2/job_templates/7/access_list/",
- "survey_spec": "/api/v2/job_templates/7/survey_spec/",
- "object_roles": "/api/v2/job_templates/7/object_roles/",
- "instance_groups": "/api/v2/job_templates/7/instance_groups/",
- "slice_workflow_jobs": "/api/v2/job_templates/7/slice_workflow_jobs/",
- "copy": "/api/v2/job_templates/7/copy/",
- "webhook_receiver": "/api/v2/job_templates/7/github/",
- "webhook_key": "/api/v2/job_templates/7/webhook_key/"
+ "id": 7,
+ "type": "job_template",
+ "url": "/api/v2/job_templates/7/",
+ "related": {
+ "named_url": "/api/v2/job_templates/Mike's JT/",
+ "created_by": "/api/v2/users/1/",
+ "modified_by": "/api/v2/users/1/",
+ "labels": "/api/v2/job_templates/7/labels/",
+ "inventory": "/api/v2/inventories/1/",
+ "project": "/api/v2/projects/6/",
+ "credentials": "/api/v2/job_templates/7/credentials/",
+ "last_job": "/api/v2/jobs/12/",
+ "jobs": "/api/v2/job_templates/7/jobs/",
+ "schedules": "/api/v2/job_templates/7/schedules/",
+ "activity_stream": "/api/v2/job_templates/7/activity_stream/",
+ "launch": "/api/v2/job_templates/7/launch/",
+ "notification_templates_started": "/api/v2/job_templates/7/notification_templates_started/",
+ "notification_templates_success": "/api/v2/job_templates/7/notification_templates_success/",
+ "notification_templates_error": "/api/v2/job_templates/7/notification_templates_error/",
+ "access_list": "/api/v2/job_templates/7/access_list/",
+ "survey_spec": "/api/v2/job_templates/7/survey_spec/",
+ "object_roles": "/api/v2/job_templates/7/object_roles/",
+ "instance_groups": "/api/v2/job_templates/7/instance_groups/",
+ "slice_workflow_jobs": "/api/v2/job_templates/7/slice_workflow_jobs/",
+ "copy": "/api/v2/job_templates/7/copy/",
+ "webhook_receiver": "/api/v2/job_templates/7/github/",
+ "webhook_key": "/api/v2/job_templates/7/webhook_key/"
+ },
+ "summary_fields": {
+ "inventory": {
+ "id": 1,
+ "name": "Mike's Inventory",
+ "description": "",
+ "has_active_failures": false,
+ "total_hosts": 1,
+ "hosts_with_active_failures": 0,
+ "total_groups": 0,
+ "groups_with_active_failures": 0,
+ "has_inventory_sources": false,
+ "total_inventory_sources": 0,
+ "inventory_sources_with_failures": 0,
+ "organization_id": 1,
+ "kind": ""
},
- "summary_fields": {
- "inventory": {
- "id": 1,
- "name": "Mike's Inventory",
- "description": "",
- "has_active_failures": false,
- "total_hosts": 1,
- "hosts_with_active_failures": 0,
- "total_groups": 0,
- "groups_with_active_failures": 0,
- "has_inventory_sources": false,
- "total_inventory_sources": 0,
- "inventory_sources_with_failures": 0,
- "organization_id": 1,
- "kind": ""
- },
- "project": {
- "id": 6,
- "name": "Mike's Project",
- "description": "",
- "status": "successful",
- "scm_type": "git"
- },
- "last_job": {
- "id": 12,
- "name": "Mike's JT",
- "description": "",
- "finished": "2019-10-01T14:34:35.142483Z",
- "status": "successful",
- "failed": false
- },
- "last_update": {
- "id": 12,
- "name": "Mike's JT",
- "description": "",
- "status": "successful",
- "failed": false
- },
- "created_by": {
- "id": 1,
- "username": "admin",
- "first_name": "",
- "last_name": ""
- },
- "modified_by": {
- "id": 1,
- "username": "admin",
- "first_name": "",
- "last_name": ""
- },
- "object_roles": {
- "admin_role": {
- "description": "Can manage all aspects of the job template",
- "name": "Admin",
- "id": 24
- },
- "execute_role": {
- "description": "May run the job template",
- "name": "Execute",
- "id": 25
- },
- "read_role": {
- "description": "May view settings for the job template",
- "name": "Read",
- "id": 26
- }
- },
- "user_capabilities": {
- "edit": true,
- "delete": true,
- "start": true,
- "schedule": true,
- "copy": true
- },
- "labels": {
- "count": 1,
- "results": [{
- "id": 91,
- "name": "L_91o2"
- }]
- },
- "survey": {
- "title": "",
- "description": ""
- },
- "recent_jobs": [{
- "id": 12,
- "status": "successful",
- "finished": "2019-10-01T14:34:35.142483Z",
- "type": "job"
- }],
- "credentials": [{
- "id": 1,
- "kind": "ssh",
- "name": "Credential 1"
- },
- {
- "id": 2,
- "kind": "awx",
- "name": "Credential 2"
- }
- ],
- "webhook_credential": {
- "id": "1",
- "name": "Webhook Credential"
-
- },
- "execution_environment": {
- "id": 1,
- "name": "Default EE",
- "description": "",
- "image": "quay.io/ansible/awx-ee"
- },
- "resolved_environment": {
- "id": 1,
- "name": "Default EE",
- "description": "",
- "image": "quay.io/ansible/awx-ee"
+ "project": {
+ "id": 6,
+ "name": "Mike's Project",
+ "description": "",
+ "status": "successful",
+ "scm_type": "git"
+ },
+ "last_job": {
+ "id": 12,
+ "name": "Mike's JT",
+ "description": "",
+ "finished": "2019-10-01T14:34:35.142483Z",
+ "status": "successful",
+ "failed": false
+ },
+ "last_update": {
+ "id": 12,
+ "name": "Mike's JT",
+ "description": "",
+ "status": "successful",
+ "failed": false
+ },
+ "created_by": {
+ "id": 1,
+ "username": "admin",
+ "first_name": "",
+ "last_name": ""
+ },
+ "modified_by": {
+ "id": 1,
+ "username": "admin",
+ "first_name": "",
+ "last_name": ""
+ },
+ "object_roles": {
+ "admin_role": {
+ "description": "Can manage all aspects of the job template",
+ "name": "Admin",
+ "id": 24
+ },
+ "execute_role": {
+ "description": "May run the job template",
+ "name": "Execute",
+ "id": 25
+ },
+ "read_role": {
+ "description": "May view settings for the job template",
+ "name": "Read",
+ "id": 26
+ }
+ },
+ "user_capabilities": {
+ "edit": true,
+ "delete": true,
+ "start": true,
+ "schedule": true,
+ "copy": true
+ },
+ "labels": {
+ "count": 1,
+ "results": [
+ {
+ "id": 91,
+ "name": "L_91o2"
}
+ ]
+ },
+ "survey": {
+ "title": "",
+ "description": ""
+ },
+ "recent_jobs": [
+ {
+ "id": 12,
+ "status": "successful",
+ "finished": "2019-10-01T14:34:35.142483Z",
+ "type": "job"
+ }
+ ],
+ "credentials": [
+ {
+ "id": 1,
+ "kind": "ssh",
+ "name": "Credential 1"
+ },
+ {
+ "id": 2,
+ "kind": "awx",
+ "name": "Credential 2"
+ }
+ ],
+ "webhook_credential": {
+ "id": "1",
+ "name": "Webhook Credential"
+ },
+ "execution_environment": {
+ "id": 1,
+ "name": "Default EE",
+ "description": "",
+ "image": "quay.io/ansible/awx-ee"
},
- "created": "2019-09-30T16:18:34.564820Z",
- "modified": "2019-10-01T14:47:31.818431Z",
- "name": "Mike's JT",
- "description": "",
- "job_type": "run",
- "inventory": 1,
- "project": 6,
- "playbook": "ping.yml",
- "scm_branch": "Foo branch",
- "forks": 0,
- "limit": "",
- "verbosity": 0,
- "extra_vars": "",
- "job_tags": "T_100,T_200",
- "force_handlers": false,
- "skip_tags": "S_100,S_200",
- "start_at_task": "",
- "timeout": 0,
- "use_fact_cache": true,
- "last_job_run": "2019-10-01T14:34:35.142483Z",
- "last_job_failed": false,
- "next_job_run": null,
- "status": "successful",
- "host_config_key": "",
- "ask_scm_branch_on_launch": false,
- "ask_diff_mode_on_launch": false,
- "ask_variables_on_launch": false,
- "ask_limit_on_launch": false,
- "ask_tags_on_launch": false,
- "ask_skip_tags_on_launch": false,
- "ask_job_type_on_launch": false,
- "ask_verbosity_on_launch": false,
- "ask_inventory_on_launch": false,
- "ask_credential_on_launch": false,
- "survey_enabled": true,
- "become_enabled": false,
- "diff_mode": false,
- "allow_simultaneous": false,
- "custom_virtualenv": null,
- "job_slice_count": 1,
- "webhook_credential": 1,
- "webhook_key": "asertdyuhjkhgfd234567kjgfds",
- "webhook_service": "github",
- "execution_environment": 1
+ "resolved_environment": {
+ "id": 1,
+ "name": "Default EE",
+ "description": "",
+ "image": "quay.io/ansible/awx-ee"
+ }
+ },
+ "created": "2019-09-30T16:18:34.564820Z",
+ "modified": "2019-10-01T14:47:31.818431Z",
+ "name": "Mike's JT",
+ "description": "",
+ "job_type": "run",
+ "inventory": 1,
+ "project": 6,
+ "playbook": "ping.yml",
+ "scm_branch": "Foo branch",
+ "forks": 0,
+ "limit": "",
+ "verbosity": 0,
+ "extra_vars": "",
+ "job_tags": "T_100,T_200",
+ "force_handlers": false,
+ "skip_tags": "S_100,S_200",
+ "start_at_task": "",
+ "timeout": 0,
+ "use_fact_cache": true,
+ "last_job_run": "2019-10-01T14:34:35.142483Z",
+ "last_job_failed": false,
+ "next_job_run": null,
+ "status": "successful",
+ "host_config_key": "",
+ "ask_scm_branch_on_launch": false,
+ "ask_diff_mode_on_launch": false,
+ "ask_variables_on_launch": false,
+ "ask_limit_on_launch": false,
+ "ask_tags_on_launch": false,
+ "ask_skip_tags_on_launch": false,
+ "ask_job_type_on_launch": false,
+ "ask_verbosity_on_launch": false,
+ "ask_inventory_on_launch": false,
+ "ask_credential_on_launch": false,
+ "survey_enabled": true,
+ "become_enabled": false,
+ "diff_mode": false,
+ "allow_simultaneous": false,
+ "custom_virtualenv": null,
+ "job_slice_count": 1,
+ "webhook_credential": 1,
+ "webhook_key": "asertdyuhjkhgfd234567kjgfds",
+ "webhook_service": "github",
+ "execution_environment": 1,
+ "prevent_instance_group_fallback": false
}
diff --git a/awx_collection/plugins/modules/inventory.py b/awx_collection/plugins/modules/inventory.py
index f04e94c533dd..b4784f526061 100644
--- a/awx_collection/plugins/modules/inventory.py
+++ b/awx_collection/plugins/modules/inventory.py
@@ -66,6 +66,10 @@
- list of Instance Groups for this Organization to run on.
type: list
elements: str
+ prevent_instance_group_fallback:
+ description:
+ - Prevent falling back to instance groups set on the organization
+ type: bool
state:
description:
- Desired state of the resource.
@@ -111,6 +115,7 @@ def main():
kind=dict(choices=['', 'smart'], default=''),
host_filter=dict(),
instance_groups=dict(type="list", elements='str'),
+ prevent_instance_group_fallback=dict(type='bool'),
state=dict(choices=['present', 'absent'], default='present'),
)
@@ -127,6 +132,7 @@ def main():
state = module.params.get('state')
kind = module.params.get('kind')
host_filter = module.params.get('host_filter')
+ prevent_instance_group_fallback = module.params.get('prevent_instance_group_fallback')
# Attempt to look up the related items the user specified (these will fail the module if not found)
org_id = module.resolve_name_to_id('organizations', organization)
@@ -157,6 +163,8 @@ def main():
'kind': kind,
'host_filter': host_filter,
}
+ if prevent_instance_group_fallback is not None:
+ inventory_fields['prevent_instance_group_fallback'] = prevent_instance_group_fallback
if description is not None:
inventory_fields['description'] = description
if variables is not None:
diff --git a/awx_collection/plugins/modules/job_template.py b/awx_collection/plugins/modules/job_template.py
index 5a7e9b6e2540..2a8408e2a4d1 100644
--- a/awx_collection/plugins/modules/job_template.py
+++ b/awx_collection/plugins/modules/job_template.py
@@ -315,6 +315,10 @@
- list of notifications to send on error
type: list
elements: str
+ prevent_instance_group_fallback:
+ description:
+ - Prevent falling back to instance groups set on the associated inventory or organization
+ type: bool
extends_documentation_fragment: awx.awx.auth
@@ -441,6 +445,7 @@ def main():
notification_templates_started=dict(type="list", elements='str'),
notification_templates_success=dict(type="list", elements='str'),
notification_templates_error=dict(type="list", elements='str'),
+ prevent_instance_group_fallback=dict(type="bool"),
state=dict(choices=['present', 'absent'], default='present'),
)
@@ -539,6 +544,7 @@ def main():
'custom_virtualenv',
'job_slice_count',
'webhook_service',
+ 'prevent_instance_group_fallback',
):
field_val = module.params.get(field_name)
if field_val is not None:
diff --git a/awxkit/awxkit/api/pages/inventory.py b/awxkit/awxkit/api/pages/inventory.py
index 33c84f2aa294..8431f1596576 100644
--- a/awxkit/awxkit/api/pages/inventory.py
+++ b/awxkit/awxkit/api/pages/inventory.py
@@ -59,7 +59,7 @@ def payload(self, organization, **kwargs):
organization=organization.id,
)
- optional_fields = ('host_filter', 'kind', 'variables')
+ optional_fields = ('host_filter', 'kind', 'variables', 'prevent_instance_group_fallback')
update_payload(payload, optional_fields, kwargs)
diff --git a/awxkit/awxkit/api/pages/job_templates.py b/awxkit/awxkit/api/pages/job_templates.py
index 46862d9f2b97..5378059843e4 100644
--- a/awxkit/awxkit/api/pages/job_templates.py
+++ b/awxkit/awxkit/api/pages/job_templates.py
@@ -79,6 +79,7 @@ def payload(self, job_type='run', playbook='ping.yml', **kwargs):
'webhook_service',
'webhook_credential',
'scm_branch',
+ 'prevent_instance_group_fallback',
)
update_payload(payload, optional_fields, kwargs)