From 3f0e2922465b4c3fedcf77cfd435ea8e76100c4f Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 30 Dec 2024 21:11:12 +0100 Subject: [PATCH] Add 'idempotent' attribute (#833) * Add 'idempotent' attribute. * Mention check mode in attribute description. Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --------- Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/doc_fragments/attributes.py | 14 ++++++++++++++ plugins/doc_fragments/module_certificate.py | 5 +++++ plugins/doc_fragments/module_csr.py | 2 ++ plugins/doc_fragments/module_privatekey.py | 4 ++++ plugins/doc_fragments/module_privatekey_convert.py | 2 ++ plugins/modules/acme_account.py | 4 ++++ plugins/modules/acme_account_info.py | 1 + plugins/modules/acme_ari_info.py | 1 + plugins/modules/acme_certificate.py | 6 ++++++ .../modules/acme_certificate_deactivate_authz.py | 2 ++ plugins/modules/acme_certificate_renewal_info.py | 1 + plugins/modules/acme_certificate_revoke.py | 2 ++ plugins/modules/acme_challenge_cert_helper.py | 5 +++++ plugins/modules/acme_inspect.py | 2 ++ plugins/modules/certificate_complete_chain.py | 1 + plugins/modules/crypto_info.py | 1 + plugins/modules/ecs_certificate.py | 7 +++++++ plugins/modules/ecs_domain.py | 6 ++++++ plugins/modules/get_certificate.py | 1 + plugins/modules/luks_device.py | 2 ++ plugins/modules/openssh_cert.py | 5 +++++ plugins/modules/openssh_keypair.py | 4 ++++ plugins/modules/openssl_csr_info.py | 1 + plugins/modules/openssl_dhparam.py | 4 ++++ plugins/modules/openssl_pkcs12.py | 4 ++++ plugins/modules/openssl_privatekey_info.py | 1 + plugins/modules/openssl_publickey.py | 4 ++++ plugins/modules/openssl_publickey_info.py | 1 + plugins/modules/openssl_signature.py | 5 +++++ plugins/modules/openssl_signature_info.py | 1 + plugins/modules/x509_certificate_convert.py | 2 ++ plugins/modules/x509_certificate_info.py | 1 + plugins/modules/x509_crl.py | 5 +++++ plugins/modules/x509_crl_info.py | 1 + 34 files changed, 108 insertions(+) diff --git a/plugins/doc_fragments/attributes.py b/plugins/doc_fragments/attributes.py index 56f42542..ff1ac659 100644 --- a/plugins/doc_fragments/attributes.py +++ b/plugins/doc_fragments/attributes.py @@ -18,6 +18,20 @@ attributes: description: Can run in C(check_mode) and return changed status prediction without modifying target. diff_mode: description: Will return details on what has changed (or possibly needs changing in C(check_mode)), when in diff mode. + idempotent: + description: + - When run twice in a row outside check mode, with the same arguments, the second invocation indicates no change. + - This assumes that the system controlled/queried by the module has not changed in a relevant way. +""" + + # Should be used together with the standard fragment + IDEMPOTENT_NOT_MODIFY_STATE = r""" +options: {} +attributes: + idempotent: + support: full + details: + - This action does not modify state. """ # Should be used together with the standard fragment diff --git a/plugins/doc_fragments/module_certificate.py b/plugins/doc_fragments/module_certificate.py index e9a18fd6..c1f7b281 100644 --- a/plugins/doc_fragments/module_certificate.py +++ b/plugins/doc_fragments/module_certificate.py @@ -19,6 +19,11 @@ description: attributes: diff_mode: support: full + idempotent: + support: partial + details: + - If relative timestamps are used and O(ignore_timestamps=false), the module is not idempotent. + - The option O(force=true) generally disables idempotency. requirements: - cryptography >= 1.6 (if using V(selfsigned) or V(ownca) provider) options: diff --git a/plugins/doc_fragments/module_csr.py b/plugins/doc_fragments/module_csr.py index 18a18cc8..90c8ba15 100644 --- a/plugins/doc_fragments/module_csr.py +++ b/plugins/doc_fragments/module_csr.py @@ -18,6 +18,8 @@ description: attributes: diff_mode: support: full + idempotent: + support: full requirements: - cryptography >= 1.3 options: diff --git a/plugins/doc_fragments/module_privatekey.py b/plugins/doc_fragments/module_privatekey.py index fad9b9b3..8e3cbe2d 100644 --- a/plugins/doc_fragments/module_privatekey.py +++ b/plugins/doc_fragments/module_privatekey.py @@ -20,6 +20,10 @@ description: attributes: diff_mode: support: full + idempotent: + support: partial + details: + - The option O(regenerate=always) generally disables idempotency. requirements: - cryptography >= 1.2.3 (older versions might work as well) options: diff --git a/plugins/doc_fragments/module_privatekey_convert.py b/plugins/doc_fragments/module_privatekey_convert.py index 4db55f48..fbe3031b 100644 --- a/plugins/doc_fragments/module_privatekey_convert.py +++ b/plugins/doc_fragments/module_privatekey_convert.py @@ -17,6 +17,8 @@ requirements: attributes: diff_mode: support: none + idempotent: + support: full options: src_path: description: diff --git a/plugins/modules/acme_account.py b/plugins/modules/acme_account.py index 1c7e2f35..e2d18f76 100644 --- a/plugins/modules/acme_account.py +++ b/plugins/modules/acme_account.py @@ -43,6 +43,10 @@ attributes: support: full diff_mode: support: full + idempotent: + support: partial + details: + - If O(state=changed_key) is used, the module is not idempotent. options: state: description: diff --git a/plugins/modules/acme_account_info.py b/plugins/modules/acme_account_info.py index 00c82a9a..01918922 100644 --- a/plugins/modules/acme_account_info.py +++ b/plugins/modules/acme_account_info.py @@ -26,6 +26,7 @@ extends_documentation_fragment: - community.crypto.attributes - community.crypto.attributes.actiongroup_acme - community.crypto.attributes.info_module + - community.crypto.attributes.idempotent_not_modify_state options: retrieve_orders: description: diff --git a/plugins/modules/acme_ari_info.py b/plugins/modules/acme_ari_info.py index 52283f0d..0fb63829 100644 --- a/plugins/modules/acme_ari_info.py +++ b/plugins/modules/acme_ari_info.py @@ -24,6 +24,7 @@ extends_documentation_fragment: - community.crypto.acme.no_account - community.crypto.attributes - community.crypto.attributes.info_module + - community.crypto.attributes.idempotent_not_modify_state options: certificate_path: description: diff --git a/plugins/modules/acme_certificate.py b/plugins/modules/acme_certificate.py index 838e7ae9..57048322 100644 --- a/plugins/modules/acme_certificate.py +++ b/plugins/modules/acme_certificate.py @@ -81,6 +81,12 @@ attributes: support: none safe_file_operations: support: full + idempotent: + support: partial + details: + - If O(force=true), the module is not idempotent. + If O(force=false), it depends on the certificate's validity period and the value of O(remaining_days). + - The second phase invocation of the module is always idempotent, assuming no error occurs. options: account_email: description: diff --git a/plugins/modules/acme_certificate_deactivate_authz.py b/plugins/modules/acme_certificate_deactivate_authz.py index 1503c6f5..f01c8b72 100644 --- a/plugins/modules/acme_certificate_deactivate_authz.py +++ b/plugins/modules/acme_certificate_deactivate_authz.py @@ -33,6 +33,8 @@ attributes: support: full diff_mode: support: none + idempotent: + support: full options: order_uri: description: diff --git a/plugins/modules/acme_certificate_renewal_info.py b/plugins/modules/acme_certificate_renewal_info.py index 60ebe950..d4b62acb 100644 --- a/plugins/modules/acme_certificate_renewal_info.py +++ b/plugins/modules/acme_certificate_renewal_info.py @@ -23,6 +23,7 @@ extends_documentation_fragment: - community.crypto.acme.no_account - community.crypto.attributes - community.crypto.attributes.info_module + - community.crypto.attributes.idempotent_not_modify_state options: certificate_path: description: diff --git a/plugins/modules/acme_certificate_revoke.py b/plugins/modules/acme_certificate_revoke.py index d6264cd7..a1fc7cc4 100644 --- a/plugins/modules/acme_certificate_revoke.py +++ b/plugins/modules/acme_certificate_revoke.py @@ -41,6 +41,8 @@ attributes: support: none diff_mode: support: none + idempotent: + support: full options: certificate: description: diff --git a/plugins/modules/acme_challenge_cert_helper.py b/plugins/modules/acme_challenge_cert_helper.py index fa6bea1d..f4b08344 100644 --- a/plugins/modules/acme_challenge_cert_helper.py +++ b/plugins/modules/acme_challenge_cert_helper.py @@ -37,6 +37,11 @@ attributes: support: N/A details: - This action does not modify state. + idempotent: + support: none + details: + - The certificates returned are never the same, since the Not Before and Not After timestamps + depend on the invocation's timestamp. options: challenge: description: diff --git a/plugins/modules/acme_inspect.py b/plugins/modules/acme_inspect.py index c7bf0b19..016eef20 100644 --- a/plugins/modules/acme_inspect.py +++ b/plugins/modules/acme_inspect.py @@ -44,6 +44,8 @@ attributes: support: none diff_mode: support: none + idempotent: + support: none options: url: description: diff --git a/plugins/modules/certificate_complete_chain.py b/plugins/modules/certificate_complete_chain.py index 83c616a4..5e1965d4 100644 --- a/plugins/modules/certificate_complete_chain.py +++ b/plugins/modules/certificate_complete_chain.py @@ -24,6 +24,7 @@ requirements: - "cryptography >= 1.5" extends_documentation_fragment: - community.crypto.attributes + - community.crypto.attributes.idempotent_not_modify_state attributes: check_mode: support: full diff --git a/plugins/modules/crypto_info.py b/plugins/modules/crypto_info.py index a0065279..6eab6f76 100644 --- a/plugins/modules/crypto_info.py +++ b/plugins/modules/crypto_info.py @@ -21,6 +21,7 @@ description: extends_documentation_fragment: - community.crypto.attributes - community.crypto.attributes.info_module + - community.crypto.attributes.idempotent_not_modify_state options: {} """ diff --git a/plugins/modules/ecs_certificate.py b/plugins/modules/ecs_certificate.py index 3214da32..288179d6 100644 --- a/plugins/modules/ecs_certificate.py +++ b/plugins/modules/ecs_certificate.py @@ -37,6 +37,13 @@ attributes: support: none safe_file_operations: support: full + idempotent: + support: partial + details: + - The module is not idempotent if O(force=true). + - Under which conditions the module is idempotent still needs to be determined. + If you are using this module and have more information, please contribute to + the documentation! options: backup: description: diff --git a/plugins/modules/ecs_domain.py b/plugins/modules/ecs_domain.py index 93e76c3c..6e1e010f 100644 --- a/plugins/modules/ecs_domain.py +++ b/plugins/modules/ecs_domain.py @@ -44,6 +44,12 @@ attributes: support: none diff_mode: support: none + idempotent: + support: partial + details: + - Under which conditions the module is idempotent still needs to be determined. + If you are using this module and have more information, please contribute to + the documentation! options: client_id: description: diff --git a/plugins/modules/get_certificate.py b/plugins/modules/get_certificate.py index 92ff82ac..0e296808 100644 --- a/plugins/modules/get_certificate.py +++ b/plugins/modules/get_certificate.py @@ -20,6 +20,7 @@ description: newer. extends_documentation_fragment: - community.crypto.attributes + - community.crypto.attributes.idempotent_not_modify_state attributes: check_mode: support: none diff --git a/plugins/modules/luks_device.py b/plugins/modules/luks_device.py index dbc1b002..156f4b32 100644 --- a/plugins/modules/luks_device.py +++ b/plugins/modules/luks_device.py @@ -23,6 +23,8 @@ attributes: support: full diff_mode: support: none + idempotent: + support: full options: device: diff --git a/plugins/modules/openssh_cert.py b/plugins/modules/openssh_cert.py index bda3673b..b6e1d82c 100644 --- a/plugins/modules/openssh_cert.py +++ b/plugins/modules/openssh_cert.py @@ -28,6 +28,11 @@ attributes: support: full safe_file_operations: support: full + idempotent: + support: partial + details: + - The module is not idempotent if O(force=true) or O(regenerate=always). + - If relative timestamps are used and O(ignore_timestamps=false) (default), the module is not idempotent. options: state: description: diff --git a/plugins/modules/openssh_keypair.py b/plugins/modules/openssh_keypair.py index 1263c684..0269e529 100644 --- a/plugins/modules/openssh_keypair.py +++ b/plugins/modules/openssh_keypair.py @@ -30,6 +30,10 @@ attributes: support: full safe_file_operations: support: full + idempotent: + support: partial + details: + - The module is not idempotent if O(force=true) or O(regenerate=always). options: state: description: diff --git a/plugins/modules/openssl_csr_info.py b/plugins/modules/openssl_csr_info.py index 5b3bc984..53cdfe85 100644 --- a/plugins/modules/openssl_csr_info.py +++ b/plugins/modules/openssl_csr_info.py @@ -26,6 +26,7 @@ extends_documentation_fragment: - community.crypto.attributes - community.crypto.attributes.info_module - community.crypto.name_encoding + - community.crypto.attributes.idempotent_not_modify_state options: path: description: diff --git a/plugins/modules/openssl_dhparam.py b/plugins/modules/openssl_dhparam.py index 159b65d2..52c85dcf 100644 --- a/plugins/modules/openssl_dhparam.py +++ b/plugins/modules/openssl_dhparam.py @@ -35,6 +35,10 @@ attributes: support: none safe_file_operations: support: full + idempotent: + support: partial + details: + - The module is not idempotent if O(force=true). options: state: description: diff --git a/plugins/modules/openssl_pkcs12.py b/plugins/modules/openssl_pkcs12.py index f7c59ba2..b3529923 100644 --- a/plugins/modules/openssl_pkcs12.py +++ b/plugins/modules/openssl_pkcs12.py @@ -32,6 +32,10 @@ attributes: support: none safe_file_operations: support: full + idempotent: + support: partial + details: + - The module is not idempotent if O(force=true). options: action: description: diff --git a/plugins/modules/openssl_privatekey_info.py b/plugins/modules/openssl_privatekey_info.py index 5b4dbc93..944f0482 100644 --- a/plugins/modules/openssl_privatekey_info.py +++ b/plugins/modules/openssl_privatekey_info.py @@ -27,6 +27,7 @@ author: extends_documentation_fragment: - community.crypto.attributes - community.crypto.attributes.info_module + - community.crypto.attributes.idempotent_not_modify_state options: path: description: diff --git a/plugins/modules/openssl_publickey.py b/plugins/modules/openssl_publickey.py index 04157725..30bd792e 100644 --- a/plugins/modules/openssl_publickey.py +++ b/plugins/modules/openssl_publickey.py @@ -34,6 +34,10 @@ attributes: support: full safe_file_operations: support: full + idempotent: + support: partial + details: + - The module is not idempotent if O(force=true). options: state: description: diff --git a/plugins/modules/openssl_publickey_info.py b/plugins/modules/openssl_publickey_info.py index 8be4599a..33b639dd 100644 --- a/plugins/modules/openssl_publickey_info.py +++ b/plugins/modules/openssl_publickey_info.py @@ -23,6 +23,7 @@ author: extends_documentation_fragment: - community.crypto.attributes - community.crypto.attributes.info_module + - community.crypto.attributes.idempotent_not_modify_state options: path: description: diff --git a/plugins/modules/openssl_signature.py b/plugins/modules/openssl_signature.py index 1881c839..d35f18db 100644 --- a/plugins/modules/openssl_signature.py +++ b/plugins/modules/openssl_signature.py @@ -30,6 +30,11 @@ attributes: - This action does not modify state. diff_mode: support: none + idempotent: + support: partial + details: + - Signature algorithms are generally not deterministic. Thus the generated signature + can change from one invocation to the next. options: privatekey_path: description: diff --git a/plugins/modules/openssl_signature_info.py b/plugins/modules/openssl_signature_info.py index 8a9d631b..4b6e049c 100644 --- a/plugins/modules/openssl_signature_info.py +++ b/plugins/modules/openssl_signature_info.py @@ -24,6 +24,7 @@ author: extends_documentation_fragment: - community.crypto.attributes - community.crypto.attributes.info_module + - community.crypto.attributes.idempotent_not_modify_state options: path: description: diff --git a/plugins/modules/x509_certificate_convert.py b/plugins/modules/x509_certificate_convert.py index 2886a340..2c30663a 100644 --- a/plugins/modules/x509_certificate_convert.py +++ b/plugins/modules/x509_certificate_convert.py @@ -28,6 +28,8 @@ attributes: support: none safe_file_operations: support: full + idempotent: + support: full options: src_path: description: diff --git a/plugins/modules/x509_certificate_info.py b/plugins/modules/x509_certificate_info.py index 2c9bf0b0..2f6e66e1 100644 --- a/plugins/modules/x509_certificate_info.py +++ b/plugins/modules/x509_certificate_info.py @@ -31,6 +31,7 @@ author: extends_documentation_fragment: - community.crypto.attributes - community.crypto.attributes.info_module + - community.crypto.attributes.idempotent_not_modify_state - community.crypto.name_encoding options: path: diff --git a/plugins/modules/x509_crl.py b/plugins/modules/x509_crl.py index 30917ade..ac23f0f1 100644 --- a/plugins/modules/x509_crl.py +++ b/plugins/modules/x509_crl.py @@ -33,6 +33,11 @@ attributes: support: full safe_file_operations: support: full + idempotent: + support: partial + details: + - The module is not idempotent if O(force=true). + - If relative timestamps and O(ignore_timestamps=false) (default), the module is not idempotent. options: state: description: diff --git a/plugins/modules/x509_crl_info.py b/plugins/modules/x509_crl_info.py index 363bba37..83bddb9c 100644 --- a/plugins/modules/x509_crl_info.py +++ b/plugins/modules/x509_crl_info.py @@ -22,6 +22,7 @@ author: extends_documentation_fragment: - community.crypto.attributes - community.crypto.attributes.info_module + - community.crypto.attributes.idempotent_not_modify_state - community.crypto.name_encoding options: path: