github.com/myhau/pulumi/pkg/v3@v3.70.2-0.20221116134521-f2775972e587/resource/provider/component_provider.go (about) 1 // Copyright 2016-2021, Pulumi Corporation. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package provider 16 17 import ( 18 "fmt" 19 20 "github.com/pulumi/pulumi/sdk/v3/go/pulumi/provider" 21 pulumirpc "github.com/pulumi/pulumi/sdk/v3/proto/go" 22 23 pbempty "github.com/golang/protobuf/ptypes/empty" 24 "golang.org/x/net/context" 25 "google.golang.org/grpc/codes" 26 "google.golang.org/grpc/status" 27 ) 28 29 type componentProvider struct { 30 host *HostClient 31 name string 32 version string 33 schema []byte 34 construct provider.ConstructFunc 35 call provider.CallFunc 36 } 37 38 type Options struct { 39 Name string 40 Version string 41 Schema []byte 42 Construct provider.ConstructFunc 43 Call provider.CallFunc 44 } 45 46 // MainWithOptions is an entrypoint for a resource provider plugin that implements `Construct` and optionally also 47 // `Call` for component resources. 48 // 49 // Using it isn't required but can cut down significantly on the amount of boilerplate necessary to fire up a new 50 // resource provider for components. 51 func MainWithOptions(opts Options) error { 52 return Main(opts.Name, func(host *HostClient) (pulumirpc.ResourceProviderServer, error) { 53 return &componentProvider{ 54 host: host, 55 name: opts.Name, 56 version: opts.Version, 57 schema: opts.Schema, 58 construct: opts.Construct, 59 call: opts.Call, 60 }, nil 61 }) 62 } 63 64 // ComponentMain is an entrypoint for a resource provider plugin that implements `Construct` for component resources. 65 // Using it isn't required but can cut down significantly on the amount of boilerplate necessary to fire up a new 66 // resource provider for components. 67 func ComponentMain(name, version string, schema []byte, construct provider.ConstructFunc) error { 68 return Main(name, func(host *HostClient) (pulumirpc.ResourceProviderServer, error) { 69 return &componentProvider{ 70 host: host, 71 name: name, 72 version: version, 73 schema: schema, 74 construct: construct, 75 }, nil 76 }) 77 } 78 79 // GetPluginInfo returns generic information about this plugin, like its version. 80 func (p *componentProvider) GetPluginInfo(context.Context, *pbempty.Empty) (*pulumirpc.PluginInfo, error) { 81 return &pulumirpc.PluginInfo{ 82 Version: p.version, 83 }, nil 84 } 85 86 // GetSchema returns the JSON-encoded schema for this provider's package. 87 func (p *componentProvider) GetSchema(ctx context.Context, 88 req *pulumirpc.GetSchemaRequest) (*pulumirpc.GetSchemaResponse, error) { 89 if v := req.GetVersion(); v != 0 { 90 return nil, fmt.Errorf("unsupported schema version %d", v) 91 } 92 schema := string(p.schema) 93 if schema == "" { 94 schema = "{}" 95 } 96 return &pulumirpc.GetSchemaResponse{Schema: schema}, nil 97 } 98 99 // Configure configures the resource provider with "globals" that control its behavior. 100 func (p *componentProvider) Configure(ctx context.Context, 101 req *pulumirpc.ConfigureRequest) (*pulumirpc.ConfigureResponse, error) { 102 return &pulumirpc.ConfigureResponse{ 103 AcceptSecrets: true, 104 SupportsPreview: true, 105 AcceptResources: true, 106 AcceptOutputs: true, 107 }, nil 108 } 109 110 // Construct creates a new instance of the provided component resource and returns its state. 111 func (p *componentProvider) Construct(ctx context.Context, 112 req *pulumirpc.ConstructRequest) (*pulumirpc.ConstructResponse, error) { 113 if p.construct != nil { 114 return provider.Construct(ctx, req, p.host.conn, p.construct) 115 } 116 return nil, status.Error(codes.Unimplemented, "Construct is not yet implemented") 117 } 118 119 // CheckConfig validates the configuration for this provider. 120 func (p *componentProvider) CheckConfig(ctx context.Context, 121 req *pulumirpc.CheckRequest) (*pulumirpc.CheckResponse, error) { 122 return nil, status.Error(codes.Unimplemented, "CheckConfig is not yet implemented") 123 } 124 125 // DiffConfig diffs the configuration for this provider. 126 func (p *componentProvider) DiffConfig(ctx context.Context, 127 req *pulumirpc.DiffRequest) (*pulumirpc.DiffResponse, error) { 128 return nil, status.Error(codes.Unimplemented, "DiffConfig is not yet implemented") 129 } 130 131 // StreamInvoke dynamically executes a built-in function in the provider. The result is streamed 132 // back as a series of messages. 133 func (p *componentProvider) StreamInvoke(req *pulumirpc.InvokeRequest, 134 server pulumirpc.ResourceProvider_StreamInvokeServer) error { 135 return status.Error(codes.Unimplemented, "StreamInvoke is not yet implemented") 136 } 137 138 // Check validates that the given property bag is valid for a resource of the given type and returns 139 // the inputs that should be passed to successive calls to Diff, Create, or Update for this 140 // resource. As a rule, the provider inputs returned by a call to Check should preserve the original 141 // representation of the properties as present in the program inputs. Though this rule is not 142 // required for correctness, violations thereof can negatively impact the end-user experience, as 143 // the provider inputs are using for detecting and rendering diffs. 144 func (p *componentProvider) Check(ctx context.Context, req *pulumirpc.CheckRequest) (*pulumirpc.CheckResponse, error) { 145 return nil, status.Error(codes.Unimplemented, "Check is not yet implemented") 146 } 147 148 // Diff checks what impacts a hypothetical update will have on the resource's properties. 149 func (p *componentProvider) Diff(ctx context.Context, req *pulumirpc.DiffRequest) (*pulumirpc.DiffResponse, error) { 150 return nil, status.Error(codes.Unimplemented, "Diff is not yet implemented") 151 } 152 153 // Create allocates a new instance of the provided resource and returns its unique ID afterwards. 154 // (The input ID must be blank.) If this call fails, the resource must not have been created (i.e., 155 // it is "transactional"). 156 func (p *componentProvider) Create(ctx context.Context, 157 req *pulumirpc.CreateRequest) (*pulumirpc.CreateResponse, error) { 158 return nil, status.Error(codes.Unimplemented, "Create is not yet implemented") 159 } 160 161 // Read the current live state associated with a resource. Enough state must be include in the 162 // inputs to uniquely identify the resource; this is typically just the resource ID, but may also 163 // include some properties. 164 func (p *componentProvider) Read(ctx context.Context, req *pulumirpc.ReadRequest) (*pulumirpc.ReadResponse, error) { 165 return nil, status.Error(codes.Unimplemented, "Read is not yet implemented") 166 } 167 168 // Update updates an existing resource with new values. 169 func (p *componentProvider) Update(ctx context.Context, 170 req *pulumirpc.UpdateRequest) (*pulumirpc.UpdateResponse, error) { 171 return nil, status.Error(codes.Unimplemented, "Update is not yet implemented") 172 } 173 174 // Delete tears down an existing resource with the given ID. If it fails, the resource is assumed 175 // to still exist. 176 func (p *componentProvider) Delete(ctx context.Context, req *pulumirpc.DeleteRequest) (*pbempty.Empty, error) { 177 return nil, status.Error(codes.Unimplemented, "Delete is not yet implemented") 178 } 179 180 // Invoke dynamically executes a built-in function in the provider. 181 func (p *componentProvider) Invoke(ctx context.Context, 182 req *pulumirpc.InvokeRequest) (*pulumirpc.InvokeResponse, error) { 183 return nil, status.Error(codes.Unimplemented, "Invoke is not yet implemented") 184 } 185 186 // Call dynamically executes a method in the provider associated with a component resource. 187 func (p *componentProvider) Call(ctx context.Context, 188 req *pulumirpc.CallRequest) (*pulumirpc.CallResponse, error) { 189 if p.call != nil { 190 return provider.Call(ctx, req, p.host.conn, p.call) 191 } 192 return nil, status.Error(codes.Unimplemented, "Call is not yet implemented") 193 } 194 195 // Cancel signals the provider to gracefully shut down and abort any ongoing resource operations. 196 // Operations aborted in this way will return an error (e.g., `Update` and `Create` will either a 197 // creation error or an initialization error). Since Cancel is advisory and non-blocking, it is up 198 // to the host to decide how long to wait after Cancel is called before (e.g.) 199 // hard-closing any gRPC connection. 200 func (p *componentProvider) Cancel(context.Context, *pbempty.Empty) (*pbempty.Empty, error) { 201 return &pbempty.Empty{}, nil 202 } 203 204 // Attach attaches to the engine for an already running provider. 205 func (p *componentProvider) Attach(ctx context.Context, 206 req *pulumirpc.PluginAttach) (*pbempty.Empty, error) { 207 host, err := NewHostClient(req.GetAddress()) 208 if err != nil { 209 return nil, err 210 } 211 p.host = host 212 return &pbempty.Empty{}, nil 213 }