def test_get_gh_repo_status_unauthorized(mocker): """ test handling unauthorized token """ mocker.patch("requests.get", side_effect=[MockResponse(401)]) mocker.patch.dict(os.environ, {'GITHUB_TOKEN': 'test_token'}) snyk_repo = SnykRepo('test_org/test_repo', "1234-5678", "new_owner", "12345", "github", "master", []) with pytest.raises(RuntimeError): get_gh_repo_status(snyk_repo)
def test_get_gh_repo_status_unauthorized(mocker): """ test handling unauthorized token """ mocker.patch("requests.get", side_effect=[MockResponse(401)]) snyk_repo = { "full_name": 'test_org/test_repo', "owner": 'test_org', "name": 'test_repo', "org_id": "1234-5678", "gh_integration_id": "12345", "branch_from_name": "", "branch": "master" } with pytest.raises(RuntimeError): get_gh_repo_status(snyk_repo, "test_token")
def test_get_gh_repo_status_github_enterprise_cloud(mocker, status_code, response_message, repo, name, owner, default_branch): # TODO: assumes a successful redirect for the 301 case mocker.patch("requests.get", side_effect=[MockResponse(status_code), MockResponse(200)]) mocker.patch.dict( os.environ, { 'GITHUB_ENTERPRISE_TOKEN': '1234', 'GITHUB_ENTERPRISE_HOST': common.GITHUB_CLOUD_API_HOST }) snyk_repo_github_enterprise = SnykRepo('new_owner/new_repo', "1234-5678", "new_owner", "12345", "github-enterprise", "master", []) repo_status = GithubRepoStatus( status_code, response_message, snyk_repo_github_enterprise["full_name"].split("/")[1], snyk_repo_github_enterprise["org_id"], snyk_repo_github_enterprise["full_name"].split("/")[0], snyk_repo_github_enterprise["full_name"], default_branch) assert get_gh_repo_status(snyk_repo_github_enterprise) == repo_status
def test_get_gh_repo_status(mocker, status_code, response_message, repo, name, owner, default_branch): # TODO: assumes a successful redirect for the 301 case mocker.patch("requests.get", side_effect=[MockResponse(status_code), MockResponse(200)]) snyk_repo = { "full_name": 'new_owner/new_repo', "owner": 'new_owner', "name": 'new_repo', "org_id": "1234-5678", "gh_integration_id": "12345", "branch_from_name": "", "branch": "master" } repo_status = { "response_code": status_code, "response_message": response_message, "repo_name": snyk_repo["name"], "snyk_org_id": snyk_repo["org_id"], "repo_owner": snyk_repo["owner"], "repo_full_name": snyk_repo["full_name"], "repo_default_branch": default_branch } assert get_gh_repo_status(snyk_repo, "test_token") == repo_status
def run(): """Begin application logic""" # pylint: disable=too-many-locals, too-many-branches, too-many-statements # pylint: disable=too-many-nested-blocks sys.stdout.write("Retrieving Snyk Repos") sys.stdout.flush() snyk_orgs = [] # if --orgId exists, use it # otherwise get all orgs the api user is part of try: if common.ARGS.org_id: snyk_orgs.append(common.snyk_client.organizations.get(common.ARGS.org_id)) else: snyk_orgs = common.snyk_client.organizations.all() except snyk.errors.SnykHTTPError as err: print(f"\n\n{err.message}, exiting...\n") sys.exit(1) print(f" for {len(snyk_orgs)} org(s)") # build snyk repo objects snyk_repos = get_snyk_repos_from_snyk_orgs(snyk_orgs, common.ARGS) len_snyk_repos = len(snyk_repos) sys.stdout.write(f" - {len_snyk_repos} found\n") if len_snyk_repos == 0: print("\nIf using repo-name filter, ensure it is correct\n") sys.exit(1) import_status_checks = [] for (i, snyk_repo) in enumerate(snyk_repos): # snyk_repo.get_projects() deleted_projects = [] is_default_renamed = False app_print(snyk_repo.org_name, snyk_repo.full_name, f"Processing {str(i+1)}/{str(len(snyk_repos))}") try: gh_repo_status = get_gh_repo_status(snyk_repo) except RuntimeError as err: raise RuntimeError("Failed to query GitHub repository!") from err app_print(snyk_repo.org_name, snyk_repo.full_name, f"Github Status {gh_repo_status.response_code}" \ f"({gh_repo_status.response_message}) [{snyk_repo.origin}]") #if snyk_repo does not still exist (removed/404), then log and skip to next repo if gh_repo_status.response_code == 404: # project no longer exists log_potential_delete(snyk_repo.org_name, snyk_repo.full_name) elif gh_repo_status.response_code == 200: # project exists and has not been renamed # if --audit-large-repos is on if common.ARGS.audit_large_repos: is_truncated_str = \ is_gh_repo_truncated( get_git_tree_from_api(snyk_repo.full_name, snyk_repo.origin) ) log_audit_large_repo_result( snyk_repo.org_name, snyk_repo.full_name, str(bool(is_truncated_str)) ) # move to next repo without processing the rest of the code continue # snyk has the wrong branch, re-import if gh_repo_status.repo_default_branch != snyk_repo.branch: app_print(snyk_repo.org_name, snyk_repo.full_name, f"Default branch name changed from {snyk_repo.branch}" \ f" -> {gh_repo_status.repo_default_branch}") updated_projects = snyk_repo.update_branch( gh_repo_status.repo_default_branch, common.ARGS.dry_run) for project in updated_projects: if not common.ARGS.dry_run: app_print(snyk_repo.org_name, snyk_repo.full_name, f"Monitored branch set to " \ f"{gh_repo_status.repo_default_branch} " \ f"for: {project['manifest']}") else: #find deltas app_print(snyk_repo.org_name, snyk_repo.full_name, f"Checking {str(len(snyk_repo.snyk_projects))} " \ f"projects for any stale manifests") # print(f"snyk repo projects: {snyk_repo.snyk_projects}") deleted_projects = snyk_repo.delete_stale_manifests(common.ARGS.dry_run) for project in deleted_projects: if not common.ARGS.dry_run: app_print(snyk_repo.org_name, snyk_repo.full_name, f"Deleted stale manifest: {project['manifest']}") else: app_print(snyk_repo.org_name, snyk_repo.full_name, f"Would delete stale manifest: {project['manifest']}") app_print(snyk_repo.org_name, snyk_repo.full_name, "Checking for new manifests in source tree") #if not common.ARGS.dry_run: projects_import = snyk_repo.add_new_manifests(common.ARGS.dry_run) if isinstance(projects_import, ImportStatus): import_status_checks.append(projects_import) app_print(snyk_repo.org_name, snyk_repo.full_name, f"Found {len(projects_import.files)} to import") for file in projects_import.files: import_message = "" if re.match(common.MANIFEST_PATTERN_CODE, file["path"]): import_message = "Triggering code analysis via" else: import_message = "Importing new manifest" app_print(snyk_repo.org_name, snyk_repo.full_name, f"{import_message}: {file['path']}") # if snyk_repo has been moved/renamed (301), then re-import the entire repo # with the new name and remove the old one (make optional) elif gh_repo_status.response_code == 301: app_print(snyk_repo.org_name, snyk_repo.full_name, f"Repo has moved to {gh_repo_status.repo_full_name}, submitting import...") if not common.ARGS.dry_run: repo_import_status = import_manifests(snyk_repo.org_id, gh_repo_status.repo_full_name, snyk_repo.integration_id) # build list of projects to delete with old name # only when the repo with new name has been imported repo_projects = snyk_repo.get_projects() # pylint: disable=unused-variable for (j, repo_project) in enumerate(repo_projects): repo_projects[j]["pending_repo"] = gh_repo_status.repo_full_name repo_import_status.pending_project_deletes = repo_projects import_status_checks.append(repo_import_status) else: app_print(snyk_repo.org_name, snyk_repo.full_name, "Would import repo (all targets) under new name") else: app_print(snyk_repo.org_name, snyk_repo.full_name, f"Skipping due to invalid response") time.sleep(1) process_import_status_checks(import_status_checks)