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

Feat/orgs data command for bitbucket cloud #287

Merged
merged 1 commit into from
Feb 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions docs/orgs.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
- Generating the data to create Organizations in Snyk
- [Github](#githubcom--github-enterprise)
- [Gitlab](#gitlabcom--hosted-gitlab)
- [Bitbucket Server](#bitbucket-server)
- [Bitbucket-Server](#bitbucket-server)
- [Bitbucket-cloud](#bitbucket-cloud)
- [Creating the organizations](#creating-organizations-in-snyk-1)
- [via the API](#via-api)
- [via the `orgs:create` util](#via-orgscreate-util)
Expand All @@ -15,8 +16,8 @@ Before an import can begin Snyk needs to be setup with the Organizations you wil
It is recommended to have as many Organizations in Snyk as you have in the source you are importing from. So for Github this would mean mirroring the Github organizations in Snyk. The tool provides a utility that can be used to make this simpler when using Groups & Organizations in Snyk.

# Generating the data required to create Organizations in Snyk with `orgs:data` util
This util helps generate data needed to mirror the Github.com / Github Enterprise / Gitlab / Bitbucket Server organization structure in Snyk.
This is an opinionated util and will assume every organization in Github.com / Github Enterprise / Gitlab / Bitbucket Server should become an organization in Snyk. If this is not what you are looking for, please look at using the [Organizations API](https://snyk.docs.apiary.io/#reference/groups/organizations-in-a-group/create-a-new-organization-in-a-group) directly to create the structure you need.
This util helps generate data needed to mirror the Github.com / Github Enterprise / Gitlab / Bitbucket Server / Bitbucket Cloud organization structure in Snyk.
This is an opinionated util and will assume every organization in Github.com / Github Enterprise / Gitlab / Bitbucket Server / Bitbucket Cloud should become an organization in Snyk. If this is not what you are looking for, please look at using the [Organizations API](https://snyk.docs.apiary.io/#reference/groups/organizations-in-a-group/create-a-new-organization-in-a-group) directly to create the structure you need.

## Options
```
Expand Down Expand Up @@ -61,6 +62,16 @@ This will create the organization data in a file `group-<snyk_group_id>-gitlab-o

This will create the organization data in a file `group-<snyk_group_id>-bitbucket-server-orgs.json`


## Bitbucket Cloud
IlanTSnyk marked this conversation as resolved.
Show resolved Hide resolved
**Note that the URL for Bitbucket Cloud is https://bitbucket.org/**
1. set the Bitbucket Cloud Username and Password as an environment variables: `export BITBUCKET_CLOUD_USERNAME=your_bitbucket_cloud_username` and `export BITBUCKET_CLOUD_PASSWORD=your_bitbucket_cloud_password`
2. Run the command to generate organization data:
- `snyk-api-import orgs:data --source=bitbucket-cloud --groupId=<snyk_group_id>`

This will create the organization data in a file `group-<snyk_group_id>-bitbucket-cloud-orgs.json`


# Creating Organizations in Snyk
Use the generated data file to help create the organizations via API or use the provided util.
## via API
Expand Down
2 changes: 1 addition & 1 deletion src/cmds/orgs:data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const builder = {
default: SupportedIntegrationTypesImportOrgData.GITHUB,
choices: [...Object.values(SupportedIntegrationTypesImportOrgData)],
desc:
'The source of the targets to be imported e.g. Github, Github Enterprise, Gitlab, Bitbucket Server',
'The source of the targets to be imported e.g. Github, Github Enterprise, Gitlab, Bitbucket Server, Bitbucket Cloud',
},
};

Expand Down
1 change: 1 addition & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export enum SupportedIntegrationTypesImportOrgData {
GHE = 'github-enterprise',
GITLAB = 'gitlab',
BITBUCKET_SERVER = 'bitbucket-server',
BITBUCKET_CLOUD = 'bitbucket-cloud',
}

// used to generate imported targets that exist in Snyk
Expand Down
8 changes: 8 additions & 0 deletions src/scripts/generate-org-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import {
listGitlabGroups,
gitlabGroupIsEmpty,
} from '../lib/source-handlers/gitlab';
import {
bitbucketCloudWorkspaceIsEmpty,
listBitbucketCloudWorkspaces,
} from '../lib/source-handlers/bitbucket-cloud/';
import {
bitbucketServerProjectIsEmpty,
listBitbucketServerProjects,
Expand All @@ -24,13 +28,15 @@ const sourceGenerators = {
[SupportedIntegrationTypesImportOrgData.GITHUB]: githubOrganizations,
[SupportedIntegrationTypesImportOrgData.GHE]: githubEnterpriseOrganizations,
[SupportedIntegrationTypesImportOrgData.BITBUCKET_SERVER]: listBitbucketServerProjects,
[SupportedIntegrationTypesImportOrgData.BITBUCKET_CLOUD]: listBitbucketCloudWorkspaces,
};

const sourceNotEmpty = {
[SupportedIntegrationTypesImportOrgData.GITHUB]: githubOrganizationIsEmpty,
[SupportedIntegrationTypesImportOrgData.GHE]: githubOrganizationIsEmpty,
[SupportedIntegrationTypesImportOrgData.GITLAB]: gitlabGroupIsEmpty,
[SupportedIntegrationTypesImportOrgData.BITBUCKET_SERVER]: bitbucketServerProjectIsEmpty,
[SupportedIntegrationTypesImportOrgData.BITBUCKET_CLOUD]: bitbucketCloudWorkspaceIsEmpty
};

export const entityName: {
Expand All @@ -40,6 +46,7 @@ export const entityName: {
'github-enterprise': 'organization',
gitlab: 'group',
'bitbucket-server': 'project',
'bitbucket-cloud': 'workspace',
};

const exportFileName: {
Expand All @@ -49,6 +56,7 @@ const exportFileName: {
'github-enterprise': 'github-enterprise',
gitlab: 'gitlab',
'bitbucket-server': 'bitbucket-server',
'bitbucket-cloud': 'bitbucket-cloud',
};

export async function generateOrgImportDataFile(
Expand Down
6 changes: 2 additions & 4 deletions src/scripts/generate-targets-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
listBitbucketServerRepos,
BitbucketServerRepoData,
listBitbucketCloudRepos,
BitbucketCloudRepoData,
} from '../lib';

const debug = debugLib('snyk:generate-targets-data');
Expand Down Expand Up @@ -92,10 +93,7 @@ export async function generateTargetsImportDataFile(
try {
validateRequiredOrgData(name, integrations, orgId);
const entities: Array<
| GithubRepoData
| GitlabRepoData
| AzureRepoData
| BitbucketServerRepoData
GithubRepoData | GitlabRepoData | AzureRepoData | BitbucketServerRepoData | BitbucketCloudRepoData
> = await sourceGenerators[source](topLevelEntity.name, sourceUrl!);
entities.forEach((entity) => {
targetsData.push({
Expand Down
89 changes: 89 additions & 0 deletions test/scripts/generate-org-data.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,92 @@ describe('generateOrgImportDataFile Gitlab script', () => {
).rejects.toThrow('401 (Unauthorized)');
});
});

describe('generateOrgImportDataFile Bitbucket Cloud script', () => {
const OLD_ENV = process.env;
process.env.SNYK_LOG_PATH = __dirname;
const filesToCleanup: string[] = [
__dirname + '/group-groupIdExample-bitbucket-cloud-orgs.json',
];
afterAll(async () => {
process.env = { ...OLD_ENV };
});

afterEach(async () => {
await deleteFiles(filesToCleanup);
});

it('generate Bitbucket Cloud Orgs data', async () => {
process.env.BITBUCKET_CLOUD_USERNAME = process.env.BBC_USERNAME;
process.env.BITBUCKET_CLOUD_PASSWORD = process.env.BBC_PASSWORD;

const groupId = 'groupIdExample';
const res = await generateOrgImportDataFile(
IlanTSnyk marked this conversation as resolved.
Show resolved Hide resolved
SupportedIntegrationTypesImportOrgData.BITBUCKET_CLOUD,
groupId,
undefined,
);
expect(res.fileName).toEqual('group-groupIdExample-bitbucket-cloud-orgs.json');
expect(res.orgs.length > 0).toBeTruthy();
expect(res.skippedEmptyOrgs).toHaveLength(0);
expect(res.orgs[0]).toEqual({
name: expect.any(String),
groupId,
});
}, 160000);

it('generate Bitbucket cloud Orgs data and skips empty orgs', async () => {
process.env.BITBUCKET_CLOUD_USERNAME = process.env.BBC_USERNAME;
process.env.BITBUCKET_CLOUD_PASSWORD = process.env.BBC_PASSWORD;

const groupId = 'groupIdExample';
const sourceOrgId = 'sourceOrgIdExample';

const res = await generateOrgImportDataFile(
SupportedIntegrationTypesImportOrgData.BITBUCKET_CLOUD,
groupId,
sourceOrgId,
undefined,
true,
);
expect(res.fileName).toEqual('group-groupIdExample-bitbucket-cloud-orgs.json');
expect(res.orgs.length > 0).toBeTruthy();
expect(res.skippedEmptyOrgs.length).toBeGreaterThanOrEqual(0);
expect(res.orgs[0]).toEqual({
name: expect.any(String),
groupId,
sourceOrgId,
});
}, 10000);
it('generate Bitbucket cloud Orgs data without sourceOrgId', async () => {
process.env.BITBUCKET_CLOUD_USERNAME = process.env.BBC_USERNAME;
process.env.BITBUCKET_CLOUD_PASSWORD = process.env.BBC_PASSWORD;

const groupId = 'groupIdExample';

const res = await generateOrgImportDataFile(
SupportedIntegrationTypesImportOrgData.BITBUCKET_CLOUD,
groupId,
undefined,
);
expect(res.fileName).toEqual('group-groupIdExample-bitbucket-cloud-orgs.json');
expect(res.orgs.length > 0).toBeTruthy();
expect(res.skippedEmptyOrgs).toHaveLength(0);
expect(res.orgs[0]).toEqual({
name: expect.any(String),
groupId,
});
});

it('Bitbucket cloud script to fail on bad credentials', async () => {
process.env.BITBUCKET_CLOUD_USERNAME = process.env.BBC_USERNAME;
process.env.BITBUCKET_CLOUD_PASSWORD = 'wrong_password';
jest.useFakeTimers()
const groupId = 'groupIdExample';

expect(generateOrgImportDataFile(
SupportedIntegrationTypesImportOrgData.BITBUCKET_CLOUD,
groupId,
)).rejects.toThrow();
});
});
10 changes: 6 additions & 4 deletions test/system/__snapshots__/orgs:data.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ Options:
--skipEmptyOrgs Skip any organizations that do not any targets. (e.g.
Github Organization does not have any repos)
--source The source of the targets to be imported e.g. Github,
Github Enterprise, Gitlab, Bitbucket Server
Github Enterprise, Gitlab, Bitbucket Server, Bitbucket
Cloud
[required] [choices: "github", "github-enterprise", "gitlab",
"bitbucket-server"] [default: "github"]
"bitbucket-server", "bitbucket-cloud"] [default: "github"]

Missing required argument: groupId
]
Expand All @@ -53,7 +54,8 @@ Options:
--skipEmptyOrgs Skip any organizations that do not any targets. (e.g.
Github Organization does not have any repos)
--source The source of the targets to be imported e.g. Github,
Github Enterprise, Gitlab, Bitbucket Server
Github Enterprise, Gitlab, Bitbucket Server, Bitbucket
Cloud
[required] [choices: \\"github\\", \\"github-enterprise\\", \\"gitlab\\",
\\"bitbucket-server\\"] [default: \\"github\\"]"
\\"bitbucket-server\\", \\"bitbucket-cloud\\"] [default: \\"github\\"]"
`;