Skip to content

Commit 4df0e0e

Browse files
author
aws-amplify-bot
committed
update vended log type
1 parent 6b50000 commit 4df0e0e

File tree

5 files changed

+169
-72
lines changed

5 files changed

+169
-72
lines changed

packages/@aws-cdk/service-spec-importers/src/diff-fmt.ts

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
UpdatedResource,
1717
UpdatedService,
1818
UpdatedTypeDefinition,
19-
VendedLog,
19+
VendedLogs,
2020
Event,
2121
EventTypeDefinition,
2222
EventProperty,
@@ -334,57 +334,88 @@ export class DiffFormatter {
334334
});
335335
}
336336

337-
private renderVendedLogsDiff(diff: ScalarDiff<VendedLog | undefined> | undefined): PrintableTree[] {
337+
private renderVendedLogsDiff(diff: ScalarDiff<VendedLogs[] | undefined> | undefined): PrintableTree[] {
338338
if (!diff || (!diff.old && !diff.new)) {
339339
return [];
340340
}
341-
const tree: PrintableTree[] = [];
342341

343342
if (!diff.old && diff.new) {
344-
return [this.renderVendedLogsType(diff.new).prefix([chalk.green(ADDITION), ' '], [' '])];
343+
return diff.new.map((vl) => this.renderVendedLog(vl).prefix([chalk.green(ADDITION), ' '], [' ']));
345344
}
346345
if (diff.old && !diff.new) {
347-
return [this.renderVendedLogsType(diff.old).prefix([chalk.red(REMOVAL), ' '], [' '])];
346+
return diff.old.map((vl) => this.renderVendedLog(vl).prefix([chalk.red(REMOVAL), ' '], [' ']));
348347
}
349348

350-
if (diff.old && diff.new) {
351-
if (diff.old.permissionsVersion !== diff.new.permissionsVersion) {
352-
tree.push(
353-
new PrintableTree(`permissionsVersion:`).addBullets([
354-
new PrintableTree(`- ${diff.old.permissionsVersion}`).colorize(chalk.red),
355-
new PrintableTree(`+ ${diff.new.permissionsVersion}`).colorize(chalk.green),
356-
]),
357-
);
349+
const tree: PrintableTree[] = [];
350+
const oldMap = new Map((diff.old ?? []).map((vl) => [vl.logType, vl]));
351+
const newMap = new Map((diff.new ?? []).map((vl) => [vl.logType, vl]));
352+
353+
const allLogTypes = new Set([...oldMap.keys(), ...newMap.keys()]);
354+
355+
for (const logType of allLogTypes) {
356+
const oldVl = oldMap.get(logType);
357+
const newVl = newMap.get(logType);
358+
359+
if (!oldVl && newVl) {
360+
tree.push(this.renderVendedLog(newVl).prefix([chalk.green(ADDITION), ' '], [' ']));
361+
} else if (oldVl && !newVl) {
362+
tree.push(this.renderVendedLog(oldVl).prefix([chalk.red(REMOVAL), ' '], [' ']));
363+
} else if (oldVl && newVl) {
364+
const changes = this.compareVendedLogs(oldVl, newVl);
365+
if (changes.length > 0) {
366+
tree.push(
367+
new PrintableTree(`logType: ${logType}`).addBullets(changes).prefix([chalk.yellow(UPDATE), ' '], [' ']),
368+
);
369+
}
358370
}
359-
360-
this.renderVendedLogListDiff(diff, tree, 'logTypes');
361-
this.renderVendedLogListDiff(diff, tree, 'destinations');
362371
}
363372
return tree;
364373
}
365374

366-
private renderVendedLogsType(vendedLogs: VendedLog): PrintableTree {
367-
return new PrintableTree(`vendedLogs`).addBullets([
368-
new PrintableTree(`permissionsVersion: ${vendedLogs.permissionsVersion}`),
369-
new PrintableTree(`logTypes: [${vendedLogs.logTypes.join(', ')}]`),
370-
new PrintableTree(`destinations: [${vendedLogs.destinations.join(', ')}]`),
375+
private renderVendedLog(vl: VendedLogs): PrintableTree {
376+
const destinations = vl.destinations
377+
.map((d) => (d.outputFormat ? `${d.destinationType}(${d.outputFormat})` : d.destinationType))
378+
.join(', ');
379+
return new PrintableTree(`logType: ${vl.logType}`).addBullets([
380+
new PrintableTree(`permissionsVersion: ${vl.permissionsVersion}`),
381+
new PrintableTree(`destinations: [${destinations}]`),
371382
]);
372383
}
373384

374-
private renderVendedLogListDiff(diff: ScalarDiff<VendedLog | undefined>, tree: PrintableTree[], diffShown: string) {
375-
if (diff.old && diff.new) {
376-
// the array should correspond to the value of diffShown
377-
const oldList = new Set(diffShown === 'logTypes' ? diff.new.logTypes : diff.new.destinations);
378-
const newList = new Set(diffShown === 'logTypes' ? diff.new.logTypes : diff.new.destinations);
379-
const added = [...newList].filter((t) => !oldList.has(t));
380-
const removed = [...oldList].filter((t) => !newList.has(t));
381-
if (added.length > 0 || removed.length > 0) {
382-
const bullets: PrintableTree[] = [];
383-
removed.forEach((obj) => bullets.push(new PrintableTree(`- ${obj}`).colorize(chalk.red)));
384-
added.forEach((obj) => bullets.push(new PrintableTree(`+ ${obj}`).colorize(chalk.green)));
385-
tree.push(new PrintableTree(`${diffShown}:`).addBullets(bullets));
386-
}
385+
private compareVendedLogs(old: VendedLogs, updated: VendedLogs): PrintableTree[] {
386+
const changes: PrintableTree[] = [];
387+
388+
if (old.permissionsVersion !== updated.permissionsVersion) {
389+
changes.push(
390+
new PrintableTree(`permissionsVersion:`).addBullets([
391+
new PrintableTree(`- ${old.permissionsVersion}`).colorize(chalk.red),
392+
new PrintableTree(`+ ${updated.permissionsVersion}`).colorize(chalk.green),
393+
]),
394+
);
387395
}
396+
397+
const oldDests = new Map(old.destinations.map((d) => [`${d.destinationType}:${d.outputFormat ?? ''}`, d]));
398+
const newDests = new Map(updated.destinations.map((d) => [`${d.destinationType}:${d.outputFormat ?? ''}`, d]));
399+
400+
const added = [...newDests.keys()].filter((k) => !oldDests.has(k));
401+
const removed = [...oldDests.keys()].filter((k) => !newDests.has(k));
402+
403+
if (added.length > 0 || removed.length > 0) {
404+
const bullets: PrintableTree[] = [];
405+
removed.forEach((k) => {
406+
const d = oldDests.get(k)!;
407+
const str = d.outputFormat ? `${d.destinationType}(${d.outputFormat})` : d.destinationType;
408+
bullets.push(new PrintableTree(`- ${str}`).colorize(chalk.red));
409+
});
410+
added.forEach((k) => {
411+
const d = newDests.get(k)!;
412+
const str = d.outputFormat ? `${d.destinationType}(${d.outputFormat})` : d.destinationType;
413+
bullets.push(new PrintableTree(`+ ${str}`).colorize(chalk.green));
414+
});
415+
changes.push(new PrintableTree(`destinations:`).addBullets(bullets));
416+
}
417+
418+
return changes;
388419
}
389420

390421
private renderEvent(e: Event, db: number): PrintableTree {

packages/@aws-cdk/service-spec-importers/src/importers/import-log-source.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export function importLogSources(
99
{
1010
LogType: string;
1111
ResourceTypes: string[];
12-
Destinations: Array<{ DestinationType: string; PermissionsVersion: string }>;
12+
Destinations: Array<{ DestinationType: string; PermissionsVersion: string; OutputFormat: string | null }>;
1313
}
1414
>,
1515
report: ProblemReport,
@@ -29,20 +29,20 @@ export function importLogSources(
2929
);
3030
}
3131

32-
const destinations = value.Destinations.map((dest) => dest.DestinationType as DestinationService);
32+
const destinations: DestinationService[] = value.Destinations.map((dest) => ({
33+
destinationType: dest.DestinationType,
34+
outputFormat: dest.OutputFormat ? dest.OutputFormat : undefined,
35+
}));
3336

34-
resource.vendedLogs ??= {
35-
// we take whatever the newest permissions value is and assume that all logs in a resource use the same permissions
37+
const newLog = {
38+
// we take whatever the newest permissions value is and assume that all destinations for a certain logType use the same permissions
3639
permissionsVersion: permissionValue,
37-
logTypes: [],
38-
destinations: [],
40+
logType: value.LogType,
41+
destinations: destinations,
3942
};
4043

41-
resource.vendedLogs.logTypes.push(value.LogType);
42-
// dedupes incoming destinations
43-
const newDestinations = destinations.filter((dest) => !resource.vendedLogs!.destinations.includes(dest));
44-
45-
resource.vendedLogs.destinations.push(...newDestinations);
44+
resource.vendedLogs ??= [];
45+
resource.vendedLogs.push(newLog);
4646
} catch (err) {
4747
// assumes the only error we are likely to see is something relating to resource type not existing in the CFN DB
4848
report.reportFailure(

packages/@aws-cdk/service-spec-importers/test/log-sources.test.ts

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ test('adds log type to resource', () => {
3838
{
3939
DestinationType: 'S3',
4040
PermissionsVersion: 'V2',
41+
OutputFormat: 'json',
4142
},
4243
],
4344
},
@@ -48,6 +49,7 @@ test('adds log type to resource', () => {
4849
{
4950
DestinationType: 'XRAY',
5051
PermissionsVersion: 'V2',
52+
OutputFormat: null,
5153
},
5254
],
5355
},
@@ -56,11 +58,28 @@ test('adds log type to resource', () => {
5658
);
5759

5860
const res = db.lookup('resource', 'cloudFormationType', 'equals', 'AWS::Some::Type')[0];
59-
expect(res.vendedLogs).toEqual({
60-
permissionsVersion: 'V2',
61-
logTypes: ['SOME_LOGS', 'TRACES'],
62-
destinations: ['S3', 'XRAY'],
63-
});
61+
expect(res.vendedLogs).toEqual([
62+
{
63+
permissionsVersion: 'V2',
64+
logType: 'SOME_LOGS',
65+
destinations: [
66+
{
67+
destinationType: 'S3',
68+
outputFormat: 'json',
69+
},
70+
],
71+
},
72+
{
73+
permissionsVersion: 'V2',
74+
logType: 'TRACES',
75+
destinations: [
76+
{
77+
destinationType: 'XRAY',
78+
outputFormat: undefined,
79+
},
80+
],
81+
},
82+
]);
6483
});
6584

6685
test('adds multiple log types to resource and does not add duplicate destinations', () => {
@@ -74,6 +93,7 @@ test('adds multiple log types to resource and does not add duplicate destination
7493
{
7594
DestinationType: 'S3',
7695
PermissionsVersion: 'V2',
96+
OutputFormat: 'json',
7797
},
7898
],
7999
},
@@ -84,6 +104,7 @@ test('adds multiple log types to resource and does not add duplicate destination
84104
{
85105
DestinationType: 'S3',
86106
PermissionsVersion: 'V2',
107+
OutputFormat: 'json',
87108
},
88109
],
89110
},
@@ -92,11 +113,28 @@ test('adds multiple log types to resource and does not add duplicate destination
92113
);
93114

94115
const res = db.lookup('resource', 'cloudFormationType', 'equals', 'AWS::Some::Type')[0];
95-
expect(res.vendedLogs).toEqual({
96-
permissionsVersion: 'V2',
97-
logTypes: ['APPLICATION_LOGS', 'EVENT_LOGS'],
98-
destinations: ['S3'],
99-
});
116+
expect(res.vendedLogs).toEqual([
117+
{
118+
permissionsVersion: 'V2',
119+
logType: 'APPLICATION_LOGS',
120+
destinations: [
121+
{
122+
destinationType: 'S3',
123+
outputFormat: 'json',
124+
},
125+
],
126+
},
127+
{
128+
permissionsVersion: 'V2',
129+
logType: 'EVENT_LOGS',
130+
destinations: [
131+
{
132+
destinationType: 'S3',
133+
outputFormat: 'json',
134+
},
135+
],
136+
},
137+
]);
100138
});
101139

102140
test('adds log types to multiple resources', () => {
@@ -110,6 +148,7 @@ test('adds log types to multiple resources', () => {
110148
{
111149
DestinationType: 'S3',
112150
PermissionsVersion: 'V2',
151+
OutputFormat: 'json',
113152
},
114153
],
115154
},
@@ -118,18 +157,32 @@ test('adds log types to multiple resources', () => {
118157
);
119158

120159
const someRes = db.lookup('resource', 'cloudFormationType', 'equals', 'AWS::Some::Type')[0];
121-
expect(someRes.vendedLogs).toEqual({
122-
permissionsVersion: 'V2',
123-
logTypes: ['APPLICATION_LOGS'],
124-
destinations: ['S3'],
125-
});
160+
expect(someRes.vendedLogs).toEqual([
161+
{
162+
permissionsVersion: 'V2',
163+
logType: 'APPLICATION_LOGS',
164+
destinations: [
165+
{
166+
destinationType: 'S3',
167+
outputFormat: 'json',
168+
},
169+
],
170+
},
171+
]);
126172

127173
const otherRes = db.lookup('resource', 'cloudFormationType', 'equals', 'AWS::Other::Type')[0];
128-
expect(otherRes.vendedLogs).toEqual({
129-
permissionsVersion: 'V2',
130-
logTypes: ['APPLICATION_LOGS'],
131-
destinations: ['S3'],
132-
});
174+
expect(otherRes.vendedLogs).toEqual([
175+
{
176+
permissionsVersion: 'V2',
177+
logType: 'APPLICATION_LOGS',
178+
destinations: [
179+
{
180+
destinationType: 'S3',
181+
outputFormat: 'json',
182+
},
183+
],
184+
},
185+
]);
133186
});
134187

135188
test('does not assign logTypes if resource does not exist in Cloudformation', () => {
@@ -143,6 +196,7 @@ test('does not assign logTypes if resource does not exist in Cloudformation', ()
143196
{
144197
DestinationType: 'S3',
145198
PermissionsVersion: 'V2',
199+
OutputFormat: 'json',
146200
},
147201
],
148202
},

packages/@aws-cdk/service-spec-types/src/types/resource.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export interface Resource extends Entity {
6767
readonly validations?: unknown;
6868
arnTemplate?: string;
6969
isStateful?: boolean;
70-
vendedLogs?: VendedLog;
70+
vendedLogs?: VendedLogs[];
7171

7272
/**
7373
* Information about the taggability of this resource
@@ -421,20 +421,32 @@ export interface RelationshipRef {
421421
readonly propertyName: string;
422422
}
423423

424-
export type DestinationService = 'S3' | 'CWL' | 'FH' | 'XRAY';
424+
/**
425+
* Represents a destination a Cloudformation Resource can send logs to
426+
*/
427+
export interface DestinationService {
428+
/**
429+
* Type of destination, can be S3 | FH | CWL | XRAY
430+
*/
431+
readonly destinationType: string;
432+
/**
433+
* Format of the logs that are send to this destination, can be json | plain | w3c | raw | parquet
434+
*/
435+
readonly outputFormat?: string;
436+
}
425437

426438
/**
427439
* Represents the types of logs a Cloudformation Resource can produce and what destinations can consume them
428440
*/
429-
export interface VendedLog {
441+
export interface VendedLogs {
430442
/**
431443
* What version of permissions the destination supports V1 | V2
432444
*/
433445
readonly permissionsVersion: string;
434446
/**
435-
* List of the types of logs a Cloudformation resource can produce
447+
* Type of log a Cloudformation resource can produce
436448
*/
437-
readonly logTypes: string[];
449+
readonly logType: string;
438450
/**
439451
* List of the destinations the can consume those logs
440452
*/

sources/LogSources/log-source-resource.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)