@gershy/lilac 0.0.14 → 0.0.16
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/cmp/cjs/main.d.ts +6 -2
- package/cmp/cjs/main.js +82 -34
- package/cmp/cjs/petal/terraform/terraform.d.ts +1 -0
- package/cmp/cjs/petal/terraform/terraform.js +28 -20
- package/cmp/cjs/soil/soil.d.ts +14 -5
- package/cmp/cjs/soil/soil.js +56 -29
- package/cmp/cjs/util/aws.d.ts +3 -14
- package/cmp/cjs/util/aws.js +6 -6
- package/cmp/cjs/util/normalize.d.ts +1 -0
- package/cmp/cjs/util/normalize.js +8 -7
- package/cmp/cjs/util/procTerraform.d.ts +3 -1
- package/cmp/cjs/util/procTerraform.js +8 -3
- package/cmp/cjs/util/slashEscape.js +1 -1
- package/cmp/cjs/util/terraform.js +1 -1
- package/cmp/mjs/main.d.ts +6 -2
- package/cmp/mjs/main.js +81 -33
- package/cmp/mjs/petal/terraform/terraform.d.ts +1 -0
- package/cmp/mjs/petal/terraform/terraform.js +17 -9
- package/cmp/mjs/soil/soil.d.ts +14 -5
- package/cmp/mjs/soil/soil.js +52 -25
- package/cmp/mjs/util/aws.d.ts +3 -14
- package/cmp/mjs/util/aws.js +6 -6
- package/cmp/mjs/util/normalize.d.ts +1 -0
- package/cmp/mjs/util/normalize.js +3 -2
- package/cmp/mjs/util/procTerraform.d.ts +3 -1
- package/cmp/mjs/util/procTerraform.js +8 -3
- package/cmp/mjs/util/slashEscape.js +1 -1
- package/cmp/mjs/util/terraform.js +1 -1
- package/package.json +11 -10
- package/readme.md +11 -6
package/cmp/cjs/util/aws.js
CHANGED
|
@@ -4,13 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.regions = exports.capitalKeys = void 0;
|
|
7
|
-
|
|
7
|
+
require("@gershy/clearing");
|
|
8
8
|
const util_phrasing_1 = __importDefault(require("@gershy/util-phrasing"));
|
|
9
9
|
const capitalKeys = (v) => {
|
|
10
|
-
if (
|
|
11
|
-
return v[map](v => (0, exports.capitalKeys)(v));
|
|
12
|
-
if (
|
|
13
|
-
return v[mapk]((val, key) => [(0, util_phrasing_1.default)(
|
|
10
|
+
if (cl.isCls(v, Array))
|
|
11
|
+
return v[cl.map](v => (0, exports.capitalKeys)(v));
|
|
12
|
+
if (cl.isCls(v, Object))
|
|
13
|
+
return v[cl.mapk]((val, key) => [(0, util_phrasing_1.default)('camel->kamel', key), (0, exports.capitalKeys)(val)]);
|
|
14
14
|
return v;
|
|
15
15
|
};
|
|
16
16
|
exports.capitalKeys = capitalKeys;
|
|
@@ -54,7 +54,7 @@ exports.regions = [
|
|
|
54
54
|
// Ignoring these for now...
|
|
55
55
|
// 'us-gov-east-1',
|
|
56
56
|
// 'us-gov-west-1',
|
|
57
|
-
][map](region => {
|
|
57
|
+
][cl.map](region => {
|
|
58
58
|
const [c, z, num] = region.split('-');
|
|
59
59
|
const [dir0, dir1 = dir0] = z.match(/central|north|south|east|west/g);
|
|
60
60
|
return {
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
3
|
+
require("@gershy/clearing");
|
|
4
|
+
const { isCls, getClsName } = clearing;
|
|
4
5
|
const normalize = (val, seen = new Set()) => {
|
|
5
6
|
// Derives a json-stringifiable value from *any* value
|
|
6
7
|
// E.g. to hash *anything*: hash(JSON.stringify(normalized(anything)));
|
|
7
8
|
// Handles terminations
|
|
8
|
-
if (
|
|
9
|
+
if (isCls(val, String))
|
|
9
10
|
return val;
|
|
10
|
-
if (
|
|
11
|
+
if (isCls(val, Number))
|
|
11
12
|
return val;
|
|
12
13
|
if (val === null)
|
|
13
14
|
return null;
|
|
@@ -16,10 +17,10 @@ const normalize = (val, seen = new Set()) => {
|
|
|
16
17
|
if (seen.has(val))
|
|
17
18
|
return '<<!circ!>>';
|
|
18
19
|
seen.add(val);
|
|
19
|
-
if (
|
|
20
|
-
return val[map](v => normalize(v, seen));
|
|
21
|
-
if (
|
|
20
|
+
if (isCls(val, Array))
|
|
21
|
+
return val[cl.map](v => normalize(v, seen));
|
|
22
|
+
if (isCls(val, Object))
|
|
22
23
|
return normalize(Object.entries(val).sort((e0, e1) => e0[0] < e1[0] ? -1 : 1), seen);
|
|
23
|
-
return normalize({ $form:
|
|
24
|
+
return normalize({ $form: getClsName(val), ...val }, seen);
|
|
24
25
|
};
|
|
25
26
|
exports.default = normalize;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Fact } from '@gershy/disk';
|
|
2
2
|
import { ProcOpts } from '@gershy/nodejs-proc';
|
|
3
|
-
export type ProcTerraformArgs = ProcOpts & {
|
|
3
|
+
export type ProcTerraformArgs = ProcOpts & {
|
|
4
|
+
config?: string;
|
|
5
|
+
};
|
|
4
6
|
declare const _default: (fact: Fact, cmd: string, opts?: ProcTerraformArgs) => Promise<{
|
|
5
7
|
logDb: Fact;
|
|
6
8
|
output: string;
|
|
@@ -17,14 +17,19 @@ exports.default = (fact, cmd, opts = {}) => {
|
|
|
17
17
|
timeoutMs: 0,
|
|
18
18
|
...opts,
|
|
19
19
|
cwd: fact,
|
|
20
|
-
env: {
|
|
20
|
+
env: {
|
|
21
|
+
...process.env,
|
|
22
|
+
TF_DATA_DIR: '',
|
|
23
|
+
TF_CLI_CONFIG_FILE: '',
|
|
24
|
+
...opts.env
|
|
25
|
+
}
|
|
21
26
|
});
|
|
22
27
|
return Object.assign(prm.then(async (result) => {
|
|
23
28
|
const logDb = await writeLog(result.output);
|
|
24
29
|
return { logDb, output: result.output.split('\n').slice(-numTailingTfLogLines).join('\n') };
|
|
25
30
|
}, async (err) => {
|
|
26
|
-
const logDb = await writeLog(err.output ?? err[limn]());
|
|
27
|
-
throw Error(`terraform failed (${err.message})`)[mod]({
|
|
31
|
+
const logDb = await writeLog(err.output ?? err[cl.limn]());
|
|
32
|
+
throw Error(`terraform failed (${err.message})`)[cl.mod]({
|
|
28
33
|
logDb,
|
|
29
34
|
...(err.output ? { output: err.output.split('\n').slice(-numTailingTfLogLines).join('\n') } : { cause: err })
|
|
30
35
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = (str, escapeChars) => {
|
|
4
|
-
if (!escapeChars[has]('\\'))
|
|
4
|
+
if (!escapeChars[cl.has]('\\'))
|
|
5
5
|
escapeChars += '\\';
|
|
6
6
|
// The regex to construct must have "\" and "]" escaped:
|
|
7
7
|
const escChars = escapeChars.replace(/([\\\]])/g, '\\$1');
|
package/cmp/mjs/main.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import '../sideEffects.js';
|
|
2
2
|
import { PetalTerraform } from './petal/terraform/terraform.ts';
|
|
3
3
|
import type Logger from '@gershy/logger';
|
|
4
|
-
import type
|
|
4
|
+
import { type Fact } from '@gershy/disk';
|
|
5
|
+
import '@gershy/clearing';
|
|
5
6
|
import { Soil } from './soil/soil.ts';
|
|
6
7
|
import { SuperIterable } from './util/superIterable.ts';
|
|
7
8
|
export type Context = {
|
|
@@ -9,6 +10,7 @@ export type Context = {
|
|
|
9
10
|
logger: Logger;
|
|
10
11
|
fact: Fact;
|
|
11
12
|
patioFact: Fact;
|
|
13
|
+
shedFact: Fact;
|
|
12
14
|
maturity: string;
|
|
13
15
|
debug: boolean;
|
|
14
16
|
pfx: string;
|
|
@@ -18,6 +20,7 @@ export declare class Flower {
|
|
|
18
20
|
constructor();
|
|
19
21
|
getDependencies(): Generator<Flower>;
|
|
20
22
|
getPetals(ctx: Context): SuperIterable<PetalTerraform.Base>;
|
|
23
|
+
cultivate(): Promise<void>;
|
|
21
24
|
}
|
|
22
25
|
type RegistryFlowers<R extends Registry<any>, M extends 'real' | 'test'> = R extends Registry<infer Flowers> ? {
|
|
23
26
|
[K in keyof Flowers]: Flowers[K][M];
|
|
@@ -39,13 +42,14 @@ export declare class Garden<Reg extends Registry<any>> {
|
|
|
39
42
|
private ctx;
|
|
40
43
|
private reg;
|
|
41
44
|
private def;
|
|
45
|
+
private tfProcArgs;
|
|
42
46
|
constructor(args: {
|
|
43
47
|
context: Context;
|
|
44
48
|
registry: Reg;
|
|
45
49
|
define: Garden<Reg>['def'];
|
|
46
50
|
});
|
|
47
51
|
private getPetals;
|
|
48
|
-
genTerraform(
|
|
52
|
+
genTerraform(soil: Soil.Base): Promise<Obj<Fact>>;
|
|
49
53
|
private terraformInit;
|
|
50
54
|
private terraformPlan;
|
|
51
55
|
private terraformApply;
|
package/cmp/mjs/main.js
CHANGED
|
@@ -2,15 +2,24 @@
|
|
|
2
2
|
// A more generic (beyond just tf) provider is very hard to support due to the multiplicity of
|
|
3
3
|
// provider/petal combos - e.g. "api" flower would need to support ,api.getCloudformationPetals,
|
|
4
4
|
// api.getTerraformPetals, etc... supporting just terraform for now
|
|
5
|
-
// Watch out when working lilac into an npm dependency, need to allow the user a way to declare
|
|
6
|
-
// their absolute repo path (so "<repo>/..." filenames work in any setup!)
|
|
7
|
-
// Can region be dealt with any better??
|
|
8
5
|
// Support test-mode (Flowers need to be able to do setup, share config, write to volumes, etc)
|
|
9
6
|
import { PetalTerraform } from "./petal/terraform/terraform.js";
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
7
|
+
import { tempFact } from '@gershy/disk';
|
|
8
|
+
import '@gershy/clearing';
|
|
12
9
|
import tryWithHealing from '@gershy/util-try-with-healing';
|
|
13
10
|
import phrasing from '@gershy/util-phrasing';
|
|
11
|
+
import proc from '@gershy/nodejs-proc';
|
|
12
|
+
const { isCls, skip } = cl;
|
|
13
|
+
const toArr = cl.toArr;
|
|
14
|
+
const allObj = cl.allObj;
|
|
15
|
+
const allArr = cl.allArr;
|
|
16
|
+
const has = cl.has;
|
|
17
|
+
const map = cl.map;
|
|
18
|
+
const mod = cl.mod;
|
|
19
|
+
const walk = cl.walk;
|
|
20
|
+
const merge = cl.merge;
|
|
21
|
+
const upper = cl.upper;
|
|
22
|
+
const baseline = cl.baseline;
|
|
14
23
|
export class Flower {
|
|
15
24
|
// TODO: The downside of having this static is that different instances may use different
|
|
16
25
|
// services - e.g. api gateway instance may have "useEdge: true", in which case we'd like to
|
|
@@ -27,6 +36,11 @@ export class Flower {
|
|
|
27
36
|
getPetals(ctx) {
|
|
28
37
|
throw Error('not implemented');
|
|
29
38
|
}
|
|
39
|
+
async cultivate() {
|
|
40
|
+
// This function is called once all Flowers for a given Garden have been constructed. The main
|
|
41
|
+
// purpose of this phase is to allow Flowers which reference each other via functions to run
|
|
42
|
+
// such functions without running into uninitialized values.
|
|
43
|
+
}
|
|
30
44
|
}
|
|
31
45
|
;
|
|
32
46
|
export class Registry {
|
|
@@ -40,7 +54,7 @@ export class Registry {
|
|
|
40
54
|
}
|
|
41
55
|
getAwsServices() {
|
|
42
56
|
const services = new Set();
|
|
43
|
-
for (const [k, { real }] of this.flowers)
|
|
57
|
+
for (const [k, { real }] of this.flowers[walk]())
|
|
44
58
|
for (const awsService of real.getAwsServices())
|
|
45
59
|
services.add(awsService);
|
|
46
60
|
return services[toArr](v => v);
|
|
@@ -58,11 +72,21 @@ export class Garden {
|
|
|
58
72
|
ctx;
|
|
59
73
|
reg;
|
|
60
74
|
def;
|
|
75
|
+
tfProcArgs;
|
|
61
76
|
constructor(args) {
|
|
62
77
|
const { define, registry, context } = args;
|
|
63
78
|
this.ctx = context;
|
|
64
79
|
this.reg = registry;
|
|
65
80
|
this.def = define;
|
|
81
|
+
this.tfProcArgs = {
|
|
82
|
+
timeoutMs: 0,
|
|
83
|
+
env: {
|
|
84
|
+
...process.env,
|
|
85
|
+
TF_LOG: 'DEBUG',
|
|
86
|
+
TF_DATA_DIR: '',
|
|
87
|
+
TF_CLI_CONFIG_FILE: ''
|
|
88
|
+
}
|
|
89
|
+
};
|
|
66
90
|
}
|
|
67
91
|
async *getPetals() {
|
|
68
92
|
// TODO: We always use the "real" flowers from the registry - this is part of the shift to
|
|
@@ -72,21 +96,22 @@ export class Garden {
|
|
|
72
96
|
// conditionally calling `this.registry.get('fake')`...
|
|
73
97
|
const seenFlowers = new Set();
|
|
74
98
|
const seenPetals = new Set();
|
|
75
|
-
for await (const topLevelFlower of await this.def(this.ctx, this.reg.get('real')))
|
|
76
|
-
for (const flower of topLevelFlower.getDependencies())
|
|
77
|
-
if (seenFlowers.has(flower))
|
|
78
|
-
continue;
|
|
99
|
+
for await (const topLevelFlower of await this.def(this.ctx, this.reg.get('real')))
|
|
100
|
+
for (const flower of topLevelFlower.getDependencies())
|
|
79
101
|
seenFlowers.add(flower);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
102
|
+
// Now we've exhaustively referenced all Flowers - we can cultivate them
|
|
103
|
+
await Promise.all(seenFlowers[toArr](f => f.cultivate()));
|
|
104
|
+
for (const flower of seenFlowers) {
|
|
105
|
+
for await (const petal of await flower.getPetals(this.ctx)) {
|
|
106
|
+
if (seenPetals.has(petal))
|
|
107
|
+
continue;
|
|
108
|
+
seenPetals.add(petal);
|
|
109
|
+
yield petal;
|
|
85
110
|
}
|
|
86
111
|
}
|
|
87
112
|
}
|
|
88
|
-
async genTerraform(
|
|
89
|
-
const soilTfPetalsPrm =
|
|
113
|
+
async genTerraform(soil) {
|
|
114
|
+
const soilTfPetalsPrm = soil.getTerraformPetals(this.ctx);
|
|
90
115
|
return this.ctx.logger.scope('garden.genTerraform', {}, async (logger) => {
|
|
91
116
|
const setupTfProj = async (args) => args.logger.scope('tf', { proj: this.ctx.name, tf: args.term }, async (logger) => {
|
|
92
117
|
// Allows a terraform project to be defined in terms of a function which writes to main.tf,
|
|
@@ -108,8 +133,7 @@ export class Garden {
|
|
|
108
133
|
const stream = await args.fact.kid(['main.tf']).getDataHeadStream();
|
|
109
134
|
await args.setup(args.fact, stream, async (petal) => {
|
|
110
135
|
// Include a utility function the caller can use to easily write petals
|
|
111
|
-
const { tf, files = {} } = await petal.getResult()
|
|
112
|
-
.then(tf => isCls(tf, String) ? { tf } : tf);
|
|
136
|
+
const { tf, files = {} } = await petal.getResult().then(tf => isCls(tf, String) ? { tf } : tf);
|
|
113
137
|
if (tf)
|
|
114
138
|
await stream.write(`${tf}\n`);
|
|
115
139
|
await Promise.all(files[toArr]((data, kfp) => args.fact.kid(kfp.split('/')).setData(data)));
|
|
@@ -154,7 +178,7 @@ export class Garden {
|
|
|
154
178
|
// Create ddb tf state locking table
|
|
155
179
|
await writePetalTfAndFiles(new PetalTerraform.Resource('awsDynamodbTable', 'tfState', {
|
|
156
180
|
name: ddbName,
|
|
157
|
-
billingMode: phrasing('
|
|
181
|
+
billingMode: phrasing('camel->snake', 'payPerRequest')[upper](),
|
|
158
182
|
hashKey: 'LockID',
|
|
159
183
|
$attribute: { name: 'LockID', type: 'S' }
|
|
160
184
|
}));
|
|
@@ -181,31 +205,55 @@ export class Garden {
|
|
|
181
205
|
});
|
|
182
206
|
});
|
|
183
207
|
}
|
|
184
|
-
|
|
208
|
+
// TODO: Write terraform output to logs??
|
|
209
|
+
async terraformInit(fact) {
|
|
210
|
+
// Consider if we ever want to pass "-reconfigure" and "-migrate-state" options; these are
|
|
211
|
+
// useful if we are moving backends (e.g. one aws account to another), and want to move our
|
|
212
|
+
// full iac definition too
|
|
213
|
+
// Ensure the mirror directory exists in the shed
|
|
214
|
+
const mirrorFact = this.ctx.shedFact.kid(['lilacTerraformMirror']);
|
|
215
|
+
await mirrorFact.kid(['note.txt']).setData(`Root of terraform mirror for @gershy/lilac`);
|
|
185
216
|
return this.ctx.logger.scope('execTf.init', { fact: fact.fsp() }, async (logger) => {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
217
|
+
const { output: result } = await tryWithHealing({
|
|
218
|
+
fn: () => logger.scope('attempt', {}, async (logger) => {
|
|
219
|
+
const configFact = tempFact.kid([`${Math.random().toString(36).slice(2)}.terraform.rc`]);
|
|
220
|
+
await configFact.setData(String[baseline](`
|
|
221
|
+
| provider_installation {
|
|
222
|
+
| filesystem_mirror {
|
|
223
|
+
| path = "${mirrorFact.fsp().replaceAll('\\', '/')}"
|
|
224
|
+
| }
|
|
225
|
+
| }
|
|
226
|
+
`));
|
|
227
|
+
return proc(`terraform init -input=false`, {}[merge](this.tfProcArgs)[merge]({
|
|
228
|
+
cwd: fact,
|
|
229
|
+
env: { TF_CLI_CONFIG_FILE: configFact.fsp() }
|
|
230
|
+
})).finally(() => configFact.rem());
|
|
231
|
+
}),
|
|
232
|
+
canHeal: err => (err?.output ?? '')[has]('Could not retrieve the list of available versions for provider'),
|
|
233
|
+
heal: () => logger.scope('mirror', { fsp: mirrorFact.fsp() }, async (logger) => {
|
|
234
|
+
const { output: result } = await proc(`terraform providers mirror "${mirrorFact.fsp().replaceAll('\\', '/')}"`, { cwd: fact, timeoutMs: 0 });
|
|
235
|
+
logger.log({ $$: 'result', result });
|
|
236
|
+
})
|
|
193
237
|
});
|
|
194
|
-
logger.log({ $$: 'result',
|
|
238
|
+
logger.log({ $$: 'result', result });
|
|
195
239
|
return result;
|
|
196
240
|
});
|
|
197
241
|
}
|
|
198
242
|
terraformPlan(fact, args) {
|
|
199
243
|
return this.ctx.logger.scope('execTf.plan', { fact: fact.fsp() }, async (logger) => {
|
|
200
|
-
const result = await
|
|
201
|
-
|
|
244
|
+
const { output: result } = await proc(`terraform plan -input=false`, {}[merge](this.tfProcArgs)[merge]({
|
|
245
|
+
cwd: fact,
|
|
246
|
+
}));
|
|
247
|
+
logger.log({ $$: 'result', result });
|
|
202
248
|
return result;
|
|
203
249
|
});
|
|
204
250
|
}
|
|
205
251
|
terraformApply(fact, args) {
|
|
206
252
|
return this.ctx.logger.scope('execTf.apply', { fact: fact.fsp() }, async (logger) => {
|
|
207
|
-
const result = await
|
|
208
|
-
|
|
253
|
+
const { output: result } = await proc(`terraform apply -input=false -auto-approve`, {}[merge](this.tfProcArgs)[merge]({
|
|
254
|
+
cwd: fact
|
|
255
|
+
}));
|
|
256
|
+
logger.log({ $$: 'result', result });
|
|
209
257
|
return result;
|
|
210
258
|
});
|
|
211
259
|
}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import '@gershy/clearing';
|
|
2
2
|
import slashEscape from "../../util/slashEscape.js";
|
|
3
3
|
import Petal from "../petal.js";
|
|
4
4
|
import ph from '@gershy/util-phrasing';
|
|
5
|
+
const { getClsName, isCls } = cl;
|
|
6
|
+
const hasHead = cl.hasHead;
|
|
7
|
+
const map = cl.map;
|
|
8
|
+
const hasTail = cl.hasTail;
|
|
9
|
+
const indent = cl.indent;
|
|
10
|
+
const mod = cl.mod;
|
|
11
|
+
const toArr = cl.toArr;
|
|
12
|
+
const has = cl.has;
|
|
5
13
|
export var PetalTerraform;
|
|
6
14
|
(function (PetalTerraform) {
|
|
7
15
|
class Base extends Petal {
|
|
@@ -49,13 +57,13 @@ export var PetalTerraform;
|
|
|
49
57
|
throw Error('tf key of this form must correspond to object value')[mod]({ k, v });
|
|
50
58
|
// Resolve to raw string?
|
|
51
59
|
if (special && isCls(v, String))
|
|
52
|
-
return [ph(
|
|
60
|
+
return [ph('camel->snake', pcs[0]), ' = ', this.terraformEncode(v[hasHead]('| ') ? v : `| ${v}`)];
|
|
53
61
|
// Resolve to nested block?
|
|
54
62
|
if (special && isCls(v, Object))
|
|
55
|
-
return [[ph(
|
|
63
|
+
return [[ph('camel->snake', pcs[0]), ...pcs.slice(1)[map](pc => ph('camel->snake', pc))].join(' '), ' ', this.terraformEncode(v)];
|
|
56
64
|
// Resolve anything else to typical property - use the key exactly as provided (to support,
|
|
57
65
|
// e.g., aws format for keys in policies, any other specific format, etc.)
|
|
58
|
-
return [ph(
|
|
66
|
+
return [ph('camel->snake', pcs[0]), ' = ', this.terraformEncode(v)];
|
|
59
67
|
});
|
|
60
68
|
const len = entryItems.length;
|
|
61
69
|
if (len === 0)
|
|
@@ -76,9 +84,9 @@ export var PetalTerraform;
|
|
|
76
84
|
refStr(props = []) {
|
|
77
85
|
if (!isCls(props, Array))
|
|
78
86
|
props = [props];
|
|
79
|
-
const base = `${ph(
|
|
87
|
+
const base = `${ph('camel->snake', this.getType())}.${ph('camel->snake', this.getHandle())}`;
|
|
80
88
|
return props.length
|
|
81
|
-
? `${base}.${props[map](v => ph(
|
|
89
|
+
? `${base}.${props[map](v => ph('camel->snake', v)).join('.')}`
|
|
82
90
|
: base;
|
|
83
91
|
}
|
|
84
92
|
ref(props = []) {
|
|
@@ -124,7 +132,7 @@ export var PetalTerraform;
|
|
|
124
132
|
getHandle() { return this.handle; }
|
|
125
133
|
getProps() { return this.props; }
|
|
126
134
|
async getResultHeader() {
|
|
127
|
-
return `resource "${ph(
|
|
135
|
+
return `resource "${ph('camel->snake', this.type)}" "${ph('camel->snake', this.handle)}"`;
|
|
128
136
|
}
|
|
129
137
|
}
|
|
130
138
|
PetalTerraform.Resource = Resource;
|
|
@@ -139,7 +147,7 @@ export var PetalTerraform;
|
|
|
139
147
|
}
|
|
140
148
|
getProps() { return this.props; }
|
|
141
149
|
async getResultHeader() {
|
|
142
|
-
return `provider "${ph(
|
|
150
|
+
return `provider "${ph('camel->snake', this.name)}"`;
|
|
143
151
|
}
|
|
144
152
|
}
|
|
145
153
|
PetalTerraform.Provider = Provider;
|
|
@@ -158,7 +166,7 @@ export var PetalTerraform;
|
|
|
158
166
|
getHandle() { return this.handle; }
|
|
159
167
|
getProps() { return this.props; }
|
|
160
168
|
async getResultHeader() {
|
|
161
|
-
return `data "${ph(
|
|
169
|
+
return `data "${ph('camel->snake', this.type)}" "${ph('camel->snake', this.handle)}"`;
|
|
162
170
|
}
|
|
163
171
|
refStr(props = []) {
|
|
164
172
|
return `data.${super.refStr(props)}`;
|
package/cmp/mjs/soil/soil.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Context, PetalTerraform, Registry } from '../main.ts';
|
|
2
2
|
import { RegionTerm } from '../util/aws.ts';
|
|
3
|
+
import '@gershy/clearing';
|
|
3
4
|
import { NetProc } from '@gershy/util-http';
|
|
4
5
|
import { SuperIterable } from '../util/superIterable.ts';
|
|
5
6
|
import type Logger from '@gershy/logger';
|
|
7
|
+
import { RestApi } from '@aws-sdk/client-api-gateway';
|
|
6
8
|
export declare namespace Soil {
|
|
7
9
|
type PetalProjArgs = {
|
|
8
10
|
s3Name: string;
|
|
@@ -13,11 +15,14 @@ export declare namespace Soil {
|
|
|
13
15
|
};
|
|
14
16
|
type LocalStackAwsService = never | 'acm' | 'apigateway' | 'cloudformation' | 'cloudwatch' | 'config' | 'dynamodb' | 'dynamodbstreams' | 'ec2' | 'es' | 'events' | 'firehose' | 'iam' | 'kinesis' | 'kms' | 'lambda' | 'logs' | 'opensearch' | 'redshift' | 'resource' | 'resourcegroupstaggingapi' | 'route53' | 'route53resolver' | 's3' | 's3control' | 'scheduler' | 'secretsmanager' | 'ses' | 'sns' | 'sqs' | 'ssm' | 'stepfunctions' | 'sts' | 'support' | 'swf' | 'transcribe';
|
|
15
17
|
type BaseArgs = {
|
|
18
|
+
logger: Logger;
|
|
16
19
|
registry: Registry<any>;
|
|
17
20
|
};
|
|
18
21
|
class Base {
|
|
22
|
+
protected logger: Logger;
|
|
19
23
|
protected registry: Registry<any>;
|
|
20
24
|
constructor(args: BaseArgs);
|
|
25
|
+
getRegion(): string;
|
|
21
26
|
getTerraformPetals(ctx: Context): Promise<PetalProjResult>;
|
|
22
27
|
}
|
|
23
28
|
type LocalStackArgs = BaseArgs & {
|
|
@@ -34,19 +39,22 @@ export declare namespace Soil {
|
|
|
34
39
|
private static localStackInternalPort;
|
|
35
40
|
private aws;
|
|
36
41
|
private localStackDocker;
|
|
37
|
-
private procArgs;
|
|
38
42
|
constructor(args: LocalStackArgs);
|
|
43
|
+
getRegion(): "ca-central-1" | "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2";
|
|
39
44
|
private getAwsServices;
|
|
40
45
|
private getDockerContainers;
|
|
41
|
-
run(
|
|
42
|
-
logger: Logger;
|
|
43
|
-
}): Promise<{
|
|
46
|
+
run(): Promise<{
|
|
44
47
|
aws: {
|
|
45
48
|
services: LocalStackAwsService[];
|
|
46
49
|
region: "ca-central-1" | "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2";
|
|
47
50
|
};
|
|
48
51
|
netProc: NetProc;
|
|
49
|
-
|
|
52
|
+
getApis: () => Promise<{
|
|
53
|
+
[x: string]: RestApi & {
|
|
54
|
+
id: string;
|
|
55
|
+
name: string;
|
|
56
|
+
};
|
|
57
|
+
}>;
|
|
50
58
|
}>;
|
|
51
59
|
end(args?: {
|
|
52
60
|
containers?: Awaited<ReturnType<Soil.LocalStack['getDockerContainers']>>;
|
|
@@ -71,6 +79,7 @@ export declare namespace Soil {
|
|
|
71
79
|
class AwsCloud extends Base {
|
|
72
80
|
private aws;
|
|
73
81
|
constructor(args: AwsCloudArgs);
|
|
82
|
+
getRegion(): "ca-central-1" | "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2";
|
|
74
83
|
getTerraformPetals(ctx: Context): Promise<{
|
|
75
84
|
boot: () => Generator<PetalTerraform.Terraform | PetalTerraform.Provider | PetalTerraform.File, void, unknown>;
|
|
76
85
|
main: (args: any) => Generator<PetalTerraform.Terraform | PetalTerraform.Provider | PetalTerraform.File, void, unknown>;
|