From 2ded6ee6df8951539aca85a5bce2e4dfee4120da 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 2dd86ee4c5d9dd5a92fd83ee5f79edfa204afdeb Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Tue, 8 Aug 2023 21:07:40 +0200 Subject: [PATCH 02/10] add vlan module and info --- README.md | 2 + docs/modules/metal_vlan.md | 66 ++++++ docs/modules/metal_vlan_info.md | 56 +++++ plugins/module_utils/metal/api_routes.py | 15 ++ plugins/module_utils/metal/metal_api.py | 14 +- plugins/modules/metal_vlan.py | 208 ++++++++++++++++++ plugins/modules/metal_vlan_info.py | 107 +++++++++ tests/integration/inventory | 2 +- .../targets/metal_vlan/tasks/main.yml | 71 ++++++ 9 files changed, 539 insertions(+), 2 deletions(-) create mode 100644 docs/modules/metal_vlan.md create mode 100644 docs/modules/metal_vlan_info.md create mode 100644 plugins/modules/metal_vlan.py create mode 100644 plugins/modules/metal_vlan_info.py create mode 100644 tests/integration/targets/metal_vlan/tasks/main.yml diff --git a/README.md b/README.md index 9b1e215..0336d41 100644 --- a/README.md +++ b/README.md @@ -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_vlan](./docs/modules/metal_vlan.md)|Manage a VLAN resource in Equinix Metal| ### Info Modules @@ -48,6 +49,7 @@ 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| +[equinix.cloud.metal_vlan_info](./docs/modules/metal_vlan_info.md)|Gather VLANs.| ### Inventory Plugins diff --git a/docs/modules/metal_vlan.md b/docs/modules/metal_vlan.md new file mode 100644 index 0000000..08f3853 --- /dev/null +++ b/docs/modules/metal_vlan.md @@ -0,0 +1,66 @@ +# metal_vlan + +Manage the VLAN in Equinix Metal. You can use *id* or *vxlan* to lookup the resource. If you want to create new resource, you must provide *metro*. + + +- [Examples](#examples) +- [Parameters](#parameters) +- [Return Values](#return-values) + +## Examples + +```yaml +- name: Create new VLAN + hosts: localhost + tasks: + - equinix.cloud.metal_vlan: + description: "This is my new VLAN." + metro: "se" + vxlan: 1234 + project_id: "778h50f7-75b6-4271-bc64-632b80f87de2" + +``` + + + + + + + + + + +## Parameters + +| Field | Type | Required | Description | +|-----------|------|----------|------------------------------------------------------------------------------| +| `id` |
`str`
|
Optional
| ID of parent project" | +| `project_id` |
`str`
|
Optional
| ID of parent project" | +| `description` |
`str`
|
Optional
| Description of the VLAN **(Updatable)** | +| `metro` |
`str`
|
Optional
| Metro in which to create the VLAN **(Updatable)** | +| `vxlan` |
`int`
|
Optional
| VLAN ID, must be unique in metro **(Updatable)** | + + + + + + +## Return Values + +- `metal_vlan` - The module object + + - Sample Response: + ```json + + { + "changed": false, + "id": "7624f0f7-75b6-4271-bc64-632b80f87de2", + "description": "This is my new VLAN.", + "metro": "se", + "vxlan": 1234, + "project_id": "778h50f7-75b6-4271-bc64-632b80f87de2" + } + + ``` + + diff --git a/docs/modules/metal_vlan_info.md b/docs/modules/metal_vlan_info.md new file mode 100644 index 0000000..7be8dca --- /dev/null +++ b/docs/modules/metal_vlan_info.md @@ -0,0 +1,56 @@ +# metal_vlan_info + +Gather information about Equinix Metal VLAN resources + + +- [Examples](#examples) +- [Parameters](#parameters) +- [Return Values](#return-values) + +## Examples + +```yaml +- name: list vlans + equinix.cloud.metal_vlan_info: + register: listed_vlan + +``` + + + + + + + + + + +## Parameters + +| Field | Type | Required | Description | +|-----------|------|----------|------------------------------------------------------------------------------| +| `project_id` |
`str`
|
Optional
| Filter vlans by Project UUID. | + + + + + + +## Return Values + +- `resources` - Found resources + + - Sample Response: + ```json + + [ + { + "vxlan": 1234, + "metro": "se", + "id": "845b45a3-c565-47e5-b9b6-a86204a73d29", + "description": "My VLAN." + } + ] + ``` + + diff --git a/plugins/module_utils/metal/api_routes.py b/plugins/module_utils/metal/api_routes.py index 0a64b62..1b1d1cb 100644 --- a/plugins/module_utils/metal/api_routes.py +++ b/plugins/module_utils/metal/api_routes.py @@ -56,6 +56,9 @@ def get_routes(mpc): ("metal_organization", action.GET): spec_types.Specs( equinix_metal.OrganizationsApi(mpc).find_organization_by_id, ), + ("metal_vlan", action.GET): spec_types.Specs( + equinix_metal.VLANsApi(mpc).get_virtual_network, + ), # LISTERS ('metal_project_device', action.LIST): spec_types.Specs( @@ -102,6 +105,10 @@ def get_routes(mpc): equinix_metal.HardwareReservationsApi(mpc).find_project_hardware_reservations, {'id': 'project_id'}, ), + ('metal_vlan', action.LIST): spec_types.Specs( + equinix_metal.VLANsApi(mpc).find_virtual_networks, + {'id': 'project_id'}, + ), # DELETERS ('metal_device', action.DELETE): spec_types.Specs( @@ -119,6 +126,9 @@ def get_routes(mpc): ('metal_ssh_key', action.DELETE): spec_types.Specs( equinix_metal.SSHKeysApi(mpc).delete_ssh_key, ), + ('metal_vlan', action.DELETE): spec_types.Specs( + equinix_metal.VLANsApi(mpc).delete_virtual_network, + ), # CREATORS @@ -152,6 +162,11 @@ def get_routes(mpc): {}, equinix_metal.SSHKeyCreateInput, ), + ('metal_vlan', action.CREATE): spec_types.Specs( + equinix_metal.VLANsApi(mpc).create_virtual_network, + {'id': 'project_id'}, + equinix_metal.VirtualNetworkCreateInput, + ), # UPDATERS ('metal_device', action.UPDATE): spec_types.Specs( diff --git a/plugins/module_utils/metal/metal_api.py b/plugins/module_utils/metal/metal_api.py index 2e4bb0a..c43b296 100644 --- a/plugins/module_utils/metal/metal_api.py +++ b/plugins/module_utils/metal/metal_api.py @@ -137,6 +137,7 @@ def extract_ids_from_projects_hrefs(resource: dict): 'operating_systems', 'hardware_reservations', 'organizations', + 'virtual_networks' ] @@ -191,6 +192,14 @@ def get_assignment_address(resource: dict): } +VLAN_RESPONSE_ATTRIBUTE_MAP = { + "id": "id", + "description": optional_str('description'), + "metro": "metro", + "vxlan": "vxlan", +} + + def get_attribute_mapper(resource_type): """ Returns attribute mapper for the given resource type. @@ -201,6 +210,7 @@ def get_attribute_mapper(resource_type): ip_assignment_resources = set(['metal_ip_assignment']) ssh_key_resources = set(['metal_ssh_key', 'metal_project_ssh_key']) hardware_reservation_resources = set(['metal_project_hardware_reservation', 'metal_hardware_reservation']) + vlan_resources = set(["metal_vlan"]) if resource_type in device_resources: return METAL_DEVICE_RESPONSE_ATTRIBUTE_MAP elif resource_type in project_resources: @@ -219,6 +229,8 @@ def get_attribute_mapper(resource_type): return METAL_HARDWARE_RESERVATION_RESPONSE_ATTRIBUTE_MAP elif resource_type == 'metal_organization': return METAL_ORGANIZATION_RESPONSE_ATTRIBUTE_MAP + elif resource_type in vlan_resources: + return VLAN_RESPONSE_ATTRIBUTE_MAP else: raise NotImplementedError("No mapper for resource type %s" % resource_type) @@ -235,7 +247,7 @@ def call(resource_type, action, equinix_metal_client, params={}): call = api_routes.build_api_call(conf, params) response = call.do() # uncomment to check response in /tmp/q - #import q; q(response) + # import q; q(response) if action == action.DELETE: return None attribute_mapper = get_attribute_mapper(resource_type) diff --git a/plugins/modules/metal_vlan.py b/plugins/modules/metal_vlan.py new file mode 100644 index 0000000..769fd91 --- /dev/null +++ b/plugins/modules/metal_vlan.py @@ -0,0 +1,208 @@ +#!/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 the VLAN in Equinix Metal. You can use *id* or *vxlan* to lookup + the resource. If you want to create new resource, you must provide *metro*. +module: metal_vlan +notes: [] +options: + description: + description: + - Description of the VLAN + required: false + type: str + id: + description: + - ID of parent project" + required: false + type: str + metro: + description: + - Metro in which to create the VLAN + required: false + type: str + project_id: + description: + - ID of parent project" + required: false + type: str + vxlan: + description: + - VLAN ID, must be unique in metro + required: false + type: int +requirements: null +short_description: Manage a VLAN resource in Equinix Metal +''' +EXAMPLES = ''' +- name: Create new VLAN + hosts: localhost + tasks: + - equinix.cloud.metal_vlan: + description: This is my new VLAN. + metro: se + vxlan: 1234 + project_id: 778h50f7-75b6-4271-bc64-632b80f87de2 +''' +RETURN = ''' +metal_vlan: + description: The module object + returned: always + sample: + - "\n{\n \"changed\": false,\n \"id\": \"7624f0f7-75b6-4271-bc64-632b80f87de2\"\ + ,\n \"description\": \"This is my new VLAN.\",\n \"metro\": \"se\",\n \"vxlan\"\ + : 1234,\n \"project_id\": \"778h50f7-75b6-4271-bc64-632b80f87de2\"\n}\n" + type: dict +''' + +# End of generated documentation + +# This is a template for a new module. It is not meant to be used as is. +# It is meant to be copied and modified to create a new module. +# Replace all occurrences of "metal_resource" with the name of the new +# module, for example "metal_vlan". + + +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_vlan" + +module_spec = dict( + id=SpecField( + type=FieldType.string, + description=['ID of parent project"'], + ), + project_id=SpecField( + type=FieldType.string, + description=['ID of parent project"'], + ), + description=SpecField( + type=FieldType.string, + description=["Description of the VLAN"], + editable=True, + ), + metro=SpecField( + type=FieldType.string, + description=["Metro in which to create the VLAN"], + editable=True, + ), + vxlan=SpecField( + type=FieldType.integer, + description=["VLAN ID, must be unique in metro"], + editable=True, + ), +) + + +specdoc_examples = [ + """ +- name: Create new VLAN + hosts: localhost + tasks: + - equinix.cloud.metal_vlan: + description: "This is my new VLAN." + metro: "se" + vxlan: 1234 + project_id: "778h50f7-75b6-4271-bc64-632b80f87de2" +""", +] + +result_sample = [ + """ +{ + "changed": false, + "id": "7624f0f7-75b6-4271-bc64-632b80f87de2", + "description": "This is my new VLAN.", + "metro": "se", + "vxlan": 1234, + "project_id": "778h50f7-75b6-4271-bc64-632b80f87de2" +} +""" +] + +MUTABLE_ATTRIBUTES = [k for k, v in module_spec.items() if v.editable] + +SPECDOC_META = getSpecDocMeta( + short_description="Manage a VLAN resource in Equinix Metal", + description=( + "Manage the VLAN in Equinix Metal. " + "You can use *id* or *vxlan* to lookup the resource. " + "If you want to create new resource, you must provide *metro*." + ), + examples=specdoc_examples, + options=module_spec, + return_values={ + "metal_vlan": SpecReturnValue( + description="The module object", + type=FieldType.dict, + sample=result_sample, + ), + }, +) + + +def main(): + module = EquinixModule( + argument_spec=SPECDOC_META.ansible_spec, + ) + + 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, + ["vxlan"], + ) + + if fetched: + module.params["id"] = fetched["id"] + if state == "present": + diff = get_diff(module.params, fetched, MUTABLE_ATTRIBUTES) + if diff: + module.fail_json(msg="Resource metal_vlan is not mutable.") + + else: + module.delete_by_id(MODULE_NAME) + changed = True + else: + if state == "present": + fetched = module.create(MODULE_NAME) + if "id" not in fetched: + module.fail_json(msg="UUID not found in resource creation response") + 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_vlan_info.py b/plugins/modules/metal_vlan_info.py new file mode 100644 index 0000000..3762023 --- /dev/null +++ b/plugins/modules/metal_vlan_info.py @@ -0,0 +1,107 @@ +#!/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 information about Equinix Metal VLAN resources +module: metal_vlan_info +notes: [] +options: + project_id: + description: + - Filter vlans by Project UUID. + required: false + type: str +requirements: null +short_description: Gather VLANs. +''' +EXAMPLES = ''' +- name: list vlans + equinix.cloud.metal_vlan_info: null + register: listed_vlan +''' +RETURN = ''' +resources: + description: Found resources + returned: always + sample: + - "\n[\n {\n \"vxlan\": 1234,\n \"metro\": \"se\",\n \"id\": \"845b45a3-c565-47e5-b9b6-a86204a73d29\"\ + ,\n \"description\": \"My VLAN.\"\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( + project_id=SpecField( + type=FieldType.string, + description=['Filter vlans by Project UUID.'], + required=False, + ), +) + +specdoc_examples = [''' +- name: list vlans + equinix.cloud.metal_vlan_info: + register: listed_vlan +''', +] + +result_sample = [''' +[ + { + "vxlan": 1234, + "metro": "se", + "id": "845b45a3-c565-47e5-b9b6-a86204a73d29", + "description": "My VLAN." + } +]''', +] + +SPECDOC_META = getSpecDocMeta( + short_description="Gather VLANs.", + description=( + 'Gather information about Equinix Metal VLAN resources' + ), + 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_vlan")} + 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() 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_vlan/tasks/main.yml b/tests/integration/targets/metal_vlan/tasks/main.yml new file mode 100644 index 0000000..01eeb7b --- /dev/null +++ b/tests/integration/targets/metal_vlan/tasks/main.yml @@ -0,0 +1,71 @@ +- name: metal_vlan + module_defaults: + equinix.cloud.metal_vlan: + metal_api_token: '{{ metal_api_token }}' + equinix.cloud.metal_vlan_info: + metal_api_token: '{{ metal_api_token }}' + equinix.cloud.metal_project: + metal_api_token: '{{ metal_api_token }}' + equinix.cloud.metal_project_info: + metal_api_token: '{{ metal_api_token }}' + metal_ua_prefix: '{{ metal_ua_prefix }}' + block: + - set_fact: + test_resource_name_prefix: 'ansible-integration-test-vlan' + - 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_metro: 'am' + - set_fact: + test_description: 'My new VLAN' + - set_fact: + test_vxlan: 123 + + - 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 vlan for test + equinix.cloud.metal_vlan: + project_id: "{{ project.id }}" + metro: "{{ test_metro }}" + description: "{{ test_description }}" + vxlan: "{{ test_vxlan }}" + register: first_vlan + + - assert: + that: + - first_vlan.vxlan == {{ test_vxlan }} + + - name: get vlan info + equinix.cloud.metal_vlan_info: + project_id: "{{ project.id }}" + + - name: delete vlan + equinix.cloud.metal_vlan: + id: "{{ first_vlan.id }}" + state: absent + + always: + - name: Announce teardown start + debug: + msg: "***** TESTING COMPLETE. COMMENCE TEARDOWN *****" + + - 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 }}" + state: absent + loop: "{{ test_projects_listed.resources }}" + ignore_errors: yes \ No newline at end of file From 1619a163db1aaf91b369c2b9a99a0eb457a9af0e Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Tue, 8 Aug 2023 21:10:31 +0200 Subject: [PATCH 03/10] remove my python bin from inventorry --- 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 704d20c00f127f63de7ad113f5802a01ad7ef8d9 Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Wed, 9 Aug 2023 14:34:10 +0200 Subject: [PATCH 04/10] clean up branch from project ssh key commit --- README.md | 2 - docs/modules/metal_project_ssh_key.md | 73 ------ docs/modules/metal_project_ssh_key_info.md | 73 ------ plugins/modules/metal_project_ssh_key.py | 213 ------------------ plugins/modules/metal_project_ssh_key_info.py | 140 ------------ 5 files changed, 501 deletions(-) delete mode 100644 docs/modules/metal_project_ssh_key.md delete mode 100644 docs/modules/metal_project_ssh_key_info.md delete mode 100644 plugins/modules/metal_project_ssh_key.py delete mode 100644 plugins/modules/metal_project_ssh_key_info.py diff --git a/README.md b/README.md index 0336d41..39c586b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,6 @@ 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| [equinix.cloud.metal_vlan](./docs/modules/metal_vlan.md)|Manage a VLAN resource in Equinix Metal| @@ -46,7 +45,6 @@ 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| [equinix.cloud.metal_vlan_info](./docs/modules/metal_vlan_info.md)|Gather VLANs.| diff --git a/docs/modules/metal_project_ssh_key.md b/docs/modules/metal_project_ssh_key.md deleted file mode 100644 index ed47b60..0000000 --- a/docs/modules/metal_project_ssh_key.md +++ /dev/null @@ -1,73 +0,0 @@ -# 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 deleted file mode 100644 index 10bd318..0000000 --- a/docs/modules/metal_project_ssh_key_info.md +++ /dev/null @@ -1,73 +0,0 @@ -# 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_project_ssh_key.py b/plugins/modules/metal_project_ssh_key.py deleted file mode 100644 index c57a4d2..0000000 --- a/plugins/modules/metal_project_ssh_key.py +++ /dev/null @@ -1,213 +0,0 @@ -#!/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 deleted file mode 100644 index c45a719..0000000 --- a/plugins/modules/metal_project_ssh_key_info.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/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 57aa7c8db50ee9c025a825e3878501a3b3fe749f Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Thu, 10 Aug 2023 22:02:50 +0200 Subject: [PATCH 05/10] adress PR remarks --- plugins/modules/metal_vlan.py | 7 ++----- tests/integration/inventory | 2 +- tests/integration/targets/metal_vlan/tasks/main.yml | 10 ++++++++++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/plugins/modules/metal_vlan.py b/plugins/modules/metal_vlan.py index 769fd91..7bff246 100644 --- a/plugins/modules/metal_vlan.py +++ b/plugins/modules/metal_vlan.py @@ -30,7 +30,7 @@ type: str project_id: description: - - ID of parent project" + - ID of parent project required: false type: str vxlan: @@ -89,7 +89,7 @@ module_spec = dict( id=SpecField( type=FieldType.string, - description=['ID of parent project"'], + description=['UUID of vlan"'], ), project_id=SpecField( type=FieldType.string, @@ -98,17 +98,14 @@ description=SpecField( type=FieldType.string, description=["Description of the VLAN"], - editable=True, ), metro=SpecField( type=FieldType.string, description=["Metro in which to create the VLAN"], - editable=True, ), vxlan=SpecField( type=FieldType.integer, description=["VLAN ID, must be unique in metro"], - editable=True, ), ) 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_vlan/tasks/main.yml b/tests/integration/targets/metal_vlan/tasks/main.yml index 01eeb7b..0854f4f 100644 --- a/tests/integration/targets/metal_vlan/tasks/main.yml +++ b/tests/integration/targets/metal_vlan/tasks/main.yml @@ -47,12 +47,22 @@ - name: get vlan info equinix.cloud.metal_vlan_info: project_id: "{{ project.id }}" + register: vlan_info_listed + + - assert: + that: + - "vlan_info_listed.resources | length == 1" - name: delete vlan equinix.cloud.metal_vlan: id: "{{ first_vlan.id }}" state: absent + - name: delete vlan again to check indempotence + equinix.cloud.metal_vlan: + id: "{{ first_vlan.id }}" + state: absent + always: - name: Announce teardown start debug: From 54d5d1a2829cb5c249cd94c337355a2135879df9 Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Thu, 10 Aug 2023 22:04:20 +0200 Subject: [PATCH 06/10] remove extra qoute mark --- plugins/modules/metal_vlan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/metal_vlan.py b/plugins/modules/metal_vlan.py index 7bff246..852cefc 100644 --- a/plugins/modules/metal_vlan.py +++ b/plugins/modules/metal_vlan.py @@ -20,7 +20,7 @@ type: str id: description: - - ID of parent project" + - ID of parent project required: false type: str metro: From f043be68eba019728de7106d9538ba3f300df228 Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Fri, 11 Aug 2023 14:29:29 +0200 Subject: [PATCH 07/10] add get vlan test --- tests/integration/targets/metal_vlan/tasks/main.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/integration/targets/metal_vlan/tasks/main.yml b/tests/integration/targets/metal_vlan/tasks/main.yml index 0854f4f..951b0f5 100644 --- a/tests/integration/targets/metal_vlan/tasks/main.yml +++ b/tests/integration/targets/metal_vlan/tasks/main.yml @@ -53,6 +53,11 @@ that: - "vlan_info_listed.resources | length == 1" + - name: fetch existing vlan + equinix.cloud.metal_vlan: + id: "{{ first_vlan.id }}" + register: first_vlan_fetched + - name: delete vlan equinix.cloud.metal_vlan: id: "{{ first_vlan.id }}" From 4a5db226626f4f555e029c15a7956dbfb135470d Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Fri, 11 Aug 2023 14:53:47 +0200 Subject: [PATCH 08/10] add new tests --- tests/integration/targets/metal_vlan/tasks/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/targets/metal_vlan/tasks/main.yml b/tests/integration/targets/metal_vlan/tasks/main.yml index 951b0f5..e894407 100644 --- a/tests/integration/targets/metal_vlan/tasks/main.yml +++ b/tests/integration/targets/metal_vlan/tasks/main.yml @@ -52,6 +52,7 @@ - assert: that: - "vlan_info_listed.resources | length == 1" + - vlan_info_listed.resources[0].id == "{{ first_vlan.id }}" - name: fetch existing vlan equinix.cloud.metal_vlan: From be87d8b5e46cb3a3d89be08c3e5ca4c70e49d272 Mon Sep 17 00:00:00 2001 From: Alexander Bacho Date: Fri, 11 Aug 2023 14:56:20 +0200 Subject: [PATCH 09/10] remove local inventory bin --- 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 1bbef7324e8ebe481223fe3b1049608593523b43 Mon Sep 17 00:00:00 2001 From: Tomas Karasek Date: Tue, 15 Aug 2023 13:51:03 +0300 Subject: [PATCH 10/10] touch commit to trigger integration tests --- plugins/modules/metal_vlan_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/metal_vlan_info.py b/plugins/modules/metal_vlan_info.py index 3762023..c911811 100644 --- a/plugins/modules/metal_vlan_info.py +++ b/plugins/modules/metal_vlan_info.py @@ -67,7 +67,7 @@ "vxlan": 1234, "metro": "se", "id": "845b45a3-c565-47e5-b9b6-a86204a73d29", - "description": "My VLAN." + "description": "My VLAN" } ]''', ]