-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
add pacemaker_resource plugin #9531
base: main
Are you sure you want to change the base?
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
3ced6e7
to
1c0286e
Compare
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.
Hi @munchtoast thanks for your contribution!
I have many comments on this PR, hope not to crush your motivation. We have all made these mistakes in the past, it is just a matter of learning. :-)
Also, please note that all new modules must have tests created with them (unit tests or integration tests).
In your case, since this is a module based on run_command()
, you can easily write unit tests using the test helper I wrote. Take a look at the directory
https://github.com/ansible-collections/community.general/tree/main/tests/unit/plugins/modules take a look at the tests modules that have an accompanying YAML file. I am yet to write proper documentation for that helper, but its use should be quite straightforward. If you decide to follow this path, I will be happy to assist you with those tests.
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.
Hi @munchtoast , still a draft, I know, but leaving a couple of comments nonetheless.
Hi @russoz, thank you so much for your reviews! I am currently writing unit tests but running into issues. I'll push what I have but I'm sorry for slow delay in applying feedback. Just wanted to give you an update that my wip commits should come in by end of this weekend. |
No worries, take your time and feel free to ask for help. We have all been there once 😉 |
Noticing that there may be an issue with the current implementation, where the Also I noticed in other |
This comment was marked as resolved.
This comment was marked as resolved.
Without seeing the specific error it's going to be hard to guess what the problem is. Could you please push the code generating that error so I can see the output here? Or if one of these runs above had that, please point it to me. Couple of housekeeping comments:
|
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.
Additionally, some comments on the code - there are some improvements that could be made.
@munchtoast this PR contains the following merge commits: Please rebase your branch to remove these commits. |
I don't think this is an error, but seems to be misunderstanding on my part as I am still learning. Other test
Should be up to date now! |
|
||
def __init_module__(self): | ||
self.runner = pacemaker_runner(self.module, cli_action='resource') | ||
self.does_not = "Error: resource or tag id '{0}' not found".format( |
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.
Is this attribute being used? If not, then remove.
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.
Hi @munchtoast
I took abother look and spotted a couple of things more. I know this can be tiring and even frustrating and I want to thank you for your resilience.
See comments below. Thx
anchors: | ||
environ: &env-def {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false} | ||
test_cases: | ||
- id: test_missing_input |
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.
please increase the indentation by 2 spaces for this list - not only as it is kinda becoming our convention in the collection, but also for consistency (see line 22 for example)
value: " * virtual-ip\t(ocf:heartbeat:IPAddr2):\t Started" | ||
mocks: | ||
run_command: | ||
- command: ["/testbin/pcs", resource, status, virtual-ip] |
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.
minor nit, not blocking anything but just for the record, those quotes are not needed:
- command: ["/testbin/pcs", resource, status, virtual-ip] | |
- command: [/testbin/pcs, resource, status, virtual-ip] |
change_params = ('name', ) | ||
diff_params = ('name', ) |
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.
I missed this before, sorry, but I don't think the value of name
will change, will it?
self.vars.set('_value', self.vars.previous_value, output=False, change=True) | ||
self.vars.set_meta('value', initial_value=self.vars.previous_value) |
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.
while on the other hand, value of value
is likely going to change, so maybe you add change=True, diff=True
to it...
... and then you can ditch the variable _value
, as you would be tracking change directly in the variable value
.
self.vars.value = None if out == "" else out | ||
return self.vars.value |
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.
This is something else that I missed - within this tiny little function (defined within another function), you're making a change to the state of an attribute of another attribute of the class. It is not a huge problem in this context, so I will not press on you changing this, but just for the record, one thing that is usually important in software engineering is separation of concerns. This function should not be concerned about the object, its attribute, and the attribute of its attribute. There are probably better ways to explain that - I am not much of an academic - but making that reference here kinda breaks that separation. What you usually want to do is to have smaller pieces specialized in doing one thing and one thing only. In this case, I would write it as:
self.vars.value = None if out == "" else out | |
return self.vars.value | |
return None if out == "" else out |
and later, when calling ctx.run()
(line 193 for example), you would do:
self.vars.value = ctx.run()
you might argue that you are saving for attributing the variable once instead of four times, but that pays off in readability, maintainability. Five years from now, someone (maybe even yourself, if you stay away from the module for a while), will read the state_absent()
method and will have no idea that self.vars.value
is altered at all. It is not obvious. Only if you read the entire thing, paying attention to the details, that will become evident. Sometimes it is better to write more and read/understand quicker than the other way around. ;-) my $0.02
Again, it is not a major issue in the context of a single Ansible module, but I try to make things better even in small situations. Feel free to reject the suggestion. :-)
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.
Thank you for the explanation! I pushed in a new commit which should remove unintended modification on self.vars.value
, and uses the proposed self.vars.value = ctx.run()
. To pass with the current unit tests, I pushed this as replacement:
self.vars.value = ctx.run()
self.vars.set('value', self._get())
...Which should pass the unit tests but I'm not sure if this is too redundant? I could maybe remove the self.vars.set('value', self._get())
, though it would be more definitive in terms of resource status.
Thoughts on this current approach?
self.vars.stdout = ctx.results_out | ||
self.vars.stderr = ctx.results_err | ||
self.vars.cmd = ctx.cmd | ||
self.vars.set('new_value', self._get(), fact=True) |
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.
whoa, and I missed that one before as well: I don't think we should be generating ansible_facts from this. Any particular reason to be using that?
Cc: @felixfontein
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.
I agree, modules should never return ansible_facts
except in very special situations. I don't think this module is one of these exceptions. Can you explain why this module should return facts?
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.
Thank you for the catch! The ansible_facts
should not be returned here, and was a mistake on my end. This should be removed in a new commit.
short_description: Manage pacemaker resources | ||
author: | ||
- Dexter Le (@munchtoast) | ||
version_added: 10.4.0 |
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.
10.4.0 has been released, please adjust this to:
version_added: 10.4.0 | |
version_added: 10.5.0 |
Refactorization on pacemaker_resource to utilize module helpers.
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
SUMMARY
Adds in pacemaker_resource plugin for managing pacemaker cluster resources.
ISSUE TYPE
COMPONENT NAME
pacemaker_resource
ADDITIONAL INFORMATION