Skip to content

Commit 666f1b9

Browse files
kaizenccgithub-actionsiliapolo
authored
feat(cli): cli-telemetry status command (#697)
- Introduces `cdk cli-telemetry --status` command that reports whether cli telemetry is enabled/disabled. - Pulls `canCollectTelemetry` command + tests out of #631 - Adds `cli-telemetry` to the readme --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --------- Signed-off-by: github-actions <github-actions@github.com> Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: Eli Polonsky <Eli.polonsky@gmail.com>
1 parent 341aed8 commit 666f1b9

File tree

15 files changed

+233
-28
lines changed

15 files changed

+233
-28
lines changed

packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cli-telemetry/cdk-cli-telemetry-adds-context-value.integtest.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ integTest(
4545
['cli-telemetry']: false,
4646
});
4747
} finally {
48-
await fs.unlink(path.join(fixture.integTestDir, 'cdk.context.json'));
48+
await fs.unlink(contextFile);
4949
}
5050
}),
5151
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { promises as fs } from 'fs';
2+
import * as path from 'path';
3+
import { integTest, withDefaultFixture } from '../../../lib';
4+
5+
jest.setTimeout(2 * 60 * 60_000); // Includes the time to acquire locks, worst-case single-threaded runtime
6+
7+
integTest(
8+
'CLI Telemetry reports status',
9+
withDefaultFixture(async (fixture) => {
10+
const userContextFile = path.join(fixture.integTestDir, 'cdk.json');
11+
try {
12+
// default status is enabled
13+
const output1 = await fixture.cdk(['cli-telemetry', '--status']);
14+
expect(output1).toContain('CLI Telemetry is enabled. See https://github.com/aws/aws-cdk-cli/tree/main/packages/aws-cdk#cdk-cli-telemetry for ways to disable.');
15+
16+
// disable status
17+
await fs.writeFile(userContextFile, JSON.stringify({ context: { 'cli-telemetry': false } }));
18+
const output2 = await fixture.cdk(['cli-telemetry', '--status']);
19+
expect(output2).toContain('CLI Telemetry is disabled. See https://github.com/aws/aws-cdk-cli/tree/main/packages/aws-cdk#cdk-cli-telemetry for ways to enable.');
20+
} finally {
21+
await fs.unlink(userContextFile);
22+
}
23+
}),
24+
);

packages/aws-cdk/README.md

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,27 @@
1111

1212
The AWS CDK Toolkit provides the `cdk` command-line interface that can be used to work with AWS CDK applications. This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project.
1313

