Merge pull request #9374 from sean-m-sullivan/copy_awx_collection

Add Copy to option to awx collection modules.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
softwarefactory-project-zuul[bot] 2021-03-12 22:00:48 +00:00 committed by GitHub
commit 9342cb012a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 480 additions and 27 deletions

View File

@ -410,6 +410,51 @@ class TowerAPIModule(TowerModule):
else:
self.fail_json(msg="Failed to associate item {0}".format(response['json'].get('detail', response['json'])))
def copy_item(self, existing_item, copy_from_name_or_id, new_item_name, endpoint=None, item_type='unknown', copy_lookup_data=None):
if existing_item is not None:
self.warn(msg="A {0} with the name {1} already exists.".format(item_type, new_item_name))
self.json_output['changed'] = False
self.json_output['copied'] = False
return existing_item
# Lookup existing item to copy from
copy_from_lookup = self.get_one(endpoint, name_or_id=copy_from_name_or_id, **{'data': copy_lookup_data})
# Fail if the copy_from_lookup is empty
if copy_from_lookup is None:
self.fail_json(msg="A {0} with the name {1} was not able to be found.".format(item_type, copy_from_name_or_id))
# Do checks for copy permisions if warrented
if item_type == 'workflow_job_template':
copy_get_check = self.get_endpoint(copy_from_lookup['related']['copy'])
if copy_get_check['status_code'] in [200]:
if (copy_get_check['json']['can_copy'] and copy_get_check['json']['can_copy_without_user_input'] and not
copy_get_check['json']['templates_unable_to_copy'] and not copy_get_check['json']['credentials_unable_to_copy'] and not
copy_get_check['json']['inventories_unable_to_copy']):
# Because checks have passed
self.json_output['copy_checks'] = 'passed'
else:
self.fail_json(msg="Unable to copy {0} {1} error: {2}".format(item_type, copy_from_name_or_id, copy_get_check))
else:
self.fail_json(msg="Error accessing {0} {1} error: {2} ".format(item_type, copy_from_name_or_id, copy_get_check))
response = self.post_endpoint(copy_from_lookup['related']['copy'], **{'data': {'name': new_item_name}})
if response['status_code'] in [201]:
self.json_output['id'] = response['json']['id']
self.json_output['changed'] = True
self.json_output['copied'] = True
new_existing_item = response['json']
else:
if 'json' in response and '__all__' in response['json']:
self.fail_json(msg="Unable to create {0} {1}: {2}".format(item_type, new_item_name, response['json']['__all__'][0]))
elif 'json' in response:
self.fail_json(msg="Unable to create {0} {1}: {2}".format(item_type, new_item_name, response['json']))
else:
self.fail_json(msg="Unable to create {0} {1}: {2}".format(item_type, new_item_name, response['status_code']))
return new_existing_item
def create_if_needed(self, existing_item, new_item, endpoint, on_create=None, auto_exit=True, item_type='unknown', associations=None):
# This will exit from the module on its own

View File

