Skip to content

Instantly share code, notes, and snippets.

@hermanbanken
Last active September 16, 2020 18:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hermanbanken/708b9b2f8c013d50ca4afd319cd05487 to your computer and use it in GitHub Desktop.
Save hermanbanken/708b9b2f8c013d50ca4afd319cd05487 to your computer and use it in GitHub Desktop.
node_modules
package-lock.json
import * as pulumi from "@pulumi/pulumi";
import { CustomResourceOptions } from "@pulumi/pulumi";
import { CheckFailure } from "@pulumi/pulumi/dynamic";
import { existsSync, writeFileSync, statSync, readFileSync, chmodSync } from "fs";
import { registerResourceOutputs } from "@pulumi/pulumi/runtime";
import { inspect } from "util";
export interface FileResourceInputs {
name: pulumi.Input<string>;
data: pulumi.Input<string>;
mode: pulumi.Input<string>;
}
export interface FileResourceOutputs {
atime: pulumi.Output<Date>;
mtime: pulumi.Output<Date>;
}
/**
* FileResource is not external but saved on disk for purpose of testing a custom provider
*/
export class FileResource extends pulumi.dynamic.Resource {
constructor(name: string, args: Omit<FileResourceInputs, "name">, opts?: CustomResourceOptions) {
super({
create: FileResource.create,
read: FileResource.read,
check: FileResource.check,
update: FileResource.update,
}, `${name}`, { ...args, name }, { ...(opts||{}), ignoreChanges: [] });
registerResourceOutputs(this, {
atime: pulumi.output(null),
mtime: pulumi.output(null),
});
}
static async check<T extends pulumi.Unwrap<FileResourceInputs>>(olds: T, news: T): Promise<pulumi.dynamic.CheckResult> {
const failures: CheckFailure[] = [];
pulumi.log.debug(`check news: ${inspect(news)} olds: ${inspect(olds)}`);
if (!/^[0-7]{3}$/.test(news.mode)) {
failures.push({ reason: `Invalid mode (${news.mode})`, property: "mode" });
}
return { failures };
}
static async create<T extends pulumi.Unwrap<FileResourceInputs>>(input: T): Promise<pulumi.dynamic.CreateResult> {
pulumi.log.debug("create " + inspect(input));
if (existsSync(input.name)) {
throw new Error("Already exists");
}
writeFileSync(input.name, input.data, { encoding: "utf8" });
const stat = statSync(input.name);
return { id: `${stat.ino}`, outs: { mtime: stat.mtime, atime: stat.atime } };
}
static async read<T extends pulumi.Unwrap<FileResourceInputs>>(id: string, input?: T): Promise<pulumi.dynamic.ReadResult> {
pulumi.log.debug(`read ${id} ${inspect(input)}`);
if (input && existsSync(input.name)) {
const data = readFileSync(input.name, { encoding: "utf8" });
const stat = statSync(input.name);
return { id: `${stat.ino}`, props: { data, name: input.name, mode: `${stat.mode}` } };
}
return { id, props: {} };
}
static async update<T extends pulumi.Unwrap<FileResourceInputs>>(id: string, olds: T, input: T): Promise<pulumi.dynamic.UpdateResult> {
pulumi.log.debug(`read ${id} ${inspect(input)}`);
if (!existsSync(input.name)) {
throw new Error("File did not exist");
}
writeFileSync(input.name, input.data, { encoding: "utf8" });
chmodSync(input.name, input.mode);
const stat = statSync(input.name);
return { outs: { atime: stat.atime, mtime: stat.mtime } };
}
}
import { FileResource } from "./custom";
import { ResourceTransformation, ResourceTransformationArgs } from "@pulumi/pulumi";
// These can be created & updated just fine:
new FileResource("test.csv", { data: "test", mode: "777" }, { transformations: [t()] });
new FileResource("other.csv", { data: "test", mode: "777" });
// Importing this fails with error:
// new FileResource("existing.txt", { data: "test", mode: "777" }, { import: "existing.txt" });
function t(): ResourceTransformation {
return (args: ResourceTransformationArgs) => {
return { props: args.props, opts: args.opts };
}
}
{
"name": "pulumi-custom-provider-test",
"devDependencies": {
"@types/node": "^8.10.59"
},
"dependencies": {
"@pulumi/pulumi": "=1.4.1"
}
}
encryptionsalt: v1:0enJ8dpuPgM=:v1:ro142xooz9MWnVOq:nudeChrJ+5y/iJ83fiHxMlj9OJh/bg==
name: file-test
runtime: nodejs
description: Demonstration of custom provider
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2016",
"module": "commonjs",
"moduleResolution": "node",
"lib": ["scripthost"],
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment