Skip to content

Commit 1d23a10

Browse files
authored
feat: [AAP-37428] add support for copy credential (#399)
* add support for copy credential
1 parent 13e6685 commit 1d23a10

File tree

2 files changed

+108
-8
lines changed

2 files changed

+108
-8
lines changed

plugins/modules/credential.py

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030
description:
3131
- Setting this option will change the existing name (lookup via name).
3232
type: str
33+
copy_from:
34+
description:
35+
- Name of the existing credential to copy.
36+
- If set, copies the specified credential.
37+
- The new credential will be created with the name given in the C(name) parameter.
38+
type: str
39+
version_added: '3.0.0'
3340
inputs:
3441
description:
3542
- Credential inputs where the keys are var names used in templating.
@@ -75,6 +82,11 @@
7582
ansible.eda.credential:
7683
name: "Example Credential"
7784
state: absent
85+
86+
- name: Copy an existing EDA Credential
87+
ansible.eda.credential:
88+
name: "New Copied Credential"
89+
copy_from: "Existing Credential"
7890
"""
7991

8092

@@ -136,6 +148,7 @@ def main() -> None:
136148
argument_spec = dict(
137149
name=dict(type="str", required=True),
138150
new_name=dict(type="str"),
151+
copy_from=dict(type="str"),
139152
description=dict(type="str"),
140153
inputs=dict(type="dict"),
141154
credential_type_name=dict(type="str"),
@@ -145,13 +158,18 @@ def main() -> None:
145158

146159
argument_spec.update(AUTH_ARGSPEC)
147160

148-
required_if = [
149-
(
150-
"state",
151-
"present",
152-
("name", "credential_type_name", "inputs", "organization_name"),
153-
)
154-
]
161+
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
162+
copy_from = module.params.get("copy_from", None)
163+
164+
required_if = []
165+
if not copy_from:
166+
required_if = [
167+
(
168+
"state",
169+
"present",
170+
("name", "credential_type_name", "inputs", "organization_name"),
171+
)
172+
]
155173

156174
module = AnsibleModule(
157175
argument_spec=argument_spec, required_if=required_if, supports_check_mode=True
@@ -179,7 +197,9 @@ def main() -> None:
179197

180198
# Attempt to look up credential based on the provided name
181199
try:
182-
credential = controller.get_exactly_one(credential_endpoint, name=name)
200+
credential = controller.get_exactly_one(
201+
credential_endpoint, name=copy_from if copy_from else name
202+
)
183203
except EDAError as e:
184204
module.fail_json(msg=f"Failed to get credential: {e}")
185205

@@ -201,6 +221,23 @@ def main() -> None:
201221
else (controller.get_item_name(credential) if credential else name)
202222
)
203223

224+
# we attempt to copy only when copy_from is passed
225+
if copy_from:
226+
try:
227+
result = controller.copy_if_needed(
228+
name,
229+
copy_from,
230+
endpoint=f"eda-credentials/{credential['id']}/copy",
231+
item_type="credential",
232+
)
233+
module.exit_json(changed=True)
234+
except KeyError as e:
235+
module.fail_json(
236+
msg=f"Unable to access {e} of the credential to copy from."
237+
)
238+
except EDAError as e:
239+
module.fail_json(msg=f"Failed to copy credential: {e}")
240+
204241
# If the state was present and we can let the module build or update the
205242
# existing credential, this will return on its own
206243
try:

tests/integration/targets/credential/tasks/main.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
set_fact:
2222
credential_name: "Test_Credential_{{ test_id }}"
2323
new_credential_name: "New_Test_Credential_{{ test_id }}"
24+
credential_copy_name: "Test_Credential_{{ test_id }}_Copy"
2425
credential_type_name: "Test_CredentialType_{{ test_id }}"
2526

2627
# CREATE
@@ -91,6 +92,68 @@
9192
ansible.eda.credential_info:
9293
name: "{{ credential_name }}"
9394

95+
- name: Copy credential
96+
ansible.eda.credential:
97+
name: "{{ credential_copy_name }}"
98+
copy_from: "{{ credential_name }}"
99+
organization_name: Default
100+
register: _result
101+
102+
- name: Check credential is copied
103+
assert:
104+
that:
105+
- _result.changed
106+
107+
- name: Get info about credentials
108+
ansible.eda.credential_info:
109+
register: _credential_info
110+
111+
- name: Get both created and copied credentials
112+
set_fact:
113+
_source_credential: "{{ _credential_info.credentials | selectattr('name', 'equalto', credential_name) | list | first }}"
114+
_copied_credential: "{{ _credential_info.credentials | selectattr('name', 'equalto', credential_copy_name) | list | first }}"
115+
116+
- name: Assert credential fields are copied correctly
117+
ansible.builtin.assert:
118+
that:
119+
- _source_credential | dict2items | rejectattr('key', 'in', ignored_fields) | items2dict == _copied_credential | dict2items | rejectattr('key', 'in', ignored_fields) | items2dict
120+
- _source_credential.name + '_Copy' == _copied_credential.name
121+
vars:
122+
ignored_fields:
123+
- name
124+
- id
125+
- created_at
126+
- updated_at
127+
- modified_at
128+
129+
- name: Copy non-existing credential
130+
ansible.eda.credential:
131+
name: "{{ credential_copy_name }}"
132+
copy_from: "invalid_credential"
133+
organization_name: Default
134+
register: _result
135+
ignore_errors: true
136+
137+
- name: Check credential copy failed
138+
assert:
139+
that:
140+
- _result.failed
141+
- "\"Unable to access 'id' of the credential to copy from\" in _result.msg"
142+
143+
- name: Copy credential and use existing name
144+
ansible.eda.credential:
145+
name: "{{ credential_copy_name }}"
146+
copy_from: "{{ credential_name }}"
147+
organization_name: Default
148+
register: _result
149+
ignore_errors: true
150+
151+
- name: Check credential copy failed
152+
assert:
153+
that:
154+
- _result.failed
155+
- "'eda credential with this name already exists.' in _result.msg"
156+
94157
# UPDATE
95158
- name: Update credential name
96159
ansible.eda.credential:

0 commit comments

Comments
 (0)