Make state exists universal in collection (#13890)

Make state: exists available for all API modules

Make state:exists return the ID just like it would if it created the resource
This commit is contained in:
John Westcott IV
2023-05-10 08:05:29 -04:00
committed by GitHub
parent 53260213ba
commit 7f020052db
40 changed files with 918 additions and 135 deletions

View File

@@ -60,7 +60,7 @@ options:
description:
- Desired state of the resource.
default: "present"
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
type: str
skip_authorization:
description:
@@ -106,7 +106,7 @@ def main():
client_type=dict(choices=['public', 'confidential']),
organization=dict(required=True),
redirect_uris=dict(type="list", elements='str'),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
skip_authorization=dict(type='bool'),
)
@@ -127,7 +127,7 @@ def main():
org_id = module.resolve_name_to_id('organizations', organization)
# Attempt to look up application based on the provided name and org ID
application = module.get_one('applications', name_or_id=name, **{'data': {'organization': org_id}})
application = module.get_one('applications', name_or_id=name, check_exists=(state == 'exists'), **{'data': {'organization': org_id}})
if state == 'absent':
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this

View File

@@ -247,7 +247,7 @@ def main():
if organization:
lookup_data['organization'] = org_id
credential = module.get_one('credentials', name_or_id=name, **{'data': lookup_data})
credential = module.get_one('credentials', name_or_id=name, check_exists=(state == 'exists'), **{'data': lookup_data})
# Attempt to look up credential to copy based on the provided name
if copy_from:
@@ -265,10 +265,6 @@ def main():
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this
module.delete_if_needed(credential)
if state == 'exists' and credential is not None:
# If credential exists and state is exists, we're done here.
module.exit_json(**module.json_output)
# Attempt to look up the related items the user specified (these will fail the module if not found)
if user:
user_id = module.resolve_name_to_id('users', user)

View File

@@ -48,7 +48,7 @@ options:
state:
description:
- Desired state of the resource.
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
default: "present"
type: str
@@ -80,7 +80,7 @@ def main():
target_credential=dict(required=True),
source_credential=dict(),
metadata=dict(type="dict"),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -101,7 +101,7 @@ def main():
'target_credential': target_credential_id,
'input_field_name': input_field_name,
}
credential_input_source = module.get_one('credential_input_sources', **{'data': lookup_data})
credential_input_source = module.get_one('credential_input_sources', check_exists=(state == 'exists'), **{'data': lookup_data})
if state == 'absent':
module.delete_if_needed(credential_input_source)

View File

