From f67bdcb3679bb54f85921e6816f0b06ece5f2a4d Mon Sep 17 00:00:00 2001 From: Bruno Lavoie Date: Thu, 3 Jul 2025 10:22:18 -0400 Subject: [PATCH 1/4] Fix issue #10299 --- plugins/lookup/github_app_access_token.py | 38 +++++++++++++---------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/plugins/lookup/github_app_access_token.py b/plugins/lookup/github_app_access_token.py index dbc8cde3b5..a9d484a03c 100644 --- a/plugins/lookup/github_app_access_token.py +++ b/plugins/lookup/github_app_access_token.py @@ -9,10 +9,12 @@ DOCUMENTATION = r""" name: github_app_access_token author: - Poh Wei Sheng (@weisheng-p) + - Bruno Lavoie (@blavoie) short_description: Obtain short-lived Github App Access tokens version_added: '8.2.0' requirements: - - jwt (https://github.com/GehirnInc/python-jwt) + - PyJWT (https://pypi.org/project/PyJWT/) + - cryptography (https://pypi.org/project/cryptography/) description: - This generates a Github access token that can be used with a C(git) command, if you use a Github App. options: @@ -66,9 +68,14 @@ _raw: elements: str """ +try: + from cryptography.hazmat.primitives import serialization + HAS_CRYPTOGRAPHY = True +except ImportError: + HAS_CRYPTOGRAPHY = False try: - from jwt import JWT, jwk_from_pem + import jwt # pyjwt HAS_JWT = True except ImportError: HAS_JWT = False @@ -81,26 +88,20 @@ from ansible.errors import AnsibleError, AnsibleOptionsError from ansible.plugins.lookup import LookupBase from ansible.utils.display import Display -if HAS_JWT: - jwt_instance = JWT() -else: - jwk_from_pem = None - jwt_instance = None - display = Display() - def read_key(path, private_key=None): try: if private_key: - return jwk_from_pem(private_key.encode('utf-8')) - with open(path, 'rb') as pem_file: - return jwk_from_pem(pem_file.read()) + key_bytes = private_key.encode('utf-8') + else: + with open(path, 'rb') as pem_file: + key_bytes = pem_file.read() + return serialization.load_pem_private_key(key_bytes, password=None) except Exception as e: raise AnsibleError(f"Error while parsing key file: {e}") - -def encode_jwt(app_id, jwk, exp=600): +def encode_jwt(app_id, private_key_obj, exp=600): now = int(time.time()) payload = { 'iat': now, @@ -108,11 +109,10 @@ def encode_jwt(app_id, jwk, exp=600): 'iss': app_id, } try: - return jwt_instance.encode(payload, jwk, alg='RS256') + return jwt.encode(payload, private_key_obj, algorithm='RS256') except Exception as e: raise AnsibleError(f"Error while encoding jwt: {e}") - def post_request(generated_jwt, installation_id): github_api_url = f'https://api.github.com/app/installations/{installation_id}/access_tokens' headers = { @@ -150,7 +150,11 @@ class LookupModule(LookupBase): def run(self, terms, variables=None, **kwargs): if not HAS_JWT: raise AnsibleError('Python jwt library is required. ' - 'Please install using "pip install jwt"') + 'Please install using "pip install pyjwt"') + + if not HAS_CRYPTOGRAPHY: + raise AnsibleError('Python cryptography library is required. ' + 'Please install using "pip install cryptography"') self.set_options(var_options=variables, direct=kwargs) From 5fd196d280b069a1e461dd7bc070d8ccc5164fdf Mon Sep 17 00:00:00 2001 From: Bruno Lavoie Date: Thu, 3 Jul 2025 11:45:41 -0400 Subject: [PATCH 2/4] Fix issue #10299 --- changelogs/fragments/10299-github_app_access_token-lookup.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelogs/fragments/10299-github_app_access_token-lookup.yml diff --git a/changelogs/fragments/10299-github_app_access_token-lookup.yml b/changelogs/fragments/10299-github_app_access_token-lookup.yml new file mode 100644 index 0000000000..16a1e31524 --- /dev/null +++ b/changelogs/fragments/10299-github_app_access_token-lookup.yml @@ -0,0 +1,4 @@ +bugfixes: + - github_app_access_token lookup plugin - avoid using jwt library requirement that conflicts with other modules requirements (https://github.com/ansible-collections/community.general/issues/10299) +breaking_changes: + - github_app_access_token lookup plugin - depends now on pyjwt rather than jwt (https://github.com/ansible-collections/community.general/issues/10299) From 6e6b8d4776d9e4bb9c2d3ff98c248b098bce8af9 Mon Sep 17 00:00:00 2001 From: Bruno Lavoie Date: Thu, 3 Jul 2025 12:56:38 -0400 Subject: [PATCH 3/4] Fix blank lines --- plugins/lookup/github_app_access_token.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/lookup/github_app_access_token.py b/plugins/lookup/github_app_access_token.py index a9d484a03c..747b857815 100644 --- a/plugins/lookup/github_app_access_token.py +++ b/plugins/lookup/github_app_access_token.py @@ -139,13 +139,11 @@ def post_request(generated_jwt, installation_id): raise AnsibleError(f"Error while dencoding JSON respone from github: {e}") return json_data.get('token') - def get_token(key_path, app_id, installation_id, private_key, expiry=600): jwk = read_key(key_path, private_key) generated_jwt = encode_jwt(app_id, jwk, exp=expiry) return post_request(generated_jwt, installation_id) - class LookupModule(LookupBase): def run(self, terms, variables=None, **kwargs): if not HAS_JWT: From 2f3b81350d97de36651c2202fa0478be70ec91e2 Mon Sep 17 00:00:00 2001 From: Bruno Lavoie Date: Thu, 3 Jul 2025 20:26:41 -0400 Subject: [PATCH 4/4] Fix blank lines --- plugins/lookup/github_app_access_token.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/lookup/github_app_access_token.py b/plugins/lookup/github_app_access_token.py index 747b857815..d2d7689ead 100644 --- a/plugins/lookup/github_app_access_token.py +++ b/plugins/lookup/github_app_access_token.py @@ -90,6 +90,7 @@ from ansible.utils.display import Display display = Display() + def read_key(path, private_key=None): try: if private_key: @@ -101,6 +102,7 @@ def read_key(path, private_key=None): except Exception as e: raise AnsibleError(f"Error while parsing key file: {e}") + def encode_jwt(app_id, private_key_obj, exp=600): now = int(time.time()) payload = { @@ -113,6 +115,7 @@ def encode_jwt(app_id, private_key_obj, exp=600): except Exception as e: raise AnsibleError(f"Error while encoding jwt: {e}") + def post_request(generated_jwt, installation_id): github_api_url = f'https://api.github.com/app/installations/{installation_id}/access_tokens' headers = { @@ -139,11 +142,13 @@ def post_request(generated_jwt, installation_id): raise AnsibleError(f"Error while dencoding JSON respone from github: {e}") return json_data.get('token') + def get_token(key_path, app_id, installation_id, private_key, expiry=600): jwk = read_key(key_path, private_key) generated_jwt = encode_jwt(app_id, jwk, exp=expiry) return post_request(generated_jwt, installation_id) + class LookupModule(LookupBase): def run(self, terms, variables=None, **kwargs): if not HAS_JWT: