PR feedback
This commit is contained in:
parent
afd7c400ad
commit
1b4ed6cce3
|
@ -1,21 +1,22 @@
|
|||
// Copyright 2016-2017, Pulumi Corporation. All rights reserved.
|
||||
|
||||
import * as pulumi from "pulumi";
|
||||
import * as dynamic from "pulumi/dynamic";
|
||||
|
||||
class OperatorCallbacks implements pulumi.ProviderCallbacks {
|
||||
class OperatorCallbacks implements dynamic.ResourceProvider {
|
||||
private op: (l: number, r: number) => any;
|
||||
|
||||
constructor(op: (l: number, r: number) => any) {
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
check = (inputs: any) => Promise.resolve(new pulumi.CheckResult(undefined, []));
|
||||
diff = (id: pulumi.ID, olds: any, news: any) => Promise.resolve(new pulumi.DiffResult([], []));
|
||||
check = (inputs: any) => Promise.resolve(new dynamic.CheckResult(undefined, []));
|
||||
diff = (id: pulumi.ID, olds: any, news: any) => Promise.resolve(new dynamic.DiffResult([], []));
|
||||
delete = (id: pulumi.ID, props: any) => Promise.resolve();
|
||||
|
||||
create = (inputs: any) => Promise.resolve(new pulumi.CreateResult("0", this.op(Number(inputs.left), Number(inputs.right))));
|
||||
create = (inputs: any) => Promise.resolve(new dynamic.CreateResult("0", this.op(Number(inputs.left), Number(inputs.right))));
|
||||
|
||||
update = (id: string, olds: any, news: any) => Promise.resolve(new pulumi.UpdateResult(this.op(Number(news.left), Number(news.right))));
|
||||
update = (id: string, olds: any, news: any) => Promise.resolve(new dynamic.UpdateResult(this.op(Number(news.left), Number(news.right))));
|
||||
}
|
||||
|
||||
class DivCallbacks extends OperatorCallbacks {
|
||||
|
@ -23,10 +24,10 @@ class DivCallbacks extends OperatorCallbacks {
|
|||
super((left: number, right: number) => <any>{ quotient: Math.floor(left / right), remainder: left % right });
|
||||
}
|
||||
|
||||
check = (ins: any) => Promise.resolve(new pulumi.CheckResult(undefined, ins.right == 0 ? [ new pulumi.CheckFailure("right", "divisor must be non-zero") ] : []));
|
||||
check = (ins: any) => Promise.resolve(new dynamic.CheckResult(undefined, ins.right == 0 ? [ new dynamic.CheckFailure("right", "divisor must be non-zero") ] : []));
|
||||
}
|
||||
|
||||
class Add extends pulumi.DynamicResource {
|
||||
class Add extends dynamic.Resource {
|
||||
public readonly sum: pulumi.Computed<number>;
|
||||
|
||||
private static callbacks = new OperatorCallbacks((left: number, right: number) => <any>{ sum: left + right });
|
||||
|
@ -36,7 +37,7 @@ class Add extends pulumi.DynamicResource {
|
|||
}
|
||||
}
|
||||
|
||||
class Mul extends pulumi.DynamicResource {
|
||||
class Mul extends dynamic.Resource {
|
||||
public readonly product: pulumi.Computed<number>;
|
||||
|
||||
private static callbacks = new OperatorCallbacks((left: number, right: number) => <any>{ product: left * right });
|
||||
|
@ -46,7 +47,7 @@ class Mul extends pulumi.DynamicResource {
|
|||
}
|
||||
}
|
||||
|
||||
class Sub extends pulumi.DynamicResource {
|
||||
class Sub extends dynamic.Resource {
|
||||
public readonly difference: pulumi.Computed<number>;
|
||||
|
||||
private static callbacks = new OperatorCallbacks((left: number, right: number) => <any>{ difference: left - right });
|
||||
|
@ -56,7 +57,7 @@ class Sub extends pulumi.DynamicResource {
|
|||
}
|
||||
}
|
||||
|
||||
class Div extends pulumi.DynamicResource {
|
||||
class Div extends dynamic.Resource {
|
||||
public readonly quotient: pulumi.Computed<number>;
|
||||
public readonly remainder: pulumi.Computed<number>;
|
||||
|
||||
|
|
|
@ -19,10 +19,11 @@ const structproto = require("google-protobuf/google/protobuf/struct_pb.js");
|
|||
const provproto = require("../../proto/provider_pb.js");
|
||||
const provrpc = require("../../proto/provider_grpc_pb.js");
|
||||
|
||||
const callbacksKey: string = "dynamic:runtime:callbacks";
|
||||
const providerKey: string = "__provider";
|
||||
|
||||
function getCallbacks(props: any): dynamic.ProviderCallbacks {
|
||||
return requireFromString(props[callbacksKey]).handler();
|
||||
function getProvider(props: any): dynamic.ResourceProvider {
|
||||
// TODO[pulumi/pulumi#414]: investigate replacing requireFromString with eval
|
||||
return requireFromString(props[providerKey]).handler();
|
||||
}
|
||||
|
||||
function configureRPC(call: any, callback: any): void {
|
||||
|
@ -42,9 +43,9 @@ async function checkRPC(call: any, callback: any): Promise<void> {
|
|||
const resp = new provproto.CheckResponse();
|
||||
|
||||
const props = req.getProperties().toJavaScript();
|
||||
const callbacks = getCallbacks(props);
|
||||
const provider = getProvider(props);
|
||||
|
||||
const result = await callbacks.check(props);
|
||||
const result = await provider.check(props);
|
||||
if (result.defaults) {
|
||||
resp.setDefaults(structproto.Struct.fromJavaScript(result.defaults));
|
||||
}
|
||||
|
@ -75,12 +76,12 @@ async function diffRPC(call: any, callback: any): Promise<void> {
|
|||
|
||||
const olds = req.getOlds().toJavaScript();
|
||||
const news = req.getNews().toJavaScript();
|
||||
if (olds[callbacksKey] !== news[callbacksKey]) {
|
||||
resp.setReplacesList([ callbacksKey ]);
|
||||
if (olds[providerKey] !== news[providerKey]) {
|
||||
resp.setReplacesList([ providerKey ]);
|
||||
} else {
|
||||
const callbacks = getCallbacks(olds);
|
||||
const provider = getProvider(olds);
|
||||
|
||||
const result: any = await callbacks.diff(req.getId(), olds, news);
|
||||
const result: any = await provider.diff(req.getId(), olds, news);
|
||||
if (result.replaces.length !== 0) {
|
||||
resp.setReplacesList(result.replaces);
|
||||
}
|
||||
|
@ -99,9 +100,9 @@ async function createRPC(call: any, callback: any): Promise<void> {
|
|||
const resp = new provproto.CreateResponse();
|
||||
|
||||
const props = req.getProperties().toJavaScript();
|
||||
const callbacks = getCallbacks(props);
|
||||
const provider = getProvider(props);
|
||||
|
||||
const result = await callbacks.create(props);
|
||||
const result = await provider.create(props);
|
||||
resp.setId(result.id);
|
||||
if (result.outs) {
|
||||
resp.setProperties(structproto.Struct.fromJavaScript(result.outs));
|
||||
|
@ -121,12 +122,12 @@ async function updateRPC(call: any, callback: any): Promise<void> {
|
|||
|
||||
const olds = req.getOlds().toJavaScript();
|
||||
const news = req.getNews().toJavaScript();
|
||||
if (olds[callbacksKey] !== news[callbacksKey]) {
|
||||
throw new Error("changes to callbacks should require replacement");
|
||||
if (olds[providerKey] !== news[providerKey]) {
|
||||
throw new Error("changes to provider should require replacement");
|
||||
}
|
||||
const callbacks = getCallbacks(olds);
|
||||
const provider = getProvider(olds);
|
||||
|
||||
const result: any = await callbacks.update(req.getId(), olds, news);
|
||||
const result: any = await provider.update(req.getId(), olds, news);
|
||||
if (result.outs) {
|
||||
resp.setProperties(structproto.Struct.fromJavaScript(result.outs));
|
||||
}
|
||||
|
@ -142,7 +143,7 @@ async function deleteRPC(call: any, callback: any): Promise<void> {
|
|||
try {
|
||||
const req: any = call.request;
|
||||
const props: any = req.getProperties().toJavaScript();
|
||||
await getCallbacks(props).delete(req.getId(), props);
|
||||
await getProvider(props).delete(req.getId(), props);
|
||||
callback(undefined, new emptyproto.Empty());
|
||||
} catch (e) {
|
||||
console.error(new Error().stack);
|
||||
|
|
|
@ -4,7 +4,7 @@ import * as resource from "./resource";
|
|||
import * as runtime from "./runtime";
|
||||
|
||||
/**
|
||||
* CheckResult represents the results of a call to `ProviderCallbacks.check`.
|
||||
* CheckResult represents the results of a call to `ResourceProvider.check`.
|
||||
*/
|
||||
export class CheckResult {
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ export class CheckResult {
|
|||
}
|
||||
|
||||
/**
|
||||
* CheckFailure represents a single failure in the results of a call to `ProviderCallbacks.check`
|
||||
* CheckFailure represents a single failure in the results of a call to `ResourceProvider.check`
|
||||
*/
|
||||
export class CheckFailure {
|
||||
/**
|
||||
|
@ -56,7 +56,7 @@ export class CheckFailure {
|
|||
}
|
||||
|
||||
/**
|
||||
* DiffResult represents the results of a call to `ProviderCallbacks.diff`.
|
||||
* DiffResult represents the results of a call to `ResourceProvider.diff`.
|
||||
*/
|
||||
export class DiffResult {
|
||||
/**
|
||||
|
@ -82,7 +82,7 @@ export class DiffResult {
|
|||
}
|
||||
|
||||
/**
|
||||
* CreateResult represents the results of a call to `ProviderCallbacks.create`.
|
||||
* CreateResult represents the results of a call to `ResourceProvider.create`.
|
||||
*/
|
||||
export class CreateResult {
|
||||
/**
|
||||
|
@ -108,7 +108,7 @@ export class CreateResult {
|
|||
}
|
||||
|
||||
/**
|
||||
* UpdateResult represents the results of a call to `ProviderCallbacks.update`.
|
||||
* UpdateResult represents the results of a call to `ResourceProvider.update`.
|
||||
*/
|
||||
export class UpdateResult {
|
||||
/**
|
||||
|
@ -127,9 +127,9 @@ export class UpdateResult {
|
|||
}
|
||||
|
||||
/**
|
||||
* Provider represents an object that provides CRUD operations for a particular type of resource.
|
||||
* ResourceProvider represents an object that provides CRUD operations for a particular type of resource.
|
||||
*/
|
||||
export interface ProviderCallbacks {
|
||||
export interface ResourceProvider {
|
||||
/**
|
||||
* Check validates that the given property bag is valid for a resource of the given type.
|
||||
*
|
||||
|
@ -172,16 +172,34 @@ export interface ProviderCallbacks {
|
|||
delete: (id: resource.ID, props: any) => Promise<void>;
|
||||
}
|
||||
|
||||
export abstract class DynamicResource extends resource.Resource {
|
||||
private static async serializeCallbacks(callbacks: ProviderCallbacks): Promise<string> {
|
||||
return runtime.serializeJavaScriptText(await runtime.serializeClosure(() => callbacks));
|
||||
/**
|
||||
* Resource represents a Pulumi Resource that incorporates an inline implementation of the Resource's CRUD operations.
|
||||
*/
|
||||
export abstract class Resource extends resource.Resource {
|
||||
private static async serializeProvider(provider: ResourceProvider): Promise<string> {
|
||||
return runtime.serializeJavaScriptText(await runtime.serializeClosure(() => provider));
|
||||
}
|
||||
|
||||
public constructor(callbacks: ProviderCallbacks,
|
||||
/**
|
||||
* Creates a new dynamic resource.
|
||||
*
|
||||
* @param provider The implementation of the resource's CRUD operations.
|
||||
* @param name The name of the resource.
|
||||
* @param props The arguments to use to populate the new resource. Must not define the reserved
|
||||
* property "__provider".
|
||||
* @param dependsOn Optional additional explicit dependencies on other resources.
|
||||
*/
|
||||
public constructor(provider: ResourceProvider,
|
||||
name: string,
|
||||
props: resource.ComputedValues,
|
||||
dependsOn?: resource.Resource[]) {
|
||||
props["dynamic:runtime:callbacks"] = DynamicResource.serializeCallbacks(callbacks);
|
||||
super("dynamic:runtime:resource", name, props, dependsOn);
|
||||
const providerKey: string = "__provider";
|
||||
|
||||
if (props[providerKey]) {
|
||||
throw new Error("A dynamic resource must not define the __provider key");
|
||||
}
|
||||
props[providerKey] = Resource.serializeProvider(provider);
|
||||
|
||||
super("pulumi-nodejs:dynamic:Resource", name, props, dependsOn);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@ import "source-map-support/register";
|
|||
|
||||
// Export top-level elements.
|
||||
export * from "./config";
|
||||
export * from "./dynamic";
|
||||
export * from "./resource";
|
||||
|
||||
// Export submodules individually.
|
||||
import * as asset from "./asset";
|
||||
import * as dynamic from "./dynamic";
|
||||
import * as log from "./log";
|
||||
import * as runtime from "./runtime";
|
||||
export { asset, log, runtime };
|
||||
export { asset, dynamic, log, runtime };
|
||||
|
||||
|
|
Loading…
Reference in a new issue