Skip to content
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

github_app_access_token: add support for private key fact #8989

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions changelogs/fragments/8989-github-app-token-from-fact.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- github_app_access_token plugin - adds new ``private_key`` parameter (https:/ansible-collections/community.general/pull/8989).
lewismiddleton marked this conversation as resolved.
Show resolved Hide resolved
16 changes: 12 additions & 4 deletions plugins/lookup/github_app_access_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
key_path:
description:
- Path to your private key.
lewismiddleton marked this conversation as resolved.
Show resolved Hide resolved
required: true
required: false
lewismiddleton marked this conversation as resolved.
Show resolved Hide resolved
type: path
app_id:
description:
Expand All @@ -34,6 +34,11 @@
- Alternatively, you can use PyGithub (U(https:/PyGithub/PyGithub)) to get your installation ID.
required: true
type: str
private_key:
description:
- GitHub App private key in PEM file format as string
lewismiddleton marked this conversation as resolved.
Show resolved Hide resolved
required: false
lewismiddleton marked this conversation as resolved.
Show resolved Hide resolved
type: str
lewismiddleton marked this conversation as resolved.
Show resolved Hide resolved
token_expiry:
description:
- How long the token should last for in seconds.
Expand Down Expand Up @@ -84,8 +89,10 @@
display = Display()


def read_key(path):
def read_key(path, private_key=None):
try:
if private_key:
return jwk_from_pem(private_key.encode())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If neither are passed by the user, they will get an error trying open the file None or something like that. I believe it would be better to have a validation check telling the user they must pass one or the other.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 8e928bb

lewismiddleton marked this conversation as resolved.
Show resolved Hide resolved
with open(path, 'rb') as pem_file:
return jwk_from_pem(pem_file.read())
except Exception as e:
Expand Down Expand Up @@ -132,8 +139,8 @@ def post_request(generated_jwt, installation_id):
return json_data.get('token')


def get_token(key_path, app_id, installation_id, expiry=600):
jwk = read_key(key_path)
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)