@@ -59,7 +59,7 @@ options:
description:
- Desired state of the resource.
default: "present"
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
type: str
extends_documentation_fragment: awx.awx.auth
'''
@@ -98,7 +98,7 @@ def main():
kind=dict(choices=list(KIND_CHOICES.keys())),
inputs=dict(type='dict'),
injectors=dict(type='dict'),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -124,7 +124,7 @@ def main():
credential_type_params['injectors'] = module.params.get('injectors')
# Attempt to look up credential_type based on the provided name
credential_type = module.get_one('credential_types', name_or_id=name)
credential_type = module.get_one('credential_types', name_or_id=name, check_exists=(state == 'exists'))
if state == 'absent':
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this

View File

@@ -50,7 +50,7 @@ options:
state:
description:
- Desired state of the resource.
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
default: "present"
type: str
pull:
@@ -83,7 +83,7 @@ def main():
description=dict(),
organization=dict(),
credential=dict(),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
# NOTE: Default for pull differs from API (which is blank by default)
pull=dict(choices=['always', 'missing', 'never'], default='missing'),
)
@@ -99,7 +99,7 @@ def main():
state = module.params.get('state')
pull = module.params.get('pull')
existing_item = module.get_one('execution_environments', name_or_id=name)
existing_item = module.get_one('execution_environments', name_or_id=name, check_exists=(state == 'exists'))
if state == 'absent':
module.delete_if_needed(existing_item)

View File

@@ -67,7 +67,7 @@ options:
description:
- Desired state of the resource.
default: "present"
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
type: str
new_name:
description:
@@ -115,7 +115,7 @@ def main():
children=dict(type='list', elements='str', aliases=['groups']),
preserve_existing_hosts=dict(type='bool', default=False),
preserve_existing_children=dict(type='bool', default=False, aliases=['preserve_existing_groups']),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -135,7 +135,7 @@ def main():
inventory_id = module.resolve_name_to_id('inventories', inventory)
# Attempt to look up the object based on the provided name and inventory ID
group = module.get_one('groups', name_or_id=name, **{'data': {'inventory': inventory_id}})
group = module.get_one('groups', name_or_id=name, check_exists=(state == 'exists'), **{'data': {'inventory': inventory_id}})
if state == 'absent':
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this

View File

@@ -50,7 +50,7 @@ options:
state:
description:
- Desired state of the resource.
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
default: "present"
type: str
extends_documentation_fragment: awx.awx.auth
@@ -83,7 +83,7 @@ def main():
inventory=dict(required=True),
enabled=dict(type='bool'),
variables=dict(type='dict'),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -102,7 +102,7 @@ def main():
inventory_id = module.resolve_name_to_id('inventories', inventory)
# Attempt to look up host based on the provided name and inventory ID
host = module.get_one('hosts', name_or_id=name, **{'data': {'inventory': inventory_id}})
host = module.get_one('hosts', name_or_id=name, check_exists=(state == 'exists'), **{'data': {'inventory': inventory_id}})
if state == 'absent':
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this

View File

@@ -81,7 +81,7 @@ options:
state:
description:
- Desired state of the resource.
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
default: "present"
type: str
extends_documentation_fragment: awx.awx.auth
@@ -107,7 +107,7 @@ def main():
policy_instance_list=dict(type='list', elements='str'),
pod_spec_override=dict(),
instances=dict(required=False, type="list", elements='str'),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -128,7 +128,7 @@ def main():
state = module.params.get('state')
# Attempt to look up an existing item based on the provided data
existing_item = module.get_one('instance_groups', name_or_id=name)
existing_item = module.get_one('instance_groups', name_or_id=name, check_exists=(state == 'exists'))
if state == 'absent':
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this

View File

@@ -78,7 +78,7 @@ options:
description:
- Desired state of the resource.
default: "present"
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
type: str
extends_documentation_fragment: awx.awx.auth
'''
@@ -149,7 +149,7 @@ def main():
host_filter=dict(),
instance_groups=dict(type="list", elements='str'),
prevent_instance_group_fallback=dict(type='bool'),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
input_inventories=dict(type='list', elements='str'),
)
@@ -172,7 +172,7 @@ def main():
org_id = module.resolve_name_to_id('organizations', organization)
# Attempt to look up inventory based on the provided name and org ID
inventory = module.get_one('inventories', name_or_id=name, **{'data': {'organization': org_id}})
inventory = module.get_one('inventories', name_or_id=name, check_exists=(state == 'exists'), **{'data': {'organization': org_id}})
# Attempt to look up credential to copy based on the provided name
if copy_from:

View File

