forked from TerraStackIO/terrastack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstack.ts
97 lines (81 loc) · 2.72 KB
/
stack.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { Construct, ISynthesisSession, Node } from 'constructs';
import * as fs from 'fs';
import * as path from 'path';
import { ResourceObject, TerraformSchemaType } from './resource-object';
import { resolve } from './_tokens';
import { removeEmpty } from './_util';
import { Names } from './names';
import {
snakeCase,
} from "./_util";
export class Stack extends Construct {
/**
* Finds the stack in which a node is defined.
* @param c a construct node
*/
public static of(c: Construct): Stack {
if (c instanceof Stack) {
return c;
}
const parent = Node.of(c).scope as Construct;
if (!parent) {
throw new Error(`cannot find a parent chart (directly or indirectly)`);
}
return Stack.of(parent);
}
/**
* The name of the stack's YAML file as emitted into the cloud assembly
* directory during synthesis.
*/
public readonly manifestFile: string;
constructor(scope: Construct, ns: string) {
super(scope, ns);
this.manifestFile = `${Node.of(this).uniqueId}.tf.json`;
}
/**
* Generates a app-unique name for an object given it's construct node path.
*
* @param resourceObject The API object to generate a name for.
*/
public generateObjectName(resourceObject: ResourceObject) {
return Names.toDnsLabel(Node.of(resourceObject).path);
}
protected onSynthesize(session: ISynthesisSession) {
const doc: {[k: string]: {[k: string]: any}} = {};
for (const resource of Node.of(this).findAll()) {
if (!(resource instanceof ResourceObject)) {
continue;
}
const resourceName = snakeCase(resource.terraform.name)
const type = snakeCase(resource.terraform.schemaType)
if (!doc[type]) {
const obj: {[k: string]: any} = {};
doc[type] = obj
}
switch(type) {
case TerraformSchemaType.PROVIDER:
case TerraformSchemaType.TERRAFORM:
case TerraformSchemaType.OUTPUT:
case TerraformSchemaType.VARIABLE:
case TerraformSchemaType.MODULE:
case TerraformSchemaType.LOCALS: {
const manifest = removeEmpty(resolve(this, resource._render()));
const merged = {...doc[type], ...manifest}
doc[type] = merged
break;
}
default: {
if (!doc[type][resourceName]) {
const obj: {[k: string]: any} = {};
doc[type][resourceName] = obj
}
const manifest = removeEmpty(resolve(this, resource._render()));
const merged = {...doc[type][resourceName], ...manifest}
doc[type][resourceName] = merged
break;
}
}
}
fs.writeFileSync(path.join(session.outdir, this.manifestFile), JSON.stringify(doc, null, 2));
}
}