Skip to content

Commit

Permalink
Add ability to update scm project using github app
Browse files Browse the repository at this point in the history
- Add github_app_id, github_app_installation_id and github_api_url to scm credential type
- Add ability to generate github app token to clone project with git for github
  • Loading branch information
TheRealHaoLiu committed Aug 28, 2024
1 parent d6493fd commit f8e9862
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
3 changes: 3 additions & 0 deletions awx/main/models/credential/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,9 @@ def create(self):
{'id': 'password', 'label': gettext_noop('Password'), 'type': 'string', 'secret': True},
{'id': 'ssh_key_data', 'label': gettext_noop('SCM Private Key'), 'type': 'string', 'format': 'ssh_private_key', 'secret': True, 'multiline': True},
{'id': 'ssh_key_unlock', 'label': gettext_noop('Private Key Passphrase'), 'type': 'string', 'secret': True},
{'id': 'github_app_id', 'label': gettext_noop('GitHub App ID'), 'type': 'string'},
{'id': 'github_app_installation_id', 'label': gettext_noop('GitHub App Installation ID'), 'type': 'string'},
{'id': 'github_api_url', 'label': gettext_noop('GitHub API URL'), 'type': 'string'},
],
},
)
Expand Down
37 changes: 35 additions & 2 deletions awx/main/tasks/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import traceback
import time
import urllib.parse as urlparse
import jwt
import requests

# Django
from django.conf import settings
Expand Down Expand Up @@ -1153,6 +1155,30 @@ def build_private_data(self, project_update, private_data_dir):
private_data['credentials'][credential] = credential.get_input('ssh_key_data', default='')
return private_data

def _get_github_app_installation_access_token(self, project_update):
jwt_token = jwt.encode(
{
'iat': int(time.time()), # Issued at time
'exp': int(time.time()) + (10 * 60), # JWT expiration time (10 minute maximum)
'iss': project_update.credential.get_input('github_app_id', default=''), # GitHub App's identifier
},
project_update.credential.get_input('ssh_key_data', default=''),
algorithm='RS256',
)

headers = {'Authorization': f'Bearer {jwt_token}', 'Accept': 'application/vnd.github.v3+json'}

github_api_url = project_update.credential.get_input('github_api_url', default='https://api.github.com')
installation_id = project_update.credential.get_input('github_app_installation_id', default='')
url = f'{github_api_url}/app/installations/{installation_id}/access_tokens'
response = requests.post(url, headers=headers)

if response.status_code == 201:
access_token = response.json()['token']
return access_token
else:
raise Exception(f"Failed to get access token: {response.status_code} {response.text}")

def build_passwords(self, project_update, runtime_passwords):
"""
Build a dictionary of passwords for SSH private key unlock and SCM
Expand All @@ -1161,8 +1187,15 @@ def build_passwords(self, project_update, runtime_passwords):
passwords = super(RunProjectUpdate, self).build_passwords(project_update, runtime_passwords)
if project_update.credential:
passwords['scm_key_unlock'] = project_update.credential.get_input('ssh_key_unlock', default='')
passwords['scm_username'] = project_update.credential.get_input('username', default='')
passwords['scm_password'] = project_update.credential.get_input('password', default='')
passwords['scm_key_data'] = project_update.credential.get_input('ssh_key_data', default='')
if project_update.credential.get_input('github_app_id', default=''):
github_installation_access_token = self._get_github_app_installation_access_token(project_update)
passwords['scm_username'] = 'x-access-token'
passwords['scm_password'] = github_installation_access_token
else:
passwords['scm_username'] = project_update.credential.get_input('username', default='')
passwords['scm_password'] = project_update.credential.get_input('password', default='')

return passwords

def build_env(self, project_update, private_data_dir, private_data_files=None):
Expand Down

0 comments on commit f8e9862

Please sign in to comment.