14-
| Command | Description |
15-
| ------------------------------------- | --------------------------------------------------------------------------------- |
16-
| [`cdk docs`](#cdk-docs) | Access the online documentation |
17-
| [`cdk init`](#cdk-init) | Start a new CDK project (app or library) |
18-
| [`cdk list`](#cdk-list) | List stacks and their dependencies in an application |
19-
| [`cdk synth`](#cdk-synth) | Synthesize a CDK app to CloudFormation template(s) |
20-
| [`cdk diff`](#cdk-diff) | Diff stacks against current state |
21-
| [`cdk deploy`](#cdk-deploy) | Deploy a stack into an AWS account |
22-
| [`cdk rollback`](#cdk-rollback) | Roll back a failed deployment |
23-
| [`cdk import`](#cdk-import) | Import existing AWS resources into a CDK stack |
24-
| [`cdk migrate`](#cdk-migrate) | Migrate AWS resources, CloudFormation stacks, and CloudFormation templates to CDK |
25-
| [`cdk watch`](#cdk-watch) | Watches a CDK app for deployable and hotswappable changes |
26-
| [`cdk destroy`](#cdk-destroy) | Deletes a stack from an AWS account |
27-
| [`cdk bootstrap`](#cdk-bootstrap) | Deploy a toolkit stack to support deploying large stacks & artifacts |
28-
| [`cdk gc`](#cdk-gc) | Garbage collect assets associated with the bootstrapped stack |
29-
| [`cdk doctor`](#cdk-doctor) | Inspect the environment and produce information useful for troubleshooting |
30-
| [`cdk acknowledge`](#cdk-acknowledge) | Acknowledge (and hide) a notice by issue number |
31-
| [`cdk notices`](#cdk-notices) | List all relevant notices for the application |
32-
| [`cdk refactor`](#cdk-refactor) | Moves resources between stacks or within the same stack |
33-
| [`cdk drift`](#cdk-drift) | Detect drifts in the given CloudFormation stack(s) |
14+
| Command | Description |
15+
| ---------------------------------------- | --------------------------------------------------------------------------------- |
16+
| [`cdk docs`](#cdk-docs) | Access the online documentation |
17+
| [`cdk init`](#cdk-init) | Start a new CDK project (app or library) |
18+
| [`cdk list`](#cdk-list) | List stacks and their dependencies in an application |
19+
| [`cdk synth`](#cdk-synth) | Synthesize a CDK app to CloudFormation template(s) |
20+
| [`cdk diff`](#cdk-diff) | Diff stacks against current state |
21+
| [`cdk deploy`](#cdk-deploy) | Deploy a stack into an AWS account |
22+
| [`cdk rollback`](#cdk-rollback) | Roll back a failed deployment |
23+
| [`cdk import`](#cdk-import) | Import existing AWS resources into a CDK stack |
24+
| [`cdk migrate`](#cdk-migrate) | Migrate AWS resources, CloudFormation stacks, and CloudFormation templates to CDK |
25+
| [`cdk watch`](#cdk-watch) | Watches a CDK app for deployable and hotswappable changes |
26+
| [`cdk destroy`](#cdk-destroy) | Deletes a stack from an AWS account |
27+
| [`cdk bootstrap`](#cdk-bootstrap) | Deploy a toolkit stack to support deploying large stacks & artifacts |
28+
| [`cdk gc`](#cdk-gc) | Garbage collect assets associated with the bootstrapped stack |
29+
| [`cdk doctor`](#cdk-doctor) | Inspect the environment and produce information useful for troubleshooting |
30+
| [`cdk acknowledge`](#cdk-acknowledge) | Acknowledge (and hide) a notice by issue number |
31+
| [`cdk notices`](#cdk-notices) | List all relevant notices for the application |
32+
| [`cdk refactor`](#cdk-refactor) | Moves resources between stacks or within the same stack |
33+
| [`cdk drift`](#cdk-drift) | Detect drifts in the given CloudFormation stack(s) |
34+
| [`cdk cli-telemetry](#cdk-cli-telemetry) | Enable or disable cli telemetry collection |
3435

3536
## Common topics
3637

@@ -1213,6 +1214,31 @@ $ # Detect drift against the currently-deployed stack with the verbose flag enab
12131214
$ cdk drift --verbose
12141215
```
12151216

1217+
### `cdk cli-telemetry`
1218+
1219+
Enables or disables cli telemetry collection for your local CDK App. Records your
1220+
choice in `cdk.context.json`. You can also set your preference manually under the `context` key in your
1221+
`~/.cdk.json` file or `<app-root>/cdk.json` file.
1222+
1223+
```bash
1224+
$ # Disable telemetry
1225+
$ cdk cli-telemetry --disable
1226+
1227+
$ # Enable telemetry
1228+
$ cdk cli-telemetry --enable
1229+
```
1230+
1231+
You can also check the current status on whether your CDK App is opted in or out of
1232+
cli telemetry collection. Note that this takes into account all methods of disabling
1233+
cli telemetry, including environment variables and
1234+
[context values](https://docs.aws.amazon.com/cdk/v2/guide/context.html)
1235+
that can be set in many different ways (such as `~/.cdk.json`).
1236+
1237+
```bash
1238+
$ # Check the current status of telemetry
1239+
$ cdk cli-telemetry --status
1240+
```
1241+
12161242
## Global Options
12171243

12181244
### `unstable`

packages/aws-cdk/lib/cli/cdk-toolkit.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import {
6464
serializeStructure,
6565
validateSnsTopicArn,
6666
} from '../util';
67+
import { canCollectTelemetry } from './telemetry/collect-telemetry';
6768

6869
// Must use a require() otherwise esbuild complains about calling a namespace
6970
// eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/consistent-type-imports
@@ -207,6 +208,15 @@ export class CdkToolkit {
207208
await this.props.configuration.saveContext();
208209
}
209210

211+
public async cliTelemetryStatus() {
212+
const canCollect = canCollectTelemetry(this.props.configuration.context);
213+
if (canCollect) {
214+
await this.ioHost.asIoHelper().defaults.info('CLI Telemetry is enabled. See https://github.com/aws/aws-cdk-cli/tree/main/packages/aws-cdk#cdk-cli-telemetry for ways to disable.');
215+
} else {
216+
await this.ioHost.asIoHelper().defaults.info('CLI Telemetry is disabled. See https://github.com/aws/aws-cdk-cli/tree/main/packages/aws-cdk#cdk-cli-telemetry for ways to enable.');
217+
}
218+
}
219+
210220
public async cliTelemetry(enable: boolean) {
211221
this.props.configuration.context.set('cli-telemetry', enable);
212222
await this.props.configuration.saveContext();

packages/aws-cdk/lib/cli/cli-config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,11 @@ export async function makeConfig(): Promise<CliConfig> {
476476
desc: 'Disable anonymous telemetry',
477477
conflicts: 'enable',
478478
},
479+
status: {
480+
type: 'boolean',
481+
desc: 'Report telemetry opt-in/out status',
482+
conflicts: ['enable', 'disable'],
483+
},
479484
},
480485
},
481486
},

packages/aws-cdk/lib/cli/cli-type-registry.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,14 @@
939939
"type": "boolean",
940940
"desc": "Disable anonymous telemetry",
941941
"conflicts": "enable"
942+
},
943+
"status": {
944+
"type": "boolean",
945+
"desc": "Report telemetry opt-in/out status",
946+
"conflicts": [
947+
"enable",
948+
"disable"
949+
]
942950
}
943951
}
944952
}

packages/aws-cdk/lib/cli/cli.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -478,13 +478,16 @@ export async function exec(args: string[], synthesizer?: Synthesizer): Promise<n
478478

479479
case 'cli-telemetry':
480480
ioHost.currentAction = 'cli-telemetry';
481-
if (args.enable === undefined && args.disable === undefined) {
482-
throw new ToolkitError('Must specify either \'--enable\' or \'--disable\'');
481+
if (args.enable === undefined && args.disable === undefined && args.status === undefined) {
482+
throw new ToolkitError('Must specify \'--enable\', \'--disable\', or \'--status\'');
483483
}
484484

485-
const enable = args.enable ?? !args.disable;
486-
return cli.cliTelemetry(enable);
487-
485+
if (args.status) {
486+
return cli.cliTelemetryStatus();
487+
} else {
488+
const enable = args.enable ?? !args.disable;
489+
return cli.cliTelemetry(enable);
490+
}
488491
case 'init':
489492
ioHost.currentAction = 'init';
490493
const language = configuration.settings.get(['language']);

packages/aws-cdk/lib/cli/convert-to-user-input.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ export function convertYargsToUserInput(args: any): UserInput {
284284
commandOptions = {
285285
enable: args.enable,
286286
disable: args.disable,
287+
status: args.status,
287288
};
288289
break;
289290
}
@@ -488,6 +489,7 @@ export function convertConfigToUserInput(config: any): UserInput {
488489
const cliTelemetryOptions = {
489490
enable: config.cliTelemetry?.enable,
490491
disable: config.cliTelemetry?.disable,
492+
status: config.cliTelemetry?.status,
491493
};
492494
const userInput: UserInput = {
493495
globalOptions,

packages/aws-cdk/lib/cli/parse-command-line-arguments.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,12 @@ export function parseCommandLineArguments(args: Array<string>): any {
926926
type: 'boolean',
927927
desc: 'Disable anonymous telemetry',
928928
conflicts: 'enable',
929+
})
930+
.option('status', {
931+
default: undefined,
932+
type: 'boolean',
933+
desc: 'Report telemetry opt-in/out status',
934+
conflicts: ['enable', 'disable'],
929935
}),
930936
)
931937
.version(helpers.cliVersion())
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { Context } from '../../api/context';
2+
3+
/**
4+
* Whether or not we collect telemetry
5+
*/
6+
export function canCollectTelemetry(context: Context): boolean {
7+
if ((['true', '1'].includes(process.env.CDK_DISABLE_CLI_TELEMETRY ?? '')) || ['false', false].includes(context.get('cli-telemetry'))) {
8+
return false;
9+
}
10+
11+
return true;
12+
}

0 commit comments

Comments
 (0)