mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-09-30 05:23:21 -07:00
pacemaker_resource: Add cloning support for resources and groups (#10665)
Some checks are pending
EOL CI / EOL Sanity (Ⓐ2.16) (push) Waiting to run
EOL CI / EOL Units (Ⓐ2.16+py2.7) (push) Waiting to run
EOL CI / EOL Units (Ⓐ2.16+py3.11) (push) Waiting to run
EOL CI / EOL Units (Ⓐ2.16+py3.6) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/1/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/2/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/3/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/1/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/2/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/3/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/1/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/2/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/3/) (push) Waiting to run
nox / Run extra sanity tests (push) Waiting to run
Some checks are pending
EOL CI / EOL Sanity (Ⓐ2.16) (push) Waiting to run
EOL CI / EOL Units (Ⓐ2.16+py2.7) (push) Waiting to run
EOL CI / EOL Units (Ⓐ2.16+py3.11) (push) Waiting to run
EOL CI / EOL Units (Ⓐ2.16+py3.6) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/1/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/2/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/3/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/1/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/2/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/3/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/1/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/2/) (push) Waiting to run
EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/3/) (push) Waiting to run
nox / Run extra sanity tests (push) Waiting to run
* add clone state for pacemaker_resource * add changelog fragment * Additional description entry for comment header * Apply suggestions from code review Co-authored-by: Felix Fontein <felix@fontein.de> * Update plugins/modules/pacemaker_resource.py Co-authored-by: Felix Fontein <felix@fontein.de> * fix formatting for yamllint * Apply code review suggestions * refactor state name to cloned * Update plugins/modules/pacemaker_resource.py Co-authored-by: Felix Fontein <felix@fontein.de> * Apply suggestions from code review Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> * Apply suggestions from code review --------- Co-authored-by: Felix Fontein <felix@fontein.de> Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
This commit is contained in:
parent
d0123a1038
commit
3baa13a3e4
4 changed files with 113 additions and 7 deletions
2
changelogs/fragments/10665-pacemaker-resource-clone.yml
Normal file
2
changelogs/fragments/10665-pacemaker-resource-clone.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- pacemaker_resource - add ``state=cloned`` for cloning pacemaker resources or groups (https://github.com/ansible-collections/community.general/issues/10322, https://github.com/ansible-collections/community.general/pull/10665).
|
|
@ -13,6 +13,7 @@ from ansible_collections.community.general.plugins.module_utils.cmd_runner impor
|
|||
_state_map = {
|
||||
"present": "create",
|
||||
"absent": "remove",
|
||||
"cloned": "clone",
|
||||
"status": "status",
|
||||
"enabled": "enable",
|
||||
"disabled": "disable",
|
||||
|
@ -65,6 +66,8 @@ def pacemaker_runner(module, **kwargs):
|
|||
resource_operation=cmd_runner_fmt.as_func(fmt_resource_operation),
|
||||
resource_meta=cmd_runner_fmt.stack(cmd_runner_fmt.as_opt_val)("meta"),
|
||||
resource_argument=cmd_runner_fmt.as_func(fmt_resource_argument),
|
||||
resource_clone_ids=cmd_runner_fmt.as_list(),
|
||||
resource_clone_meta=cmd_runner_fmt.as_list(),
|
||||
apply_all=cmd_runner_fmt.as_bool("--all"),
|
||||
agent_validation=cmd_runner_fmt.as_bool("--agent-validation"),
|
||||
wait=cmd_runner_fmt.as_opt_eq_val("--wait"),
|
||||
|
|
|
@ -27,13 +27,14 @@ options:
|
|||
state:
|
||||
description:
|
||||
- Indicate desired state for cluster resource.
|
||||
- The state V(cleanup) has been added in community.general 11.3.0.
|
||||
choices: [present, absent, enabled, disabled, cleanup]
|
||||
- The states V(cleanup) and V(cloned) have been added in community.general 11.3.0.
|
||||
- If O(state=cloned) or O(state=present), you can set O(resource_clone_ids) and O(resource_clone_meta) to determine exactly what and how to clone.
|
||||
choices: [present, absent, cloned, enabled, disabled, cleanup]
|
||||
default: present
|
||||
type: str
|
||||
name:
|
||||
description:
|
||||
- Specify the resource name to create.
|
||||
- Specify the resource name to create or clone to.
|
||||
- This is required if O(state=present), O(state=absent), O(state=enabled), or O(state=disabled).
|
||||
type: str
|
||||
resource_type:
|
||||
|
@ -95,6 +96,18 @@ options:
|
|||
- Options to associate with resource action.
|
||||
type: list
|
||||
elements: str
|
||||
resource_clone_ids:
|
||||
description:
|
||||
- List of clone resource IDs to clone from.
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 11.3.0
|
||||
resource_clone_meta:
|
||||
description:
|
||||
- List of metadata to associate with clone resource.
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 11.3.0
|
||||
wait:
|
||||
description:
|
||||
- Timeout period for polling the resource creation.
|
||||
|
@ -142,7 +155,7 @@ class PacemakerResource(StateModuleHelper):
|
|||
module = dict(
|
||||
argument_spec=dict(
|
||||
state=dict(type='str', default='present', choices=[
|
||||
'present', 'absent', 'enabled', 'disabled', 'cleanup']),
|
||||
'present', 'absent', 'cloned', 'enabled', 'disabled', 'cleanup']),
|
||||
name=dict(type='str'),
|
||||
resource_type=dict(type='dict', options=dict(
|
||||
resource_name=dict(type='str'),
|
||||
|
@ -159,6 +172,8 @@ class PacemakerResource(StateModuleHelper):
|
|||
argument_action=dict(type='str', choices=['clone', 'master', 'group', 'promotable']),
|
||||
argument_option=dict(type='list', elements='str'),
|
||||
)),
|
||||
resource_clone_ids=dict(type='list', elements='str'),
|
||||
resource_clone_meta=dict(type='list', elements='str'),
|
||||
wait=dict(type='int', default=300),
|
||||
),
|
||||
required_if=[
|
||||
|
@ -194,6 +209,10 @@ class PacemakerResource(StateModuleHelper):
|
|||
('out', result[1] if result[1] != "" else None),
|
||||
('err', result[2])])
|
||||
|
||||
def fmt_as_stack_argument(self, value, arg):
|
||||
if value is not None:
|
||||
return [x for k in value for x in (arg, k)]
|
||||
|
||||
def state_absent(self):
|
||||
force = get_pacemaker_maintenance_mode(self.runner)
|
||||
with self.runner('cli_action state name force', output_process=self._process_command_output(True, "does not exist"), check_mode_skip=True) as ctx:
|
||||
|
@ -201,10 +220,19 @@ class PacemakerResource(StateModuleHelper):
|
|||
|
||||
def state_present(self):
|
||||
with self.runner(
|
||||
'cli_action state name resource_type resource_option resource_operation resource_meta resource_argument wait',
|
||||
'cli_action state name resource_type resource_option resource_operation resource_meta resource_argument '
|
||||
'resource_clone_ids resource_clone_meta wait',
|
||||
output_process=self._process_command_output(not get_pacemaker_maintenance_mode(self.runner), "already exists"),
|
||||
check_mode_skip=True) as ctx:
|
||||
ctx.run(cli_action='resource')
|
||||
ctx.run(cli_action='resource', resource_clone_ids=self.fmt_as_stack_argument(self.module.params["resource_clone_ids"], "clone"))
|
||||
|
||||
def state_cloned(self):
|
||||
with self.runner(
|
||||
'cli_action state name resource_clone_ids resource_clone_meta wait',
|
||||
output_process=self._process_command_output(
|
||||
not get_pacemaker_maintenance_mode(self.runner),
|
||||
"already a clone resource"), check_mode_skip=True) as ctx:
|
||||
ctx.run(cli_action='resource', resource_clone_meta=self.fmt_as_stack_argument(self.module.params["resource_clone_meta"], "meta"))
|
||||
|
||||
def state_enabled(self):
|
||||
with self.runner('cli_action state name', output_process=self._process_command_output(True, "Starting"), check_mode_skip=True) as ctx:
|
||||
|
|
|
@ -78,6 +78,10 @@ test_cases:
|
|||
argument_action: group
|
||||
argument_option:
|
||||
- test_group
|
||||
resource_clone_ids:
|
||||
- test_clone
|
||||
resource_clone_meta:
|
||||
- test_clone_meta1=789
|
||||
wait: 200
|
||||
output:
|
||||
changed: true
|
||||
|
@ -100,7 +104,7 @@ test_cases:
|
|||
dc-version=2.1.9-1.fc41-7188dbf
|
||||
have-watchdog=false
|
||||
err: ""
|
||||
- command: [/testbin/pcs, resource, create, virtual-ip, ocf:heartbeat:IPaddr2, "ip=[192.168.2.1]", op, start, timeout=1200, op, stop, timeout=1200, op, monitor, timeout=1200, meta, test_meta1=123, meta, test_meta2=456, --group, test_group, --wait=200]
|
||||
- command: [/testbin/pcs, resource, create, virtual-ip, ocf:heartbeat:IPaddr2, "ip=[192.168.2.1]", op, start, timeout=1200, op, stop, timeout=1200, op, monitor, timeout=1200, meta, test_meta1=123, meta, test_meta2=456, --group, test_group, clone, test_clone, test_clone_meta1=789, --wait=200]
|
||||
environ: *env-def
|
||||
rc: 0
|
||||
out: "Assumed agent name 'ocf:heartbeat:IPaddr2'"
|
||||
|
@ -496,3 +500,72 @@ test_cases:
|
|||
rc: 0
|
||||
out: "NO resources configured"
|
||||
err: ""
|
||||
- id: test_clone_minimal_input_resource_not_exist
|
||||
input:
|
||||
state: cloned
|
||||
name: virtual-ip
|
||||
output:
|
||||
failed: true
|
||||
msg: "pcs failed with error (rc=1): Error: unable to find group or resource: virtual-ip"
|
||||
mocks:
|
||||
run_command:
|
||||
- command: [/testbin/pcs, resource, status, virtual-ip]
|
||||
environ: *env-def
|
||||
rc: 1
|
||||
out: ""
|
||||
err: "Error: resource or tag id 'virtual-ip' not found"
|
||||
- command: [/testbin/pcs, property, config]
|
||||
environ: *env-def
|
||||
rc: 1
|
||||
out: |
|
||||
Cluster Properties: cib-bootstrap-options
|
||||
cluster-infrastructure=corosync
|
||||
cluster-name=hacluster
|
||||
dc-version=2.1.9-1.fc41-7188dbf
|
||||
have-watchdog=false
|
||||
err: ""
|
||||
- command: [/testbin/pcs, resource, clone, virtual-ip, --wait=300]
|
||||
environ: *env-def
|
||||
rc: 1
|
||||
out: ""
|
||||
err: "Error: unable to find group or resource: virtual-ip"
|
||||
- id: test_clone_filled_input_resource_exists
|
||||
input:
|
||||
state: cloned
|
||||
name: virtual-ip
|
||||
resource_clone_ids:
|
||||
- test_clone
|
||||
resource_clone_meta:
|
||||
- test_clone_meta1=789
|
||||
wait: 200
|
||||
output:
|
||||
changed: true
|
||||
previous_value: " * virtual-ip\t(ocf:heartbeat:IPAddr2):\t Started"
|
||||
value: " * Clone Set: virtual-ip-clone [virtual-ip]\t(ocf:heartbeat:IPAddr2):\t Started"
|
||||
mocks:
|
||||
run_command:
|
||||
- command: [/testbin/pcs, resource, status, virtual-ip]
|
||||
environ: *env-def
|
||||
rc: 0
|
||||
out: " * virtual-ip\t(ocf:heartbeat:IPAddr2):\t Started"
|
||||
err: ""
|
||||
- command: [/testbin/pcs, property, config]
|
||||
environ: *env-def
|
||||
rc: 1
|
||||
out: |
|
||||
Cluster Properties: cib-bootstrap-options
|
||||
cluster-infrastructure=corosync
|
||||
cluster-name=hacluster
|
||||
dc-version=2.1.9-1.fc41-7188dbf
|
||||
have-watchdog=false
|
||||
err: ""
|
||||
- command: [/testbin/pcs, resource, clone, virtual-ip, test_clone, meta, test_clone_meta1=789, --wait=200]
|
||||
environ: *env-def
|
||||
rc: 0
|
||||
out: ""
|
||||
err: ""
|
||||
- command: [/testbin/pcs, resource, status, virtual-ip]
|
||||
environ: *env-def
|
||||
rc: 0
|
||||
out: " * Clone Set: virtual-ip-clone [virtual-ip]\t(ocf:heartbeat:IPAddr2):\t Started"
|
||||
err: ""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue