@terra-graph/conventions-aws 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/README.md +25 -0
- package/dist/cjs/conventions/dataflow/profiles/base.js +89 -0
- package/dist/cjs/conventions/dataflow/profiles/dot.js +44 -0
- package/dist/cjs/conventions/dataflow/profiles/dot.test.js +147 -0
- package/dist/cjs/conventions/dataflow/rules.js +4 -0
- package/dist/cjs/conventions/dataflow/rules.test.js +11 -0
- package/dist/cjs/conventions/dataflow/rulesets.js +751 -0
- package/dist/cjs/conventions/dataflow/rulesets.test.js +27 -0
- package/dist/cjs/conventions/index.js +7 -0
- package/dist/cjs/conventions/index.test.js +8 -0
- package/dist/cjs/index.js +70 -0
- package/dist/cjs/index.test.js +58 -0
- package/dist/cjs/namespaces.js +14 -0
- package/dist/cjs/namespaces.test.js +17 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/plugins/AwsApiGateway.js +218 -0
- package/dist/cjs/plugins/AwsApiGateway.test.js +427 -0
- package/dist/cjs/plugins/AwsIam.js +432 -0
- package/dist/cjs/plugins/AwsIam.test.js +468 -0
- package/dist/cjs/plugins/AwsS3.js +107 -0
- package/dist/cjs/plugins/AwsS3.test.js +102 -0
- package/dist/cjs/plugins/AwsSns.js +52 -0
- package/dist/cjs/plugins/AwsSns.test.js +55 -0
- package/dist/cjs/plugins/AwsTransferFamily.js +105 -0
- package/dist/cjs/plugins/AwsTransferFamily.test.js +279 -0
- package/dist/cjs/rules/dot.js +36 -0
- package/dist/cjs/rules/dot.test.js +42 -0
- package/dist/cjs/rules/general.js +69 -0
- package/dist/cjs/rules/general.test.js +47 -0
- package/dist/cjs/rulesets/dot.js +25 -0
- package/dist/cjs/rulesets/dot.test.js +48 -0
- package/dist/esm/conventions/dataflow/profiles/base.d.ts +4 -0
- package/dist/esm/conventions/dataflow/profiles/base.js +86 -0
- package/dist/esm/conventions/dataflow/profiles/dot.d.ts +4 -0
- package/dist/esm/conventions/dataflow/profiles/dot.js +38 -0
- package/dist/esm/conventions/dataflow/profiles/dot.test.d.ts +1 -0
- package/dist/esm/conventions/dataflow/profiles/dot.test.js +109 -0
- package/dist/esm/conventions/dataflow/rules.d.ts +3 -0
- package/dist/esm/conventions/dataflow/rules.js +2 -0
- package/dist/esm/conventions/dataflow/rules.test.d.ts +1 -0
- package/dist/esm/conventions/dataflow/rules.test.js +6 -0
- package/dist/esm/conventions/dataflow/rulesets.d.ts +3 -0
- package/dist/esm/conventions/dataflow/rulesets.js +749 -0
- package/dist/esm/conventions/dataflow/rulesets.test.d.ts +1 -0
- package/dist/esm/conventions/dataflow/rulesets.test.js +22 -0
- package/dist/esm/conventions/index.d.ts +3 -0
- package/dist/esm/conventions/index.js +4 -0
- package/dist/esm/conventions/index.test.d.ts +1 -0
- package/dist/esm/conventions/index.test.js +6 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +32 -0
- package/dist/esm/index.test.d.ts +1 -0
- package/dist/esm/index.test.js +53 -0
- package/dist/esm/namespaces.d.ts +7 -0
- package/dist/esm/namespaces.js +6 -0
- package/dist/esm/namespaces.test.d.ts +1 -0
- package/dist/esm/namespaces.test.js +15 -0
- package/dist/esm/plugins/AwsApiGateway.d.ts +6 -0
- package/dist/esm/plugins/AwsApiGateway.js +214 -0
- package/dist/esm/plugins/AwsApiGateway.test.d.ts +1 -0
- package/dist/esm/plugins/AwsApiGateway.test.js +425 -0
- package/dist/esm/plugins/AwsIam.d.ts +32 -0
- package/dist/esm/plugins/AwsIam.js +428 -0
- package/dist/esm/plugins/AwsIam.test.d.ts +1 -0
- package/dist/esm/plugins/AwsIam.test.js +466 -0
- package/dist/esm/plugins/AwsS3.d.ts +12 -0
- package/dist/esm/plugins/AwsS3.js +103 -0
- package/dist/esm/plugins/AwsS3.test.d.ts +1 -0
- package/dist/esm/plugins/AwsS3.test.js +100 -0
- package/dist/esm/plugins/AwsSns.d.ts +6 -0
- package/dist/esm/plugins/AwsSns.js +48 -0
- package/dist/esm/plugins/AwsSns.test.d.ts +1 -0
- package/dist/esm/plugins/AwsSns.test.js +53 -0
- package/dist/esm/plugins/AwsTransferFamily.d.ts +6 -0
- package/dist/esm/plugins/AwsTransferFamily.js +101 -0
- package/dist/esm/plugins/AwsTransferFamily.test.d.ts +1 -0
- package/dist/esm/plugins/AwsTransferFamily.test.js +277 -0
- package/dist/esm/rules/dot.d.ts +3 -0
- package/dist/esm/rules/dot.js +34 -0
- package/dist/esm/rules/dot.test.d.ts +1 -0
- package/dist/esm/rules/dot.test.js +37 -0
- package/dist/esm/rules/general.d.ts +3 -0
- package/dist/esm/rules/general.js +67 -0
- package/dist/esm/rules/general.test.d.ts +1 -0
- package/dist/esm/rules/general.test.js +42 -0
- package/dist/esm/rulesets/dot.d.ts +3 -0
- package/dist/esm/rulesets/dot.js +23 -0
- package/dist/esm/rulesets/dot.test.d.ts +1 -0
- package/dist/esm/rulesets/dot.test.js +43 -0
- package/package.json +45 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AwsSns = void 0;
|
|
4
|
+
const core_1 = require("@terra-graph/core");
|
|
5
|
+
const namespaces_js_1 = require("../namespaces.js");
|
|
6
|
+
class AwsSns extends core_1.GraphPlugin {
|
|
7
|
+
static id = (0, namespaces_js_1.pluginId)(`aws.${AwsSns.name}`);
|
|
8
|
+
constructor() {
|
|
9
|
+
super(AwsSns.id);
|
|
10
|
+
}
|
|
11
|
+
build(_input) {
|
|
12
|
+
return {
|
|
13
|
+
phases: [
|
|
14
|
+
{
|
|
15
|
+
phase: 'main',
|
|
16
|
+
rules: [
|
|
17
|
+
new core_1.EdgeReverse({
|
|
18
|
+
edge: {
|
|
19
|
+
from: {
|
|
20
|
+
attr: {
|
|
21
|
+
key: 'terraform.resource',
|
|
22
|
+
eq: 'aws_sns_topic',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
to: {
|
|
26
|
+
attr: {
|
|
27
|
+
key: 'terraform.resource',
|
|
28
|
+
eq: 'aws_sns_topic_subscription',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
phase: 'main',
|
|
37
|
+
rules: [
|
|
38
|
+
new core_1.ConvertNodeToEdge({
|
|
39
|
+
node: {
|
|
40
|
+
attr: {
|
|
41
|
+
key: 'terraform.resource',
|
|
42
|
+
eq: 'aws_sns_topic_subscription',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
}),
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.AwsSns = AwsSns;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@terra-graph/core");
|
|
4
|
+
const AwsSns_js_1 = require("./AwsSns.js");
|
|
5
|
+
const buildPhases = () => {
|
|
6
|
+
const plugin = new AwsSns_js_1.AwsSns();
|
|
7
|
+
const result = plugin.build({
|
|
8
|
+
options: {},
|
|
9
|
+
namedRules: new core_1.NamedRuleRegistry(),
|
|
10
|
+
namedRuleSets: new core_1.NamedRuleSetRegistry(),
|
|
11
|
+
});
|
|
12
|
+
return (result.phases ?? []).map((phase) => ({
|
|
13
|
+
phase: phase.phase,
|
|
14
|
+
rules: phase.rules.map((rule) => rule.serialize()),
|
|
15
|
+
}));
|
|
16
|
+
};
|
|
17
|
+
describe('AwsSns.build', () => {
|
|
18
|
+
it('shoud reverse subscription edges and convert subscriptions into edges', () => {
|
|
19
|
+
const phases = buildPhases();
|
|
20
|
+
expect(phases).toHaveLength(2);
|
|
21
|
+
expect(phases.map((phase) => phase.phase)).toStrictEqual(['main', 'main']);
|
|
22
|
+
expect(phases[0]?.rules).toHaveLength(1);
|
|
23
|
+
expect(phases[0]?.rules[0]).toStrictEqual({
|
|
24
|
+
id: 'EdgeReverse',
|
|
25
|
+
config: {
|
|
26
|
+
edge: {
|
|
27
|
+
from: {
|
|
28
|
+
attr: {
|
|
29
|
+
key: 'terraform.resource',
|
|
30
|
+
eq: 'aws_sns_topic',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
to: {
|
|
34
|
+
attr: {
|
|
35
|
+
key: 'terraform.resource',
|
|
36
|
+
eq: 'aws_sns_topic_subscription',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
expect(phases[1]?.rules).toHaveLength(1);
|
|
43
|
+
expect(phases[1]?.rules[0]).toStrictEqual({
|
|
44
|
+
id: 'ConvertNodeToEdge',
|
|
45
|
+
config: {
|
|
46
|
+
node: {
|
|
47
|
+
attr: {
|
|
48
|
+
key: 'terraform.resource',
|
|
49
|
+
eq: 'aws_sns_topic_subscription',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AwsTransferFamily = void 0;
|
|
4
|
+
const core_1 = require("@terra-graph/core");
|
|
5
|
+
const namespaces_js_1 = require("../namespaces.js");
|
|
6
|
+
const DEFAULT_EVENT_BUS_ADDRESS = 'aws_cloudwatch_event_bus.default';
|
|
7
|
+
const DEFAULT_EVENT_BUS_NODE_ID = (0, core_1.tgNodeIdFrom)('resource', DEFAULT_EVENT_BUS_ADDRESS);
|
|
8
|
+
const ensureDefaultEventBus = (graph) => {
|
|
9
|
+
return graph.setNodeAttributes(DEFAULT_EVENT_BUS_NODE_ID, {
|
|
10
|
+
terraform: {
|
|
11
|
+
kind: 'resource',
|
|
12
|
+
address: DEFAULT_EVENT_BUS_ADDRESS,
|
|
13
|
+
resource: 'aws_cloudwatch_event_bus',
|
|
14
|
+
name: 'default',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
class ConnectTransferConnectorToDefaultEventBus extends core_1.NodeRule {
|
|
19
|
+
constructor() {
|
|
20
|
+
super({
|
|
21
|
+
node: {
|
|
22
|
+
attr: {
|
|
23
|
+
key: 'terraform.resource',
|
|
24
|
+
eq: 'aws_transfer_connector',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
apply(nodeId, _node, graph) {
|
|
30
|
+
if (!this.wasMatched(nodeId)) {
|
|
31
|
+
return graph;
|
|
32
|
+
}
|
|
33
|
+
const updated = ensureDefaultEventBus(graph);
|
|
34
|
+
return updated.setEdge((0, core_1.edgeIdFrom)(nodeId, DEFAULT_EVENT_BUS_NODE_ID, 'transfer:connector-bus'), nodeId, DEFAULT_EVENT_BUS_NODE_ID, {});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
class RewireTransferEventRuleToDefaultEventBus extends core_1.NodeRule {
|
|
38
|
+
constructor() {
|
|
39
|
+
super({
|
|
40
|
+
node: {
|
|
41
|
+
attr: {
|
|
42
|
+
key: 'terraform.resource',
|
|
43
|
+
eq: 'aws_cloudwatch_event_rule',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
apply(nodeId, _node, graph) {
|
|
49
|
+
if (!this.wasMatched(nodeId)) {
|
|
50
|
+
return graph;
|
|
51
|
+
}
|
|
52
|
+
const outEdges = graph.outEdges(nodeId);
|
|
53
|
+
let updated = ensureDefaultEventBus(graph);
|
|
54
|
+
if (outEdges.length === 0) {
|
|
55
|
+
return updated.setEdge((0, core_1.edgeIdFrom)(DEFAULT_EVENT_BUS_NODE_ID, nodeId, 'transfer:rule-bus'), DEFAULT_EVENT_BUS_NODE_ID, nodeId, {});
|
|
56
|
+
}
|
|
57
|
+
let didRewire = false;
|
|
58
|
+
for (const outEdgeId of outEdges) {
|
|
59
|
+
const targetNodeId = graph.edgeTarget(outEdgeId);
|
|
60
|
+
const targetNode = graph.getNodeAttributes(targetNodeId);
|
|
61
|
+
if (targetNode?.terraform?.resource !== 'aws_transfer_connector') {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
updated = updated.removeEdge(outEdgeId);
|
|
65
|
+
didRewire = true;
|
|
66
|
+
}
|
|
67
|
+
if (!didRewire) {
|
|
68
|
+
return updated;
|
|
69
|
+
}
|
|
70
|
+
return updated.setEdge((0, core_1.edgeIdFrom)(DEFAULT_EVENT_BUS_NODE_ID, nodeId, 'transfer:rule-bus'), DEFAULT_EVENT_BUS_NODE_ID, nodeId, {});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
class AwsTransferFamily extends core_1.GraphPlugin {
|
|
74
|
+
static id = (0, namespaces_js_1.pluginId)(`aws.${AwsTransferFamily.name}`);
|
|
75
|
+
constructor() {
|
|
76
|
+
super(AwsTransferFamily.id);
|
|
77
|
+
}
|
|
78
|
+
build(_input) {
|
|
79
|
+
return {
|
|
80
|
+
phases: [
|
|
81
|
+
{
|
|
82
|
+
phase: 'main',
|
|
83
|
+
rules: [
|
|
84
|
+
new core_1.RemoveNode({
|
|
85
|
+
node: {
|
|
86
|
+
attr: {
|
|
87
|
+
key: 'terraform.resource',
|
|
88
|
+
eq: 'aws_transfer_tag',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
}),
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
phase: 'main',
|
|
96
|
+
rules: [
|
|
97
|
+
new ConnectTransferConnectorToDefaultEventBus(),
|
|
98
|
+
new RewireTransferEventRuleToDefaultEventBus(),
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.AwsTransferFamily = AwsTransferFamily;
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@terra-graph/core");
|
|
4
|
+
const AwsTransferFamily_js_1 = require("./AwsTransferFamily.js");
|
|
5
|
+
const buildPhases = () => {
|
|
6
|
+
const plugin = new AwsTransferFamily_js_1.AwsTransferFamily();
|
|
7
|
+
const result = plugin.build({
|
|
8
|
+
options: {},
|
|
9
|
+
namedRules: new core_1.NamedRuleRegistry(),
|
|
10
|
+
namedRuleSets: new core_1.NamedRuleSetRegistry(),
|
|
11
|
+
});
|
|
12
|
+
return (result.phases ?? []).map((phase) => ({
|
|
13
|
+
phase: phase.phase,
|
|
14
|
+
rules: phase.rules.map((rule) => rule.serialize()),
|
|
15
|
+
}));
|
|
16
|
+
};
|
|
17
|
+
const buildMainRules = () => {
|
|
18
|
+
const plugin = new AwsTransferFamily_js_1.AwsTransferFamily();
|
|
19
|
+
const result = plugin.build({
|
|
20
|
+
options: {},
|
|
21
|
+
namedRules: new core_1.NamedRuleRegistry(),
|
|
22
|
+
namedRuleSets: new core_1.NamedRuleSetRegistry(),
|
|
23
|
+
});
|
|
24
|
+
return (result.phases?.[1]?.rules ?? []).map((rule) => rule);
|
|
25
|
+
};
|
|
26
|
+
const getConnectorRule = () => {
|
|
27
|
+
const rule = buildMainRules()[0];
|
|
28
|
+
if (!rule) {
|
|
29
|
+
throw new Error('Missing ConnectTransferConnectorToDefaultEventBus rule');
|
|
30
|
+
}
|
|
31
|
+
return rule;
|
|
32
|
+
};
|
|
33
|
+
const getRewireRule = () => {
|
|
34
|
+
const rule = buildMainRules()[1];
|
|
35
|
+
if (!rule) {
|
|
36
|
+
throw new Error('Missing RewireTransferEventRuleToDefaultEventBus rule');
|
|
37
|
+
}
|
|
38
|
+
return rule;
|
|
39
|
+
};
|
|
40
|
+
const defaultBusId = (0, core_1.tgNodeIdFrom)('resource', 'aws_cloudwatch_event_bus.default');
|
|
41
|
+
const buildAdapter = (graph) => {
|
|
42
|
+
return new core_1.GraphologyAdapter().withTgGraph(graph);
|
|
43
|
+
};
|
|
44
|
+
describe('AwsTransferFamily.build', () => {
|
|
45
|
+
it('shoud remove transfer tags and connect transfer eventing to a default bus', () => {
|
|
46
|
+
const phases = buildPhases();
|
|
47
|
+
expect(phases).toHaveLength(2);
|
|
48
|
+
expect(phases.map((phase) => phase.phase)).toStrictEqual(['main', 'main']);
|
|
49
|
+
expect(phases[0]?.rules[0]).toStrictEqual({
|
|
50
|
+
id: 'RemoveNode',
|
|
51
|
+
config: {
|
|
52
|
+
node: {
|
|
53
|
+
attr: {
|
|
54
|
+
key: 'terraform.resource',
|
|
55
|
+
eq: 'aws_transfer_tag',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
expect(phases[1]?.rules).toHaveLength(2);
|
|
61
|
+
expect(phases[1]?.rules[0]?.id).toBe('ConnectTransferConnectorToDefaultEventBus');
|
|
62
|
+
expect(phases[1]?.rules[1]?.id).toBe('RewireTransferEventRuleToDefaultEventBus');
|
|
63
|
+
});
|
|
64
|
+
it('shoud connect aws_transfer_connector nodes to the implicit default event bus', () => {
|
|
65
|
+
const connectorId = (0, core_1.asNodeId)('resource.aws_transfer_connector.main');
|
|
66
|
+
const adapter = buildAdapter({
|
|
67
|
+
schemaVersion: core_1.TG_SCHEMA_VERSION,
|
|
68
|
+
description: {},
|
|
69
|
+
nodes: {
|
|
70
|
+
[connectorId]: {
|
|
71
|
+
id: connectorId,
|
|
72
|
+
label: 'connector',
|
|
73
|
+
terraform: {
|
|
74
|
+
kind: 'resource',
|
|
75
|
+
address: 'aws_transfer_connector.main',
|
|
76
|
+
resource: 'aws_transfer_connector',
|
|
77
|
+
name: 'main',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
edges: [],
|
|
82
|
+
});
|
|
83
|
+
const connectorRule = getConnectorRule();
|
|
84
|
+
const connectorNode = adapter.getNodeAttributes(connectorId);
|
|
85
|
+
if (!connectorNode) {
|
|
86
|
+
throw new Error('Missing aws_transfer_connector node');
|
|
87
|
+
}
|
|
88
|
+
connectorRule.match(connectorId, connectorNode, adapter);
|
|
89
|
+
const updated = connectorRule.apply(connectorId, connectorNode, adapter);
|
|
90
|
+
const busNode = updated.getNodeAttributes(defaultBusId);
|
|
91
|
+
expect(busNode?.terraform?.resource).toBe('aws_cloudwatch_event_bus');
|
|
92
|
+
expect(updated.edgesBetween(connectorId, defaultBusId)).toHaveLength(1);
|
|
93
|
+
});
|
|
94
|
+
it('shoud rewire event rule edges to the default bus when rule has no outbound edges', () => {
|
|
95
|
+
const ruleId = (0, core_1.asNodeId)('resource.aws_cloudwatch_event_rule.primary');
|
|
96
|
+
const adapter = buildAdapter({
|
|
97
|
+
schemaVersion: core_1.TG_SCHEMA_VERSION,
|
|
98
|
+
description: {},
|
|
99
|
+
nodes: {
|
|
100
|
+
[ruleId]: {
|
|
101
|
+
id: ruleId,
|
|
102
|
+
label: 'event_rule',
|
|
103
|
+
terraform: {
|
|
104
|
+
kind: 'resource',
|
|
105
|
+
address: 'aws_cloudwatch_event_rule.primary',
|
|
106
|
+
resource: 'aws_cloudwatch_event_rule',
|
|
107
|
+
name: 'primary',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
edges: [],
|
|
112
|
+
});
|
|
113
|
+
const rewireRule = getRewireRule();
|
|
114
|
+
const ruleNode = adapter.getNodeAttributes(ruleId);
|
|
115
|
+
if (!ruleNode) {
|
|
116
|
+
throw new Error('Missing aws_cloudwatch_event_rule node');
|
|
117
|
+
}
|
|
118
|
+
rewireRule.match(ruleId, ruleNode, adapter);
|
|
119
|
+
const updated = rewireRule.apply(ruleId, ruleNode, adapter);
|
|
120
|
+
const busNode = updated.getNodeAttributes(defaultBusId);
|
|
121
|
+
expect(busNode?.terraform?.resource).toBe('aws_cloudwatch_event_bus');
|
|
122
|
+
expect(updated.edgesBetween(defaultBusId, ruleId)).toHaveLength(1);
|
|
123
|
+
const outboundToDefaultBus = updated
|
|
124
|
+
.outEdges(ruleId)
|
|
125
|
+
.filter((edgeId) => updated.edgeTarget(edgeId) === defaultBusId);
|
|
126
|
+
expect(outboundToDefaultBus).toHaveLength(0);
|
|
127
|
+
});
|
|
128
|
+
it('shoud replace event rule to connector edges with default bus edges', () => {
|
|
129
|
+
const ruleId = (0, core_1.asNodeId)('resource.aws_cloudwatch_event_rule.forward');
|
|
130
|
+
const connectorId = (0, core_1.asNodeId)('resource.aws_transfer_connector.main');
|
|
131
|
+
const adapter = buildAdapter({
|
|
132
|
+
schemaVersion: core_1.TG_SCHEMA_VERSION,
|
|
133
|
+
description: {},
|
|
134
|
+
nodes: {
|
|
135
|
+
[ruleId]: {
|
|
136
|
+
id: ruleId,
|
|
137
|
+
label: 'event_rule',
|
|
138
|
+
terraform: {
|
|
139
|
+
kind: 'resource',
|
|
140
|
+
address: 'aws_cloudwatch_event_rule.forward',
|
|
141
|
+
resource: 'aws_cloudwatch_event_rule',
|
|
142
|
+
name: 'forward',
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
[connectorId]: {
|
|
146
|
+
id: connectorId,
|
|
147
|
+
label: 'connector',
|
|
148
|
+
terraform: {
|
|
149
|
+
kind: 'resource',
|
|
150
|
+
address: 'aws_transfer_connector.main',
|
|
151
|
+
resource: 'aws_transfer_connector',
|
|
152
|
+
name: 'main',
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
edges: [
|
|
157
|
+
{
|
|
158
|
+
id: (0, core_1.asEdgeId)('edge-rule-connector'),
|
|
159
|
+
from: ruleId,
|
|
160
|
+
to: connectorId,
|
|
161
|
+
attributes: {},
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
});
|
|
165
|
+
const rewireRule = getRewireRule();
|
|
166
|
+
const ruleNode = adapter.getNodeAttributes(ruleId);
|
|
167
|
+
if (!ruleNode) {
|
|
168
|
+
throw new Error('Missing aws_cloudwatch_event_rule node');
|
|
169
|
+
}
|
|
170
|
+
rewireRule.match(ruleId, ruleNode, adapter);
|
|
171
|
+
const updated = rewireRule.apply(ruleId, ruleNode, adapter);
|
|
172
|
+
expect(updated.edgesBetween(ruleId, connectorId)).toHaveLength(0);
|
|
173
|
+
expect(updated.edgesBetween(defaultBusId, ruleId)).toHaveLength(1);
|
|
174
|
+
});
|
|
175
|
+
it('shoud preserve non-connector event rule edges and still create the default bus', () => {
|
|
176
|
+
const ruleId = (0, core_1.asNodeId)('resource.aws_cloudwatch_event_rule.unchanged');
|
|
177
|
+
const targetId = (0, core_1.asNodeId)('resource.aws_lambda_function.handler');
|
|
178
|
+
const adapter = buildAdapter({
|
|
179
|
+
schemaVersion: core_1.TG_SCHEMA_VERSION,
|
|
180
|
+
description: {},
|
|
181
|
+
nodes: {
|
|
182
|
+
[ruleId]: {
|
|
183
|
+
id: ruleId,
|
|
184
|
+
label: 'event_rule',
|
|
185
|
+
terraform: {
|
|
186
|
+
kind: 'resource',
|
|
187
|
+
address: 'aws_cloudwatch_event_rule.unchanged',
|
|
188
|
+
resource: 'aws_cloudwatch_event_rule',
|
|
189
|
+
name: 'unchanged',
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
[targetId]: {
|
|
193
|
+
id: targetId,
|
|
194
|
+
label: 'target',
|
|
195
|
+
terraform: {
|
|
196
|
+
kind: 'resource',
|
|
197
|
+
address: 'aws_lambda_function.handler',
|
|
198
|
+
resource: 'aws_lambda_function',
|
|
199
|
+
name: 'handler',
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
edges: [
|
|
204
|
+
{
|
|
205
|
+
id: (0, core_1.asEdgeId)('edge-rule-target'),
|
|
206
|
+
from: ruleId,
|
|
207
|
+
to: targetId,
|
|
208
|
+
attributes: {},
|
|
209
|
+
},
|
|
210
|
+
],
|
|
211
|
+
});
|
|
212
|
+
const rewireRule = getRewireRule();
|
|
213
|
+
const ruleNode = adapter.getNodeAttributes(ruleId);
|
|
214
|
+
if (!ruleNode) {
|
|
215
|
+
throw new Error('Missing aws_cloudwatch_event_rule node');
|
|
216
|
+
}
|
|
217
|
+
rewireRule.match(ruleId, ruleNode, adapter);
|
|
218
|
+
const updated = rewireRule.apply(ruleId, ruleNode, adapter);
|
|
219
|
+
expect(updated.edgesBetween(ruleId, targetId)).toHaveLength(1);
|
|
220
|
+
expect(updated.edgesBetween(defaultBusId, ruleId)).toHaveLength(0);
|
|
221
|
+
expect(updated.getNodeAttributes(defaultBusId)).toBeDefined();
|
|
222
|
+
});
|
|
223
|
+
it('shoud do nothing when connector rule does not match', () => {
|
|
224
|
+
const eventRuleId = (0, core_1.asNodeId)('resource.aws_cloudwatch_event_rule.primary');
|
|
225
|
+
const adapter = buildAdapter({
|
|
226
|
+
schemaVersion: core_1.TG_SCHEMA_VERSION,
|
|
227
|
+
description: {},
|
|
228
|
+
nodes: {
|
|
229
|
+
[eventRuleId]: {
|
|
230
|
+
id: eventRuleId,
|
|
231
|
+
label: 'event_rule',
|
|
232
|
+
terraform: {
|
|
233
|
+
kind: 'resource',
|
|
234
|
+
address: 'aws_cloudwatch_event_rule.primary',
|
|
235
|
+
resource: 'aws_cloudwatch_event_rule',
|
|
236
|
+
name: 'primary',
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
edges: [],
|
|
241
|
+
});
|
|
242
|
+
const connectorRule = getConnectorRule();
|
|
243
|
+
const eventRuleNode = adapter.getNodeAttributes(eventRuleId);
|
|
244
|
+
if (!eventRuleNode) {
|
|
245
|
+
throw new Error('Missing aws_cloudwatch_event_rule node');
|
|
246
|
+
}
|
|
247
|
+
const updated = connectorRule.apply(eventRuleId, eventRuleNode, adapter);
|
|
248
|
+
expect(updated).toBe(adapter);
|
|
249
|
+
expect(updated.getNodeAttributes(defaultBusId)).toBeUndefined();
|
|
250
|
+
});
|
|
251
|
+
it('shoud do nothing when rewire rule does not match', () => {
|
|
252
|
+
const eventRuleId = (0, core_1.asNodeId)('resource.aws_cloudwatch_event_rule.primary');
|
|
253
|
+
const adapter = buildAdapter({
|
|
254
|
+
schemaVersion: core_1.TG_SCHEMA_VERSION,
|
|
255
|
+
description: {},
|
|
256
|
+
nodes: {
|
|
257
|
+
[eventRuleId]: {
|
|
258
|
+
id: eventRuleId,
|
|
259
|
+
label: 'event_rule',
|
|
260
|
+
terraform: {
|
|
261
|
+
kind: 'resource',
|
|
262
|
+
address: 'aws_cloudwatch_event_rule.primary',
|
|
263
|
+
resource: 'aws_cloudwatch_event_rule',
|
|
264
|
+
name: 'primary',
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
edges: [],
|
|
269
|
+
});
|
|
270
|
+
const rewireRule = getRewireRule();
|
|
271
|
+
const eventRuleNode = adapter.getNodeAttributes(eventRuleId);
|
|
272
|
+
if (!eventRuleNode) {
|
|
273
|
+
throw new Error('Missing aws_cloudwatch_event_rule node');
|
|
274
|
+
}
|
|
275
|
+
const updated = rewireRule.apply(eventRuleId, eventRuleNode, adapter);
|
|
276
|
+
expect(updated).toBe(adapter);
|
|
277
|
+
expect(updated.getNodeAttributes(defaultBusId)).toBeUndefined();
|
|
278
|
+
});
|
|
279
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@terra-graph/core");
|
|
4
|
+
const namespaces_js_1 = require("../namespaces.js");
|
|
5
|
+
exports.default = new core_1.NamedRuleRegistry({
|
|
6
|
+
[(0, namespaces_js_1.ruleName)('dot.sqs.dlq.align')]: new core_1.AlignNodes({
|
|
7
|
+
edge: {
|
|
8
|
+
from: {
|
|
9
|
+
attr: { key: 'terraform.resource', eq: 'aws_sqs_queue' },
|
|
10
|
+
},
|
|
11
|
+
to: {
|
|
12
|
+
attr: { key: 'terraform.resource', eq: 'aws_sqs_queue' },
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
}),
|
|
16
|
+
[(0, namespaces_js_1.ruleName)('dot.schedule.align')]: new core_1.AlignNodes({
|
|
17
|
+
edge: {
|
|
18
|
+
from: {
|
|
19
|
+
attr: { key: 'terraform.resource', eq: 'aws_scheduler_schedule' },
|
|
20
|
+
},
|
|
21
|
+
to: {
|
|
22
|
+
any: true,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
}),
|
|
26
|
+
[(0, namespaces_js_1.ruleName)('dot.iam_role.align')]: new core_1.AlignNodes({
|
|
27
|
+
edge: {
|
|
28
|
+
from: {
|
|
29
|
+
attr: { key: 'terraform.resource', eq: 'aws_iam_role' },
|
|
30
|
+
},
|
|
31
|
+
to: {
|
|
32
|
+
any: true,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
}),
|
|
36
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const namespaces_js_1 = require("../namespaces.js");
|
|
7
|
+
const dot_js_1 = __importDefault(require("./dot.js"));
|
|
8
|
+
const serialize = (name) => {
|
|
9
|
+
return dot_js_1.default.resolve(name).serialize();
|
|
10
|
+
};
|
|
11
|
+
describe('dot rules', () => {
|
|
12
|
+
it('shoud expose all dot named rules', () => {
|
|
13
|
+
expect(dot_js_1.default.names().sort()).toStrictEqual([
|
|
14
|
+
(0, namespaces_js_1.ruleName)('dot.sqs.dlq.align'),
|
|
15
|
+
(0, namespaces_js_1.ruleName)('dot.schedule.align'),
|
|
16
|
+
(0, namespaces_js_1.ruleName)('dot.iam_role.align'),
|
|
17
|
+
].sort());
|
|
18
|
+
});
|
|
19
|
+
it('shoud align SQS DLQ edges and AWS scheduling/identity edges', () => {
|
|
20
|
+
expect(serialize((0, namespaces_js_1.ruleName)('dot.sqs.dlq.align'))).toStrictEqual({
|
|
21
|
+
id: 'AlignNodes',
|
|
22
|
+
config: {
|
|
23
|
+
edge: {
|
|
24
|
+
from: {
|
|
25
|
+
attr: {
|
|
26
|
+
key: 'terraform.resource',
|
|
27
|
+
eq: 'aws_sqs_queue',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
to: {
|
|
31
|
+
attr: {
|
|
32
|
+
key: 'terraform.resource',
|
|
33
|
+
eq: 'aws_sqs_queue',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
expect(serialize((0, namespaces_js_1.ruleName)('dot.schedule.align')).id).toBe('AlignNodes');
|
|
40
|
+
expect(serialize((0, namespaces_js_1.ruleName)('dot.iam_role.align')).id).toBe('AlignNodes');
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@terra-graph/core");
|
|
4
|
+
const namespaces_js_1 = require("../namespaces.js");
|
|
5
|
+
exports.default = new core_1.NamedRuleRegistry({
|
|
6
|
+
[(0, namespaces_js_1.ruleName)('data.remove')]: new core_1.RemoveNode({
|
|
7
|
+
node: {
|
|
8
|
+
or: [
|
|
9
|
+
{
|
|
10
|
+
and: [
|
|
11
|
+
{ attr: { key: 'terraform.kind', eq: 'data' } },
|
|
12
|
+
{
|
|
13
|
+
not: {
|
|
14
|
+
attr: {
|
|
15
|
+
key: 'terraform.resource',
|
|
16
|
+
in: ['aws_iam_policy_document', 'aws_iam_policy'],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
}),
|
|
25
|
+
[(0, namespaces_js_1.ruleName)('log_groups.only_event_bridge')]: new core_1.RemoveNode({
|
|
26
|
+
node: {
|
|
27
|
+
and: [
|
|
28
|
+
{
|
|
29
|
+
attr: {
|
|
30
|
+
key: 'terraform.resource',
|
|
31
|
+
eq: 'aws_cloudwatch_log_group',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
not: {
|
|
36
|
+
edge: {
|
|
37
|
+
in: {
|
|
38
|
+
attr: {
|
|
39
|
+
key: 'terraform.resource',
|
|
40
|
+
eq: 'aws_cloudwatch_event_target',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
}),
|
|
49
|
+
// TODO: this should probably be part of the convention too?
|
|
50
|
+
[(0, namespaces_js_1.ruleName)('lambda.only_event_source_mapping')]: new core_1.RemoveNode({
|
|
51
|
+
node: {
|
|
52
|
+
and: [
|
|
53
|
+
{ attr: { key: 'terraform.resource', startsWith: 'aws_lambda' } },
|
|
54
|
+
{
|
|
55
|
+
not: {
|
|
56
|
+
attr: {
|
|
57
|
+
key: 'terraform.resource',
|
|
58
|
+
in: [
|
|
59
|
+
'aws_lambda_function',
|
|
60
|
+
'aws_lambda_event_source_mapping',
|
|
61
|
+
'aws_lambda_permission',
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const namespaces_js_1 = require("../namespaces.js");
|
|
7
|
+
const general_js_1 = __importDefault(require("./general.js"));
|
|
8
|
+
const serialize = (name) => {
|
|
9
|
+
return general_js_1.default.resolve(name).serialize();
|
|
10
|
+
};
|
|
11
|
+
describe('general rules', () => {
|
|
12
|
+
it('shoud expose all general named rules', () => {
|
|
13
|
+
expect(general_js_1.default.names().sort()).toStrictEqual([
|
|
14
|
+
(0, namespaces_js_1.ruleName)('data.remove'),
|
|
15
|
+
(0, namespaces_js_1.ruleName)('lambda.only_event_source_mapping'),
|
|
16
|
+
(0, namespaces_js_1.ruleName)('log_groups.only_event_bridge'),
|
|
17
|
+
].sort());
|
|
18
|
+
});
|
|
19
|
+
it('shoud remove data nodes except policy artifacts by default', () => {
|
|
20
|
+
expect(serialize((0, namespaces_js_1.ruleName)('data.remove'))).toStrictEqual({
|
|
21
|
+
id: 'RemoveNode',
|
|
22
|
+
config: {
|
|
23
|
+
node: {
|
|
24
|
+
or: [
|
|
25
|
+
{
|
|
26
|
+
and: [
|
|
27
|
+
{ attr: { key: 'terraform.kind', eq: 'data' } },
|
|
28
|
+
{
|
|
29
|
+
not: {
|
|
30
|
+
attr: {
|
|
31
|
+
key: 'terraform.resource',
|
|
32
|
+
in: ['aws_iam_policy_document', 'aws_iam_policy'],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
it('shoud remove non-event-bridge log groups and non-core lambda resources by query', () => {
|
|
44
|
+
expect(serialize((0, namespaces_js_1.ruleName)('log_groups.only_event_bridge')).id).toBe('RemoveNode');
|
|
45
|
+
expect(serialize((0, namespaces_js_1.ruleName)('lambda.only_event_source_mapping')).id).toBe('RemoveNode');
|
|
46
|
+
});
|
|
47
|
+
});
|