diff options
author | Seth Foster <fosterbseth@gmail.com> | 2023-11-15 18:34:19 +0100 |
---|---|---|
committer | Seth Foster <fosterseth@users.noreply.github.com> | 2024-02-02 16:37:41 +0100 |
commit | 04cbbbccfad5e4b8cadf8fec124ca52dfdf9b4a3 (patch) | |
tree | 7bda42e3e0a2a03ef3eca518183ada5238e34821 /awx_collection/plugins/modules | |
parent | Add functional and unit tests (diff) | |
download | awx-04cbbbccfad5e4b8cadf8fec124ca52dfdf9b4a3.tar.xz awx-04cbbbccfad5e4b8cadf8fec124ca52dfdf9b4a3.zip |
Update awx_collection to support ReceptorAddress
- Add receptor_address module which allows
users to create addresses for instances
- Update awx_collection functional and integration
tests to support new peering design
Signed-off-by: Seth Foster <fosterbseth@gmail.com>
Diffstat (limited to 'awx_collection/plugins/modules')
-rw-r--r-- | awx_collection/plugins/modules/instance.py | 47 | ||||
-rw-r--r-- | awx_collection/plugins/modules/receptor_address.py | 136 |
2 files changed, 163 insertions, 20 deletions
diff --git a/awx_collection/plugins/modules/instance.py b/awx_collection/plugins/modules/instance.py index 54866fb731..c29246ae31 100644 --- a/awx_collection/plugins/modules/instance.py +++ b/awx_collection/plugins/modules/instance.py @@ -58,23 +58,15 @@ options: - installed required: False type: str - listener_port: - description: - - Port that Receptor will listen for incoming connections on. - required: False - type: int peers: description: - List of peers to connect outbound to. Only configurable for hop and execution nodes. - To remove all current peers, set value to an empty list, []. + - Each item is an ID or address of a receptor address. + - If item is address, it must be unique across all receptor addresses. required: False type: list elements: str - peers_from_control_nodes: - description: - - If enabled, control plane nodes will automatically peer to this node. - required: False - type: bool extends_documentation_fragment: awx.awx.auth ''' @@ -83,12 +75,24 @@ EXAMPLES = ''' awx.awx.instance: hostname: my-instance.prod.example.com capacity_adjustment: 0.4 - listener_port: 31337 - name: Deprovision the instance awx.awx.instance: hostname: my-instance.prod.example.com node_state: deprovisioning + +- name: Create execution node + awx.awx.instance: + hostname: execution.example.com + node_type: execution + peers: + - 12 + - route.to.hop.example.com + +- name: Remove peers + awx.awx.instance: + hostname: execution.example.com + peers: ''' from ..module_utils.controller_api import ControllerAPIModule @@ -103,9 +107,7 @@ def main(): managed_by_policy=dict(type='bool'), node_type=dict(type='str', choices=['execution', 'hop']), node_state=dict(type='str', choices=['deprovisioning', 'installed']), - listener_port=dict(type='int'), peers=dict(required=False, type='list', elements='str'), - peers_from_control_nodes=dict(required=False, type='bool'), ) # Create a module for ourselves @@ -118,12 +120,21 @@ def main(): managed_by_policy = module.params.get('managed_by_policy') node_type = module.params.get('node_type') node_state = module.params.get('node_state') - listener_port = module.params.get('listener_port') peers = module.params.get('peers') - peers_from_control_nodes = module.params.get('peers_from_control_nodes') # Attempt to look up an existing item based on the provided data existing_item = module.get_one('instances', name_or_id=hostname) + # peer item can be an id or address + # if address, get the id + peers_ids = [] + if peers: + for p in peers: + if not p.isdigit(): + p_id = module.get_one('receptor_addresses', allow_none=False, data={'address': p}) + peers_ids.append(p_id['id']) + else: + peers_ids.append(p) + # Create the data that gets sent for create and update new_fields = {'hostname': hostname} if capacity_adjustment is not None: @@ -136,12 +147,8 @@ def main(): new_fields['node_type'] = node_type if node_state is not None: new_fields['node_state'] = node_state - if listener_port is not None: - new_fields['listener_port'] = listener_port if peers is not None: - new_fields['peers'] = peers - if peers_from_control_nodes is not None: - new_fields['peers_from_control_nodes'] = peers_from_control_nodes + new_fields['peers'] = peers_ids module.create_or_update_if_needed( existing_item, diff --git a/awx_collection/plugins/modules/receptor_address.py b/awx_collection/plugins/modules/receptor_address.py new file mode 100644 index 0000000000..0e2e2b6f62 --- /dev/null +++ b/awx_collection/plugins/modules/receptor_address.py @@ -0,0 +1,136 @@ +#!/usr/bin/python +# coding: utf-8 -*- + + +# (c) 2023 Red Hat, Inc. +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} + +DOCUMENTATION = ''' +--- +module: receptor_address +author: "Seth Foster (@fosterseth)" +version_added: "4.5.0" +short_description: create, update, or destroy Automation Platform Controller receptor addresses. +description: + - Create, update, or destroy Automation Platform Controller receptor addresses. See + U(https://www.ansible.com/tower) for an overview. +options: + address: + description: + - Routable address for this instance. + required: True + type: str + instance: + description: + - ID or hostname of instance this address belongs to. + required: True + type: str + peers_from_control_nodes: + description: + - If True, control plane cluster nodes should automatically peer to it. + required: False + type: bool + port: + description: + - Port for the address. + required: False + type: int + protocol: + description: + - Protocol to use when connecting. + required: False + type: str + choices: [ 'tcp', 'ws', 'wss' ] + websocket_path: + description: + - Websocket path. + required: False + type: str + state: + description: + - Desired state of the resource. + choices: ["present", "absent", "exists"] + default: "present" + type: str +extends_documentation_fragment: awx.awx.auth +''' + +EXAMPLES = ''' + - name: Create receptor address + awx.awx.receptor_address: + address: exec1addr + instance: exec1.example.com + peers_from_control_nodes: false + port: 6791 + protocol: ws + websocket_path: service + state: present + register: exec1addr +''' + +from ..module_utils.controller_api import ControllerAPIModule + + +def main(): + # Any additional arguments that are not fields of the item can be added here + argument_spec = dict( + address=dict(required=True, type='str'), + instance=dict(type='str'), + peers_from_control_nodes=dict(type='bool'), + port=dict(type='int'), + protocol=dict(type='str'), + websocket_path=dict(type='str'), + state=dict(choices=['present', 'absent', 'exists'], default='present'), + + ) + + # Create a module for ourselves + module = ControllerAPIModule(argument_spec=argument_spec) + + # Extract our parameters + address = module.params.get('address') + peers_from_control_nodes = module.params.get('peers_from_control_nodes') + port = module.params.get('port') + protocol = module.params.get('protocol', 'tcp') + websocket_path = module.params.get('websocket_path') + instance_name_or_id = module.params.get('instance') + state = module.params.get('state') + + # Attempt to look up an existing instance + receptor_address = module.get_one('receptor_addresses', allow_none=True, data=dict(address=address, protocol=protocol)) + if receptor_address: + receptor_address['type'] = 'receptor_address' + + if receptor_address and state == 'absent': + module.delete_if_needed(receptor_address) + + instance = module.get_one('instances', allow_none=False, name_or_id=instance_name_or_id) + + # Create the data that gets sent for create and update + new_fields = {'instance': instance['id'], 'address': address} + if port: + new_fields['port'] = port + if protocol: + new_fields['protocol'] = protocol + if peers_from_control_nodes: + new_fields['peers_from_control_nodes'] = peers_from_control_nodes + if websocket_path: + new_fields['websocket_path'] = websocket_path + + module.create_or_update_if_needed( + receptor_address, + new_fields, + endpoint='receptor_addresses', + item_type='receptor_address', + ) + + +if __name__ == '__main__': + main() |