Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: module metal_plan_info #146

Merged
merged 14 commits into from
Feb 22, 2024
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Name | Description |
[equinix.cloud.metal_metro_info](https://github.com/equinix-labs/ansible-collection-equinix/blob/0.3.0/docs/modules/metal_metro_info.md)|Gather information about Equinix Metal metros|
[equinix.cloud.metal_operating_system_info](https://github.com/equinix-labs/ansible-collection-equinix/blob/0.3.0/docs/modules/metal_operating_system_info.md)|Gather information about Operating Systems available for devices in Equinix Metal|
[equinix.cloud.metal_organization_info](https://github.com/equinix-labs/ansible-collection-equinix/blob/0.3.0/docs/modules/metal_organization_info.md)|Gather information about Equinix Metal organizations|
[equinix.cloud.metal_plan_info](https://github.com/equinix-labs/ansible-collection-equinix/blob/0.3.0/docs/modules/metal_plan_info.md)|Gather information about Equinix Metal plans|
[equinix.cloud.metal_project_info](https://github.com/equinix-labs/ansible-collection-equinix/blob/0.3.0/docs/modules/metal_project_info.md)|Gather information about Equinix Metal projects|
[equinix.cloud.metal_project_ssh_key_info](https://github.com/equinix-labs/ansible-collection-equinix/blob/0.3.0/docs/modules/metal_project_ssh_key_info.md)|Gather project SSH keys.|
[equinix.cloud.metal_reserved_ip_block_info](https://github.com/equinix-labs/ansible-collection-equinix/blob/0.3.0/docs/modules/metal_reserved_ip_block_info.md)|Gather list of reserved IP blocks|
Expand Down
96 changes: 96 additions & 0 deletions docs/modules/metal_plan_info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# metal_plan_info

Gather information about Equinix Metal plans


- [Examples](#examples)
- [Parameters](#parameters)
- [Return Values](#return-values)

## Examples

```yaml
- name: Gather information about all plans
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info

```

```yaml
- name: Gather information for plans with storage category
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info:
categories: ['storage']

```

```yaml
- name: Gather information for plans with slug c3.medium
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info:
slug: c3.medium

```

```yaml
- name: Gather information for plans with a standard plan
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info:
type: standard

```










## Parameters

| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
| `categories` | <center>`list`</center> | <center>Optional</center> | Filter plans by its categories. |
| `type` | <center>`str`</center> | <center>Optional</center> | Filter plans by its plan type. |
| `slug` | <center>`str`</center> | <center>Optional</center> | Filter plans by slug. |






## Return Values

- `resources` - Found resources

- Sample Response:
```json

{
"available_in": [],
"available_in_metros": [],
"category": [
"compute",
"current_gen"
],
"class": "a3.large.opt-m3a2",
"deployment_types": [],
"description": "a3.large.opt-m3a2.x86",
"id": "8c04950a-87ab-5e52-a112-5a90bbca8868",
"legacy": false,
"line": "baremetal",
"name": "a3.large.opt-m3a2.x86",
"pricing_hour": 8.2,
"pricing_month": null,
"slug": "a3.large.opt-m3a2"
}
```


7 changes: 7 additions & 0 deletions plugins/module_utils/metal/api_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ def get_routes(mpc):
('metal_project_bgp_config', action.GET): spec_types.Specs(
equinix_metal.BGPApi(mpc).find_bgp_config_by_project,
),
("metal_plan", action.GET): spec_types.Specs(
equinix_metal.PlansApi(mpc).find_plans_by_project,
),

# LISTERS
('metal_project_device', action.LIST): spec_types.Specs(
Expand Down Expand Up @@ -154,6 +157,10 @@ def get_routes(mpc):
equinix_metal.BGPApi(mpc).find_bgp_config_by_project,
{'id': 'project_id'},
),
('metal_plan', action.LIST): spec_types.Specs(
equinix_metal.PlansApi(mpc).find_plans,
{'category': 'category', 'type': 'type', 'slug': 'slug', 'include': 'include', 'exclude': 'exclude'},
),

# DELETERS
('metal_device', action.DELETE): spec_types.Specs(
Expand Down
25 changes: 23 additions & 2 deletions plugins/module_utils/metal/metal_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ def optional_bool(key: str):
return lambda resource: resource.get(key, False)


def optional_float(key: str):
return lambda resource: resource.get(key, 0.0)
def optional_float(key: str, default=0.0):
return lambda resource: resource.get(key, default)

def cidr_to_quantity(key: str):
return lambda resource: ip_count_from_mask(resource.get(key))
Expand Down Expand Up @@ -151,6 +151,7 @@ def extract_ids_from_projects_hrefs(resource: dict):
'metal_gateways',
'bgp_sessions', # metal_bgp_session
'sessions', # metal_bgp_session_info
'plans',
]


Expand Down Expand Up @@ -272,6 +273,23 @@ def private_ipv4_subnet_size(resource: dict):

}

METAL_PLAN_RESPONSE_ATTRIBUTE_MAP = {
'id': 'id',
'categories': 'categories',
'name': 'name',
'slug': 'slug',
'description': 'description',
'line': 'line',
'legacy': 'legacy',
'class': 'class',
'pricing_hour': 'pricing.hour',
'pricing_month': optional_float('pricing.month', None),
'deployment_types': 'deployment_types',
'available_in': 'available_in',
'available_in_metros': 'available_in_metros',
}


def get_attribute_mapper(resource_type):
"""
Returns attribute mapper for the given resource type.
Expand All @@ -290,6 +308,7 @@ def get_attribute_mapper(resource_type):
gateway_resources = set(["metal_gateway", "metal_gateway_vrf"])
bgp_resources = {'metal_bgp_session', 'metal_bgp_session_by_project'}
project_bgp_config_resources = {'metal_project_bgp_config'}
plan_resources = set(["metal_plan"])
if resource_type in device_resources:
return METAL_DEVICE_RESPONSE_ATTRIBUTE_MAP
elif resource_type in project_resources:
Expand Down Expand Up @@ -320,6 +339,8 @@ def get_attribute_mapper(resource_type):
return METAL_BGP_SESSION_RESPONSE_ATTRIBUTE_MAP
elif resource_type in project_bgp_config_resources:
return METAL_PROJECT_BGP_CONFIG_RESPONSE_ATTRIBUTE_MAP
elif resource_type in plan_resources:
return METAL_PLAN_RESPONSE_ATTRIBUTE_MAP
else:
raise NotImplementedError("No mapper for resource type %s" % resource_type)

Expand Down
177 changes: 177 additions & 0 deletions plugins/modules/metal_plan_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
#!/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) <[email protected]>
description: Gather information about Equinix Metal plans
module: metal_plan_info
notes: []
options:
categories:
description:
- Filter plans by its categories.
required: false
type: list
slug:
description:
- Filter plans by slug.
required: false
type: str
type:
description:
- Filter plans by its plan type.
required: false
type: str
requirements: null
short_description: Gather information about Equinix Metal plans
'''
EXAMPLES = '''
- name: Gather information about all plans
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info
- name: Gather information for plans with storage category
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info:
categories:
- storage
- name: Gather information for plans with slug c3.medium
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info:
slug: c3.medium
- name: Gather information for plans with a standard plan
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info:
type: standard
'''
RETURN = '''
resources:
description: Found resources
returned: always
sample:
- "\n{ \
\ \n \"available_in\": [], \
\ \
\ \n \"available_in_metros\": [],\n \"category\"\
: [\n \"compute\",\n \"current_gen\"\n ],\n \"class\": \"a3.large.opt-m3a2\"\
,\n \"deployment_types\": [],\n \"description\": \"a3.large.opt-m3a2.x86\",\n\
\ \"id\": \"8c04950a-87ab-5e52-a112-5a90bbca8868\",\n \"legacy\": false,\n \
\ \"line\": \"baremetal\",\n \"name\": \"a3.large.opt-m3a2.x86\",\n \"pricing_hour\"\
: 8.2,\n \"pricing_month\": null,\n \"slug\": \"a3.large.opt-m3a2\"\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(
categories=SpecField(
type=FieldType.list,
description=['Filter plans by categories.'],
),
type=SpecField(
type=FieldType.string,
description=['Filter plans by type.'],
),
slug=SpecField(
type=FieldType.string,
description=['Filter plans by slug.'],
),
)

specdoc_examples = ['''
- name: Gather information about all plans
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info
''', '''
- name: Gather information for plans with storage category
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info:
categories: ['storage']
''', '''
- name: Gather information for plans with slug c3.medium
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info:
slug: c3.medium
''', '''
- name: Gather information for plans with a standard plan
hosts: localhost
tasks:
- equinix.cloud.metal_plan_info:
type: standard
''',
]

result_sample = ['''
{
"available_in": [],
"available_in_metros": [],
"category": [
"compute",
"current_gen"
],
"class": "a3.large.opt-m3a2",
"deployment_types": [],
"description": "a3.large.opt-m3a2.x86",
"id": "8c04950a-87ab-5e52-a112-5a90bbca8868",
"legacy": false,
"line": "baremetal",
"name": "a3.large.opt-m3a2.x86",
"pricing_hour": 8.2,
"pricing_month": null,
"slug": "a3.large.opt-m3a2"
}''',
]

SPECDOC_META = getSpecDocMeta(
short_description="Gather information about Equinix Metal plans",
description=(
'Gather information about Equinix Metal plans'
),
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_plan")}

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()
Loading
Loading