Skip to content

Commit

Permalink
Implement as new credential type
Browse files Browse the repository at this point in the history
  • Loading branch information
TheRealHaoLiu committed Sep 3, 2024
1 parent f8e9862 commit 633d8ea
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 13 deletions.
25 changes: 22 additions & 3 deletions awx/main/models/credential/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,28 @@ def create(self):
},
)

ManagedCredentialType(
namespace='scm_github_app',
kind='scm',
name=gettext_noop('GitHub App'),
managed=True,
inputs={
'fields': [
{'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': 'ssh_key_data',
'label': gettext_noop('GitHub App Private Key'),
'type': 'string',
'format': 'ssh_private_key',
'secret': True,
'multiline': True,
},
{'id': 'github_api_url', 'label': gettext_noop('GitHub API URL'), 'type': 'string'},
],
},
)

ManagedCredentialType(
namespace='scm',
kind='scm',
Expand All @@ -645,9 +667,6 @@ 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
19 changes: 9 additions & 10 deletions awx/main/tasks/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1155,21 +1155,21 @@ 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):
def _get_github_app_installation_access_token(self, credential):
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
'iss': credential.get_input('github_app_id', default=''), # GitHub App's identifier
},
project_update.credential.get_input('ssh_key_data', default=''),
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='')
github_api_url = credential.get_input('github_api_url', default='https://api.github.com')
installation_id = 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)

Expand All @@ -1186,13 +1186,12 @@ 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_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)
if project_update.credential.credential_type.namespace == 'github_app':
passwords['scm_username'] = 'x-access-token'
passwords['scm_password'] = github_installation_access_token
passwords['scm_password'] = self._get_github_app_installation_access_token(project_update.credential)
else:
passwords['scm_key_unlock'] = project_update.credential.get_input('ssh_key_unlock', default='')
passwords['scm_key_data'] = project_update.credential.get_input('ssh_key_data', default='')
passwords['scm_username'] = project_update.credential.get_input('username', default='')
passwords['scm_password'] = project_update.credential.get_input('password', default='')

Expand Down
1 change: 1 addition & 0 deletions awx/main/tests/functional/test_credential.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def test_default_cred_types():
'thycotic_tss',
'vault',
'vmware',
'scm_github_app',
]
)

Expand Down
4 changes: 4 additions & 0 deletions awx/main/tests/unit/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,10 @@ def test_ssh_key_auth(self, project_update, scm_type, mock_me):
expect_passwords = task.create_expect_passwords_data_struct(password_prompts, passwords)
assert 'bob' in expect_passwords.values()

def test_github_app_auth(self, project_update, mock_me):
# TODO: Implement me
pass

def test_awx_task_env(self, project_update, settings, private_data_dir, scm_type, execution_environment, mock_me):
project_update.execution_environment = execution_environment
settings.AWX_TASK_ENV = {'FOO': 'BAR'}
Expand Down

0 comments on commit 633d8ea

Please sign in to comment.