@ -32,6 +32,14 @@ options:
- Setting this option will change the existing name (looked up via the name field.
required: False
type: str
copy_from:
description:
- Name or id to copy the credential from.
- This will copy an existing credential and change any parameters supplied.
- The new credential name will be the one provided in the name parameter.
- The organization parameter is not used in this, to facilitate copy from one organization to another.
- Provide the id or use the lookup plugin to provide the id if multiple credentials share the same name.
type: str
description:
description:
- The description to use for the credential.
@ -274,6 +282,12 @@ EXAMPLES = '''
vault_password: 'new_password'
vault_id: 'My ID'
- name: Copy Credential
tower_credential:
name: Copy password
copy_from: Example password
credential_type: Vault
organization: Foo
'''
from ..module_utils.tower_api import TowerAPIModule
@ -318,6 +332,7 @@ def main():
argument_spec = dict(
name=dict(required=True),
new_name=dict(),
copy_from=dict(),
description=dict(),
organization=dict(),
credential_type=dict(),
@ -356,6 +371,7 @@ def main():
# Extract our parameters
name = module.params.get('name')
new_name = module.params.get('new_name')
copy_from = module.params.get('copy_from')
description = module.params.get('description')
organization = module.params.get('organization')
credential_type = module.params.get('credential_type')
@ -382,11 +398,22 @@ def main():
lookup_data = {
'credential_type': cred_type_id,
}
# Create a copy of lookup data for copying without org.
copy_lookup_data = lookup_data
if organization:
lookup_data['organization'] = org_id
credential = module.get_one('credentials', name_or_id=name, **{'data': lookup_data})
# Attempt to look up credential to copy based on the provided name
if copy_from:
# a new existing item is formed when copying and is returned.
credential = module.copy_item(
credential, copy_from, name,
endpoint='credentials', item_type='credential',
copy_lookup_data=copy_lookup_data,
)
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(credential)

View File

@ -52,6 +52,18 @@ options:
elements: str
aliases:
- groups
preserve_existing_hosts:
description:
- Provide option (False by default) to preserves existing hosts in an existing group in tower.
default: False
type: bool
preserve_existing_children:
description:
- Provide option (False by default) to preserves existing children in an existing group in tower.
default: False
type: bool
aliases:
- preserve_existing_groups
state:
description:
- Desired state of the resource.
@ -74,6 +86,18 @@ EXAMPLES = '''
inventory: "Local Inventory"
state: present
tower_config_file: "~/tower_cli.cfg"
- name: Add tower group
tower_group:
name: Cities
description: "Local Host Group"
inventory: Default Inventory
hosts:
- fda
children:
- NewYork
preserve_existing_hosts: True
preserve_existing_children: True
'''
from ..module_utils.tower_api import TowerAPIModule
@ -90,6 +114,8 @@ def main():
variables=dict(type='dict'),
hosts=dict(type='list', elements='str'),
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'),
)
@ -102,6 +128,8 @@ def main():
inventory = module.params.get('inventory')
description = module.params.get('description')
state = module.params.pop('state')
preserve_existing_hosts = module.params.get('preserve_existing_hosts')
preserve_existing_children = module.params.get('preserve_existing_groups')
variables = module.params.get('variables')
# Attempt to look up the related items the user specified (these will fail the module if not found)
@ -141,6 +169,11 @@ def main():
if sub_obj is None:
module.fail_json(msg='Could not find {0} with name {1}'.format(resource, sub_name))
id_list.append(sub_obj['id'])
# Preserve existing objects
if (preserve_existing_hosts and relationship == 'hosts') or (preserve_existing_children and relationship == 'children'):
preserve_existing_check = module.get_endpoint(group['related'][relationship])
for sub_obj in preserve_existing_check['json']['results']:
id_list.append(sub_obj['id'])
if id_list:
association_fields[relationship] = id_list

View File

@ -27,6 +27,14 @@ options:
- The name to use for the inventory.
required: True
type: str
copy_from:
description:
- Name or id to copy the inventory from.
- This will copy an existing inventory and change any parameters supplied.
- The new inventory name will be the one provided in the name parameter.
- The organization parameter is not used in this, to facilitate copy from one organization to another.
- Provide the id or use the lookup plugin to provide the id if multiple inventories share the same name.
type: str
description:
description:
- The description to use for the inventory.
@ -72,6 +80,14 @@ EXAMPLES = '''
organization: "Bar Org"
state: present
tower_config_file: "~/tower_cli.cfg"
- name: Copy tower inventory
tower_inventory:
name: Copy Foo Inventory
copy_from: Default Inventory
description: "Our Foo Cloud Servers"
organization: Foo
state: present
'''
@ -83,6 +99,7 @@ def main():
# Any additional arguments that are not fields of the item can be added here
argument_spec = dict(
name=dict(required=True),
copy_from=dict(),
description=dict(),
organization=dict(required=True),
variables=dict(type='dict'),
@ -97,6 +114,7 @@ def main():
# Extract our parameters
name = module.params.get('name')
copy_from = module.params.get('copy_from')
description = module.params.get('description')
organization = module.params.get('organization')
variables = module.params.get('variables')
@ -115,6 +133,15 @@ def main():
}
})
# Attempt to look up credential to copy based on the provided name
if copy_from:
# a new existing item is formed when copying and is returned.
inventory = module.copy_item(
inventory, copy_from, name,
endpoint='inventories', item_type='inventory',
copy_lookup_data={},
)
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(inventory)

