-
Notifications
You must be signed in to change notification settings - Fork 89
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
Refactor x509_certificate module, add x509_certificate_pipe module #135
Refactor x509_certificate module, add x509_certificate_pipe module #135
Conversation
ready_for_review @ctrufan could you test whether with this PR the |
Probably not until later this week or this weekend unfortunately, need to rebuild my testing VM. |
4a5d6d1
to
369e92d
Compare
Tests should run better now that #137 is done and merged. The remaining failed run is because RHEL8 is currently broken in CI (unrelated to any PR). |
@ctrufan did you got around to test this already? |
369e92d
to
480ea30
Compare
(I rebased to be able to work with this module with the bugfix from #141.) |
@felixfontein Do I need to run the tests from the primary ansible subdirectory? I tried running from the checked out branch for openssl_certificate_pipe and got an error. The documentation doesn't quite make it clear how to run tests within a collection-from-code.
|
Nevermind, I didn't have quite the right folder structure. Working on testing now/today. Sorry about the unnecessary ping! |
It's not working even pre-pull request because entrust_certificate was broken when the additions were made to support providing the full cert instead of path for 2.10/community migration.
vs, for example, ownca:
I forgot you can't bold within a code block, but it's a difference between and and or. [Edit: I'll keep testing tomorrow after manually fixing ] |
plugins/module_utils/crypto/module_backends/certificate_entrust.py
Outdated
Show resolved
Hide resolved
Hmm, that bad condition comes from ansible/ansible#66384. Looks like we totally overlooked it back then... |
I guess we should sooner or later add some kind of tests for the ECS modules. Integration tests will need some kind of API simulator. Alternatively, this could be done as a unit test which patches the |
I like the idea of returning a mocked response, but it would get a bit tricky, because there's a call to download the API spec unless it's provided locally (the download is unauthenticated, but I don't think it would be great to have a unit test download a large file hah, nor would it be good to include large file in the repo). So the easier route to go might be to mock the module_util return somehow. We do have integration tests on 'our' side, but I neglected to update them for the new collections paradigm, which requires quite a few tweaks to the molecule framework. |
I've run the new acme provider tests from #142 with this PR and they passed. So at least the acme provider still seems to work with this PR ;) |
@ctrufan with large file, do you mean https://cloud.entrust.net/EntrustCloud/documentation/cms-api-2.1.0.yaml ? It's "only" 110 kb, so downloading it during the tests should be ok. (Assuming your server doesn't mind.) It's probably best to download it once during test setup, and then keep the file locally. In any case, mocking the module_utils is definitely easier. And it still allows us to do some modifications to the caller and being half-way confident that it still works ;) |
Previously, if the certificate file pointed to by path was an empty or invalid file, the module still worked, and replaced it with a valid certificate. That's no longer the case, but I think that's valid behavior, it's only "not backwards compatible" in a "this probably shouldn't have worked anyways" sense. Running into some issues getting the test CA recognized properly after updating Python, because using custom CA certs is an OS/python version dependent nightmare, so might not have the valid test case through until tomorrow - module is working correctly up through the cert request stage though. |
Yeah our server has no problem with multiple downloads of the spec. Something that's been on my to-do list for ages is to update the module so that it can 'cache' the API spec, but it's not something (last I looked) that Ansible has elegant solutions for. |
That wasn't an intended change - I've restored the old behavior in dce4f76.
Indeed!
BTW, I recently learned of https://trustme.readthedocs.io/en/latest/ (ansible-community/antsibull-build#133). Haven't gotten around to really look into it yet, but it might help with such things. Or at least its internals might be useful :) |
Since modules can run anywhere, it's kind of hard to cache something reliably. (And most users don't want modules to create files in random positions they didn't explicitly ask for.) Maybe there could be a module |
That's a neat project, I'll have to look at it more indepth sometime, but I suspect it solves a different problem - I've got a robust test CA infrastructure set up, CRLs/OCSP included, but the underlying HTTP calls made by the python url libraries like to insist there's no such thing as an operating system or editable trust store, especially if certifi is installed. |
That was my thought process when I was first developing the module and wanted to cache - don't want to create a file the user isn't expecting, can't easily store it in memory because of how modules run anywhere. |
Tested the module, and it looks good, worked with entrust provider after the fixes. (I'm assuming from PR description entrust doesn't leverage the new "pipe" module, so there's no new input/output paradigms I need to test?) Though now I definitely need to carve time out to add unit tests and update our integration tests to work properly with collections, newer python min version, etc... and probably update x509 w/ entrust provider, and ecs_certificate to take advantage of similar new functionality... |
@ctrufan thanks for testing!!! I noticed that I wrote the PR description some time ago when I didn't actually implement the _pipe module; right now the _pipe module also supports the entrust provider, but from the way the unified provider interface works, it should probably just work. But then, it's still better to check it I guess ;) I guess there are two choices: a) remove the entrust provider - that's a very simple change. b) you actually test it. I'd like to get this merged soon, so I guess if you don't have time now to test it, it's better to remove it for now. Re-adding it later is very easy, so we can do that for the next release without much work involved. (Well, at least not for me - it's mostly work for you, thanks to testing :) ) What do you think? |
It looks like if I use x509_certificate_pipe, requests fail when I pass file contents in with lookup(), because the value of "csr" that gets populated in the API request that goes out to the server is bytes rather than a string. It works if I throw an arbitrary to_text in the line of entrust_certificate around line 100 (along with an import of to_text at the top) I think a better answer might be that I should be converting all the values in the array that gets passed to the ECS api.py file to normalize them to text. Either that or doing something on first parameter load. I'll have to revisit the ansible guidelines on this stuff and Python 2/3, all the string/byte stuff is not something I recall without looking it up again! I don't think I'll have time to investigate any farther until tomorrow, so feel free to merge it with the provider removed for now, I don't want to delay your merge. |
Actually x509_certificate would fail the same way if you use
This is the correct fix (except that using
For everything that is taken from
I'll still wait a few days, in the hope that @MarkusTeufelberger also finds some time to look at this :) |
Co-authored-by: Chris Trufan <31186388+ctrufan@users.noreply.github.com>
Co-authored-by: Chris Trufan <31186388+ctrufan@users.noreply.github.com>
This reverts commit 6ee5d7d.
01bbf93
to
a5f5424
Compare
I rebased to |
@Xyon @Shaps @MarkusTeufelberger @puiterwijk would be happy if one of you could take a look at this PR! |
Sorry for the radio silence, bit busy times right now... :-/ I'll take a look at it in the evening today. |
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 mostly looked at documentation and kinda hope that immediate failures would be caught by the integration tests. Hope it still helps, thanks for the great work as always!
- debug: | ||
var: result.certificate | ||
|
||
- name: Generate an OpenSSL Certificate Signing Request with an inline certificate |
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.
Create a CSR with an inline certificate? I'm not sure I understand what this should do...
Probably this task should also be delegated to localhost
in a more realistic scenario, right?
Might be worth having an example where a certificate is slurp
ed to the Ansible host, checked/modified by community.crypto.x509_certificate_pipe
there and then copied back with copy
to the target host again.
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.
Heh, it should have been Generate certificate with inline CSR
:) I've fixed that. I also added more comments and a delegate_to
to the copy
task. This example should show that while the OwnCA data (private key, certificate) is on the remote machine, we don't have to copy CSR and certificate to/from there.
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 reformatted the example and added another one as you suggested.
Co-authored-by: MarkusTeufelberger <mteufelberger@mgit.at>
recheck |
@MarkusTeufelberger if you're happy with the changes, I'll merge (and release 1.3.0 I guess, if nobody objects). |
def get_certificate_argument_spec(): | ||
return ArgumentSpec( | ||
argument_spec=dict( | ||
provider=dict(type='str', choices=[]), |
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.
ehm is this as it should?
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.
Yes: the choices
list is updated for example here: https://github.com/ansible-collections/community.crypto/pull/135/files#diff-ccf70653d5d26e8f8b623afd6fccc608043ef7ac3b6481e4a9851a0c74338409R113
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.
(Maybe a comment would help, though :) )
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.
Added 14a0ca7
# General properties of a certificate | ||
privatekey_path=dict(type='path'), | ||
privatekey_content=dict(type='str', no_log=True), | ||
privatekey_passphrase=dict(type='str', no_log=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.
👌 no_log=True ;)
@ctrufan @MarkusTeufelberger @resmo thanks a lot for all the testing and reviewing!!! |
SUMMARY
Similar refactoring / addition than in #119 and #123: refactor x509_certificate module to move large parts of documentation to doc fragments and large pieces of code to module backends, in this case split up per provider, and add a new x509_certificate_pipe module which does not operate on certificate files (and supports only a subset of the providers, maybe just selfsigned and ownca in the beginning).
ISSUE TYPE
COMPONENT NAME
x509_certificate
x509_certificate_pipe