@@ -118,7 +118,7 @@ options:
description:
- Desired state of the resource.
default: "present"
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
type: str
notification_templates_started:
description:
@@ -192,7 +192,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'),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -219,6 +219,7 @@ def main():
inventory_source_object = module.get_one(
'inventory_sources',
name_or_id=name,
check_exists=(state == 'exists'),
**{
'data': {
'inventory': inventory_object['id'],

View File

@@ -295,7 +295,7 @@ options:
description:
- Desired state of the resource.
default: "present"
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
type: str
notification_templates_started:
description:
@@ -444,7 +444,7 @@ def main():
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'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -484,7 +484,7 @@ def main():
new_fields['execution_environment'] = module.resolve_name_to_id('execution_environments', ee)
# Attempt to look up an existing item based on the provided data
existing_item = module.get_one('job_templates', name_or_id=name, **{'data': search_fields})
existing_item = module.get_one('job_templates', name_or_id=name, check_exists=(state == 'exists'), **{'data': search_fields})
# Attempt to look up credential to copy based on the provided name
if copy_from:

View File

@@ -41,7 +41,7 @@ options:
description:
- Desired state of the resource.
default: "present"
choices: ["present"]
choices: ["present", "exists"]
type: str
extends_documentation_fragment: awx.awx.auth
'''
@@ -62,7 +62,7 @@ def main():
name=dict(required=True),
new_name=dict(),
organization=dict(required=True),
state=dict(choices=['present'], default='present'),
state=dict(choices=['present', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -72,6 +72,7 @@ def main():
name = module.params.get('name')
new_name = module.params.get("new_name")
organization = module.params.get('organization')
state = module.params.get("state")
# Attempt to look up the related items the user specified (these will fail the module if not found)
organization_id = None
@@ -82,6 +83,7 @@ def main():
existing_item = module.get_one(
'labels',
name_or_id=name,
check_exists=(state == 'exists'),
**{
'data': {
'organization': organization_id,

View File

@@ -97,7 +97,7 @@ options:
description:
- Desired state of the resource.
default: "present"
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
type: str
extends_documentation_fragment: awx.awx.auth
'''
@@ -222,7 +222,7 @@ def main():
notification_type=dict(choices=['email', 'grafana', 'irc', 'mattermost', 'pagerduty', 'rocketchat', 'slack', 'twilio', 'webhook']),
notification_configuration=dict(type='dict'),
messages=dict(type='dict'),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -248,6 +248,7 @@ def main():
existing_item = module.get_one(
'notification_templates',
name_or_id=name,
check_exists=(state == 'exists'),
**{
'data': {
'organization': organization_id,

View File

@@ -52,7 +52,7 @@ options:
description:
- Desired state of the resource.
default: "present"
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
type: str
instance_groups:
description:
@@ -130,7 +130,7 @@ def main():
notification_templates_error=dict(type="list", elements='str'),
notification_templates_approvals=dict(type="list", elements='str'),
galaxy_credentials=dict(type="list", elements='str'),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -146,7 +146,7 @@ def main():
state = module.params.get('state')
# Attempt to look up organization based on the provided name
organization = module.get_one('organizations', name_or_id=name)
organization = module.get_one('organizations', name_or_id=name, check_exists=(state == 'exists'))
if state == 'absent':
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this

View File

@@ -122,7 +122,7 @@ options:
description:
- Desired state of the resource.
default: "present"
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
type: str
wait:
description:
@@ -272,7 +272,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'),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
wait=dict(type='bool', default=True),
update_project=dict(default=False, type='bool'),
interval=dict(default=2.0, type='float'),
@@ -313,7 +313,7 @@ def main():
lookup_data['organization'] = org_id
# Attempt to look up project based on the provided name and org ID
project = module.get_one('projects', name_or_id=name, data=lookup_data)
project = module.get_one('projects', name_or_id=name, check_exists=(state == 'exists'), data=lookup_data)
# Attempt to look up credential to copy based on the provided name
if copy_from:

View File

@@ -146,7 +146,7 @@ options:
state:
description:
- Desired state of the resource.
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
default: "present"
type: str
extends_documentation_fragment: awx.awx.auth
@@ -220,7 +220,7 @@ def main():
unified_job_template=dict(),
organization=dict(),
enabled=dict(type='bool'),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -265,8 +265,13 @@ def main():
search_fields['name'] = unified_job_template
unified_job_template_id = module.get_one('unified_job_templates', **{'data': search_fields})['id']
sched_search_fields['unified_job_template'] = unified_job_template_id
# Attempt to look up an existing item based on the provided data
existing_item = module.get_one('schedules', name_or_id=name, **{'data': sched_search_fields})
existing_item = module.get_one('schedules', name_or_id=name, check_exists=(state == 'exists'), **{'data': sched_search_fields})
if state == 'absent':
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this
module.delete_if_needed(existing_item)
association_fields = {}
@@ -343,18 +348,14 @@ def main():
else:
new_fields['execution_environment'] = ee['id']
if state == 'absent':
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this
module.delete_if_needed(existing_item)
elif state == 'present':
# If the state was present and we can let the module build or update the existing item, this will return on its own
module.create_or_update_if_needed(
existing_item,
new_fields,
endpoint='schedules',
item_type='schedule',
associations=association_fields,
)
# If the state was present and we can let the module build or update the existing item, this will return on its own
module.create_or_update_if_needed(
existing_item,
new_fields,
endpoint='schedules',
item_type='schedule',
associations=association_fields,
)
if __name__ == '__main__':

View File

@@ -42,7 +42,7 @@ options:
state:
description:
- Desired state of the resource.
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
default: "present"
type: str
extends_documentation_fragment: awx.awx.auth
@@ -69,7 +69,7 @@ def main():
new_name=dict(),
description=dict(),
organization=dict(required=True),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -86,7 +86,7 @@ def main():
org_id = module.resolve_name_to_id('organizations', organization)
# Attempt to look up team based on the provided name and org ID
team = module.get_one('teams', name_or_id=name, **{'data': {'organization': org_id}})
team = module.get_one('teams', name_or_id=name, check_exists=(state == 'exists'), **{'data': {'organization': org_id}})
if state == 'absent':
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this

View File

@@ -69,7 +69,7 @@ options:
state:
description:
- Desired state of the resource.
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
default: "present"
type: str
extends_documentation_fragment: awx.awx.auth
@@ -137,7 +137,7 @@ def main():
password=dict(no_log=True),
update_secrets=dict(type='bool', default=True, no_log=False),
organization=dict(),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -158,7 +158,7 @@ def main():
# Attempt to look up the related items the user specified (these will fail the module if not found)
# Attempt to look up an existing item based on the provided data
existing_item = module.get_one('users', name_or_id=username)
existing_item = module.get_one('users', name_or_id=username, check_exists=(state == 'exists'))
if state == 'absent':
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this

View File

@@ -144,6 +144,7 @@ options:
choices:
- present
- absent
- exists
default: "present"
type: str
notification_templates_started:
@@ -667,8 +668,7 @@ def create_workflow_nodes(module, response, workflow_nodes, workflow_id):
inv_lookup_data = {}
if 'organization' in workflow_node['inventory']:
inv_lookup_data['organization'] = module.resolve_name_to_id('organizations', workflow_node['inventory']['organization']['name'])
workflow_node_fields['inventory'] = module.get_one(
'inventories', name_or_id=workflow_node['inventory']['name'], data=inv_lookup_data)['id']
workflow_node_fields['inventory'] = module.get_one('inventories', name_or_id=workflow_node['inventory']['name'], data=inv_lookup_data)['id']
else:
workflow_node_fields['inventory'] = module.get_one('inventories', name_or_id=workflow_node['inventory'])['id']
@@ -843,7 +843,7 @@ def main():
notification_templates_approvals=dict(type="list", elements='str'),
workflow_nodes=dict(type='list', elements='dict', aliases=['schema']),
destroy_current_nodes=dict(type='bool', default=False, aliases=['destroy_current_schema']),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
# Create a module for ourselves
@@ -871,7 +871,7 @@ def main():
search_fields['organization'] = new_fields['organization'] = organization_id
# Attempt to look up an existing item based on the provided data
existing_item = module.get_one('workflow_job_templates', name_or_id=name, **{'data': search_fields})
existing_item = module.get_one('workflow_job_templates', name_or_id=name, check_exists=(state == 'exists'), **{'data': search_fields})
# Attempt to look up credential to copy based on the provided name
if copy_from:

View File

@@ -179,7 +179,7 @@ options:
state:
description:
- Desired state of the resource.
choices: ["present", "absent"]
choices: ["present", "absent", "exists"]
default: "present"
type: str
extends_documentation_fragment: awx.awx.auth
@@ -285,7 +285,7 @@ def main():
job_slice_count=dict(type='int'),
labels=dict(type='list', elements='str'),
timeout=dict(type='int'),
state=dict(choices=['present', 'absent'], default='present'),
state=dict(choices=['present', 'absent', 'exists'], default='present'),
)
mutually_exclusive = [("unified_job_template", "approval_node")]
required_if = [
@@ -327,7 +327,7 @@ def main():
search_fields['workflow_job_template'] = new_fields['workflow_job_template'] = workflow_job_template_id
# Attempt to look up an existing item based on the provided data
existing_item = module.get_one('workflow_job_template_nodes', **{'data': search_fields})
existing_item = module.get_one('workflow_job_template_nodes', check_exists=(state == 'exists'), **{'data': search_fields})
if state == 'absent':
# If the state was absent we can let the module delete it if needed, the module will handle exiting from this