303 lines
9.3 KiB
Python
303 lines
9.3 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright (c) 2021 by Red Hat, Inc.
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
DOCUMENTATION = r'''
|
|
module: baremetal_port
|
|
short_description: Create/Delete Bare Metal port Resources from OpenStack
|
|
author: OpenStack Ansible SIG
|
|
description:
|
|
- Create, Update and Remove ironic ports from OpenStack.
|
|
options:
|
|
address:
|
|
description:
|
|
- Physical hardware address of this network Port, typically the
|
|
hardware MAC address.
|
|
type: str
|
|
extra:
|
|
description:
|
|
- A set of one or more arbitrary metadata key and value pairs.
|
|
type: dict
|
|
id:
|
|
description:
|
|
- ID of the Port.
|
|
- Will be auto-generated if not specified.
|
|
type: str
|
|
aliases: ['uuid']
|
|
is_pxe_enabled:
|
|
description:
|
|
- Whether PXE should be enabled or disabled on the Port.
|
|
type: bool
|
|
aliases: ['pxe_enabled']
|
|
local_link_connection:
|
|
description:
|
|
- The Port binding profile.
|
|
type: dict
|
|
suboptions:
|
|
switch_id:
|
|
description:
|
|
- A MAC address or an OpenFlow based datapath_id of the switch.
|
|
type: str
|
|
port_id:
|
|
description:
|
|
- Identifier of the physical port on the switch to which node's
|
|
port is connected to.
|
|
type: str
|
|
switch_info:
|
|
description:
|
|
- An optional string field to be used to store any vendor-specific
|
|
information.
|
|
type: str
|
|
node:
|
|
description:
|
|
- ID or Name of the Node this resource belongs to.
|
|
type: str
|
|
physical_network:
|
|
description:
|
|
- The name of the physical network to which a port is connected.
|
|
type: str
|
|
port_group:
|
|
description:
|
|
- ID or Name of the portgroup this resource belongs to.
|
|
type: str
|
|
aliases: ['portgroup']
|
|
state:
|
|
description:
|
|
- Indicates desired state of the resource
|
|
choices: ['present', 'absent']
|
|
default: present
|
|
type: str
|
|
requirements:
|
|
- "python >= 3.6"
|
|
- "openstacksdk"
|
|
extends_documentation_fragment:
|
|
- openstack.cloud.openstack
|
|
'''
|
|
|
|
EXAMPLES = r'''
|
|
- name: Create Bare Metal port
|
|
openstack.cloud.baremetal_port:
|
|
cloud: devstack
|
|
state: present
|
|
node: bm-0
|
|
address: fa:16:3e:aa:aa:aa
|
|
is_pxe_enabled: True
|
|
local_link_connection:
|
|
switch_id: 0a:1b:2c:3d:4e:5f
|
|
port_id: Ethernet3/1
|
|
switch_info: switch1
|
|
extra:
|
|
something: extra
|
|
physical_network: datacenter
|
|
register: result
|
|
|
|
- name: Delete Bare Metal port
|
|
openstack.cloud.baremetal_port:
|
|
cloud: devstack
|
|
state: absent
|
|
address: fa:16:3e:aa:aa:aa
|
|
register: result
|
|
|
|
- name: Update Bare Metal port
|
|
openstack.cloud.baremetal_port:
|
|
cloud: devstack
|
|
state: present
|
|
id: 1a85ebca-22bf-42eb-ad9e-f640789b8098
|
|
is_pxe_enabled: False
|
|
local_link_connection:
|
|
switch_id: a0:b1:c2:d3:e4:f5
|
|
port_id: Ethernet4/12
|
|
switch_info: switch2
|
|
'''
|
|
|
|
RETURN = r'''
|
|
port:
|
|
description: A port dictionary, subset of the dictionary keys listed below
|
|
may be returned, depending on your cloud provider.
|
|
returned: success
|
|
type: dict
|
|
contains:
|
|
address:
|
|
description: Physical hardware address of this network Port,
|
|
typically the hardware MAC address.
|
|
returned: success
|
|
type: str
|
|
created_at:
|
|
description: Bare Metal port created at timestamp.
|
|
returned: success
|
|
type: str
|
|
extra:
|
|
description: A set of one or more arbitrary metadata key and value
|
|
pairs.
|
|
returned: success
|
|
type: dict
|
|
id:
|
|
description: The UUID for the Baremetal Port resource.
|
|
returned: success
|
|
type: str
|
|
internal_info:
|
|
description: Internal metadata set and stored by the Port. This
|
|
field is read-only.
|
|
returned: success
|
|
type: dict
|
|
is_pxe_enabled:
|
|
description: Whether PXE is enabled or disabled on the Port.
|
|
returned: success
|
|
type: bool
|
|
links:
|
|
description: A list of relative links, including the self and
|
|
bookmark links.
|
|
returned: success
|
|
type: list
|
|
local_link_connection:
|
|
description: The Port binding profile. If specified, must contain
|
|
switch_id (only a MAC address or an OpenFlow based
|
|
datapath_id of the switch are accepted in this field
|
|
and port_id (identifier of the physical port on the
|
|
switch to which node's port is connected to) fields.
|
|
switch_info is an optional string field to be used to
|
|
store any vendor-specific information.
|
|
returned: success
|
|
type: dict
|
|
location:
|
|
description: Cloud location of this resource (cloud, project,
|
|
region, zone)
|
|
returned: success
|
|
type: dict
|
|
name:
|
|
description: Bare Metal port name.
|
|
returned: success
|
|
type: str
|
|
node_id:
|
|
description: UUID of the Bare Metal Node this resource belongs to.
|
|
returned: success
|
|
type: str
|
|
physical_network:
|
|
description: The name of the physical network to which a port is
|
|
connected.
|
|
returned: success
|
|
type: str
|
|
port_group_id:
|
|
description: UUID of the Portgroup this resource belongs to.
|
|
returned: success
|
|
type: str
|
|
updated_at:
|
|
description: Bare Metal port updated at timestamp.
|
|
returned: success
|
|
type: str
|
|
'''
|
|
|
|
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (
|
|
OpenStackModule
|
|
)
|
|
|
|
|
|
class BaremetalPortModule(OpenStackModule):
|
|
argument_spec = dict(
|
|
address=dict(),
|
|
extra=dict(type='dict'),
|
|
id=dict(aliases=['uuid']),
|
|
is_pxe_enabled=dict(type='bool', aliases=['pxe_enabled']),
|
|
local_link_connection=dict(type='dict'),
|
|
node=dict(),
|
|
physical_network=dict(),
|
|
port_group=dict(aliases=['portgroup']),
|
|
state=dict(default='present', choices=['present', 'absent']),
|
|
)
|
|
|
|
module_kwargs = dict(
|
|
required_one_of=[
|
|
('id', 'address'),
|
|
],
|
|
required_if=[
|
|
('state', 'present', ('node', 'address',), False),
|
|
],
|
|
)
|
|
|
|
def run(self):
|
|
port = self._find_port()
|
|
state = self.params['state']
|
|
if state == 'present':
|
|
# create or update port
|
|
|
|
kwargs = {}
|
|
id = self.params['id']
|
|
if id:
|
|
kwargs['id'] = id
|
|
|
|
node_name_or_id = self.params['node']
|
|
# assert node_name_or_id
|
|
node = self.conn.baremetal.find_node(node_name_or_id,
|
|
ignore_missing=False)
|
|
kwargs['node_id'] = node['id']
|
|
|
|
port_group_name_or_id = self.params['port_group']
|
|
if port_group_name_or_id:
|
|
port_group = self.conn.baremetal.find_port_group(
|
|
port_group_name_or_id, ignore_missing=False)
|
|
kwargs['port_group_id'] = port_group['id']
|
|
|
|
for k in ['address', 'extra', 'is_pxe_enabled',
|
|
'local_link_connection', 'physical_network']:
|
|
if self.params[k] is not None:
|
|
kwargs[k] = self.params[k]
|
|
|
|
changed = True
|
|
if not port:
|
|
# create port
|
|
port = self.conn.baremetal.create_port(**kwargs)
|
|
else:
|
|
# update port
|
|
updates = dict((k, v)
|
|
for k, v in kwargs.items()
|
|
if v != port[k])
|
|
|
|
if updates:
|
|
port = \
|
|
self.conn.baremetal.update_port(port['id'], **updates)
|
|
else:
|
|
changed = False
|
|
|
|
self.exit_json(changed=changed, port=port.to_dict(computed=False))
|
|
|
|
if state == 'absent':
|
|
# remove port
|
|
if not port:
|
|
self.exit_json(changed=False)
|
|
|
|
port = self.conn.baremetal.delete_port(port['id'])
|
|
self.exit_json(changed=True)
|
|
|
|
def _find_port(self):
|
|
id = self.params['id']
|
|
if id:
|
|
return self.conn.baremetal.get_port(id)
|
|
|
|
address = self.params['address']
|
|
if address:
|
|
ports = list(self.conn.baremetal.ports(address=address,
|
|
details=True))
|
|
|
|
if len(ports) == 1:
|
|
return ports[0]
|
|
elif len(ports) > 1:
|
|
raise ValueError(
|
|
'Multiple ports with address {address} found. A ID'
|
|
' must be defined in order to identify a unique'
|
|
' port.'.format(address=address))
|
|
else:
|
|
return None
|
|
|
|
raise AssertionError("id or address must be specified")
|
|
|
|
|
|
def main():
|
|
module = BaremetalPortModule()
|
|
module()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|