// Copyright 2016-2021, Pulumi Corporation. All rights reserved. //go:build !all // +build !all package main import ( "context" "errors" "fmt" "reflect" "github.com/pulumi/pulumi/pkg/v3/resource/provider" "github.com/pulumi/pulumi/sdk/v3/go/common/resource" "github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" pulumiprovider "github.com/pulumi/pulumi/sdk/v3/go/pulumi/provider" pulumirpc "github.com/pulumi/pulumi/sdk/v3/proto/go" "google.golang.org/protobuf/types/known/emptypb" ) type Resource struct { pulumi.CustomResourceState } type resourceArgs struct { Echo interface{} `pulumi:"echo"` } type ResourceArgs struct { Echo pulumi.Input } func (ResourceArgs) ElementType() reflect.Type { return reflect.TypeOf((*resourceArgs)(nil)).Elem() } func NewResource(ctx *pulumi.Context, name string, echo pulumi.Input, opts ...pulumi.ResourceOption, ) (*Resource, error) { args := &ResourceArgs{Echo: echo} var resource Resource err := ctx.RegisterResource(providerName+":index:Resource", name, args, &resource, opts...) if err != nil { return nil, err } return &resource, nil } type Component struct { pulumi.ResourceState Echo pulumi.Input `pulumi:"echo"` ChildID pulumi.IDOutput `pulumi:"childId"` Secret pulumi.StringOutput `pulumi:"secret"` } type ComponentArgs struct { Echo pulumi.Input `pulumi:"echo"` } func NewComponent(ctx *pulumi.Context, name string, args *ComponentArgs, opts ...pulumi.ResourceOption, ) (*Component, error) { if args == nil { return nil, errors.New("args is required") } secretKey := "secret" fullSecretKey := fmt.Sprintf("%s:%s", ctx.Project(), secretKey) if !ctx.IsConfigSecret(fullSecretKey) { return nil, fmt.Errorf("expected configuration key to be secret: %s", fullSecretKey) } conf := config.New(ctx, "") secret := conf.RequireSecret(secretKey) component := &Component{} err := ctx.RegisterComponentResource(providerName+":index:Component", name, component, opts...) if err != nil { return nil, err } res, err := NewResource(ctx, fmt.Sprintf("child-%s", name), args.Echo, pulumi.Parent(component)) if err != nil { return nil, err } component.Echo = args.Echo component.ChildID = res.ID() component.Secret = secret if err := ctx.RegisterResourceOutputs(component, pulumi.Map{ "secret": component.Secret, "echo": component.Echo, "childId": component.ChildID, }); err != nil { return nil, err } return component, nil } const ( providerName = "testcomponent" version = "0.0.1" ) var currentID int func main() { err := provider.Main(providerName, func(host *provider.HostClient) (pulumirpc.ResourceProviderServer, error) { return makeProvider(host, providerName, version) }) if err != nil { cmdutil.ExitError(err.Error()) } } type Provider struct { pulumirpc.UnimplementedResourceProviderServer host *provider.HostClient name string version string expectResourceArg bool } func makeProvider(host *provider.HostClient, name, version string) (pulumirpc.ResourceProviderServer, error) { return &Provider{ host: host, name: name, version: version, }, nil } func (p *Provider) Create(ctx context.Context, req *pulumirpc.CreateRequest, ) (*pulumirpc.CreateResponse, error) { urn := resource.URN(req.GetUrn()) typ := urn.Type() if typ != providerName+":index:Resource" { return nil, fmt.Errorf("Unknown resource type '%s'", typ) } if s, ok := req.GetProperties().Fields["echo"].AsInterface().(string); ok && s == "checkExpected" && !p.expectResourceArg { return nil, fmt.Errorf("did not receive configured provider") } id := currentID currentID++ return &pulumirpc.CreateResponse{ Id: fmt.Sprintf("%v", id), }, nil } func (p *Provider) Construct(ctx context.Context, req *pulumirpc.ConstructRequest, ) (*pulumirpc.ConstructResponse, error) { return pulumiprovider.Construct(ctx, req, p.host.EngineConn(), func(ctx *pulumi.Context, typ, name string, inputs pulumiprovider.ConstructInputs, options pulumi.ResourceOption, ) (*pulumiprovider.ConstructResult, error) { if typ != providerName+":index:Component" { return nil, fmt.Errorf("unknown resource type %s", typ) } args := &ComponentArgs{} if err := inputs.CopyTo(args); err != nil { return nil, fmt.Errorf("setting args: %w", err) } component, err := NewComponent(ctx, name, args, options) if err != nil { return nil, fmt.Errorf("creating component: %w", err) } return pulumiprovider.NewConstructResult(component) }) } func (p *Provider) CheckConfig(ctx context.Context, req *pulumirpc.CheckRequest, ) (*pulumirpc.CheckResponse, error) { return &pulumirpc.CheckResponse{Inputs: req.GetNews()}, nil } func (p *Provider) DiffConfig(ctx context.Context, req *pulumirpc.DiffRequest, ) (*pulumirpc.DiffResponse, error) { return &pulumirpc.DiffResponse{}, nil } func (p *Provider) Configure(ctx context.Context, req *pulumirpc.ConfigureRequest, ) (*pulumirpc.ConfigureResponse, error) { if _, ok := req.GetArgs().Fields["expectResourceArg"]; ok { p.expectResourceArg = true } return &pulumirpc.ConfigureResponse{ AcceptSecrets: true, SupportsPreview: true, AcceptResources: true, }, nil } func (p *Provider) Invoke(ctx context.Context, req *pulumirpc.InvokeRequest, ) (*pulumirpc.InvokeResponse, error) { return nil, fmt.Errorf("Unknown Invoke token '%s'", req.GetTok()) } func (p *Provider) StreamInvoke(req *pulumirpc.InvokeRequest, server pulumirpc.ResourceProvider_StreamInvokeServer, ) error { return fmt.Errorf("Unknown StreamInvoke token '%s'", req.GetTok()) } func (p *Provider) Call(ctx context.Context, req *pulumirpc.CallRequest, ) (*pulumirpc.CallResponse, error) { return nil, fmt.Errorf("Unknown Call token '%s'", req.GetTok()) } func (p *Provider) Check(ctx context.Context, req *pulumirpc.CheckRequest, ) (*pulumirpc.CheckResponse, error) { return &pulumirpc.CheckResponse{Inputs: req.News, Failures: nil}, nil } func (p *Provider) Diff(ctx context.Context, req *pulumirpc.DiffRequest) (*pulumirpc.DiffResponse, error) { return &pulumirpc.DiffResponse{}, nil } func (p *Provider) Read(ctx context.Context, req *pulumirpc.ReadRequest) (*pulumirpc.ReadResponse, error) { return &pulumirpc.ReadResponse{ Id: req.GetId(), Properties: req.GetProperties(), }, nil } func (p *Provider) Update(ctx context.Context, req *pulumirpc.UpdateRequest, ) (*pulumirpc.UpdateResponse, error) { return &pulumirpc.UpdateResponse{ Properties: req.GetNews(), }, nil } func (p *Provider) Delete(ctx context.Context, req *pulumirpc.DeleteRequest) (*emptypb.Empty, error) { return &emptypb.Empty{}, nil } func (p *Provider) GetPluginInfo(context.Context, *emptypb.Empty) (*pulumirpc.PluginInfo, error) { return &pulumirpc.PluginInfo{ Version: p.version, }, nil } func (p *Provider) Attach(ctx context.Context, req *pulumirpc.PluginAttach) (*emptypb.Empty, error) { return &emptypb.Empty{}, nil } func (p *Provider) GetSchema(ctx context.Context, req *pulumirpc.GetSchemaRequest, ) (*pulumirpc.GetSchemaResponse, error) { return &pulumirpc.GetSchemaResponse{}, nil } func (p *Provider) Cancel(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { return &emptypb.Empty{}, nil } func (p *Provider) GetMapping(context.Context, *pulumirpc.GetMappingRequest) (*pulumirpc.GetMappingResponse, error) { return &pulumirpc.GetMappingResponse{}, nil }