Skip to content

Commit

Permalink
Merge pull request #38 from snyk-tech-services/feat/filter-results-by…
Browse files Browse the repository at this point in the history
…-projects

feat: allow filter by projects
  • Loading branch information
lili2311 authored Oct 22, 2020
2 parents 762ef29 + cfe6589 commit 5b0ec07
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 73 deletions.
28 changes: 25 additions & 3 deletions src/cmds/generate.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as debugLib from 'debug';
import * as pathLib from 'path';
import * as _ from 'lodash';

import { getApiToken } from '../lib/get-api-token';
import {
LicenseReportData,
Expand Down Expand Up @@ -46,6 +48,10 @@ export const builder = {
desc:
'How should the data be represented. Defaults to a license based view.',
},
project: {
default: [],
desc: 'Project ID to filter the results by. E.g. --project=uuid --project=uuid2',
},
};
export const aliases = ['g'];

Expand All @@ -54,16 +60,29 @@ export async function handler(argv: {
outputFormat: OutputFormat;
template: string;
view: SupportedViews;
project?: string | string[];
}) {
try {
const { orgPublicId, outputFormat, template, view } = argv;
const { orgPublicId, outputFormat, template, view, project } = argv;
debug(
'ℹ️ Options: ' +
JSON.stringify({ orgPublicId, outputFormat, template, view }),
JSON.stringify({
orgPublicId,
outputFormat,
template,
view,
project: _.castArray(project),
}),
);
getApiToken();
const options = {
filters: {
projects: _.castArray(project),
},
};
const licenseData: LicenseReportData = await generateLicenseData(
orgPublicId,
options,
);
const orgData = await getOrgData(orgPublicId);
const reportData = await generateHtmlReport(
Expand All @@ -80,7 +99,10 @@ export async function handler(argv: {
)}.${outputFormat}`;
await generateReportFunc(reportFileName, reportData);
console.log(
`${outputFormat.toUpperCase()} license report saved at: ${pathLib.resolve(process.cwd(), reportFileName)}`,
`${outputFormat.toUpperCase()} license report saved at: ${pathLib.resolve(
__dirname,
reportFileName,
)}`,
);
} catch (e) {
console.error(e);
Expand Down
26 changes: 19 additions & 7 deletions src/cmds/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as debugLib from 'debug';
import { getApiToken } from '../lib/get-api-token';
import { generateLicenseData } from '../lib/generate-org-license-report';
import { SupportedViews } from '../lib/types';
import * as _ from 'lodash';

const debug = debugLib('snyk-licenses:json');

Expand All @@ -12,22 +13,33 @@ export const builder = {
orgPublicId: {
required: true,
default: undefined,
}
},
project: {
default: [],
desc:
'Project ID to filter the results by. E.g. --project=uuid --project=uuid2',
},
};
export const aliases = ['j'];

export async function handler(argv: {
orgPublicId: string;
view: SupportedViews;
project?: string | string[];
}) {
try {
const { orgPublicId, view } = argv;
debug('ℹ️ Options: ' + JSON.stringify({ orgPublicId, view }));
// check SNYK_TOKEN is set as the sdk uses it
const { orgPublicId, view, project } = argv;
debug(
'ℹ️ Options: ' +
JSON.stringify({ orgPublicId, view, project: _.castArray(project) }),
);
getApiToken();
// TODO: define and pass options to help filter the response
// based on filters available in API
const data = await generateLicenseData(orgPublicId, {});
const options = {
filters: {
projects: _.castArray(project),
},
};
const data = await generateLicenseData(orgPublicId, options);
console.log(JSON.stringify(data));
} catch (e) {
console.error(e);
Expand Down
22 changes: 3 additions & 19 deletions src/lib/api/org/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,23 @@ import 'source-map-support/register';
import * as debugLib from 'debug';
import * as snykApiSdk from 'snyk-api-ts-client';
import { getApiToken } from '../../get-api-token';
import { SortBy, Order } from './types';
import { GetLicenseDataOptions } from '../../types';

const debug = debugLib('snyk-licenses:getDependenciesDataForOrg');

interface GetDependenciesDataOptions {
sortBy: SortBy;
order: Order;
filters?: snykApiSdk.OrgTypes.DependenciesPostBodyType;
}

export async function getDependenciesDataForOrg(
orgPublicId: string,
options?: GetDependenciesDataOptions,
options?: GetLicenseDataOptions,
): Promise<snykApiSdk.OrgTypes.DependenciesPostResponseType> {
getApiToken();
const snykApiClient = await new snykApiSdk.Org({ orgId: orgPublicId });
const sortBy = options?.sortBy;
const order = options?.order;
const body: snykApiSdk.OrgTypes.DependenciesPostBodyType = {
...options?.filters,
filters: options?.filters,
};
try {
const dependenciesData = await getAllDependenciesData(
snykApiClient,
body,
sortBy,
order,
);
return dependenciesData;
} catch (e) {
Expand All @@ -40,15 +30,11 @@ export async function getDependenciesDataForOrg(
async function getAllDependenciesData(
snykApiClient,
body,
sortBy,
order,
page = 1,
): Promise<snykApiSdk.OrgTypes.DependenciesPostResponseType> {
const perPage = 200;
const dependenciesData = await snykApiClient.dependencies.post(
body,
sortBy,
order,
page,
perPage,
);
Expand All @@ -58,8 +44,6 @@ async function getAllDependenciesData(
const data = await getAllDependenciesData(
snykApiClient,
body,
sortBy,
order,
nextPage,
);
result.results = [...result.results, ...data.results];
Expand Down
20 changes: 3 additions & 17 deletions src/lib/api/org/licenses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,21 @@ import 'source-map-support/register';
import * as debugLib from 'debug';
import * as snykApiSdk from 'snyk-api-ts-client';
import { getApiToken } from '../../get-api-token';
import { SortBy, Order } from './types';
import { GetLicenseDataOptions } from '../../types';

const debug = debugLib('snyk-licenses:getLicenseDataForOrg');

interface GetLicenseDataOptions {
sortBy: SortBy;
order: Order;
filters?: snykApiSdk.OrgTypes.LicensesPostBodyType;
}

export async function getLicenseDataForOrg(
orgPublicId: string,
options?: GetLicenseDataOptions,
): Promise<snykApiSdk.OrgTypes.LicensesPostResponseType> {
getApiToken();
const snykApiClient = await new snykApiSdk.Org({ orgId: orgPublicId });
const sortBy = options?.sortBy;
const order = options?.order;
const body: snykApiSdk.OrgTypes.LicensesPostBodyType = {
...options?.filters,
filters: options?.filters,
};
try {
const licenseData = await getAllLicensesData(snykApiClient, body, sortBy, order);
const licenseData = await getAllLicensesData(snykApiClient, body);
return licenseData;
} catch (e) {
debug('❌ Failed to fetch licenses' + e);
Expand All @@ -35,15 +27,11 @@ export async function getLicenseDataForOrg(
async function getAllLicensesData(
snykApiClient,
body,
sortBy,
order,
page = 1,
): Promise<snykApiSdk.OrgTypes.LicensesPostResponseType> {
const perPage = 200;
const licensesData = await snykApiClient.licenses.post(
body,
sortBy,
order,
page,
perPage,
);
Expand All @@ -53,8 +41,6 @@ async function getAllLicensesData(
const data = await getAllLicensesData(
snykApiClient,
body,
sortBy,
order,
nextPage,
);
result.results.push(data.results);
Expand Down
31 changes: 21 additions & 10 deletions src/lib/generate-org-license-report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@ import * as _ from 'lodash';
export * from './license-text';
export * from './get-api-token';
import { getLicenseDataForOrg, getDependenciesDataForOrg } from './api/org';
import { fetchSpdxLicenseTextAndUrl, fetchNonSpdxLicenseTextAndUrl } from './license-text';
import { LicenseReportDataEntry, EnrichedDependency, Dependency, DependencyData } from './types';
import {
fetchSpdxLicenseTextAndUrl,
fetchNonSpdxLicenseTextAndUrl,
} from './license-text';
import {
LicenseReportDataEntry,
EnrichedDependency,
Dependency,
DependencyData,
} from './types';

const debug = debugLib('snyk-licenses:generateOrgLicensesReport');

Expand All @@ -15,7 +23,11 @@ export interface LicenseReportData {

export async function generateLicenseData(
orgPublicId: string,
options?,
options?: {
filters?: {
projects: string[];
};
},
): Promise<LicenseReportData> {
debug(`ℹ️ Generating license data for Org:${orgPublicId}`);

Expand All @@ -37,9 +49,10 @@ export async function generateLicenseData(
debug(`⏳ Processing ${licenseData.total} licenses`);

const dependenciesAll = [];

for (const license of licenseData.results) {
const dependencies = license.dependencies;
if(!dependencies.length) {
if (!dependencies.length) {
continue;
}
dependenciesAll.push(...dependencies);
Expand All @@ -50,9 +63,7 @@ export async function generateLicenseData(
if (dependenciesEnriched.length) {
license.dependencies = dependenciesEnriched;
}
const licenseData = await getLicenseTextAndUrl(
license.id,
);
const licenseData = await getLicenseTextAndUrl(license.id);
licenseReportData[license.id] = {
...(license as any),
licenseText: licenseData?.licenseText,
Expand All @@ -68,12 +79,12 @@ export async function generateLicenseData(
}
}


function enrichDependencies(
dependencies: Dependency[],
dependenciesData,
): EnrichedDependency[] {
const enrichDependencies: EnrichedDependency [] = [];
const enrichDependencies: EnrichedDependency[] = [];

for (const dependency of dependencies) {
const dep: DependencyData[] = dependenciesData[dependency.id];
if (dep && dep[0]) {
Expand All @@ -82,7 +93,7 @@ function enrichDependencies(
...dep[0],
});
} else {
debug('Dep information not found for ' + dependency.id);
debug('Dep information not available from /dependencies API response for ' + dependency.id);
}
}

Expand Down
21 changes: 19 additions & 2 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface Dependency {
packageManager: string;
}

export type LicenseSeverity = 'none' | 'high' | 'medium' | 'low';
export type EnrichedDependency = Dependency & DependencyData;

export interface LicenseReportDataEntry {
Expand All @@ -24,7 +25,7 @@ export interface LicenseReportDataEntry {
/**
* Snyk license severity setup on the org license policy
*/
severity?: 'none' | 'high' | 'medium' | 'low';
severity?: LicenseSeverity;
/**
* Snyk license instruction setup on the org license policy
*/
Expand Down Expand Up @@ -129,8 +130,24 @@ export interface DependencyData {
}
[];


export const enum SupportedViews {
ORG_LICENSES = 'org-licenses',
PROJECT_DEPENDENCIES = 'project-dependencies',
}
export interface GetLicenseDataOptions {
filters?: {
projects?: string[];
/**
* The list of dependency IDs to filter the results by
*/
dependencies?: string[];
/**
* The list of license IDs to filter the results by
*/
licenses?: string[];
/**
* The severities to filter the results by
*/
severity?: LicenseSeverity[];
};
}
Loading

0 comments on commit 5b0ec07

Please sign in to comment.