Skip to content

Commit

Permalink
fix: use provided org to check flags are set
Browse files Browse the repository at this point in the history
  • Loading branch information
lili2311 committed Dec 17, 2019
1 parent 85effc7 commit db6b946
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 39 deletions.
8 changes: 3 additions & 5 deletions src/cli/commands/monitor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ import * as spinner from '../../../lib/spinner';
import * as detect from '../../../lib/detect';
import * as plugins from '../../../lib/plugins';
import { ModuleInfo } from '../../../lib/module-info'; // TODO(kyegupov): fix import
import { MonitorOptions, MonitorMeta } from '../../../lib/types';
import { MonitorOptions, MonitorMeta, Options } from '../../../lib/types';
import { MethodArgs, ArgsOptions } from '../../args';
import { maybePrintDeps } from '../../../lib/print-deps';
import * as analytics from '../../../lib/analytics';
import {
MonitorError,
} from '../../../lib/errors';
import { MonitorError } from '../../../lib/errors';
import { legacyPlugin as pluginApi } from '@snyk/cli-interface';
import { formatMonitorOutput } from './formatters/format-monitor-response';

Expand Down Expand Up @@ -164,7 +162,7 @@ async function monitor(...args0: MethodArgs): Promise<any> {
maybePrintDeps(options, projectDeps.package);

const res = await promiseOrCleanup(
snykMonitor(path, meta, projectDeps, targetFile),
snykMonitor(path, meta, projectDeps, options, targetFile),
spinner.clear(postingMonitorSpinnerLabel),
);

Expand Down
2 changes: 1 addition & 1 deletion src/cli/commands/protect/wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ function processAnswers(answers, policy, options) {
plugin: inspectRes.plugin,
package: _.get(inspectRes, 'scannedProjects[0].depTree'),
};
return snykMonitor(cwd, meta as MonitorMeta, singleRes);
return snykMonitor(cwd, meta as MonitorMeta, singleRes, options);
})
// clear spinner in case of success or failure
.then(spinner.clear(lbl))
Expand Down
2 changes: 1 addition & 1 deletion src/cli/commands/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ async function test(...args: MethodArgs): Promise<string> {

const pinningSupported =
pipResults &&
(await isFeatureFlagSupportedForOrg('pythonPinningAdvice')).ok;
(await isFeatureFlagSupportedForOrg('pythonPinningAdvice', config.org)).ok;

let response = results
.map((unused, i) => {
Expand Down
3 changes: 3 additions & 0 deletions src/lib/feature-flags.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import request = require('./request');
import snyk = require('.'); // TODO(kyegupov): fix import
import * as config from './config';
import { assembleQueryString } from './snyk-test/common';

interface OrgFeatureFlagResponse {
ok?: boolean;
Expand All @@ -11,12 +12,14 @@ interface OrgFeatureFlagResponse {

export async function isFeatureFlagSupportedForOrg(
featureFlag: string,
org,
): Promise<OrgFeatureFlagResponse> {
const response = await request({
method: 'GET',
headers: {
Authorization: `token ${snyk.api}`,
},
qs: assembleQueryString({ org }),
url: `${config.API}/cli-config/feature-flags/${featureFlag}`,
gzip: true,
json: true,
Expand Down
35 changes: 27 additions & 8 deletions src/lib/monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,20 @@ import * as os from 'os';
import * as _ from 'lodash';
import { isCI } from './is-ci';
import * as analytics from './analytics';
import { DepTree, MonitorMeta, MonitorResult } from './types';
import {
DepTree,
MonitorMeta,
MonitorResult,
MonitorOptions,
Options,
} from './types';
import * as projectMetadata from './project-metadata';
import * as path from 'path';
import { MonitorError, ConnectionTimeoutError, AuthFailedError } from './errors';
import {
MonitorError,
ConnectionTimeoutError,
AuthFailedError,
} from './errors';
import { countPathsToGraphRoot, pruneGraph } from './prune';
import { GRAPH_SUPPORTED_PACKAGE_MANAGERS } from './package-managers';
import { legacyPlugin as pluginApi } from '@snyk/cli-interface';
Expand Down Expand Up @@ -140,6 +150,7 @@ export async function monitor(
root: string,
meta: MonitorMeta,
info: pluginApi.SinglePackageResult,
options,
targetFile?: string,
): Promise<MonitorResult> {
apiTokenExists();
Expand All @@ -148,21 +159,26 @@ export async function monitor(
const packageManager = meta.packageManager;
analytics.add('packageManager', packageManager);
analytics.add('isDocker', !!meta.isDocker);
analytics.add('monitorGraph', true);

if (
GRAPH_SUPPORTED_PACKAGE_MANAGERS.includes(packageManager)
) {
if (GRAPH_SUPPORTED_PACKAGE_MANAGERS.includes(packageManager)) {
const monitorGraphSupportedRes = await isFeatureFlagSupportedForOrg(
_.camelCase('experimental-dep-graph'),
options.org || config.org,
);

if (monitorGraphSupportedRes.code === 401) {
throw AuthFailedError(monitorGraphSupportedRes.error, monitorGraphSupportedRes.code);
throw AuthFailedError(
monitorGraphSupportedRes.error,
monitorGraphSupportedRes.code,
);
}

if (monitorGraphSupportedRes.ok) {
return await monitorGraph(root, meta, info, targetFile);
}
if (monitorGraphSupportedRes.userMessage) {
debug(monitorGraphSupportedRes.userMessage);
}
}

let pkg = info.package;
Expand Down Expand Up @@ -228,7 +244,8 @@ export async function monitor(
? pkg.docker.dockerfileLayers
: undefined,
projectName: meta['project-name'],
prePruneDepCount, // undefined unless 'prune' is used
prePruneDepCount, // undefined unless 'prune' is used,
monitorGraph: false,
},
policy: policy ? policy.toString() : undefined,
package: pkg,
Expand Down Expand Up @@ -276,6 +293,7 @@ export async function monitorGraph(
targetFile?: string,
): Promise<MonitorResult> {
const packageManager = meta.packageManager;
analytics.add('monitorGraph', true);

let treeMissingDeps: string[];
let pkg = info.package;
Expand Down Expand Up @@ -345,6 +363,7 @@ export async function monitorGraph(
projectName: meta['project-name'],
prePruneDepCount, // undefined unless 'prune' is used
missingDeps: treeMissingDeps,
monitorGraph: true,
},
policy: policy ? policy.toString() : undefined,
depGraphJSON: prunedGraph, // depGraph will be auto serialized to JSON on send
Expand Down
46 changes: 25 additions & 21 deletions test/acceptance/cli-monitor/cli-monitor.acceptance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as cli from '../../../src/cli/commands';
import { fakeServer } from '../fake-server';
import * as subProcess from '../../../src/lib/sub-process';
import * as version from '../../../src/lib/version';
import * as userConfig from '../../../src/lib/user-config';

// ensure this is required *after* the demo server, since this will
// configure our fake configuration too
Expand Down Expand Up @@ -170,7 +171,9 @@ test('`monitor npm-package`', async (t) => {
const depGraphJSON = req.body.depGraphJSON;
t.ok(depGraphJSON);
const debug = depGraphJSON.pkgs.find((pkg) => pkg.info.name === 'debug');
const objectAssign = depGraphJSON.pkgs.find((pkg) => pkg.info.name === 'object-assign');
const objectAssign = depGraphJSON.pkgs.find(
(pkg) => pkg.info.name === 'object-assign',
);
t.match(req.url, '/monitor/npm/graph', 'puts at correct url');
t.ok(debug, 'dependency');
t.notOk(req.body.targetFile, 'doesnt send the targetFile');
Expand Down Expand Up @@ -200,20 +203,6 @@ test('`monitor npm-out-of-sync graph monitor`', async (t) => {
);
});

test('`monitor npm-out-of-sync old monitor`', async (t) => {
chdirWorkspaces();
await cli.monitor('npm-out-of-sync-graph', {
strictOutOfSync: false,
});
const req = server.popRequest();
t.match(req.url, '/monitor/npm', 'puts at correct url');
t.deepEqual(
req.body.meta.missingDeps,
['body-parser@^1.18.2'],
'missingDeps passed',
);
});

test('`monitor npm-package-pruneable --prune-repeated-subdependencies`', async (t) => {
chdirWorkspaces();

Expand All @@ -228,10 +217,13 @@ test('`monitor npm-package-pruneable --prune-repeated-subdependencies`', async (
'sends version number',
);
t.match(req.url, '/monitor/npm/graph', 'puts at correct url');
t.deepEqual(req.body.meta.monitorGraph, true, 'correct meta set');
t.ok(req.body.meta.prePruneDepCount, 'sends meta.prePruneDepCount');
const depGraphJSON = req.body.depGraphJSON;
t.ok(depGraphJSON);
const packageC = depGraphJSON.graph.nodes.find((pkg) => pkg.pkgId === 'c@1.0.0');
const packageC = depGraphJSON.graph.nodes.find(
(pkg) => pkg.pkgId === 'c@1.0.0',
);
t.ok(packageC.info.labels.pruned, 'a.d.c is pruned');
t.notOk(packageC.dependencies, 'a.d.c has no dependencies');
});
Expand Down Expand Up @@ -261,6 +253,19 @@ test('`monitor npm-package-pruneable --experimental-dep-graph`', async (t) => {
t.ok(req.body.depGraphJSON, 'sends depGraphJSON');
});

test('`monitor npm-package-pruneable experimental for no-flag org`', async (t) => {
chdirWorkspaces();
await cli.monitor('npm-package-pruneable', {
org: 'no-flag',
});
const req = server.popRequest();
t.equal(req.method, 'PUT', 'makes PUT request');
t.match(req.url, '/monitor/npm', 'puts at correct url');
t.deepEqual(req.body.meta.monitorGraph, false, 'correct meta set');
t.ok(req.body.package, 'sends package');
userConfig.delete('org');
});

test('`monitor sbt package --experimental-dep-graph --sbt-graph`', async (t) => {
chdirWorkspaces();

Expand Down Expand Up @@ -420,14 +425,13 @@ test('`monitor npm-package with dev dep flag`', async (t) => {
);
const depGraphJSON = req.body.depGraphJSON;
const debug = depGraphJSON.pkgs.find((pkg) => pkg.info.name === 'debug');
const objectAssign = depGraphJSON.pkgs.find((pkg) => pkg.info.name === 'object-assign');
const objectAssign = depGraphJSON.pkgs.find(
(pkg) => pkg.info.name === 'object-assign',
);
t.ok(depGraphJSON, 'monitor is a depgraph format');
t.match(req.url, '/monitor/npm/graph', 'puts at correct url');
t.ok(debug, 'debug dependency found');
t.ok(
objectAssign,
'includes dev dependency',
);
t.ok(objectAssign, 'includes dev dependency');
});

test('`monitor yarn-package with dev dep flag`', async (t) => {
Expand Down
9 changes: 9 additions & 0 deletions test/acceptance/fake-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@ export function fakeServer(root, apikey) {
server.get(
root + '/cli-config/feature-flags/:featureFlag',
(req, res, next) => {
const flag = req.params.featureFlag;
if ((req as any).params.org === 'no-flag') {
res.send({
ok: false,
userMessage: `Org ${
(req as any).org
} doesn\'t have \'${flag}\' feature enabled'`,
});
}
res.send({
ok: true,
});
Expand Down
6 changes: 3 additions & 3 deletions test/monitor-target.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ test('Make sure that target is sent correctly', async (t) => {
.resolves('master');

const { data } = await getFakeServerRequestBody();
t.true(requestSpy.calledOnce, 'needle.request was called once');
t.true(requestSpy.calledTwice, 'needle.request was called once');
t.true(!_.isEmpty(data.target), 'target passed to request');
t.true(
!_.isEmpty(data.targetFileRelativePath),
Expand All @@ -77,7 +77,7 @@ test("Make sure it's not failing monitor for non git projects", async (t) => {
const requestSpy = sinon.spy(requestLib, 'request');
const { data } = await getFakeServerRequestBody();

t.true(requestSpy.calledOnce, 'needle.request was called once');
t.true(requestSpy.calledTwice, 'needle.request was called once');
t.true(_.isEmpty(data.target), 'empty target passed to request');
t.match(
data.targetFileRelativePath,
Expand All @@ -94,7 +94,7 @@ test("Make sure it's not failing if there is no remote configured", async (t) =>
const requestSpy = sinon.spy(requestLib, 'request');
const { data } = await getFakeServerRequestBody();

t.true(requestSpy.calledOnce, 'needle.request was called once');
t.true(requestSpy.calledTwice, 'needle.request was called once');
t.true(_.isEmpty(data.target), 'empty target passed to request');
t.match(
data.targetFileRelativePath,
Expand Down

0 comments on commit db6b946

Please sign in to comment.