generated from linux-system-roles/template
-
Notifications
You must be signed in to change notification settings - Fork 22
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: export corosync configuration #231
Open
tomjelinek
wants to merge
6
commits into
linux-system-roles:main
Choose a base branch
from
tomjelinek:export-corosync
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0dd4080
feat: add ha_cluster_info module
tomjelinek 84bfe8a
refactor: ha_cluster_info: reorganize exceptions
tomjelinek 0fa3484
refactor: ha_cluster_info: split data loading and transformation
tomjelinek a8ad557
refactor: ha_cluster_info: split to several modules
tomjelinek f5ff638
refactor: ha_cluster_info: cleanup
tomjelinek 58ae985
test: update pcs version vs ubuntu version matrix
tomjelinek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
#!/usr/bin/python | ||
# -*- coding: utf-8 -*- | ||
|
||
# Copyright (C) 2024 Red Hat, Inc. | ||
# Author: Tomas Jelinek <[email protected]> | ||
# SPDX-License-Identifier: MIT | ||
|
||
# make ansible-test happy, even though the module requires Python 3 | ||
from __future__ import absolute_import, division, print_function | ||
|
||
# make ansible-test happy, even though the module requires Python 3 | ||
# pylint: disable=invalid-name | ||
__metaclass__ = type | ||
|
||
DOCUMENTATION = r""" | ||
--- | ||
module: ha_cluster_info | ||
short_description: Export HA cluster configuration | ||
description: | ||
This module exports live cluster configuration in form of variables which | ||
recreate the same configuration when passed to ha_cluster role. Note that | ||
the set of variables may not be complete and manual modification of the | ||
result is expected (at least setting ha_cluster_hacluster_password is | ||
required). | ||
author: | ||
- Tomas Jelinek (@tomjelinek) | ||
requirements: | ||
- pcs-0.10.8 or newer installed on managed nodes | ||
- pcs-0.10.8 or newer for exporting corosync configuration | ||
- python 3.6 or newer | ||
""" | ||
|
||
EXAMPLES = r""" | ||
- name: Get HA cluster configuration | ||
ha_cluster_info: | ||
register: my_ha_cluster_info | ||
""" | ||
|
||
RETURN = r""" | ||
ha_cluster: | ||
returned: success | ||
type: dict | ||
description: | ||
- Information about existing cluster on the node. If passed to | ||
ha_cluster role, the role recreates the same cluster. Note that the | ||
set of variables may not be complete and manual modification of the | ||
result is expected. The variables are documented in the role. | ||
- Note that depending on pcs version present on the managed node, | ||
certain variables may not be exported. | ||
- HORIZONTALLINE | ||
- Following variables are present in the output | ||
- ha_cluster_cluster_present | ||
- ha_cluster_start_on_boot | ||
- ha_cluster_cluster_name | ||
- ha_cluster_transport | ||
- ha_cluster_totem | ||
- ha_cluster_quorum | ||
- ha_cluster_node_options - currently only node_name, | ||
corosync_addresses and pcs_address are present | ||
- HORIZONTALLINE | ||
- Following variables are required for running ha_cluster role but are | ||
never present in this module output | ||
- ha_cluster_hacluster_password | ||
- HORIZONTALLINE | ||
- Following variables are never present in this module output (consult | ||
the role documentation for impact of the variables missing) | ||
- ha_cluster_corosync_key_src | ||
- ha_cluster_pacemaker_key_src | ||
- ha_cluster_fence_virt_key_src | ||
- ha_cluster_regenerate_keys | ||
- HORIZONTALLINE | ||
""" | ||
|
||
from typing import Any, Dict, List, Optional, Tuple | ||
|
||
from ansible.module_utils.basic import AnsibleModule | ||
|
||
# pylint: disable=no-name-in-module | ||
from ansible.module_utils.ha_cluster_lsr.info import exporter, loader | ||
|
||
|
||
def get_cmd_runner(module: AnsibleModule) -> loader.CommandRunner: | ||
""" | ||
Provide a function responsible for running external processes | ||
""" | ||
|
||
def runner( | ||
args: List[str], environ_update: Optional[Dict[str, str]] = None | ||
) -> Tuple[int, str, str]: | ||
return module.run_command( | ||
args, check_rc=False, environ_update=environ_update | ||
) | ||
|
||
return runner | ||
|
||
|
||
def export_cluster_configuration(module: AnsibleModule) -> Dict[str, Any]: | ||
""" | ||
Export existing HA cluster configuration | ||
""" | ||
# Until pcs is able to export the whole configuration in one go, we need to | ||
# put it together from separate parts provided by pcs. Some parts are only | ||
# available in recent pcs versions. Check pcs capabilities. | ||
result: dict[str, Any] = dict() | ||
cmd_runner = get_cmd_runner(module) | ||
|
||
corosync_enabled = loader.is_service_enabled(cmd_runner, "corosync") | ||
pacemaker_enabled = loader.is_service_enabled(cmd_runner, "pacemaker") | ||
result["ha_cluster_start_on_boot"] = exporter.export_start_on_boot( | ||
corosync_enabled, pacemaker_enabled | ||
) | ||
|
||
# Corosync config is availabe via CLI since pcs-0.10.8, via API v2 since | ||
# pcs-0.12.0 and pcs-0.11.9. For old pcs versions, CLI must be used, and | ||
# there is no benefit in implementing access via API on top of that. | ||
# No need to check pcs capabilities. If this is not supported by pcs, | ||
# exporting anything else is pointless (and not supported by pcs anyway). | ||
corosync_conf_pcs = loader.get_corosync_conf(cmd_runner) | ||
# known-hosts file is available since pcs-0.10, but is not exported by pcs | ||
# in any version. | ||
# No need to check pcs capabilities. | ||
known_hosts_pcs = loader.get_pcsd_known_hosts() | ||
|
||
# Convert corosync config to role format | ||
result["ha_cluster_cluster_name"] = exporter.export_corosync_cluster_name( | ||
corosync_conf_pcs | ||
) | ||
result["ha_cluster_transport"] = exporter.export_corosync_transport( | ||
corosync_conf_pcs | ||
) | ||
exported_totem = exporter.export_corosync_totem(corosync_conf_pcs) | ||
if exported_totem: | ||
result["ha_cluster_totem"] = exported_totem | ||
exported_quorum = exporter.export_corosync_quorum(corosync_conf_pcs) | ||
if exported_quorum: | ||
result["ha_cluster_quorum"] = exported_quorum | ||
|
||
# Convert nodes definition to role format | ||
result["ha_cluster_node_options"] = exporter.export_cluster_nodes( | ||
corosync_conf_pcs, known_hosts_pcs | ||
) | ||
|
||
return result | ||
|
||
|
||
def main() -> None: | ||
""" | ||
Top level module function | ||
""" | ||
module_args: Dict[str, Any] = dict() | ||
module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) | ||
|
||
module_result: Dict[str, Any] = dict() | ||
ha_cluster_result: Dict[str, Any] = dict() | ||
module_result["ha_cluster"] = ha_cluster_result | ||
|
||
try: | ||
if loader.has_corosync_conf(): | ||
ha_cluster_result.update(**export_cluster_configuration(module)) | ||
ha_cluster_result["ha_cluster_cluster_present"] = True | ||
else: | ||
ha_cluster_result["ha_cluster_cluster_present"] = False | ||
module.exit_json(**module_result) | ||
except exporter.JsonMissingKey as e: | ||
module.fail_json( | ||
msg=f"Missing key {e.key} in pcs {e.data_desc} JSON output", | ||
error_details=e.kwargs, | ||
) | ||
except loader.JsonParseError as e: | ||
module.fail_json( | ||
msg="Error while parsing pcs JSON output", error_details=e.kwargs | ||
) | ||
except loader.CliCommandError as e: | ||
module.fail_json(msg="Error while running pcs", error_details=e.kwargs) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Empty file.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
System roles, by convention, do not support users using modules directly. In every other role that does something like this, users use the role with either no arguments like https://github.com/linux-system-roles/firewall?tab=readme-ov-file#gathering-firewall-ansible-facts:
or with some special variable
I think the ha_cluster role will have to do something like the latter, since there are numerous public api variables, as opposed to the firewall role which just has the one main
firewall
variable. The latter also makes it possible for the role toThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The role would then set a global variable e.g.
ha_cluster_info
that users would use. This return variable will be declared in the README.md in the sectionVariables Exported by the Role
e.g. https://github.com/linux-system-roles/kernel_settings?tab=readme-ov-file#variables-exported-by-the-roleThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bootloader and snapshot roles export info with
<rolename>_facts
variable. Let's be consistent with this naming.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I've been busy with other projects.
I wasn't sure what would be the correct way to expose the export functionality. So I'm glad you pointed me in the right direction. I'm going to implement this change, hopefully in a couple of weeks, once I finish tasks that require my immediate attention.