From b2b52c6b3561b1743329f7b58e6e01a97c7dfcc7 Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Sun, 30 Jul 2023 15:19:06 +0200 Subject: [PATCH 01/10] add metal_project_ssh_key and _key_info plus docs --- README.md | 4 +- docs/modules/metal_organization.md | 2 +- docs/modules/metal_project_ssh_key.md | 73 ++++++ docs/modules/metal_project_ssh_key_info.md | 73 ++++++ plugins/modules/metal_organization.py | 2 +- plugins/modules/metal_project_ssh_key.py | 213 ++++++++++++++++++ plugins/modules/metal_project_ssh_key_info.py | 140 ++++++++++++ 7 files changed, 504 insertions(+), 3 deletions(-) create mode 100644 docs/modules/metal_project_ssh_key.md create mode 100644 docs/modules/metal_project_ssh_key_info.md create mode 100644 plugins/modules/metal_project_ssh_key.py create mode 100644 plugins/modules/metal_project_ssh_key_info.py diff --git a/README.md b/README.md index c3ca647..9b1e215 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Name | Description | [equinix.cloud.metal_ip_assignment](./docs/modules/metal_ip_assignment.md)|Manage Equinix Metal IP assignments| [equinix.cloud.metal_organization](./docs/modules/metal_organization.md)|Lookup a single organization by ID in Equinix Metal| [equinix.cloud.metal_project](./docs/modules/metal_project.md)|Manage Projects in Equinix Metal| +[equinix.cloud.metal_project_ssh_key](./docs/modules/metal_project_ssh_key.md)|Manage a project ssh key in Equinix Metal| [equinix.cloud.metal_reserved_ip_block](./docs/modules/metal_reserved_ip_block.md)|Create/delete blocks of reserved IP addresses in a project.| [equinix.cloud.metal_ssh_key](./docs/modules/metal_ssh_key.md)|Manage personal SSH keys in Equinix Metal| @@ -44,6 +45,7 @@ Name | Description | [equinix.cloud.metal_operating_system_info](./docs/modules/metal_operating_system_info.md)|Gather information about Operating Systems available for devices in Equinix Metal| [equinix.cloud.metal_organization_info](./docs/modules/metal_organization_info.md)|Gather information about Equinix Metal organizations| [equinix.cloud.metal_project_info](./docs/modules/metal_project_info.md)|Gather information about Equinix Metal projects| +[equinix.cloud.metal_project_ssh_key_info](./docs/modules/metal_project_ssh_key_info.md)|Gather project SSH keys.| [equinix.cloud.metal_reserved_ip_block_info](./docs/modules/metal_reserved_ip_block_info.md)|Gather list of reserved IP blocks| [equinix.cloud.metal_ssh_key_info](./docs/modules/metal_ssh_key_info.md)|Gather personal SSH keys| @@ -142,4 +144,4 @@ Verify that new version of [equinix.cloud](https://galaxy.ansible.com/equinix/cl GNU General Public License v3.0. -See [COPYING](COPYING) to see the full text. +See [COPYING](COPYING) to see the full text. \ No newline at end of file diff --git a/docs/modules/metal_organization.md b/docs/modules/metal_organization.md index a0ca13d..66ee6fe 100644 --- a/docs/modules/metal_organization.md +++ b/docs/modules/metal_organization.md @@ -2,7 +2,7 @@ Lookup a single organization by ID in Equinix Metal. -This resource only fetches a single organization resource ID. +This resource only fetches a single organization by resource ID. It doesn't allow to create or update organizations. diff --git a/docs/modules/metal_project_ssh_key.md b/docs/modules/metal_project_ssh_key.md new file mode 100644 index 0000000..ed47b60 --- /dev/null +++ b/docs/modules/metal_project_ssh_key.md @@ -0,0 +1,73 @@ +# metal_project_ssh_key + +Manage project ssh key in Equinix Metal. Read more about personal and project SSH keys in [Equinix Metal documentation](https://deploy.equinix.com/developers/docs/metal/accounts/ssh-keys/#personal-keys-vs-project-keys). You can use *id* or *label* to lookup a project SSH key. If you want to create new resource, you must provide *name*, *public_key* and *project_id*. + + +- [Examples](#examples) +- [Parameters](#parameters) +- [Return Values](#return-values) + +## Examples + +```yaml +- name: Create new project project ssh_key + hosts: localhost + tasks: + - equinix.cloud.metal_project_ssh_key: + name: "test_key" + public_key: "ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@node" + project_id: "local.project_id" + +``` + +```yaml +- name: Remove project ssh_key by id + hosts: localhost + tasks: + - equinix.cloud.metal_project_ssh_key: + id: "eef49903-7a09-4ca1-af67-4087c29ab5b6" + state: absent + +``` + + + + + + + + + + +## Parameters + +| Field | Type | Required | Description | +|-----------|------|----------|------------------------------------------------------------------------------| +| `id` |
`str`
|
Optional
| UUID of the ssh_key. | +| `name` |
`str`
|
Optional
| The name of the ssh_key. **(Updatable)** | +| `public_key` |
`str`
|
Optional
| The public key of the project ssh_key. **(Updatable)** | +| `project_id` |
`str`
|
Optional
| The ID of parent project. **(Updatable)** | + + + + + + +## Return Values + +- `metal_project_ssh_key` - The module object + + - Sample Response: + ```json + + { + "fingerprint": "98:9c:35:ed:f9:75:5b:52:e2:70:50:22:ea:77:5b:b6", + "id": "eef49903-7a09-4ca1-af67-4087c29ab5b6", + "public_key": "ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@xps", + "name": "test_key", + "project_id": "local.project_id" + } + + ``` + + diff --git a/docs/modules/metal_project_ssh_key_info.md b/docs/modules/metal_project_ssh_key_info.md new file mode 100644 index 0000000..10bd318 --- /dev/null +++ b/docs/modules/metal_project_ssh_key_info.md @@ -0,0 +1,73 @@ +# metal_project_ssh_key_info + +Gather project SSH keys. Read more about project vs project SSH keys in [Equinix Metal documentation](https://metal.equinix.com/developers/docs/accounts/ssh-keys/#personal-keys-vs-project-keys). + + +- [Examples](#examples) +- [Parameters](#parameters) +- [Return Values](#return-values) + +## Examples + +```yaml + +- set_fact: + desired_name_substring: "tkarasek" + +- name: list project ssh keys + equinix.cloud.metal_project_ssh_key_info: + register: ssh_keys_listed + +- name: filter found ssh keys + set_fact: + both_ssh_keys_listed: "{{ ssh_keys_listed.resources | selectattr('name', 'match', desired_name_substring) }}" + +``` + + + + + + + + + + +## Parameters + +| Field | Type | Required | Description | +|-----------|------|----------|------------------------------------------------------------------------------| +| `name` |
`str`
|
**Required**
| Name to search for in existing keys. | + + + + + + +## Return Values + +- `resources` - Found resources + + - Sample Response: + ```json + + [ + { + "fingerprint": "70:c1:73:8b:3f:2f:a4:18:ea:4d:79:13:52:7b:c4:3e", + "id": "6edfcbc2-17e5-4221-9eac-2f40dbe60daf", + "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAt5gwVMhwcCrxyxpMEKwiS0xgit3PIIEgVXt6SQHc8eONq0mYJJ5TOBNTnySqXd9RtSv/Jbf5Aq9BzBGWeoZ6sZfKwh984Ip35StJtjXtyIOlY3skovndtupBIwlGXgX/WQzyLr+G/+Yu9/nhdxQi801PDZnDvKoeomM0rMD29nV+m0ud+GrtsAt6VFul2PxqpypZ1TYviyED6IKo7rgQsQDkE9QHcNdfT1FZWiJbfP7o8TIurQJcAXg+MtLoc8rKKcxFMeZ9FSydgtTC7nP1h558RtECGWiUgaBPI7TpBmcdMtbEfAiBoGT17GWnT8qmy2u5xnEKPD9Qft4w4fjfpw==", + "label": "tkarasek", + "project_id": local.project_id + }, + { + "fingerprint": "ba:70:af:b3:0f:0e:7f:e5:eb:97:e2:27:b1:f5:6f:94", + "id": "d00c596d-b42a-44a7-ac14-e299b85e73d3", + "key": "ssh-dss AAAAB3NzaC1kc3MAAACBAOpXVtmc0Bla98bt0o5/Zj7sb4mHIukgVFZu7F32R3VK1cEKB4rEE8uS0oLS/qMRLue45TWVJwRMYGlPjt3p/VyraelxoyJZLuITIsqa5hBc9w0oTlB5Bmbkn16umW96WCaWEoq/aitpocbRChTiP5biI6FyQTQlIHDaYzBDOi11AAAAFQDUXy7cmuzphDpJSYYTiudiUhVokwAAAIEAyUQ9m8qL/1HPkFe6jbXAvtSSmW27F4c+G2xR5HizaHQzXgBOxPcsOsY17KTU+Ddbg+OF9soWNwSpm9pyVjVmNGqH3S8R1pwvuJF/O2Asy1m6wpWhbPw8JdEBW7WHoptBpfuzJoS2LOzJUEmUu4Eb+xS237KG1d1BVny/49KAoH0AAACBAJKBSsm9Xey0fUN6vYtTQgoYeGxxj/LqAIAOs/TpCxZDntly860y/SzHYai8x48k4t7whENY1CJ41fpMcPlz8xIsrNP3326Wbr0ExwOIvJKAVN1YLYqF8NXWzaVrjo5WbSeI8PiWTYemvLAujVxZssIrApTZBhp55nnwge6K1zTG tomk@air", + "label": "ansible-integration-test-ssh_key-ztiapihf-ssh_key1_renamed", + "project_id": local.project_id + } + ] + + ``` + + diff --git a/plugins/modules/metal_organization.py b/plugins/modules/metal_organization.py index 609e7a5..b72d5dc 100644 --- a/plugins/modules/metal_organization.py +++ b/plugins/modules/metal_organization.py @@ -10,7 +10,7 @@ author: Equinix DevRel Team (@equinix) description: !!python/tuple - 'Lookup a single organization by ID in Equinix Metal. ' -- 'This resource only fetches a single organization resource ID. ' +- 'This resource only fetches a single organization by resource ID. ' - It doesn't allow to create or update organizations. module: metal_organization notes: [] diff --git a/plugins/modules/metal_project_ssh_key.py b/plugins/modules/metal_project_ssh_key.py new file mode 100644 index 0000000..c57a4d2 --- /dev/null +++ b/plugins/modules/metal_project_ssh_key.py @@ -0,0 +1,213 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# DOCUMENTATION, EXAMPLES, and RETURN are generated by +# ansible_specdoc. Do not edit them directly. + +DOCUMENTATION = ''' +author: Equinix DevRel Team (@equinix) +description: Manage project ssh key in Equinix Metal. Read more about personal and + project SSH keys in [Equinix Metal documentation](https://deploy.equinix.com/developers/docs/metal/accounts/ssh-keys/#personal-keys-vs-project-keys). + You can use *id* or *label* to lookup a project SSH key. If you want to create new + resource, you must provide *name*, *public_key* and *project_id*. +module: metal_project_ssh_key +notes: [] +options: + id: + description: + - UUID of the ssh_key. + required: false + type: str + name: + description: + - The name of the ssh_key. + required: false + type: str + project_id: + description: + - The ID of parent project. + required: false + type: str + public_key: + description: + - The public key of the project ssh_key. + required: false + type: str +requirements: null +short_description: Manage a project ssh key in Equinix Metal +''' +EXAMPLES = ''' +- name: Create new project project ssh_key + hosts: localhost + tasks: + - equinix.cloud.metal_project_ssh_key: + name: test_key + public_key: ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== + tomk@node + project_id: local.project_id +- name: Remove project ssh_key by id + hosts: localhost + tasks: + - equinix.cloud.metal_project_ssh_key: + id: eef49903-7a09-4ca1-af67-4087c29ab5b6 + state: absent +''' +RETURN = ''' +metal_project_ssh_key: + description: The module object + returned: always + sample: + - "\n{\n \"fingerprint\": \"98:9c:35:ed:f9:75:5b:52:e2:70:50:22:ea:77:5b:b6\",\n\ + \ \"id\": \"eef49903-7a09-4ca1-af67-4087c29ab5b6\",\n \"public_key\": \"ssh-dss\ + \ AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw==\ + \ tomk@xps\",\n \"name\": \"test_key\",\n \"project_id\": \"local.project_id\"\ + \n}\n" + type: dict +''' + +# End of generated documentation + +from ansible.module_utils._text import to_native +from ansible_specdoc.objects import ( + SpecField, + FieldType, + SpecReturnValue, +) +import traceback + +from ansible_collections.equinix.cloud.plugins.module_utils.equinix import ( + EquinixModule, + get_diff, + getSpecDocMeta, +) + + +MODULE_NAME = "metal_project_ssh_key" + +module_spec = dict( + id=SpecField( + type=FieldType.string, + description=["UUID of the ssh_key."], + ), + name=SpecField( + type=FieldType.string, + description=["The name of the ssh_key."], + editable=True, + ), + public_key=SpecField( + type=FieldType.string, + description=["The public key of the project ssh_key."], + editable=True, + ), + project_id=SpecField( + type=FieldType.string, + description=["The ID of parent project."], + editable=True, + ), +) + + +specdoc_examples = [ + """ +- name: Create new project project ssh_key + hosts: localhost + tasks: + - equinix.cloud.metal_project_ssh_key: + name: "test_key" + public_key: "ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@node" + project_id: "local.project_id" +""", + """ +- name: Remove project ssh_key by id + hosts: localhost + tasks: + - equinix.cloud.metal_project_ssh_key: + id: "eef49903-7a09-4ca1-af67-4087c29ab5b6" + state: absent +""", +] + +result_sample = [ + """ +{ + "fingerprint": "98:9c:35:ed:f9:75:5b:52:e2:70:50:22:ea:77:5b:b6", + "id": "eef49903-7a09-4ca1-af67-4087c29ab5b6", + "public_key": "ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@xps", + "name": "test_key", + "project_id": "local.project_id" +} +""" +] + +MUTABLE_ATTRIBUTES = [k for k, v in module_spec.items() if v.editable] + +SPECDOC_META = getSpecDocMeta( + short_description="Manage a project ssh key in Equinix Metal", + description=( + "Manage project ssh key in Equinix Metal. " + "Read more about personal and project SSH keys in [Equinix Metal documentation](https://deploy.equinix.com/developers/docs/metal/accounts/ssh-keys/#personal-keys-vs-project-keys). " + "You can use *id* or *label* to lookup a project SSH key. " + "If you want to create new resource, you must provide *name*, *public_key* and *project_id*." + ), + examples=specdoc_examples, + options=module_spec, + return_values={ + MODULE_NAME: SpecReturnValue( + description="The module object", + type=FieldType.dict, + sample=result_sample, + ), + }, +) + + +def main(): + module = EquinixModule( + argument_spec=SPECDOC_META.ansible_spec, + required_one_of=[("name", "id")], + required_together=[("name", "public_key", "project_id")], + ) + + state = module.params.get("state") + changed = False + + try: + module.params_syntax_check() + if module.params.get("id"): + tolerate_not_found = state == "absent" + fetched = module.get_by_id(MODULE_NAME, tolerate_not_found) + else: + fetched = module.get_one_from_list( + MODULE_NAME, + ["name"], + ) + + if fetched: + module.params["id"] = fetched["id"] + if state == "present": + diff = get_diff(module.params, fetched, MUTABLE_ATTRIBUTES) + if diff: + fetched = module.update_by_id(diff, MODULE_NAME) + changed = True + + else: + module.delete_by_id(MODULE_NAME) + changed = True + else: + if state == "present": + fetched = module.create(MODULE_NAME) + changed = True + else: + fetched = {} + except Exception as e: + tb = traceback.format_exc() + module.fail_json(msg=f"Error in {MODULE_NAME}: {to_native(e)}", exception=tb) + + fetched.update({"changed": changed}) + module.exit_json(**fetched) + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/metal_project_ssh_key_info.py b/plugins/modules/metal_project_ssh_key_info.py new file mode 100644 index 0000000..c45a719 --- /dev/null +++ b/plugins/modules/metal_project_ssh_key_info.py @@ -0,0 +1,140 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# DOCUMENTATION, EXAMPLES, and RETURN are generated by +# ansible_specdoc. Do not edit them directly. + +DOCUMENTATION = ''' +author: Equinix DevRel Team (@equinix) +description: Gather project SSH keys. Read more about project vs project SSH keys + in [Equinix Metal documentation](https://metal.equinix.com/developers/docs/accounts/ssh-keys/#personal-keys-vs-project-keys). +module: metal_project_ssh_key_info +notes: [] +options: + name: + description: + - Name to search for in existing keys. + required: true + type: str +requirements: null +short_description: Gather project SSH keys. +''' +EXAMPLES = ''' +- set_fact: + desired_name_substring: tkarasek +- name: list project ssh keys + equinix.cloud.metal_project_ssh_key_info: null + register: ssh_keys_listed +- name: filter found ssh keys + set_fact: + both_ssh_keys_listed: '{{ ssh_keys_listed.resources | selectattr(''name'', ''match'', + desired_name_substring) }}' +''' +RETURN = ''' +resources: + description: Found resources + returned: always + sample: + - "\n[\n {\n \"fingerprint\": \"70:c1:73:8b:3f:2f:a4:18:ea:4d:79:13:52:7b:c4:3e\"\ + ,\n \"id\": \"6edfcbc2-17e5-4221-9eac-2f40dbe60daf\",\n \"key\"\ + : \"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAt5gwVMhwcCrxyxpMEKwiS0xgit3PIIEgVXt6SQHc8eONq0mYJJ5TOBNTnySqXd9RtSv/Jbf5Aq9BzBGWeoZ6sZfKwh984Ip35StJtjXtyIOlY3skovndtupBIwlGXgX/WQzyLr+G/+Yu9/nhdxQi801PDZnDvKoeomM0rMD29nV+m0ud+GrtsAt6VFul2PxqpypZ1TYviyED6IKo7rgQsQDkE9QHcNdfT1FZWiJbfP7o8TIurQJcAXg+MtLoc8rKKcxFMeZ9FSydgtTC7nP1h558RtECGWiUgaBPI7TpBmcdMtbEfAiBoGT17GWnT8qmy2u5xnEKPD9Qft4w4fjfpw==\"\ + ,\n \"label\": \"tkarasek\",\n \"project_id\": local.project_id\n\ + \ },\n {\n \"fingerprint\": \"ba:70:af:b3:0f:0e:7f:e5:eb:97:e2:27:b1:f5:6f:94\"\ + ,\n \"id\": \"d00c596d-b42a-44a7-ac14-e299b85e73d3\",\n \"key\"\ + : \"ssh-dss AAAAB3NzaC1kc3MAAACBAOpXVtmc0Bla98bt0o5/Zj7sb4mHIukgVFZu7F32R3VK1cEKB4rEE8uS0oLS/qMRLue45TWVJwRMYGlPjt3p/VyraelxoyJZLuITIsqa5hBc9w0oTlB5Bmbkn16umW96WCaWEoq/aitpocbRChTiP5biI6FyQTQlIHDaYzBDOi11AAAAFQDUXy7cmuzphDpJSYYTiudiUhVokwAAAIEAyUQ9m8qL/1HPkFe6jbXAvtSSmW27F4c+G2xR5HizaHQzXgBOxPcsOsY17KTU+Ddbg+OF9soWNwSpm9pyVjVmNGqH3S8R1pwvuJF/O2Asy1m6wpWhbPw8JdEBW7WHoptBpfuzJoS2LOzJUEmUu4Eb+xS237KG1d1BVny/49KAoH0AAACBAJKBSsm9Xey0fUN6vYtTQgoYeGxxj/LqAIAOs/TpCxZDntly860y/SzHYai8x48k4t7whENY1CJ41fpMcPlz8xIsrNP3326Wbr0ExwOIvJKAVN1YLYqF8NXWzaVrjo5WbSeI8PiWTYemvLAujVxZssIrApTZBhp55nnwge6K1zTG\ + \ tomk@air\",\n \"label\": \"ansible-integration-test-ssh_key-ztiapihf-ssh_key1_renamed\"\ + ,\n \"project_id\": local.project_id\n }\n]\n" + type: dict +''' + +# End + +from ansible.module_utils._text import to_native +from ansible_specdoc.objects import SpecField, FieldType, SpecReturnValue +import traceback + +from ansible_collections.equinix.cloud.plugins.module_utils.equinix import ( + EquinixModule, + getSpecDocMeta, +) + +module_spec = dict( + name=SpecField( + type=FieldType.string, + description=["Name to search for in existing keys."], + required=True, + ), +) + +specdoc_examples = [ + """ + +- set_fact: + desired_name_substring: "tkarasek" + +- name: list project ssh keys + equinix.cloud.metal_project_ssh_key_info: + register: ssh_keys_listed + +- name: filter found ssh keys + set_fact: + both_ssh_keys_listed: "{{ ssh_keys_listed.resources | selectattr('name', 'match', desired_name_substring) }}" +""", +] + +result_sample = [ + """ +[ + { + "fingerprint": "70:c1:73:8b:3f:2f:a4:18:ea:4d:79:13:52:7b:c4:3e", + "id": "6edfcbc2-17e5-4221-9eac-2f40dbe60daf", + "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAt5gwVMhwcCrxyxpMEKwiS0xgit3PIIEgVXt6SQHc8eONq0mYJJ5TOBNTnySqXd9RtSv/Jbf5Aq9BzBGWeoZ6sZfKwh984Ip35StJtjXtyIOlY3skovndtupBIwlGXgX/WQzyLr+G/+Yu9/nhdxQi801PDZnDvKoeomM0rMD29nV+m0ud+GrtsAt6VFul2PxqpypZ1TYviyED6IKo7rgQsQDkE9QHcNdfT1FZWiJbfP7o8TIurQJcAXg+MtLoc8rKKcxFMeZ9FSydgtTC7nP1h558RtECGWiUgaBPI7TpBmcdMtbEfAiBoGT17GWnT8qmy2u5xnEKPD9Qft4w4fjfpw==", + "label": "tkarasek", + "project_id": local.project_id + }, + { + "fingerprint": "ba:70:af:b3:0f:0e:7f:e5:eb:97:e2:27:b1:f5:6f:94", + "id": "d00c596d-b42a-44a7-ac14-e299b85e73d3", + "key": "ssh-dss AAAAB3NzaC1kc3MAAACBAOpXVtmc0Bla98bt0o5/Zj7sb4mHIukgVFZu7F32R3VK1cEKB4rEE8uS0oLS/qMRLue45TWVJwRMYGlPjt3p/VyraelxoyJZLuITIsqa5hBc9w0oTlB5Bmbkn16umW96WCaWEoq/aitpocbRChTiP5biI6FyQTQlIHDaYzBDOi11AAAAFQDUXy7cmuzphDpJSYYTiudiUhVokwAAAIEAyUQ9m8qL/1HPkFe6jbXAvtSSmW27F4c+G2xR5HizaHQzXgBOxPcsOsY17KTU+Ddbg+OF9soWNwSpm9pyVjVmNGqH3S8R1pwvuJF/O2Asy1m6wpWhbPw8JdEBW7WHoptBpfuzJoS2LOzJUEmUu4Eb+xS237KG1d1BVny/49KAoH0AAACBAJKBSsm9Xey0fUN6vYtTQgoYeGxxj/LqAIAOs/TpCxZDntly860y/SzHYai8x48k4t7whENY1CJ41fpMcPlz8xIsrNP3326Wbr0ExwOIvJKAVN1YLYqF8NXWzaVrjo5WbSeI8PiWTYemvLAujVxZssIrApTZBhp55nnwge6K1zTG tomk@air", + "label": "ansible-integration-test-ssh_key-ztiapihf-ssh_key1_renamed", + "project_id": local.project_id + } +] +""", +] + +SPECDOC_META = getSpecDocMeta( + short_description="Gather project SSH keys.", + description=( + "Gather project SSH keys. Read more about project vs project SSH keys in [Equinix Metal documentation](https://metal.equinix.com/developers/docs/accounts/ssh-keys/#personal-keys-vs-project-keys)." + ), + examples=specdoc_examples, + options=module_spec, + return_values={ + "resources": SpecReturnValue( + description="Found resources", + type=FieldType.dict, + sample=result_sample, + ), + }, +) + + +def main(): + module = EquinixModule( + argument_spec=SPECDOC_META.ansible_spec, + is_info=True, + ) + try: + module.params_syntax_check() + return_value = {"resources": module.get_list("metal_project_ssh_key")} + except Exception as e: + tr = traceback.format_exc() + module.fail_json(msg=to_native(e), exception=tr) + module.exit_json(**return_value) + + +if __name__ == "__main__": + main() From 2b5027329c5e2eae3911d5a0ff6ac30a89fa211a Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Sun, 30 Jul 2023 16:03:53 +0200 Subject: [PATCH 02/10] make project_id unchangeble, add int test --- plugins/modules/metal_project_ssh_key.py | 2 +- .../targets/metal_project_ssh_key/main.yml | 114 ++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 tests/integration/targets/metal_project_ssh_key/main.yml diff --git a/plugins/modules/metal_project_ssh_key.py b/plugins/modules/metal_project_ssh_key.py index c57a4d2..e6b44d0 100644 --- a/plugins/modules/metal_project_ssh_key.py +++ b/plugins/modules/metal_project_ssh_key.py @@ -104,7 +104,7 @@ project_id=SpecField( type=FieldType.string, description=["The ID of parent project."], - editable=True, + editable=False, ), ) diff --git a/tests/integration/targets/metal_project_ssh_key/main.yml b/tests/integration/targets/metal_project_ssh_key/main.yml new file mode 100644 index 0000000..a8d2c9d --- /dev/null +++ b/tests/integration/targets/metal_project_ssh_key/main.yml @@ -0,0 +1,114 @@ +- name: metal_project_ssh_key + module_defaults: + equinix.cloud.metal_project_ssh_key: + metal_api_token: '{{ metal_api_token }}' + equinix.cloud.metal_device: + metal_api_token: '{{ metal_api_token }}' + equinix.cloud.metal_project_ssh_key_info: + metal_api_token: '{{ metal_api_token }}' + block: + - set_fact: + test_resource_name_prefix: 'ansible-integration-test-ssh_key' + - set_fact: + unique_id: "{{ lookup('community.general.random_string', upper=false, numbers=false, special=false) }}" + - set_fact: + test_prefix: "{{ test_resource_name_prefix }}-{{ unique_id }}" + - set_fact: + test_key: "ssh-dss AAAAB3NzaC1kc3MAAACBAOpXVtmc0Bla98bt0o5/Zj7sb4mHIukgVFZu7F32R3VK1cEKB4rEE8uS0oLS/qMRLue45TWVJwRMYGlPjt3p/VyraelxoyJZLuITIsqa5hBc9w0oTlB5Bmbkn16umW96WCaWEoq/aitpocbRChTiP5biI6FyQTQlIHDaYzBDOi11AAAAFQDUXy7cmuzphDpJSYYTiudiUhVokwAAAIEAyUQ9m8qL/1HPkFe6jbXAvtSSmW27F4c+G2xR5HizaHQzXgBOxPcsOsY17KTU+Ddbg+OF9soWNwSpm9pyVjVmNGqH3S8R1pwvuJF/O2Asy1m6wpWhbPw8JdEBW7WHoptBpfuzJoS2LOzJUEmUu4Eb+xS237KG1d1BVny/49KAoH0AAACBAJKBSsm9Xey0fUN6vYtTQgoYeGxxj/LqAIAOs/TpCxZDntly860y/SzHYai8x48k4t7whENY1CJ41fpMcPlz8xIsrNP3326Wbr0ExwOIvJKAVN1YLYqF8NXWzaVrjo5WbSeI8PiWTYemvLAujVxZssIrApTZBhp55nnwge6K1zTG tomk@air" + - set_fact: + test_key2: "ssh-dss AAAAB3NzaC1kc3MAAACBAPWcHWkA06LxBQ67WmNsp1+aZMwNNz9v67pftePlQg94Z1cU4s/5j5S/Fknj7gapWw/ouiOYqXhC2p/hC9/1ARY15t0aHYqLjRhWzs3j8miL1YyXYjqLPLDtgNpX9E09We5ogjbYCB8CCtZrujm/MB6NWvX+T4uG8C/g66I4/bGdAAAAFQDa4SS+q9aQK/XwiqnWpFpAEY74TQAAAIEAklEfXCf1qbUvTquHhtNVKTiKm+qGRsqxnLnu7aduzU81JDFzveF/agkE5x30olTvKECb1PAziDmt63z/obO3Da8TUz0QVdqv81pNWU5JUNiTB8d3rDJU3B66DA6GI305W8qyt0AGUNGR3rDIzNpZY958faBg+TaILRg8ZFNh0PAAAACAdUhJS6bl5M5sQr6XNilHa0nOTk/PB54faGWWMq7zQvxUKJKsDklNTc0MCPjRppyuokbQ6297tq8pEEFqUAyllMvAf75X7DsBQivLzbNuzp41NqFdS/Oka+T1ypRD7mT6g0Kg8yCVYD2ti874wyTpV9riUUaoItveEF3AdC9AzmI= tomk@air" + - set_fact: + project_id: "4394a515-846c-46ed-b0f5-8bfd09f2ea06" + + - name: create first project ssh_key for test + equinix.cloud.metal_project_ssh_key: + name: "{{ test_prefix }}-ssh_key1" + public_key: "{{ test_key }}" + project_id: "{{ project_id }}" + register: first_ssh_key + + - name: create first ssh_key for test again, to check idempotence + equinix.cloud.metal_project_ssh_key: + name: "{{ test_prefix }}-ssh_key1" + public_key: "{{ test_key }}" + project_id: "{{ project_id }}" + register: first_ssh_key_2 + + - assert: + that: + - first_ssh_key.name == '{{ test_prefix }}-ssh_key1' + - first_ssh_key.public_key == "{{ test_key }}" + - first_ssh_key.project_id == "{{ project_id }}" + - first_ssh_key_2.changed == false + + - name: update ssh_key name + equinix.cloud.metal_project_ssh_key: + id: "{{ first_ssh_key.id }}" + public_key: "{{ test_key }}" + name: "{{ test_prefix }}-ssh_key1_renamed" + + - name: fetch updated ssh_key + equinix.cloud.metal_project_ssh_key: + id: "{{ first_ssh_key.id }}" + register: first_ssh_key_updated + + - assert: + that: + - first_ssh_key_updated.name == '{{ test_prefix }}-ssh_key1_renamed' + - first_ssh_key.public_key == "{{ test_key }}" + + - name: create second ssh_key for test + equinix.cloud.metal_project_ssh_key: + name: "{{ test_prefix }}-ssh_key2" + public_key: "{{ test_key2 }}" + register: second_ssh_key + + - name: list ssh_keys + equinix.cloud.metal_project_ssh_key_info: + register: ssh_keys_listed + + - debug: + msg: "{{ ssh_keys_listed.resources }}" + + - debug: + msg: 'ssh_keys_listed.resources | selectattr("name", "equalto", "{{ test_prefix }}-ssh_key2")' + + - assert: + that: + - 'ssh_keys_listed.resources | selectattr("name", "equalto", "{{ test_prefix }}-ssh_key2") | length == 1' + + - name: list test ssh keys + set_fact: + both_ssh_keys_listed: "{{ ssh_keys_listed.resources | selectattr('name', 'match', test_prefix) }}" + + - assert: + that: + - "both_ssh_keys_listed | length == 2" + + - name: delete second ssh_key + equinix.cloud.metal_project_ssh_key: + id: "{{ second_ssh_key.id }}" + state: absent + + - name: check that deleting nonexistent resource doesn't err + equinix.cloud.metal_project_ssh_key: + id: "{{ second_ssh_key.id }}" + state: absent + + always: + - name: Announce teardown start + debug: + msg: "***** TESTING COMPLETE. COMMENCE TEARDOWN *****" + + - name: list ssh_keys + equinix.cloud.metal_project_ssh_key_info: + register: ssh_keys_listed + + - name: delete test ssh_keys + equinix.cloud.metal_project_ssh_key: + id: "{{ item.id }}" + state: absent + loop: "{{ ssh_keys_listed.resources }}" + when: "test_prefix in item.name" + ignore_errors: yes + From bb2ac56d99c270a975df0f14ba3c3bc2b51a69ec Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Sun, 30 Jul 2023 17:46:21 +0200 Subject: [PATCH 03/10] rename name and public key to match personal ssh key format, add routers, update readme --- README.md | 5 ++- plugins/module_utils/metal/api_routes.py | 19 +++++++++++ plugins/module_utils/metal/metal_api.py | 1 + plugins/modules/metal_project_ssh_key.py | 20 +++++------ plugins/modules/metal_project_ssh_key_info.py | 4 +-- .../targets/metal_project_ssh_key/main.yml | 34 +++++++++---------- 6 files changed, 53 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 9b1e215..68b9ca8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Equinix Ansible Collection -[![Ansible Galaxy](https://img.shields.io/badge/galaxy-equinix.cloud-660198.svg?style=flat)](https://galaxy.ansible.com/equinix/cloud/) +[![Ansible Galaxy](https://img.shields.io/badge/galaxy-equinix.cloud-660198.svg?style=flat)](https://galaxy.ansible.com/equinix/cloud/) ![Tests](https://img.shields.io/github/actions/workflow/status/equinix-labs/ansible-collection-equinix/integration-tests.yml?branch=main) The Ansible Collection Equinix contains various plugins for managing Equinix services. @@ -29,6 +29,7 @@ Name | Description | [equinix.cloud.metal_project_ssh_key](./docs/modules/metal_project_ssh_key.md)|Manage a project ssh key in Equinix Metal| [equinix.cloud.metal_reserved_ip_block](./docs/modules/metal_reserved_ip_block.md)|Create/delete blocks of reserved IP addresses in a project.| [equinix.cloud.metal_ssh_key](./docs/modules/metal_ssh_key.md)|Manage personal SSH keys in Equinix Metal| +[equinix.cloud.metal_project_ssh_key](./docs/modules/metal_project_ssh_key.md)|Manage project SSH keys in Equinix Metal| ### Info Modules @@ -48,6 +49,8 @@ Name | Description | [equinix.cloud.metal_project_ssh_key_info](./docs/modules/metal_project_ssh_key_info.md)|Gather project SSH keys.| [equinix.cloud.metal_reserved_ip_block_info](./docs/modules/metal_reserved_ip_block_info.md)|Gather list of reserved IP blocks| [equinix.cloud.metal_ssh_key_info](./docs/modules/metal_ssh_key_info.md)|Gather personal SSH keys| +list project SSH keys +[equinix.cloud.metal_project_ssh_key_info](./docs/modules/metal_project_ssh_key_info.md)|Gather project SSH keys| ### Inventory Plugins diff --git a/plugins/module_utils/metal/api_routes.py b/plugins/module_utils/metal/api_routes.py index 0a64b62..2936719 100644 --- a/plugins/module_utils/metal/api_routes.py +++ b/plugins/module_utils/metal/api_routes.py @@ -50,6 +50,9 @@ def get_routes(mpc): ('metal_ssh_key', action.GET): spec_types.Specs( equinix_metal.SSHKeysApi(mpc).find_ssh_key_by_id, ), + ('metal_project_ssh_key', action.GET): spec_types.Specs( + equinix_metal.SSHKeysApi(mpc).find_ssh_key_by_id, + ), ('metal_hardware_reservation', action.GET): spec_types.Specs( equinix_metal.HardwareReservationsApi(mpc).find_hardware_reservation_by_id, ), @@ -88,6 +91,9 @@ def get_routes(mpc): ('metal_ssh_key', action.LIST): spec_types.Specs( equinix_metal.SSHKeysApi(mpc).find_ssh_keys, ), + ('metal_project_ssh_key', action.LIST): spec_types.Specs( + equinix_metal.SSHKeysApi(mpc).find_project_ssh_keys, + ), ('metal_organization', action.LIST): spec_types.Specs( equinix_metal.OrganizationsApi(mpc).find_organizations, {'personal': 'personal', 'with_projects': 'with_projects'}, @@ -119,6 +125,9 @@ def get_routes(mpc): ('metal_ssh_key', action.DELETE): spec_types.Specs( equinix_metal.SSHKeysApi(mpc).delete_ssh_key, ), + ('metal_project_ssh_key', action.DELETE): spec_types.Specs( + equinix_metal.SSHKeysApi(mpc).delete_ssh_key, + ), # CREATORS @@ -152,6 +161,11 @@ def get_routes(mpc): {}, equinix_metal.SSHKeyCreateInput, ), + ('metal_project_ssh_key', action.CREATE): spec_types.Specs( + equinix_metal.SSHKeysApi(mpc).create_project_ssh_key, + {}, + equinix_metal.SSHKeyCreateInput, + ), # UPDATERS ('metal_device', action.UPDATE): spec_types.Specs( @@ -174,4 +188,9 @@ def get_routes(mpc): {}, equinix_metal.SSHKeyInput, ), + ('metal_ssh_key', action.UPDATE): spec_types.Specs( + equinix_metal.SSHKeysApi(mpc).update_ssh_key, + {}, + equinix_metal.SSHKeyInput, + ), } diff --git a/plugins/module_utils/metal/metal_api.py b/plugins/module_utils/metal/metal_api.py index 2e4bb0a..70f4811 100644 --- a/plugins/module_utils/metal/metal_api.py +++ b/plugins/module_utils/metal/metal_api.py @@ -166,6 +166,7 @@ def get_assignment_address(resource: dict): 'label': 'label', 'key': 'key', 'fingerprint': 'fingerprint', + 'project_id': optional_str('project_id'), } diff --git a/plugins/modules/metal_project_ssh_key.py b/plugins/modules/metal_project_ssh_key.py index e6b44d0..a47c27d 100644 --- a/plugins/modules/metal_project_ssh_key.py +++ b/plugins/modules/metal_project_ssh_key.py @@ -91,12 +91,12 @@ type=FieldType.string, description=["UUID of the ssh_key."], ), - name=SpecField( + label=SpecField( type=FieldType.string, description=["The name of the ssh_key."], editable=True, ), - public_key=SpecField( + key=SpecField( type=FieldType.string, description=["The public key of the project ssh_key."], editable=True, @@ -115,8 +115,8 @@ hosts: localhost tasks: - equinix.cloud.metal_project_ssh_key: - name: "test_key" - public_key: "ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@node" + label: "test_key" + key: "ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@node" project_id: "local.project_id" """, """ @@ -134,8 +134,8 @@ { "fingerprint": "98:9c:35:ed:f9:75:5b:52:e2:70:50:22:ea:77:5b:b6", "id": "eef49903-7a09-4ca1-af67-4087c29ab5b6", - "public_key": "ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@xps", - "name": "test_key", + "key": "ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@xps", + "label": "test_key", "project_id": "local.project_id" } """ @@ -149,7 +149,7 @@ "Manage project ssh key in Equinix Metal. " "Read more about personal and project SSH keys in [Equinix Metal documentation](https://deploy.equinix.com/developers/docs/metal/accounts/ssh-keys/#personal-keys-vs-project-keys). " "You can use *id* or *label* to lookup a project SSH key. " - "If you want to create new resource, you must provide *name*, *public_key* and *project_id*." + "If you want to create new resource, you must provide *label*, *key* and *project_id*." ), examples=specdoc_examples, options=module_spec, @@ -166,8 +166,8 @@ def main(): module = EquinixModule( argument_spec=SPECDOC_META.ansible_spec, - required_one_of=[("name", "id")], - required_together=[("name", "public_key", "project_id")], + required_one_of=[("label", "id")], + required_together=[("label", "key", "project_id")], ) state = module.params.get("state") @@ -181,7 +181,7 @@ def main(): else: fetched = module.get_one_from_list( MODULE_NAME, - ["name"], + ["label"], ) if fetched: diff --git a/plugins/modules/metal_project_ssh_key_info.py b/plugins/modules/metal_project_ssh_key_info.py index c45a719..f2e243e 100644 --- a/plugins/modules/metal_project_ssh_key_info.py +++ b/plugins/modules/metal_project_ssh_key_info.py @@ -61,7 +61,7 @@ ) module_spec = dict( - name=SpecField( + label=SpecField( type=FieldType.string, description=["Name to search for in existing keys."], required=True, @@ -80,7 +80,7 @@ - name: filter found ssh keys set_fact: - both_ssh_keys_listed: "{{ ssh_keys_listed.resources | selectattr('name', 'match', desired_name_substring) }}" + both_ssh_keys_listed: "{{ ssh_keys_listed.resources | selectattr('label', 'match', desired_name_substring) }}" """, ] diff --git a/tests/integration/targets/metal_project_ssh_key/main.yml b/tests/integration/targets/metal_project_ssh_key/main.yml index a8d2c9d..28dae0d 100644 --- a/tests/integration/targets/metal_project_ssh_key/main.yml +++ b/tests/integration/targets/metal_project_ssh_key/main.yml @@ -22,30 +22,30 @@ - name: create first project ssh_key for test equinix.cloud.metal_project_ssh_key: - name: "{{ test_prefix }}-ssh_key1" - public_key: "{{ test_key }}" + label: "{{ test_prefix }}-ssh_key1" + key: "{{ test_key }}" project_id: "{{ project_id }}" register: first_ssh_key - name: create first ssh_key for test again, to check idempotence equinix.cloud.metal_project_ssh_key: - name: "{{ test_prefix }}-ssh_key1" - public_key: "{{ test_key }}" + label: "{{ test_prefix }}-ssh_key1" + key: "{{ test_key }}" project_id: "{{ project_id }}" register: first_ssh_key_2 - assert: that: - - first_ssh_key.name == '{{ test_prefix }}-ssh_key1' - - first_ssh_key.public_key == "{{ test_key }}" + - first_ssh_key.label == '{{ test_prefix }}-ssh_key1' + - first_ssh_key.key == "{{ test_key }}" - first_ssh_key.project_id == "{{ project_id }}" - first_ssh_key_2.changed == false - - name: update ssh_key name + - name: update ssh_key label equinix.cloud.metal_project_ssh_key: id: "{{ first_ssh_key.id }}" - public_key: "{{ test_key }}" - name: "{{ test_prefix }}-ssh_key1_renamed" + key: "{{ test_key }}" + label: "{{ test_prefix }}-ssh_key1_renamed" - name: fetch updated ssh_key equinix.cloud.metal_project_ssh_key: @@ -54,13 +54,13 @@ - assert: that: - - first_ssh_key_updated.name == '{{ test_prefix }}-ssh_key1_renamed' - - first_ssh_key.public_key == "{{ test_key }}" + - first_ssh_key_updated.label == '{{ test_prefix }}-ssh_key1_renamed' + - first_ssh_key.key == "{{ test_key }}" - name: create second ssh_key for test equinix.cloud.metal_project_ssh_key: - name: "{{ test_prefix }}-ssh_key2" - public_key: "{{ test_key2 }}" + label: "{{ test_prefix }}-ssh_key2" + key: "{{ test_key2 }}" register: second_ssh_key - name: list ssh_keys @@ -71,15 +71,15 @@ msg: "{{ ssh_keys_listed.resources }}" - debug: - msg: 'ssh_keys_listed.resources | selectattr("name", "equalto", "{{ test_prefix }}-ssh_key2")' + msg: 'ssh_keys_listed.resources | selectattr("label", "equalto", "{{ test_prefix }}-ssh_key2")' - assert: that: - - 'ssh_keys_listed.resources | selectattr("name", "equalto", "{{ test_prefix }}-ssh_key2") | length == 1' + - 'ssh_keys_listed.resources | selectattr("label", "equalto", "{{ test_prefix }}-ssh_key2") | length == 1' - name: list test ssh keys set_fact: - both_ssh_keys_listed: "{{ ssh_keys_listed.resources | selectattr('name', 'match', test_prefix) }}" + both_ssh_keys_listed: "{{ ssh_keys_listed.resources | selectattr('label', 'match', test_prefix) }}" - assert: that: @@ -109,6 +109,6 @@ id: "{{ item.id }}" state: absent loop: "{{ ssh_keys_listed.resources }}" - when: "test_prefix in item.name" + when: "test_prefix in item.label" ignore_errors: yes From 3795eaa7c21c8b127fe7c60686e6f1527acf19c5 Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Tue, 1 Aug 2023 13:37:52 +0200 Subject: [PATCH 04/10] create new project for integration tests, fix some issues --- plugins/module_utils/metal/api_routes.py | 5 ++-- plugins/module_utils/metal/metal_api.py | 1 - plugins/modules/metal_project_ssh_key.py | 8 +++--- plugins/modules/metal_project_ssh_key_info.py | 2 +- tests/integration/inventory | 2 +- .../targets/metal_project/tasks/main.yml | 6 ++--- .../{ => tasks}/main.yml | 26 +++++++++++++++---- 7 files changed, 34 insertions(+), 16 deletions(-) rename tests/integration/targets/metal_project_ssh_key/{ => tasks}/main.yml (87%) diff --git a/plugins/module_utils/metal/api_routes.py b/plugins/module_utils/metal/api_routes.py index 2936719..eca1c68 100644 --- a/plugins/module_utils/metal/api_routes.py +++ b/plugins/module_utils/metal/api_routes.py @@ -93,6 +93,7 @@ def get_routes(mpc): ), ('metal_project_ssh_key', action.LIST): spec_types.Specs( equinix_metal.SSHKeysApi(mpc).find_project_ssh_keys, + {'id': 'project_id'} ), ('metal_organization', action.LIST): spec_types.Specs( equinix_metal.OrganizationsApi(mpc).find_organizations, @@ -163,7 +164,7 @@ def get_routes(mpc): ), ('metal_project_ssh_key', action.CREATE): spec_types.Specs( equinix_metal.SSHKeysApi(mpc).create_project_ssh_key, - {}, + {'id': 'project_id'}, equinix_metal.SSHKeyCreateInput, ), @@ -188,7 +189,7 @@ def get_routes(mpc): {}, equinix_metal.SSHKeyInput, ), - ('metal_ssh_key', action.UPDATE): spec_types.Specs( + ('metal_project_ssh_key', action.UPDATE): spec_types.Specs( equinix_metal.SSHKeysApi(mpc).update_ssh_key, {}, equinix_metal.SSHKeyInput, diff --git a/plugins/module_utils/metal/metal_api.py b/plugins/module_utils/metal/metal_api.py index 70f4811..2e4bb0a 100644 --- a/plugins/module_utils/metal/metal_api.py +++ b/plugins/module_utils/metal/metal_api.py @@ -166,7 +166,6 @@ def get_assignment_address(resource: dict): 'label': 'label', 'key': 'key', 'fingerprint': 'fingerprint', - 'project_id': optional_str('project_id'), } diff --git a/plugins/modules/metal_project_ssh_key.py b/plugins/modules/metal_project_ssh_key.py index a47c27d..b9b3d56 100644 --- a/plugins/modules/metal_project_ssh_key.py +++ b/plugins/modules/metal_project_ssh_key.py @@ -167,9 +167,11 @@ def main(): module = EquinixModule( argument_spec=SPECDOC_META.ansible_spec, required_one_of=[("label", "id")], - required_together=[("label", "key", "project_id")], + required_together=[("label", "key")], ) - + print("!!!!!!!!!!!!!") + print(module) + print("!!!!!!!!!!!!!") state = module.params.get("state") changed = False @@ -181,7 +183,7 @@ def main(): else: fetched = module.get_one_from_list( MODULE_NAME, - ["label"], + ["key"], ) if fetched: diff --git a/plugins/modules/metal_project_ssh_key_info.py b/plugins/modules/metal_project_ssh_key_info.py index f2e243e..37692ae 100644 --- a/plugins/modules/metal_project_ssh_key_info.py +++ b/plugins/modules/metal_project_ssh_key_info.py @@ -111,7 +111,7 @@ "Gather project SSH keys. Read more about project vs project SSH keys in [Equinix Metal documentation](https://metal.equinix.com/developers/docs/accounts/ssh-keys/#personal-keys-vs-project-keys)." ), examples=specdoc_examples, - options=module_spec, + options={}, return_values={ "resources": SpecReturnValue( description="Found resources", diff --git a/tests/integration/inventory b/tests/integration/inventory index 7c937f8..848b923 100644 --- a/tests/integration/inventory +++ b/tests/integration/inventory @@ -1,2 +1,2 @@ [testgroup] -testhost ansible_connection="local" ansible_pipelining="yes" ansible_python_interpreter="/usr/bin/python3" +testhost ansible_connection="local" ansible_pipelining="yes" ansible_python_interpreter="/mnt/c/Users/sani/code/python-env/ans/bin/python" diff --git a/tests/integration/targets/metal_project/tasks/main.yml b/tests/integration/targets/metal_project/tasks/main.yml index de41a4e..dc78a74 100644 --- a/tests/integration/targets/metal_project/tasks/main.yml +++ b/tests/integration/targets/metal_project/tasks/main.yml @@ -60,13 +60,13 @@ - assert: that: - - "second_project_listed.resources | length == 1" + - "second_project_listed.resources | length == 1" - name: list both projects equinix.cloud.metal_project_info: name: "{{ test_prefix }}" register: both_projects_listed - + - assert: that: - "both_projects_listed.resources | length == 2" @@ -80,7 +80,7 @@ equinix.cloud.metal_project: id: "{{ second_project.id }}" state: absent - + always: - name: Announce teardown start debug: diff --git a/tests/integration/targets/metal_project_ssh_key/main.yml b/tests/integration/targets/metal_project_ssh_key/tasks/main.yml similarity index 87% rename from tests/integration/targets/metal_project_ssh_key/main.yml rename to tests/integration/targets/metal_project_ssh_key/tasks/main.yml index 28dae0d..4217cda 100644 --- a/tests/integration/targets/metal_project_ssh_key/main.yml +++ b/tests/integration/targets/metal_project_ssh_key/tasks/main.yml @@ -6,6 +6,8 @@ metal_api_token: '{{ metal_api_token }}' equinix.cloud.metal_project_ssh_key_info: metal_api_token: '{{ metal_api_token }}' + equinix.cloud.metal_project: + metal_api_token: '{{ metal_api_token }}' block: - set_fact: test_resource_name_prefix: 'ansible-integration-test-ssh_key' @@ -17,28 +19,34 @@ test_key: "ssh-dss AAAAB3NzaC1kc3MAAACBAOpXVtmc0Bla98bt0o5/Zj7sb4mHIukgVFZu7F32R3VK1cEKB4rEE8uS0oLS/qMRLue45TWVJwRMYGlPjt3p/VyraelxoyJZLuITIsqa5hBc9w0oTlB5Bmbkn16umW96WCaWEoq/aitpocbRChTiP5biI6FyQTQlIHDaYzBDOi11AAAAFQDUXy7cmuzphDpJSYYTiudiUhVokwAAAIEAyUQ9m8qL/1HPkFe6jbXAvtSSmW27F4c+G2xR5HizaHQzXgBOxPcsOsY17KTU+Ddbg+OF9soWNwSpm9pyVjVmNGqH3S8R1pwvuJF/O2Asy1m6wpWhbPw8JdEBW7WHoptBpfuzJoS2LOzJUEmUu4Eb+xS237KG1d1BVny/49KAoH0AAACBAJKBSsm9Xey0fUN6vYtTQgoYeGxxj/LqAIAOs/TpCxZDntly860y/SzHYai8x48k4t7whENY1CJ41fpMcPlz8xIsrNP3326Wbr0ExwOIvJKAVN1YLYqF8NXWzaVrjo5WbSeI8PiWTYemvLAujVxZssIrApTZBhp55nnwge6K1zTG tomk@air" - set_fact: test_key2: "ssh-dss AAAAB3NzaC1kc3MAAACBAPWcHWkA06LxBQ67WmNsp1+aZMwNNz9v67pftePlQg94Z1cU4s/5j5S/Fknj7gapWw/ouiOYqXhC2p/hC9/1ARY15t0aHYqLjRhWzs3j8miL1YyXYjqLPLDtgNpX9E09We5ogjbYCB8CCtZrujm/MB6NWvX+T4uG8C/g66I4/bGdAAAAFQDa4SS+q9aQK/XwiqnWpFpAEY74TQAAAIEAklEfXCf1qbUvTquHhtNVKTiKm+qGRsqxnLnu7aduzU81JDFzveF/agkE5x30olTvKECb1PAziDmt63z/obO3Da8TUz0QVdqv81pNWU5JUNiTB8d3rDJU3B66DA6GI305W8qyt0AGUNGR3rDIzNpZY958faBg+TaILRg8ZFNh0PAAAACAdUhJS6bl5M5sQr6XNilHa0nOTk/PB54faGWWMq7zQvxUKJKsDklNTc0MCPjRppyuokbQ6297tq8pEEFqUAyllMvAf75X7DsBQivLzbNuzp41NqFdS/Oka+T1ypRD7mT6g0Kg8yCVYD2ti874wyTpV9riUUaoItveEF3AdC9AzmI= tomk@air" - - set_fact: - project_id: "4394a515-846c-46ed-b0f5-8bfd09f2ea06" + + - name: create project for test + equinix.cloud.metal_project: + name: "{{ test_prefix }}-project" + register: project + + - assert: + that: + - project.name == '{{ test_prefix }}-project' - name: create first project ssh_key for test equinix.cloud.metal_project_ssh_key: label: "{{ test_prefix }}-ssh_key1" key: "{{ test_key }}" - project_id: "{{ project_id }}" + project_id: "{{ project.id }}" register: first_ssh_key - name: create first ssh_key for test again, to check idempotence equinix.cloud.metal_project_ssh_key: label: "{{ test_prefix }}-ssh_key1" key: "{{ test_key }}" - project_id: "{{ project_id }}" + project_id: "{{ project.id }}" register: first_ssh_key_2 - assert: that: - first_ssh_key.label == '{{ test_prefix }}-ssh_key1' - first_ssh_key.key == "{{ test_key }}" - - first_ssh_key.project_id == "{{ project_id }}" - first_ssh_key_2.changed == false - name: update ssh_key label @@ -61,6 +69,7 @@ equinix.cloud.metal_project_ssh_key: label: "{{ test_prefix }}-ssh_key2" key: "{{ test_key2 }}" + project_id: "{{ project.id }}" register: second_ssh_key - name: list ssh_keys @@ -107,8 +116,15 @@ - name: delete test ssh_keys equinix.cloud.metal_project_ssh_key: id: "{{ item.id }}" + project_id: "{{ project.id }}" state: absent loop: "{{ ssh_keys_listed.resources }}" when: "test_prefix in item.label" ignore_errors: yes + - name: delete test projects + equinix.cloud.metal_project: + id: "{{ item.id }}" + state: absent + loop: "{{ test_projects_listed.resources }}" + ignore_errors: yes From 18fa14135d40c87c6a66103182ea333a41a4dd02 Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Tue, 1 Aug 2023 14:50:36 +0200 Subject: [PATCH 05/10] remove projects after test run --- plugins/modules/metal_project_ssh_key_info.py | 9 +++++++-- .../targets/metal_project_ssh_key/tasks/main.yml | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/plugins/modules/metal_project_ssh_key_info.py b/plugins/modules/metal_project_ssh_key_info.py index 37692ae..0966723 100644 --- a/plugins/modules/metal_project_ssh_key_info.py +++ b/plugins/modules/metal_project_ssh_key_info.py @@ -64,7 +64,12 @@ label=SpecField( type=FieldType.string, description=["Name to search for in existing keys."], - required=True, + required=False, + ), + project_id=SpecField( + type=FieldType.string, + description=["Name of the project for listing project keys."], + required=False, ), ) @@ -111,7 +116,7 @@ "Gather project SSH keys. Read more about project vs project SSH keys in [Equinix Metal documentation](https://metal.equinix.com/developers/docs/accounts/ssh-keys/#personal-keys-vs-project-keys)." ), examples=specdoc_examples, - options={}, + options=module_spec, return_values={ "resources": SpecReturnValue( description="Found resources", diff --git a/tests/integration/targets/metal_project_ssh_key/tasks/main.yml b/tests/integration/targets/metal_project_ssh_key/tasks/main.yml index 4217cda..0aa475e 100644 --- a/tests/integration/targets/metal_project_ssh_key/tasks/main.yml +++ b/tests/integration/targets/metal_project_ssh_key/tasks/main.yml @@ -6,8 +6,11 @@ metal_api_token: '{{ metal_api_token }}' equinix.cloud.metal_project_ssh_key_info: metal_api_token: '{{ metal_api_token }}' + metal_ua_prefix: '{{ metal_ua_prefix }}' equinix.cloud.metal_project: metal_api_token: '{{ metal_api_token }}' + equinix.cloud.metal_project_info: + metal_api_token: '{{ metal_api_token }}' block: - set_fact: test_resource_name_prefix: 'ansible-integration-test-ssh_key' @@ -74,6 +77,7 @@ - name: list ssh_keys equinix.cloud.metal_project_ssh_key_info: + project_id: "{{ project.id }}" register: ssh_keys_listed - debug: @@ -111,6 +115,7 @@ - name: list ssh_keys equinix.cloud.metal_project_ssh_key_info: + project_id: "{{ project.id }}" register: ssh_keys_listed - name: delete test ssh_keys @@ -122,6 +127,11 @@ when: "test_prefix in item.label" ignore_errors: yes + - name: list test projects + equinix.cloud.metal_project_info: + name: "{{ test_prefix }}" + register: test_projects_listed + - name: delete test projects equinix.cloud.metal_project: id: "{{ item.id }}" From 0ecc08823c87d0b11505387b7a9ba5fac097de7e Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Tue, 1 Aug 2023 15:15:10 +0200 Subject: [PATCH 06/10] fix tests inventory -> remove my namespace --- tests/integration/inventory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/inventory b/tests/integration/inventory index 848b923..7c937f8 100644 --- a/tests/integration/inventory +++ b/tests/integration/inventory @@ -1,2 +1,2 @@ [testgroup] -testhost ansible_connection="local" ansible_pipelining="yes" ansible_python_interpreter="/mnt/c/Users/sani/code/python-env/ans/bin/python" +testhost ansible_connection="local" ansible_pipelining="yes" ansible_python_interpreter="/usr/bin/python3" From c48701273aa607d3a7562e00a593d09ec93c5c53 Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Wed, 2 Aug 2023 19:58:22 +0200 Subject: [PATCH 07/10] address PR remarks --- README.md | 3 +-- plugins/module_utils/metal/api_routes.py | 7 ------- plugins/modules/metal_project_ssh_key.py | 20 +++++++++---------- plugins/modules/metal_project_ssh_key_info.py | 8 ++++---- 4 files changed, 14 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 68b9ca8..3042fb3 100644 --- a/README.md +++ b/README.md @@ -48,8 +48,7 @@ Name | Description | [equinix.cloud.metal_project_info](./docs/modules/metal_project_info.md)|Gather information about Equinix Metal projects| [equinix.cloud.metal_project_ssh_key_info](./docs/modules/metal_project_ssh_key_info.md)|Gather project SSH keys.| [equinix.cloud.metal_reserved_ip_block_info](./docs/modules/metal_reserved_ip_block_info.md)|Gather list of reserved IP blocks| -[equinix.cloud.metal_ssh_key_info](./docs/modules/metal_ssh_key_info.md)|Gather personal SSH keys| -list project SSH keys +[equinix.cloud.metal_ssh_key_info](./docs/modules/metal_ssh_key_info.md)|Gather personal SSH keys|list project SSH keys [equinix.cloud.metal_project_ssh_key_info](./docs/modules/metal_project_ssh_key_info.md)|Gather project SSH keys| diff --git a/plugins/module_utils/metal/api_routes.py b/plugins/module_utils/metal/api_routes.py index eca1c68..6dfd17d 100644 --- a/plugins/module_utils/metal/api_routes.py +++ b/plugins/module_utils/metal/api_routes.py @@ -50,9 +50,6 @@ def get_routes(mpc): ('metal_ssh_key', action.GET): spec_types.Specs( equinix_metal.SSHKeysApi(mpc).find_ssh_key_by_id, ), - ('metal_project_ssh_key', action.GET): spec_types.Specs( - equinix_metal.SSHKeysApi(mpc).find_ssh_key_by_id, - ), ('metal_hardware_reservation', action.GET): spec_types.Specs( equinix_metal.HardwareReservationsApi(mpc).find_hardware_reservation_by_id, ), @@ -126,10 +123,6 @@ def get_routes(mpc): ('metal_ssh_key', action.DELETE): spec_types.Specs( equinix_metal.SSHKeysApi(mpc).delete_ssh_key, ), - ('metal_project_ssh_key', action.DELETE): spec_types.Specs( - equinix_metal.SSHKeysApi(mpc).delete_ssh_key, - ), - # CREATORS ('metal_device', action.CREATE): spec_types.Specs( diff --git a/plugins/modules/metal_project_ssh_key.py b/plugins/modules/metal_project_ssh_key.py index b9b3d56..695b531 100644 --- a/plugins/modules/metal_project_ssh_key.py +++ b/plugins/modules/metal_project_ssh_key.py @@ -46,7 +46,7 @@ name: test_key public_key: ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@node - project_id: local.project_id + project_id: b8c6c653-3c96-446e-987e-9c4d12f25353 - name: Remove project ssh_key by id hosts: localhost tasks: @@ -62,7 +62,7 @@ - "\n{\n \"fingerprint\": \"98:9c:35:ed:f9:75:5b:52:e2:70:50:22:ea:77:5b:b6\",\n\ \ \"id\": \"eef49903-7a09-4ca1-af67-4087c29ab5b6\",\n \"public_key\": \"ssh-dss\ \ AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw==\ - \ tomk@xps\",\n \"name\": \"test_key\",\n \"project_id\": \"local.project_id\"\ + \ tomk@xps\",\n \"name\": \"test_key\",\n \"project_id\": \"b8c6c653-3c96-446e-987e-9c4d12f25353\"\ \n}\n" type: dict ''' @@ -85,6 +85,7 @@ MODULE_NAME = "metal_project_ssh_key" +METAL_SSH_KEY = "metal_ssh_key" module_spec = dict( id=SpecField( @@ -117,7 +118,7 @@ - equinix.cloud.metal_project_ssh_key: label: "test_key" key: "ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@node" - project_id: "local.project_id" + project_id: "b8c6c653-3c96-446e-987e-9c4d12f25353" """, """ - name: Remove project ssh_key by id @@ -136,7 +137,7 @@ "id": "eef49903-7a09-4ca1-af67-4087c29ab5b6", "key": "ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@xps", "label": "test_key", - "project_id": "local.project_id" + "project_id": "b8c6c653-3c96-446e-987e-9c4d12f25353" } """ ] @@ -169,9 +170,6 @@ def main(): required_one_of=[("label", "id")], required_together=[("label", "key")], ) - print("!!!!!!!!!!!!!") - print(module) - print("!!!!!!!!!!!!!") state = module.params.get("state") changed = False @@ -179,10 +177,10 @@ def main(): module.params_syntax_check() if module.params.get("id"): tolerate_not_found = state == "absent" - fetched = module.get_by_id(MODULE_NAME, tolerate_not_found) + fetched = module.get_by_id(METAL_SSH_KEY, tolerate_not_found) else: fetched = module.get_one_from_list( - MODULE_NAME, + METAL_SSH_KEY, ["key"], ) @@ -191,11 +189,11 @@ def main(): if state == "present": diff = get_diff(module.params, fetched, MUTABLE_ATTRIBUTES) if diff: - fetched = module.update_by_id(diff, MODULE_NAME) + fetched = module.update_by_id(diff, METAL_SSH_KEY) changed = True else: - module.delete_by_id(MODULE_NAME) + module.delete_by_id(METAL_SSH_KEY) changed = True else: if state == "present": diff --git a/plugins/modules/metal_project_ssh_key_info.py b/plugins/modules/metal_project_ssh_key_info.py index 0966723..46d5e64 100644 --- a/plugins/modules/metal_project_ssh_key_info.py +++ b/plugins/modules/metal_project_ssh_key_info.py @@ -40,12 +40,12 @@ - "\n[\n {\n \"fingerprint\": \"70:c1:73:8b:3f:2f:a4:18:ea:4d:79:13:52:7b:c4:3e\"\ ,\n \"id\": \"6edfcbc2-17e5-4221-9eac-2f40dbe60daf\",\n \"key\"\ : \"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAt5gwVMhwcCrxyxpMEKwiS0xgit3PIIEgVXt6SQHc8eONq0mYJJ5TOBNTnySqXd9RtSv/Jbf5Aq9BzBGWeoZ6sZfKwh984Ip35StJtjXtyIOlY3skovndtupBIwlGXgX/WQzyLr+G/+Yu9/nhdxQi801PDZnDvKoeomM0rMD29nV+m0ud+GrtsAt6VFul2PxqpypZ1TYviyED6IKo7rgQsQDkE9QHcNdfT1FZWiJbfP7o8TIurQJcAXg+MtLoc8rKKcxFMeZ9FSydgtTC7nP1h558RtECGWiUgaBPI7TpBmcdMtbEfAiBoGT17GWnT8qmy2u5xnEKPD9Qft4w4fjfpw==\"\ - ,\n \"label\": \"tkarasek\",\n \"project_id\": local.project_id\n\ + ,\n \"label\": \"tkarasek\",\n \"project_id\": b8c6c653-3c96-446e-987e-9c4d12f25353\n\ \ },\n {\n \"fingerprint\": \"ba:70:af:b3:0f:0e:7f:e5:eb:97:e2:27:b1:f5:6f:94\"\ ,\n \"id\": \"d00c596d-b42a-44a7-ac14-e299b85e73d3\",\n \"key\"\ : \"ssh-dss AAAAB3NzaC1kc3MAAACBAOpXVtmc0Bla98bt0o5/Zj7sb4mHIukgVFZu7F32R3VK1cEKB4rEE8uS0oLS/qMRLue45TWVJwRMYGlPjt3p/VyraelxoyJZLuITIsqa5hBc9w0oTlB5Bmbkn16umW96WCaWEoq/aitpocbRChTiP5biI6FyQTQlIHDaYzBDOi11AAAAFQDUXy7cmuzphDpJSYYTiudiUhVokwAAAIEAyUQ9m8qL/1HPkFe6jbXAvtSSmW27F4c+G2xR5HizaHQzXgBOxPcsOsY17KTU+Ddbg+OF9soWNwSpm9pyVjVmNGqH3S8R1pwvuJF/O2Asy1m6wpWhbPw8JdEBW7WHoptBpfuzJoS2LOzJUEmUu4Eb+xS237KG1d1BVny/49KAoH0AAACBAJKBSsm9Xey0fUN6vYtTQgoYeGxxj/LqAIAOs/TpCxZDntly860y/SzHYai8x48k4t7whENY1CJ41fpMcPlz8xIsrNP3326Wbr0ExwOIvJKAVN1YLYqF8NXWzaVrjo5WbSeI8PiWTYemvLAujVxZssIrApTZBhp55nnwge6K1zTG\ \ tomk@air\",\n \"label\": \"ansible-integration-test-ssh_key-ztiapihf-ssh_key1_renamed\"\ - ,\n \"project_id\": local.project_id\n }\n]\n" + ,\n \"project_id\": b8c6c653-3c96-446e-987e-9c4d12f25353\n }\n]\n" type: dict ''' @@ -97,14 +97,14 @@ "id": "6edfcbc2-17e5-4221-9eac-2f40dbe60daf", "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAt5gwVMhwcCrxyxpMEKwiS0xgit3PIIEgVXt6SQHc8eONq0mYJJ5TOBNTnySqXd9RtSv/Jbf5Aq9BzBGWeoZ6sZfKwh984Ip35StJtjXtyIOlY3skovndtupBIwlGXgX/WQzyLr+G/+Yu9/nhdxQi801PDZnDvKoeomM0rMD29nV+m0ud+GrtsAt6VFul2PxqpypZ1TYviyED6IKo7rgQsQDkE9QHcNdfT1FZWiJbfP7o8TIurQJcAXg+MtLoc8rKKcxFMeZ9FSydgtTC7nP1h558RtECGWiUgaBPI7TpBmcdMtbEfAiBoGT17GWnT8qmy2u5xnEKPD9Qft4w4fjfpw==", "label": "tkarasek", - "project_id": local.project_id + "project_id": b8c6c653-3c96-446e-987e-9c4d12f25353 }, { "fingerprint": "ba:70:af:b3:0f:0e:7f:e5:eb:97:e2:27:b1:f5:6f:94", "id": "d00c596d-b42a-44a7-ac14-e299b85e73d3", "key": "ssh-dss AAAAB3NzaC1kc3MAAACBAOpXVtmc0Bla98bt0o5/Zj7sb4mHIukgVFZu7F32R3VK1cEKB4rEE8uS0oLS/qMRLue45TWVJwRMYGlPjt3p/VyraelxoyJZLuITIsqa5hBc9w0oTlB5Bmbkn16umW96WCaWEoq/aitpocbRChTiP5biI6FyQTQlIHDaYzBDOi11AAAAFQDUXy7cmuzphDpJSYYTiudiUhVokwAAAIEAyUQ9m8qL/1HPkFe6jbXAvtSSmW27F4c+G2xR5HizaHQzXgBOxPcsOsY17KTU+Ddbg+OF9soWNwSpm9pyVjVmNGqH3S8R1pwvuJF/O2Asy1m6wpWhbPw8JdEBW7WHoptBpfuzJoS2LOzJUEmUu4Eb+xS237KG1d1BVny/49KAoH0AAACBAJKBSsm9Xey0fUN6vYtTQgoYeGxxj/LqAIAOs/TpCxZDntly860y/SzHYai8x48k4t7whENY1CJ41fpMcPlz8xIsrNP3326Wbr0ExwOIvJKAVN1YLYqF8NXWzaVrjo5WbSeI8PiWTYemvLAujVxZssIrApTZBhp55nnwge6K1zTG tomk@air", "label": "ansible-integration-test-ssh_key-ztiapihf-ssh_key1_renamed", - "project_id": local.project_id + "project_id": b8c6c653-3c96-446e-987e-9c4d12f25353 } ] """, From 64654b3735ab717175ce41712e4a92e50e9dfe65 Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Wed, 2 Aug 2023 19:59:55 +0200 Subject: [PATCH 08/10] use metal ssh key updater --- plugins/module_utils/metal/api_routes.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/module_utils/metal/api_routes.py b/plugins/module_utils/metal/api_routes.py index 6dfd17d..ab5a895 100644 --- a/plugins/module_utils/metal/api_routes.py +++ b/plugins/module_utils/metal/api_routes.py @@ -182,9 +182,4 @@ def get_routes(mpc): {}, equinix_metal.SSHKeyInput, ), - ('metal_project_ssh_key', action.UPDATE): spec_types.Specs( - equinix_metal.SSHKeysApi(mpc).update_ssh_key, - {}, - equinix_metal.SSHKeyInput, - ), } From eaec37deb92566fe652ef1e65c09e7941083b20b Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Wed, 2 Aug 2023 20:41:37 +0200 Subject: [PATCH 09/10] fix idempotence issue --- plugins/modules/metal_project_ssh_key.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/metal_project_ssh_key.py b/plugins/modules/metal_project_ssh_key.py index 695b531..75ac83f 100644 --- a/plugins/modules/metal_project_ssh_key.py +++ b/plugins/modules/metal_project_ssh_key.py @@ -105,7 +105,7 @@ project_id=SpecField( type=FieldType.string, description=["The ID of parent project."], - editable=False, + editable=True, ), ) @@ -180,7 +180,7 @@ def main(): fetched = module.get_by_id(METAL_SSH_KEY, tolerate_not_found) else: fetched = module.get_one_from_list( - METAL_SSH_KEY, + MODULE_NAME, ["key"], ) From aac865bd1f85f036efae800465615b52bf8a6ed6 Mon Sep 17 00:00:00 2001 From: Tomas Karasek Date: Tue, 15 Aug 2023 13:55:40 +0300 Subject: [PATCH 10/10] touch commit to trigger integration tests --- plugins/modules/metal_project_ssh_key.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/metal_project_ssh_key.py b/plugins/modules/metal_project_ssh_key.py index 75ac83f..8f89673 100644 --- a/plugins/modules/metal_project_ssh_key.py +++ b/plugins/modules/metal_project_ssh_key.py @@ -135,7 +135,7 @@ { "fingerprint": "98:9c:35:ed:f9:75:5b:52:e2:70:50:22:ea:77:5b:b6", "id": "eef49903-7a09-4ca1-af67-4087c29ab5b6", - "key": "ssh-dss AAAAB3NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@xps", + "key": "ssh-dss AAAAB4NzaC1kc3MAAACBAPLEVntPO3L7VUbEwWZ2ErkQJ3KJ8o9kFXJrPcpvVfdNag4jIhQDqbtAUgUy6BclhhbfH9l5nlGTprrpEFkxm/GL91qJUX6xrPkDMjMqx2wSKa4YraReOrCOfkqqEkC3o3G/gYSuvTzLgp2rmPiflypftZyzNM4JZT8jDwFGotJhAAAAFQDPk43bayONtUxjkAcOf+6zP1qb6QAAAIBZHHH0tIlth5ot+Xa/EYuB/M4qh77EkrWUbER0Kki7suskw/ffdKQ0y/v+ZhoAHtBU7BeE3HmP98Vrha1i4cOU+A7DCqV+lK/a+5LoEpua0M2M+VzNSGluYuV4qGpAOxNh3mxUi2R7yXxheN1oks1ROJ/bqkF4BJQXU9Nv49GkZgAAAIByWcsFeOitvzyDaNJOZzEHv9fqGuj0L3maRVWb6O47HGzlMzniIy8WjL2dfgm2/ek+NxVR/yFnYTKDPr6+0uqSD/cb4eHaFbIj7v+k7H8hA1Ioz+duJ1ONAjn6KwneXxOXu15bYIR49P7Go0s9jCdSAP/r9NE5TnE3yiRiQzgEzw== tomk@xps", "label": "test_key", "project_id": "b8c6c653-3c96-446e-987e-9c4d12f25353" }