Skip to content

Commit

Permalink
Merge pull request #584 from hashicorp/refactor-modules
Browse files Browse the repository at this point in the history
  • Loading branch information
skorfmann authored Mar 11, 2021
2 parents 6c3ceb1 + d33d1ee commit d0bb6d2
Show file tree
Hide file tree
Showing 81 changed files with 15,994 additions and 2,984 deletions.
19 changes: 16 additions & 3 deletions examples/python/aws-eks/cdktf.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,24 @@
"language": "python",
"app": "pipenv run python main.py",
"terraformProviders": [
"aws@~> 2.55"
{
"name": "aws",
"source": "hashicorp/aws",
"version": "~> 3.22"
}
],
"terraformModules": [
"terraform-aws-modules/vpc/aws",
"terraform-aws-modules/eks/aws"
{
"name": "vpc",
"source": "terraform-aws-modules/vpc/aws",
"version": "2.77.0"
},
{
"name": "eks",
"source": "terraform-aws-modules/eks/aws",
"version": "~> 14.0"
}
],
"codeMakerOutput": "imports"
}

8 changes: 4 additions & 4 deletions examples/python/aws-eks/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
from imports.aws import AwsProvider, DataAwsCallerIdentity

# for terraform module
from imports.terraform_aws_modules.vpc.aws import Vpc
from imports.terraform_aws_modules.eks.aws import Eks
from imports.terraform_aws_modules.vpc.aws import TerraformAwsModulesVpcAws
from imports.terraform_aws_modules.eks.aws import TerraformAwsModulesEksAws

class MyStack(TerraformStack):
def __init__(self, scope: Construct, ns: str):
super().__init__(scope, ns)

AwsProvider(self, 'Aws', region='us-west-2')