Expand All @@ -150,6 +157,7 @@ def run(self, terms, variables=None, **kwargs):
self.get_option('key_path'),
self.get_option('app_id'),
self.get_option('installation_id'),
self.get_option('private_key'),
self.get_option('token_expiry'),
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAr/EjKUujUdliSX79ZlDwq/+RCnOF1JCrekWGOOK4YGqgfJBM
Z/CLHYTW+BQAH172NTEwLlegwJpXtalae9WVhyMs4sFm7nxSZsFjRK7Gof1tuFbD
i4+GGlu4kci7xVcxzoZoVvswX4Xw/9MCg/Je35H8xbugwsWYg+ou79e0wx0fYU4d
dwiUte8K+/d1l5acMQuqcnUfJLRmXvw3w7hyemB51EPTGqkpcA4KmYns1W12ianD
Zo9/d2kLC2mcyxDkHmqWCv9vfUVrKB7yIC8DU5uY/acFtBaVE1yyvI+1lCCkxNWX
5IDbpP/xRJk68B0WXKaU2IdFUVYSD48u3nSZoQIDAQABAoIBAGLL9KOevqIagK+m
qKKItuzOgOKuhisb5b6uRbWx0jkKBv6LhOwkzemQi6oYiQ0UpQqviU+sky80PCZd
Z9r7z5Bn9y+JzMQEeb0LwTNzNUUHa1JFHl9DA9nPQXBTmOUyllxTa0nUmZA6RV9S
XSo8snu2nYtnVdmpXYBNw3eY1/9rb1blXEZHLJbCTaTX3MuWDYuJ4G0K6EArjSwG
DDGhOWIWfkk3zZAHqdsrJxgqXIx2Cv9m40hmC0XMwqh8/H3j4kZZhdglJhNbvnBM
8ZKRzpMOP1hbGATmi9A1HU+o6BpdIl1dyMRiod3WjSS7CKvs8BVR0XMK/SXDV9Wl
Jy6kwYUCgYEA4HwzV/YT+cTb61VL5ICj871m5VMaGJD96dOrnX33QYRNw5aLRc35
HMaJ1t5Bp0d2J5h0mPoQkSvQxuPYfaytTYknSUE/bObYNMEnII3XeTmA8ILlG7kV
8OQah66GMKjyHocie2PxUuu9BWtuPvZJDrOuR9Pmw5aH6+oiXBSM0YcCgYEAyKRW
FHtDGC8ZHgBaytaGvlbVo3RTKboQgYqzf9HdvzWHlSbeZVuCk6MWtSNU+5+26RBK
FCI8FTBxqY/vai9zRgp/1u3jY3N1WIsowBgBV7C84IP6gEr/FAJlx++Eqzfmx1W7
lU3/0IJ/jYS7D6C4aADifo4aGF0mFHFBk7sfpZcCgYBaIyTOnf15XgVcIjy9/LVY
amXFkS+6S4XY/Og87dZ5VTGQZoN3vPPZDRNN1qKQE46q6Xlv74D1eZ10Lwq/s7VG
m9rNfEiGZs7Lp/8ZADtT7rYKXNS35AKeXkkU0AwLv9qwTVyYJRJCVGvqoC99UpEV
OSqyprBTOr9LCBFR3eKJQwKBgHXRqoqUZy3IWmN3qdj6aF1U+Fbnc/5IuHCZVhZ0
0lX5xQgcrvOt7NttJWRwvvKTMwFhA18XS1jV/aioUNp1yqcSe0dmoeRAZGP+M4u5
jPBFZGQim/LCF09UqRfi2nEAfpAHFAP0rYdvWh9sFbxzkFXiTx4pq8Eq0bWnW+64
Lzk5AoGAVeV9KgqJZLbl2Vbii3bJOuvtNeHOkIYPIoU6kgox9qp1derccWuMtwLT
PjhnWuCAX5dN1d7Rve4EovkjvuomDuZy6NCQlmLA6ff2pxtcJAkGy8Blc5VQeWs9
i9DUFz2Sx6olEO7MDykj4B6O2YNlAwb8xq1oivE24laZPufprwI=
-----END RSA PRIVATE KEY-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Copyright (c) Ansible Project
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
SPDX-License-Identifier: GPL-3.0-or-later
30 changes: 30 additions & 0 deletions tests/integration/targets/github_app_access_token/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
####################################################################
# WARNING: These are designed specifically for Ansible tests #
# and should not be used as examples of how to write Ansible roles #
####################################################################

# Test code for the github_app_access_token plugin.
#
# Copyright (c) 2017-2018, Abhijeet Kasurde <[email protected]>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

- name: Install JWT
ansible.builtin.pip:
name:
- jwt

- name: Read file
ansible.builtin.set_fact:
github_app_private_key: "{{ lookup('ansible.builtin.file', 'app-private-key.pem') }}"

- name: Generate Github App Token
register: github_app_access_token
ignore_errors: true
ansible.builtin.set_fact:
github_app_token: "{{ lookup('community.general.github_app_access_token', app_id=github_app_id, installation_id=github_app_installation_id, private_key=github_app_private_key) }}"

- assert:
that:
- github_app_access_token is failed
- '"Github return error" in github_app_access_token.msg'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

github_app_id: 123456
github_app_installation_id: 123456
20 changes: 19 additions & 1 deletion tests/unit/plugins/lookup/test_github_app_access_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def read(self):

class TestLookupModule(unittest.TestCase):

def test_get_token(self):
def test_get_token_with_file(self):
with patch.multiple("ansible_collections.community.general.plugins.lookup.github_app_access_token",
open=mock_open(read_data="foo_bar"),
open_url=MagicMock(return_value=MockResponse()),
Expand All @@ -50,3 +50,21 @@ def test_get_token(self):
token_expiry=600
)
)

def test_get_token_with_fact(self):
with patch.multiple("ansible_collections.community.general.plugins.lookup.github_app_access_token",
open_url=MagicMock(return_value=MockResponse()),
jwk_from_pem=MagicMock(return_value='private_key'),
jwt_instance=MockJWT(),
HAS_JWT=True):
lookup = lookup_loader.get('community.general.github_app_access_token')
self.assertListEqual(
[MockResponse.response_token],
lookup.run(
[],
app_id="app_id",
installation_id="installation_id",
private_key="foo_bar",
token_expiry=600
)
)