Skip to content

Commit

Permalink
feat: metal_device return network ports from api response (#197)
Browse files Browse the repository at this point in the history
when we create a device, the api returns the network_ports for that
device - but the ansible module doesn't expose any of that.
this PR adds the network_ports attribute to the response in the ansible
task, containing a minimum amount of attributes about the port
configuration (id, name, bond, vlans, network_type).
  • Loading branch information
ctreatma authored Jul 25, 2024
2 parents c7b2c75 + 73d19e7 commit 8df6827
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
29 changes: 29 additions & 0 deletions plugins/module_utils/metal/metal_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,34 @@ def ip_address_getter(resource: dict):
pick_keys = ['address', 'address_family', 'public']
return [dict((k, ip[k]) for k in pick_keys) for ip in resource.get('ip_addresses', [])]

def network_ports_getter(resource: dict):
ports = resource.get('network_ports')
result = []
for port in ports:
actual_port = {'id': port.get('id', ''), 'name': port.get('name')}

bond = port.get('bond', None)
if bond:
actual_port['bond'] = bond.get('id', '')

network_type = port.get('network_type', None)
if network_type:
actual_port['network_type'] = network_type

native_vlan = port.get('native_virtual_network', None)
if native_vlan:
actual_port['native_vlan'] = native_vlan.get('id', '')

vlans = port.get('virtual_networks', [])
if vlans:
actual_port['vlans'] = []
for vlan in vlans:
actual_port['vlans'].append(vlan.get('id'))

result.append(actual_port)

return result


def extract_ids_from_projects_hrefs(resource: dict):
return [href_to_id(p['href']) for p in resource.get('projects', [])]
Expand All @@ -68,6 +96,7 @@ def extract_ids_from_projects_hrefs(resource: dict):
'hostname': 'hostname',
'id': 'id',
'ip_addresses': ip_address_getter,
'network_ports': network_ports_getter,
'ipxe_script_url': optional_str('ipxe_script_url'),
'locked': 'locked',
'metal_state': optional_str('state'),
Expand Down
32 changes: 32 additions & 0 deletions plugins/modules/metal_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,38 @@
description="Whether the device network should be frozen, preventing any changes to the network configuration.",
editable=True,
),
network_ports=SpecField(
type=FieldType.list,
description="Network ports for this device.",
element_type=FieldType.dict,
suboptions=dict(
id=SpecField(
type=FieldType.string,
description="Port ID.",
),
name=SpecField(
type=FieldType.string,
description="Port name.",
),
bond=SpecField(
type=FieldType.string,
description="ID for the bond parent of this port.",
),
network_type=SpecField(
type=FieldType.string,
description="Network type.",
),
native_vlan=SpecField(
type=FieldType.string,
description="Native virtual network set on this port.",
),
vlans=SpecField(
type=FieldType.list,
description="Non native virtual networks on this port.",
element_type=FieldType.string,
),
),
),
no_ssh_keys=SpecField(
type=FieldType.bool,
description="Overrides default behaviour of attaching all of the organization members ssh keys and project ssh keys to device if no specific keys specified.",
Expand Down
12 changes: 12 additions & 0 deletions tests/integration/targets/metal_device/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
test_os: ubuntu_22_04
- set_fact:
test_plan: c3.small.x86
- set_fact:
interface_count: 3 # depends on the amount of interfaces we expect for the plan above. by default, we get bonded interfaces, so we count 2 nics + 1 bond
- set_fact:
wait_seconds: 1200

Expand Down Expand Up @@ -49,6 +51,16 @@
that:
- "test_device_1.metal_state == 'active'"
- "test_device_1_2.changed == false"
- "test_device_1.network_ports | length == interface_count"
- "test_device_1_2.network_ports | length == interface_count"

- name: assert network ports
assert:
that:
- "item.0.id == item.1.id"
- "item.0.id != ''"
- "item.1.id != ''"
loop: "{{ test_device_1.network_ports|zip(test_device_1_2.network_ports)|list }}"

- name: start second test device
equinix.cloud.metal_device:
Expand Down

0 comments on commit 8df6827

Please sign in to comment.