my_vpc = Vpc(self, 'MyVpc',
my_vpc = TerraformAwsModulesVpcAws(self, 'MyVpc',
name='my-vpc',
cidr='10.0.0.0/16',
azs=['us-west-2a', 'us-west-2b', 'us-west-2c'],
Expand All @@ -26,7 +26,7 @@ def __init__(self, scope: Construct, ns: str):
enable_nat_gateway=True
)

my_eks= Eks(self, 'MyEks',
my_eks= TerraformAwsModulesEksAws(self, 'MyEks',
cluster_name='my-eks',
subnets=Token().as_list(my_vpc.private_subnets_output),
vpc_id=Token().as_string(my_vpc.vpc_id_output),
Expand Down
2 changes: 1 addition & 1 deletion examples/python/aws-eks/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@examples/python-aws-eks",
"name": "@disabled-examples/python-aws-eks",
"version": "0.0.0",
"license": "MPL-2.0",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion examples/python/aws/cdktf.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"language": "python",
"app": "pipenv run python main.py",
"terraformProviders": ["aws@~> 2.0"],
"terraformModules": ["terraform-aws-modules/vpc/aws"],
"terraformModules": ["terraform-aws-modules/vpc/aws@2.77.0"],
"codeMakerOutput": "imports"
}
4 changes: 2 additions & 2 deletions examples/python/aws/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from constructs import Construct
from cdktf import App, TerraformStack
from imports.aws import SnsTopic, AwsProvider
from imports.terraform_aws_modules.vpc.aws import Vpc
from imports.terraform_aws_modules.vpc.aws import TerraformAwsModulesVpcAws


class MyStack(TerraformStack):
Expand All @@ -11,7 +11,7 @@ def __init__(self, scope: Construct, ns: str):

AwsProvider(self, 'Aws', region='eu-central-1')

Vpc(self, 'CustomVpc',
TerraformAwsModulesVpcAws(self, 'CustomVpc',
name='custom-vpc',
cidr='10.0.0.0/16',
azs=["us-east-1a", "us-east-1b"],
Expand Down
1 change: 1 addition & 0 deletions lerna.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"packages": [
"packages/*",
"packages/@cdktf/*",
"examples/*",
"examples/typescript/*",
"examples/python/*",
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"build": "lerna run --scope cdktf* build",
"build": "lerna run --scope cdktf* --scope @cdktf/* build",
"package": "lerna run package && tools/collect-dist.sh",
"package:python": "lerna run package:python && tools/collect-dist.sh",
"package:java": "lerna run package:java && tools/collect-dist.sh",
Expand All @@ -16,9 +16,9 @@
"examples:integration:csharp": "test/run-against-dist tools/build-examples.sh csharp",
"examples:integration:python": "test/run-against-dist tools/build-examples.sh python",
"examples:integration:typescript": "test/run-against-dist tools/build-examples.sh typescript",
"test": "lerna run --scope cdktf* test",
"test": "lerna run --scope cdktf* --scope @cdktf* test",
"watch": "lerna run --parallel --stream --scope cdktf* watch-preserve-output",
"link-packages": "lerna exec --scope cdktf* yarn link",
"link-packages": "lerna exec --scope cdktf* --scope @cdktf* yarn link",
"integration": "cd test && ./run-against-dist npx jest --runInBand",
"integration:typescript": "cd test && ./run-against-dist npx jest --runInBand --group=typescript",
"integration:python": "cd test && ./run-against-dist npx jest --runInBand --group=python",
Expand All @@ -37,6 +37,7 @@
"workspaces": {
"packages": [
"packages/*",
"packages/@cdktf/*",
"examples/*",
"examples/python/*",
"examples/typescript/*",
Expand Down
7 changes: 7 additions & 0 deletions packages/@cdktf/hcl2json/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
**/*.d.ts.map
**/*.js.map
**/*wasm
**/*wasm.gz
tsconfig.tsbuildinfo
wasm.md
!tsconfig.json
22 changes: 22 additions & 0 deletions packages/@cdktf/hcl2json/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
*.ts

!*.d.ts
!*.js
!.jsii

test

# Exclude jsii outdir
dist
coverage

**/*wasm
tsconfig.tsbuildinfo
wasm.md
**/*.go
go.sum
go.mod
package.sh
build-go.sh
tsconfig.json
Dockerfile
6 changes: 6 additions & 0 deletions packages/@cdktf/hcl2json/build-go.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash
set -euo pipefail

GOOS=js GOARCH=wasm go get .
GOOS=js GOARCH=wasm go build -ldflags="-s -w" -o main.wasm
gzip -9 -v -c main.wasm > main.wasm.gz
8 changes: 8 additions & 0 deletions packages/@cdktf/hcl2json/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/hashicorp/terraform-cdk/hcl2json

go 1.16

require (
github.com/tmccombs/hcl2json v0.3.2
)

50 changes: 50 additions & 0 deletions packages/@cdktf/hcl2json/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0=
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
github.com/apparentlymart/go-textseg/v12 v12.0.0 h1:bNEQyAGak9tojivJNkoqWErVCQbjdL7GzRt3F8NvfJ0=
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/hashicorp/hcl/v2 v2.6.0 h1:3krZOfGY6SziUXa6H9PJU6TyohHn7I+ARYnhbeNBz+o=
github.com/hashicorp/hcl/v2 v2.6.0/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/tmccombs/hcl2json v0.3.2 h1:9f7wGicNPt3Pr2oTj1jLuFFzz8DjLfnVVZ0ugMSGAu4=
github.com/tmccombs/hcl2json v0.3.2/go.mod h1:ljY0/prd2IFUF3cagQjV3cpPEEQKzqyGqnKI7m5DBVY=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
github.com/zclconf/go-cty v1.6.1 h1:wHtZ+LSSQVwUSb+XIJ5E9hgAQxyWATZsAWT+ESJ9dQ0=
github.com/zclconf/go-cty v1.6.1/go.mod h1:VDR4+I79ubFBGm1uJac1226K5yANQFHeauxPBoP54+o=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
14 changes: 14 additions & 0 deletions packages/@cdktf/hcl2json/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
"roots": [
"<rootDir>/test"
],
testMatch: ['**/*.test.ts', '**/*.test.tsx'],
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
moduleFileExtensions: [
"js",
"ts",
"tsx"
],
}
45 changes: 45 additions & 0 deletions packages/@cdktf/hcl2json/lib/deepmerge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Merges `source` into `target`, overriding any existing values.
* `undefined` will cause a value to be deleted.
*/
export function deepMerge(target: any, ...sources: any[]) {
for (const source of sources) {
if (typeof(source) !== 'object' || typeof(target) !== 'object') {
throw new Error(`Invalid usage. Both source (${JSON.stringify(source)}) and target (${JSON.stringify(target)}) must be objects`);
}

for (const key of Object.keys(source)) {
const value = source[key];
if (typeof(value) === 'object' && value != null && !Array.isArray(value)) {
// if the value at the target is not an object, override it with an
// object so we can continue the recursion
if (typeof(target[key]) !== 'object') {
target[key] = {};
}

deepMerge(target[key], value)

// if the result of the merge is an empty object, it's because the
// eventual value we assigned is `undefined`, and there are no
// sibling concrete values alongside, so we can delete this tree.
const output = target[key];
if (typeof(output) === 'object' && Object.keys(output).length === 0) {
delete target[key];
}
}
else if (typeof(value) === 'object' && value != null && Array.isArray(value)) {
if (Array.isArray(target[key])) {
target[key] = [...target[key], ...value];
} else {
target[key] = value;
}
} else if (value === undefined) {
delete target[key];
} else {
target[key] = value;
}
}
}

return target;
}
105 changes: 105 additions & 0 deletions packages/@cdktf/hcl2json/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
/// <reference lib="dom" />

// Inspired by
// https://github.com/ts-terraform/ts-terraform
// https://github.com/aaronpowell/webpack-golang-wasm-async-loader

import fs from 'fs-extra'
import path from 'path'
import { Go } from './wasm_exec'
import { deepMerge } from './deepmerge';
import { gunzipSync } from 'zlib';

interface GoBridge {
parse: (filename: string, hcl: string) => Promise<string>
}

// eslint-disable-next-line @typescript-eslint/ban-types
const jsRoot: Record<string, Function> = {}

function sleep() {
return new Promise(global.setImmediate)
}

function goBridge(getBytes: Promise<Buffer>) {
let ready = false

async function init() {
const go = new Go()
const bytes = await getBytes
const result = await WebAssembly.instantiate(bytes, go.importObject)
void go.run(result.instance, {__parse_terraform_config_wasm__: jsRoot})
ready = true
}

init().catch((error) => {
throw error
})

const proxy = new Proxy({} as GoBridge, {
get: (_, key: string) => {
return async (...args: unknown[]) => {
while (!ready) {
await sleep()
}

if (!(key in jsRoot)) {
throw new Error(`There is nothing defined with the name "${key.toString()}"`)
}

if (typeof jsRoot[key] !== 'function') {
return jsRoot[key]
}

return new Promise((resolve, reject) => {
// @ts-ignore
const cb = (err: string, ...msg: string[]) => (err ? reject(new Error(err)) : resolve(...msg))

const run = () => {
jsRoot[key].apply(undefined, [...args, cb])
}

run()
})
}
},
})

return proxy
}

const loadWasm = async () => {
return gunzipSync(await fs.readFile(path.join(__dirname, '..', 'main.wasm.gz')))
}

const wasm = goBridge(loadWasm())

export async function parse(filename: string, contents: string): Promise<Record<string, any>> {
const res = await wasm.parse(filename, contents)
return JSON.parse(res)
}

export async function convertFiles(workingDirectory: string): Promise<Record<string, any> | void> {
let tfFileContents = '';
const tfJSONFileContents: Record<string, any>[] = []

for (const file of fs.readdirSync(workingDirectory)) {
const filePath = path.resolve(workingDirectory, file)
if (!fs.lstatSync(filePath).isDirectory()) {
if (file.match(/\.tf$/)) {
tfFileContents += fs.readFileSync(filePath, 'utf-8')
}
else if (file.match(/\.tf\.json$/)) {
tfJSONFileContents.push(JSON.parse(fs.readFileSync(filePath, 'utf-8')))
}
}
}

if (tfFileContents === '' && tfJSONFileContents === []) {
console.error(`No '.tf' or '.tf.json' files found in ${workingDirectory}`)
return;
}

return deepMerge(await parse('hcl2json.tf', tfFileContents), ...tfJSONFileContents)
}
Loading

0 comments on commit d0bb6d2

Please sign in to comment.