View File

@ -31,6 +31,14 @@ options:
description:
- Setting this option will change the existing name (looed up via the name field.
type: str
copy_from:
description:
- Name or id to copy the job template from.
- This will copy an existing job template and change any parameters supplied.
- The new job template name will be the one provided in the name parameter.
- The organization parameter is not used in this, to facilitate copy from one organization to another.
- Provide the id or use the lookup plugin to provide the id if multiple job templates share the same name.
type: str
description:
description:
- Description to use for the job template.
@ -314,6 +322,15 @@ EXAMPLES = '''
notification_templates_started:
- Notification2
- name: Copy Job Template
tower_job_template:
name: copy job template
copy_from: test job template
job_type: "run"
inventory: Copy Foo Inventory
project: test
playbook: hello_world.yml
state: "present"
'''
from ..module_utils.tower_api import TowerAPIModule
@ -339,6 +356,7 @@ def main():
argument_spec = dict(
name=dict(required=True),
new_name=dict(),
copy_from=dict(),
description=dict(),
organization=dict(),
job_type=dict(choices=['run', 'check']),
@ -392,6 +410,7 @@ def main():
# Extract our parameters
name = module.params.get('name')
new_name = module.params.get("new_name")
copy_from = module.params.get('copy_from')
state = module.params.get('state')
# Deal with legacy credential and vault_credential
@ -424,6 +443,15 @@ def main():
# 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})
# Attempt to look up credential to copy based on the provided name
if copy_from:
# a new existing item is formed when copying and is returned.
existing_item = module.copy_item(
existing_item, copy_from, name,
endpoint='job_templates', item_type='job_template',
copy_lookup_data={},
)
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)

View File

@ -31,6 +31,14 @@ options:
description:
- Setting this option will change the existing name (looked up via the name field.
type: str
copy_from:
description:
- Name or id to copy the notification from.
- This will copy an existing notification and change any parameters supplied.
- The new notification name will be the one provided in the name parameter.
- The organization parameter is not used in this, to facilitate copy from one organization to another.
- Provide the id or use the lookup plugin to provide the id if multiple notifications share the same name.
type: str
description:
description:
- The description of the notification.
@ -294,6 +302,12 @@ EXAMPLES = '''
name: old notification
state: absent
tower_config_file: "~/tower_cli.cfg"
- name: Copy webhook notification
tower_notification_template:
name: foo notification
copy_from: email notification
organization: Foo
'''
@ -318,6 +332,7 @@ def main():
argument_spec = dict(
name=dict(required=True),
new_name=dict(),
copy_from=dict(),
description=dict(),
organization=dict(),
notification_type=dict(choices=[
@ -360,6 +375,7 @@ def main():
# Extract our parameters
name = module.params.get('name')
new_name = module.params.get('new_name')
copy_from = module.params.get('copy_from')
description = module.params.get('description')
organization = module.params.get('organization')
notification_type = module.params.get('notification_type')
@ -386,6 +402,15 @@ def main():
}
})
# Attempt to look up credential to copy based on the provided name
if copy_from:
# a new existing item is formed when copying and is returned.
existing_item = module.copy_item(
existing_item, copy_from, name,
endpoint='notification_templates', item_type='notification_template',
copy_lookup_data={},
)
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)

View File

@ -27,6 +27,14 @@ options:
- Name to use for the project.
required: True
type: str
copy_from:
description:
- Name or id to copy the project from.
- This will copy an existing project and change any parameters supplied.
- The new project name will be the one provided in the name parameter.
- The organization parameter is not used in this, to facilitate copy from one organization to another.
- Provide the id or use the lookup plugin to provide the id if multiple projects share the same name.
type: str
description:
description:
- Description to use for the project.
@ -160,7 +168,7 @@ EXAMPLES = '''
state: present
tower_config_file: "~/tower_cli.cfg"
- name: Add Tower Project with cache timeout and custom virtualenv
- name: Add Tower Project with cache timeout
tower_project:
name: "Foo"
description: "Foo bar project"
@ -169,6 +177,14 @@ EXAMPLES = '''
scm_update_cache_timeout: 60
state: present
tower_config_file: "~/tower_cli.cfg"
- name: Copy tower project
tower_project:
name: copy
copy_from: test
description: Foo copy project
organization: Foo
state: present
'''
import time
@ -223,6 +239,7 @@ def main():
# Any additional arguments that are not fields of the item can be added here
argument_spec = dict(
name=dict(required=True),
copy_from=dict(),
description=dict(),
scm_type=dict(choices=['manual', 'git', 'svn', 'insights'], default='manual'),
scm_url=dict(),
@ -252,21 +269,14 @@ def main():
# Extract our parameters
name = module.params.get('name')
description = module.params.get('description')
copy_from = module.params.get('copy_from')
scm_type = module.params.get('scm_type')
if scm_type == "manual":
scm_type = ""
scm_url = module.params.get('scm_url')
local_path = module.params.get('local_path')
scm_branch = module.params.get('scm_branch')
scm_refspec = module.params.get('scm_refspec')
credential = module.params.get('credential')
scm_clean = module.params.get('scm_clean')
scm_delete_on_update = module.params.get('scm_delete_on_update')
scm_update_on_launch = module.params.get('scm_update_on_launch')
scm_update_cache_timeout = module.params.get('scm_update_cache_timeout')
allow_override = module.params.get('allow_override')
timeout = module.params.get('timeout')
default_ee = module.params.get('default_environment')
organization = module.params.get('organization')
state = module.params.get('state')
@ -284,6 +294,15 @@ def main():
# 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)
# Attempt to look up credential to copy based on the provided name
if copy_from:
# a new existing item is formed when copying and is returned.
project = module.copy_item(
project, copy_from, name,
endpoint='projects', item_type='project',
copy_lookup_data={},
)
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(project)
@ -316,26 +335,27 @@ def main():
project_fields = {
'name': module.get_item_name(project) if project else name,
'scm_type': scm_type,
'scm_url': scm_url,
'scm_branch': scm_branch,
'scm_refspec': scm_refspec,
'scm_clean': scm_clean,
'scm_delete_on_update': scm_delete_on_update,
'timeout': timeout,
'organization': org_id,
'scm_update_on_launch': scm_update_on_launch,
'scm_update_cache_timeout': scm_update_cache_timeout,
}
if description is not None:
project_fields['description'] = description
for field_name in (
'scm_url', 'scm_branch', 'scm_refspec', 'scm_clean', 'scm_delete_on_update',
'timeout', 'scm_update_cache_timeout', 'custom_virtualenv',
'description', 'allow_override',
):
field_val = module.params.get(field_name)
if field_val is not None:
project_fields[field_name] = field_val
if credential is not None:
project_fields['credential'] = credential
if default_ee is not None:
project_fields['default_environment'] = module.resolve_name_to_id('execution_environments', default_ee)
if allow_override is not None:
project_fields['allow_override'] = allow_override
if scm_type == '':
project_fields['local_path'] = local_path
if local_path is not None:
project_fields['local_path'] = local_path
if scm_update_cache_timeout != 0 and scm_update_on_launch is not True:
module.warn('scm_update_cache_timeout will be ignored since scm_update_on_launch was not set to true')

View File

@ -32,6 +32,14 @@ options:
description:
- Setting this option will change the existing name.
type: str
copy_from:
description:
- Name or id to copy the workflow job template from.
- This will copy an existing workflow job template and change any parameters supplied.
- The new workflow job template name will be the one provided in the name parameter.
- The organization parameter is not used in this, to facilitate copy from one organization to another.
- Provide the id or use the lookup plugin to provide the id if multiple workflow job templates share the same name.
type: str
description:
description:
- Optional description of this workflow job template.
@ -146,6 +154,12 @@ EXAMPLES = '''
name: example-workflow
description: created by Ansible Playbook
organization: Default
- name: Copy a workflow job template
tower_workflow_job_template:
name: copy-workflow
copy_from: example-workflow
organization: Foo
'''
from ..module_utils.tower_api import TowerAPIModule
@ -172,6 +186,7 @@ def main():
argument_spec = dict(
name=dict(required=True),
new_name=dict(),
copy_from=dict(),
description=dict(),
extra_vars=dict(type='dict'),
organization=dict(),
@ -202,6 +217,7 @@ def main():
# Extract our parameters
name = module.params.get('name')
new_name = module.params.get("new_name")
copy_from = module.params.get('copy_from')
state = module.params.get('state')
new_fields = {}
@ -220,6 +236,15 @@ def main():
# 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})
# Attempt to look up credential to copy based on the provided name
if copy_from:
# a new existing item is formed when copying and is returned.
existing_item = module.copy_item(
existing_item, copy_from, name,
endpoint='workflow_job_templates', item_type='workflow_job_template',
copy_lookup_data={},
)
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)

View File

@ -30,7 +30,7 @@ no_endpoint_for_module = [
# Global module parameters we can ignore
ignore_parameters = [
'state', 'new_name', 'update_secrets'
'state', 'new_name', 'update_secrets', 'copy_from'
]
# Some modules take additional parameters that do not appear in the API
@ -48,8 +48,10 @@ no_api_parameter_ok = {
'tower_workflow_job_template_node': ['organization', 'approval_node'],
# Survey is how we handle associations
'tower_workflow_job_template': ['survey_spec'],
# ad hoc commands support interval and timeout since its more like tower_job_launc
# ad hoc commands support interval and timeout since its more like tower_job_launch
'tower_ad_hoc_command': ['interval', 'timeout', 'wait'],
# tower_group parameters to perserve hosts and children.
'tower_group': ['preserve_existing_children', 'preserve_existing_hosts'],
}
# When this tool was created we were not feature complete. Adding something in here indicates a module

View File

@ -203,6 +203,29 @@
that:
- result is not changed
- name: Copy ssh Credential
tower_credential:
name: "copy_{{ ssh_cred_name2 }}"
copy_from: "{{ ssh_cred_name2 }}"
credential_type: Machine
register: result
- assert:
that:
- result.copied
- name: Delete an SSH credential
tower_credential:
name: "copy_{{ ssh_cred_name2 }}"
organization: Default
state: absent
credential_type: Machine
register: result
- assert:
that:
- "result is changed"
- name: Create a valid SSH credential from lookup source (old school)
tower_credential:
name: "{{ ssh_cred_name3 }}"

View File

@ -29,9 +29,79 @@
that:
- "result is changed"
- name: Create a Group
tower_group:
name: "{{ group_name2 }}"
inventory: "{{ inv_name }}"
state: present
variables:
foo: bar
register: result
- assert:
that:
- "result is changed"
- name: Create a Group
tower_group:
name: "{{ group_name3 }}"
inventory: "{{ inv_name }}"
state: present
variables:
foo: bar
register: result
- assert:
that:
- "result is changed"
- name: add hosts
tower_host:
name: "{{ item }}"
inventory: "{{ inv_name }}"
loop:
- "{{ host_name1 }}"
- "{{ host_name2 }}"
- "{{ host_name3 }}"
- name: Create a Group with hosts and sub group
tower_group:
name: "{{ group_name1 }}"
inventory: "{{ inv_name }}"
hosts:
- "{{ host_name1 }}"
- "{{ host_name2 }}"
children:
- "{{ group_name2 }}"
state: present
variables:
foo: bar
register: result
- name: Create a Group with hosts and sub group
tower_group:
name: "{{ group_name1 }}"
inventory: "{{ inv_name }}"
hosts:
- "{{ host_name3 }}"
children:
- "{{ group_name3 }}"
state: present
preserve_existing_hosts: true
preserve_existing_children: true
register: result
- name: "Find number of hosts in {{ group_name1 }}"
set_fact:
group1_host_count: "{{ lookup('awx.awx.tower_api', 'groups/{{result.id}}/all_hosts/') |length}}"
- assert:
that:
- group1_host_count == "3"
- name: Delete a Group
tower_group:
name: "{{ result.id }}"
name: "{{ group_name1 }}"
inventory: "{{ inv_name }}"
state: absent
register: result
@ -40,6 +110,28 @@
that:
- "result is changed"
- name: Delete a Group
tower_group:
name: "{{ group_name2 }}"
inventory: "{{ inv_name }}"
state: absent
register: result
- assert:
that:
- "result is changed"
- name: Delete a Group
tower_group:
name: "{{ group_name3 }}"
inventory: "{{ inv_name }}"
state: absent
register: result
- assert:
that:
- "result is not changed"
- name: Check module fails with correct msg
tower_group:
name: test-group

View File

@ -36,7 +36,6 @@
- assert:
that:
- "result is changed"
- name: Test Inventory module idempotency
tower_inventory:
name: "{{ result.id }}"
@ -49,6 +48,30 @@
that:
- "result is not changed"
- name: Copy an inventory
tower_inventory:
name: "copy_{{ inv_name1 }}"
copy_from: "{{ inv_name1 }}"
organization: Default
description: "Our Foo Cloud Servers"
state: present
register: result
- assert:
that:
- result.copied
- name: Delete an Inventory
tower_inventory:
name: "copy_{{ inv_name1 }}"
organization: Default
state: absent
register: result
- assert:
that:
- "result is changed"
- name: Fail Change Regular to Smart
tower_inventory:
name: "{{ inv_name1 }}"
@ -133,6 +156,7 @@
loop:
- "{{ inv_name1 }}"
- "{{ inv_name2 }}"
- "copy_{{ inv_name1 }}"
- name: Delete Insights Credential
tower_credential:

View File

@ -155,6 +155,19 @@
that:
- "result is changed"
- name: Copy Job Template
tower_job_template:
name: "copy_{{ jt1 }}"
copy_from: "{{ jt1 }}"
state: "present"
- name: Delete copied Job Template
tower_job_template:
name: "copy_{{ jt1 }}"
job_type: run
state: absent
register: result
# This doesnt work if you include the credentials parameter
- name: Delete Job Template 1
tower_job_template:

View File

@ -133,6 +133,28 @@
that:
- result is changed
- name: Copy email notification
tower_notification_template:
name: "copy_{{ email_not }}"
copy_from: "{{ email_not }}"
organization: Default
register: result
- assert:
that:
- result.copied
- name: Delete copied email notification
tower_notification_template:
name: "copy_{{ email_not }}"
organization: Default
state: absent
register: result
- assert:
that:
- result is changed
- name: Delete email notification
tower_notification_template:
name: "{{ email_not }}"

View File

@ -75,20 +75,21 @@
scm_credential: "{{ cred_name }}"
check_mode: true
- name: Create a new test project
- name: "Copy tower project from {{ project_name1 }}"
tower_project:
name: "{{ project_name2 }}"
copy_from: "{{ project_name1 }}"
organization: "{{ org_name }}"
scm_type: git
scm_url: https://github.com/ansible/test-playbooks
scm_credential: "{{ cred_name }}"
state: present
register: result
# If this fails it may be because the check_mode task actually already created
# the project, or it could be because the module actually failed somehow
- assert:
that:
- "result is changed"
- result.copied
- name: Check module fails with correct msg when given non-existing org as param
tower_project:

View File

@ -241,6 +241,52 @@
that:
- "result is changed"
- name: Copy a workflow job template
tower_workflow_job_template:
name: "copy_{{ wfjt_name }}"
copy_from: "{{ wfjt_name }}"
organization: Default
register: result
- assert:
that:
- result.copied
- name: Fail Remove "on start" webhook notification from copied workflow job template
tower_workflow_job_template:
name: "copy_{{ wfjt_name }}"
notification_templates_started:
- "{{ email_not }}123"
register: remove_copied_workflow_node
ignore_errors: true
- assert:
that:
- "remove_copied_workflow_node is failed"
- "remove_copied_workflow_node is not changed"
- "'returned 0 items' in remove_copied_workflow_node.msg"
- name: Remove "on start" webhook notification from copied workflow job template
tower_workflow_job_template:
name: "copy_{{ wfjt_name }}"
notification_templates_started:
- "{{ email_not }}"
register: result
- assert:
that:
- "result is changed"
- name: Delete copied workflow job template
tower_workflow_job_template:
name: "copy_{{ wfjt_name }}"
state: absent
register: result
- assert:
that:
- "result is changed"
- name: Remove "on start" webhook notification from workflow job template
tower_workflow_job_template:
name: "{{ wfjt_name }}"