Last active
July 8, 2021 13:54
-
-
Save skorfmann/f1b9a972eadac072cc4dd84959cd96fa to your computer and use it in GitHub Desktop.
A custom data source for cdktf without generics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Construct, Node, } from "constructs"; | |
import { Resource, TerraformResource, TerraformAsset, AssetType } from 'cdktf'; | |
import * as fs from "fs"; | |
import * as path from 'path' | |
import { DataExternal } from "@cdktf/provider-external" | |
export interface CustomDataSourceConfig { | |
code(input: any): Promise<any> | |
inputs: any; | |
dependsOn?: TerraformResource[]; | |
} | |
export abstract class CustomDataSource extends Resource { | |
public readonly data: DataExternal; | |
constructor(scope: Construct, name: string, config: CustomDataSourceConfig) { | |
super(scope, name); | |
const { code, inputs, dependsOn } = config; | |
const filePath = this.writeHandler(code); | |
const asset = new TerraformAsset(this, 'data-source-asset', { | |
path: filePath, | |
type: AssetType.FILE, | |
}); | |
this.data = new DataExternal(this, 'external', { | |
program: ['node', asset.path], | |
query: inputs, | |
workingDir: asset.path, | |
dependsOn | |
}) | |
} | |
private writeHandler(code: (input: any) => Promise<any>) { | |
const name = Node.of(this).addr | |
const tmpWorkDir = path.join(process.cwd(), 'tmp', 'build', 'data-soruces') | |
fs.mkdirSync(tmpWorkDir, { recursive: true }) | |
const filePath = path.join(tmpWorkDir, `${name}-data-source.js`) | |
fs.writeFileSync(filePath, ` | |
const handler = ${code.toString()} | |
const stdin = process.stdin, | |
stdout = process.stdout, | |
inputChunks = []; | |
stdin.setEncoding('utf8'); | |
stdin.on('data', function (chunk) { | |
inputChunks.push(chunk) | |
}); | |
stdin.on('end', async function () { | |
const input = JSON.parse(inputChunks.join('')) | |
try { | |
const output = await handler(input) | |
stdout.write(JSON.stringify(output)); | |
stdout.write('\\n'); | |
} catch(e) { | |
console.error("error", e) | |
} | |
}) | |
`) | |
return filePath; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Construct, } from "constructs"; | |
import { TerraformResource } from 'cdktf'; | |
import { CustomDataSource } from '../custom-data-source' | |
import { AwsEcrRepository } from "./aws-ecr-repository"; | |
export interface CustomDockerImageConfig { | |
repository: AwsEcrRepository, | |
dependsOn?: TerraformResource[]; | |
} | |
export class CustomDockerImage extends CustomDataSource { | |
public readonly digest: string; | |
public readonly url: string; | |
constructor(scope: Construct, name: string, config: CustomDockerImageConfig) { | |
const { repository } = config; | |
super(scope, name, { | |
inputs: { | |
repositoryUrl: repository.url, | |
username: repository.authorizationUser, | |
password: repository.authorizationPassword | |
}, | |
code: async (args: any) => { | |
const drc = require('docker-registry-client') | |
return new Promise((resolve, reject) => { | |
var rar = drc.parseRepoAndRef(args.repositoryUrl); | |
var client = drc.createClientV2({ | |
repo: rar, | |
insecure: false, | |
username: args.username, | |
password: args.password, | |
maxSchemaVersion: 2 | |
}); | |
var tagOrDigest = rar.tag || rar.digest; | |
client.getManifest({ref: tagOrDigest}, function (err:any, _manifest:any, _res:any, manifestStr:any) { | |
client.close(); | |
if (err) { | |
reject(err) | |
} | |
resolve({sha256Digest: drc.digestFromManifestStr(manifestStr)}); | |
}); | |
}); | |
}, | |
dependsOn: config.dependsOn | |
}); | |
this.digest = this.data.result('sha256Digest'); | |
this.url = `${repository.url}@${this.digest}` | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment