Skip to content

Commit

Permalink
Merge pull request #6 from snyk-labs/feature/github-server-app
Browse files Browse the repository at this point in the history
Support for GitHub Server App
  • Loading branch information
thavelock authored Oct 10, 2024
2 parents 89ea0d5 + b75f6a6 commit 6ec5eb3
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 45 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## Introduction

This tool is designed to help you easily migrate your Snyk Targets that were imported using either the existing GitHub or GitHub Enterprise integrations to the new GitHub Cloud App integration. Below, you will learn how to install the tool and how to run the tool.
This tool is designed to help you easily migrate your Snyk Targets that were imported using either the existing GitHub or GitHub Enterprise integrations to the new GitHub Cloud App or GitHub Server App integrations. Below, you will learn how to install the tool and how to run the tool.

## Installation

Expand Down Expand Up @@ -39,7 +39,7 @@ snyk-migrate-to-github-app --help

## Using the Tool

All you need to run the tool is a [Snyk API token](https://docs.snyk.io/getting-started/how-to-obtain-and-authenticate-with-your-snyk-api-token) and the Organization ID of the Organization where you want to migrate your targets to the new GitHub Cloud App
All you need to run the tool is a [Snyk API token](https://docs.snyk.io/getting-started/how-to-obtain-and-authenticate-with-your-snyk-api-token) and the Organization ID of the Organization where you want to migrate your targets to the new GitHub Cloud App or GitHub Server App

**Before Running the Tool:** It is assumed that the GitHub Cloud App integration has already been configured in the Snyk Organization where you will be migrating targets

Expand All @@ -65,6 +65,12 @@ export SNYK_ORG_ID=<YOUR_ORGANIZATION_ID>
snyk-migrate-to-github-app
```

By default, it is assumed you are migrating to the GitHub Cloud App. If you want to migrate to the GitHub Server App, include the flag as follows

```shell
snyk-migrate-to-github-app <ORG_ID> <SNYK_TOKEN> --github-server-app
```

Running the tool will immediately start the migration process. However, you may want to see which projects will be migrated before you start the migration process. You can run the tool with the `--dry-run` option which will only print the effected targets to the terminal without actually migrating them

```shell
Expand Down
56 changes: 28 additions & 28 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 30 additions & 15 deletions snyk_migrate_to_github_app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
SNYK_REST_API_BASE_URL = 'https://api.snyk.io/rest'
SNYK_REST_API_BASE_URL_AU = 'https://api.au.snyk.io/rest'
SNYK_REST_API_BASE_URL_EU = 'https://api.eu.snyk.io/rest'
SNYK_REST_API_VERSION = '2023-11-27~beta'
SNYK_REST_API_VERSION = '2024-08-25'
SNYK_HIDDEN_API_BASE_URL = 'https://api.snyk.io/hidden'
SNYK_HIDDEN_API_BASE_URL_AU = 'https://api.au.snyk.io/hidden'
SNYK_HIDDEN_API_BASE_URL_EU = 'https://api.eu.snyk.io/hidden'
Expand Down Expand Up @@ -61,6 +61,11 @@ def main(
bool,
typer.Option(
help='Migrate both github and github-enterprise projects, default is only github-enterprise')] = False,
github_server_app:
Annotated[
bool,
typer.Option(
help="Migrate to github-server-app, Defaults to False (github-cloud-app)")] = False,
verbose: bool = False):
"""CLI Tool to help you migrate your targets from the GitHub or GitHub Enterprise integration to the new GitHub App Integration
"""
Expand All @@ -72,7 +77,7 @@ def main(
print("Must me either 'eu' or 'au'")
return

if verify_org_integrations(snyk_token, org_id, tenant=tenant):
if verify_org_integrations(snyk_token, org_id, github_server_app=github_server_app, tenant=tenant):
targets = get_all_targets(snyk_token, org_id, tenant=tenant)

if include_github_targets:
Expand All @@ -81,14 +86,15 @@ def main(
if (dry_run):
dry_run_targets(targets)
else:
migrate_targets(snyk_token, org_id, targets, tenant=tenant)
migrate_targets(snyk_token, org_id, targets, github_server_app=github_server_app, tenant=tenant)

def verify_org_integrations(snyk_token, org_id, tenant=''):
def verify_org_integrations(snyk_token, org_id, github_server_app=False, tenant=''):
"""Helper function to make sure the Snyk Organization has the relevant github integrations set up
Args:
snyk_token (str): Snyk API token
org_id (str): Snyk Organization ID
github_server_app (bool, optional): Flag to indicate migrating to GitHub Server App
tenant (str, optional): Snyk tenant
Returns:
Expand Down Expand Up @@ -130,10 +136,13 @@ def verify_org_integrations(snyk_token, org_id, tenant=''):
print(f"No GitHub or GitHub Enterprise integration detected for Snyk Org: {org_id}")
return False

if ('github-cloud-app' not in integrations):

print(f"No GitHub Cloud App integration detected for Snyk Org: {org_id}, please set up before migrating GitHub or GitHub Enterprise targets")
return False
if (github_server_app):
if ('github-server-app' not in integrations):
print(f"No GitHub Server App integration detected for Snyk Org: {org_id}, please set up before migrating GitHub or GitHub Enterprise targets")
else:
if ('github-cloud-app' not in integrations):
print(f"No GitHub Cloud App integration detected for Snyk Org: {org_id}, please set up before migrating GitHub or GitHub Enterprise targets")
return False

return True

Expand Down Expand Up @@ -163,7 +172,7 @@ def get_all_targets(snyk_token, org_id, origin='github-enterprise', tenant=''):
if tenant == 'eu':
base_url = SNYK_REST_API_BASE_URL_EU

url = f'{base_url}/orgs/{org_id}/targets?version={SNYK_REST_API_VERSION}&limit=100&origin={origin}&excludeEmpty=false'
url = f'{base_url}/orgs/{org_id}/targets?version={SNYK_REST_API_VERSION}&limit=100&source_types={origin}&exclude_empty=false'

while True:
response = requests.request(
Expand All @@ -190,18 +199,19 @@ def dry_run_targets(targets):
targets: List of targets to be logged
"""
for target in targets:
print(f"Target: {target['id']}, Name: {target['attributes']['displayName']}")
print(f"Target: {target['id']}, Name: {target['attributes']['display_name']}")

print()
print(f"Total Targets: {len(targets)}")

def migrate_targets(snyk_token, org_id, targets, tenant=''):
def migrate_targets(snyk_token, org_id, targets, github_server_app=False, tenant=''):
"""Helper function to migrate list of github and github-enterprise targets to github-cloud-app
Args:
snyk_token (str): Snyk API token
org_id (str): Snyk Organization ID
targets (list): List of targets to be migrated
github_server_app (bool, optional): Flag to indicate migrating to GitHub Server App
tenant (str, optional): Snyk tenant
"""

Expand All @@ -212,6 +222,11 @@ def migrate_targets(snyk_token, org_id, targets, tenant=''):
if tenant == 'eu':
base_url = SNYK_HIDDEN_API_BASE_URL_EU

source_type = 'github-cloud-app'

if github_server_app:
source_type = 'github-server-app'

headers = {
'Content-Type': 'application/vnd.api+json',
'Authorization': f'token {snyk_token}'
Expand All @@ -224,7 +239,7 @@ def migrate_targets(snyk_token, org_id, targets, tenant=''):
"data": {
"id": f"{target['id']}",
"attributes": {
"source_type": "github-cloud-app"
"source_type": f"{source_type}"
}
}
})
Expand All @@ -237,11 +252,11 @@ def migrate_targets(snyk_token, org_id, targets, tenant=''):
timeout=SNYK_API_TIMEOUT_DEFAULT)

if response.status_code == 200:
print(f"Migrated target: {target['id']} {target['attributes']['displayName']} to github-cloud-app")
print(f"Migrated target: {target['id']} {target['attributes']['display_name']} to {source_type}")
elif response.status_code == 409:
print(f"Unable to migrate target: {target['id']} {target['attributes']['displayName']} to github-cloud-app because it has already been migrated")
print(f"Unable to migrate target: {target['id']} {target['attributes']['display_name']} to {source_type} because it has already been migrated")
else:
print(f"Unable to migrate target: {target['id']} {target['attributes']['displayName']} to github-cloud-app, reason: {response.status_code}")
print(f"Unable to migrate target: {target['id']} {target['attributes']['display_name']} to {source_type}, reason: {response.status_code}, request ID: {response.headers['snyk-request-id']}")

def run():
"""Run the defined typer CLI app
Expand Down

0 comments on commit 6ec5eb3

Please sign in to comment.