Adds initial support for resource methods (via a new `Call` gRPC method similar to `Invoke`), with support for authoring methods from Node.js, and calling methods from Python.
215 lines
7.3 KiB
Go
215 lines
7.3 KiB
Go
// Copyright 2016-2018, Pulumi Corporation.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package deploytest
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/blang/semver"
|
|
uuid "github.com/gofrs/uuid"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/tokens"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/workspace"
|
|
)
|
|
|
|
type Provider struct {
|
|
Name string
|
|
Package tokens.Package
|
|
Version semver.Version
|
|
|
|
Config resource.PropertyMap
|
|
configured bool
|
|
|
|
GetSchemaF func(version int) ([]byte, error)
|
|
|
|
CheckConfigF func(urn resource.URN, olds,
|
|
news resource.PropertyMap, allowUnknowns bool) (resource.PropertyMap, []plugin.CheckFailure, error)
|
|
DiffConfigF func(urn resource.URN, olds, news resource.PropertyMap,
|
|
ignoreChanges []string) (plugin.DiffResult, error)
|
|
ConfigureF func(news resource.PropertyMap) error
|
|
|
|
CheckF func(urn resource.URN,
|
|
olds, news resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error)
|
|
DiffF func(urn resource.URN, id resource.ID, olds, news resource.PropertyMap,
|
|
ignoreChanges []string) (plugin.DiffResult, error)
|
|
CreateF func(urn resource.URN, inputs resource.PropertyMap, timeout float64,
|
|
preview bool) (resource.ID, resource.PropertyMap, resource.Status, error)
|
|
UpdateF func(urn resource.URN, id resource.ID, olds, news resource.PropertyMap, timeout float64,
|
|
ignoreChanges []string, preview bool) (resource.PropertyMap, resource.Status, error)
|
|
DeleteF func(urn resource.URN, id resource.ID, olds resource.PropertyMap, timeout float64) (resource.Status, error)
|
|
ReadF func(urn resource.URN, id resource.ID,
|
|
inputs, state resource.PropertyMap) (plugin.ReadResult, resource.Status, error)
|
|
|
|
ConstructF func(monitor *ResourceMonitor, typ, name string, parent resource.URN, inputs resource.PropertyMap,
|
|
options plugin.ConstructOptions) (plugin.ConstructResult, error)
|
|
|
|
InvokeF func(tok tokens.ModuleMember,
|
|
inputs resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error)
|
|
|
|
CallF func(monitor *ResourceMonitor, tok tokens.ModuleMember, args resource.PropertyMap, info plugin.CallInfo,
|
|
options plugin.CallOptions) (plugin.CallResult, error)
|
|
|
|
CancelF func() error
|
|
}
|
|
|
|
func (prov *Provider) SignalCancellation() error {
|
|
if prov.CancelF == nil {
|
|
return nil
|
|
}
|
|
return prov.CancelF()
|
|
}
|
|
|
|
func (prov *Provider) Close() error {
|
|
return nil
|
|
}
|
|
|
|
func (prov *Provider) Pkg() tokens.Package {
|
|
return prov.Package
|
|
}
|
|
|
|
func (prov *Provider) GetPluginInfo() (workspace.PluginInfo, error) {
|
|
return workspace.PluginInfo{
|
|
Name: prov.Name,
|
|
Version: &prov.Version,
|
|
}, nil
|
|
}
|
|
|
|
func (prov *Provider) GetSchema(version int) ([]byte, error) {
|
|
if prov.GetSchemaF == nil {
|
|
return []byte("{}"), nil
|
|
}
|
|
return prov.GetSchemaF(version)
|
|
}
|
|
|
|
func (prov *Provider) CheckConfig(urn resource.URN, olds,
|
|
news resource.PropertyMap, allowUnknowns bool) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
|
if prov.CheckConfigF == nil {
|
|
return news, nil, nil
|
|
}
|
|
return prov.CheckConfigF(urn, olds, news, allowUnknowns)
|
|
}
|
|
func (prov *Provider) DiffConfig(urn resource.URN, olds, news resource.PropertyMap, _ bool,
|
|
ignoreChanges []string) (plugin.DiffResult, error) {
|
|
if prov.DiffConfigF == nil {
|
|
return plugin.DiffResult{}, nil
|
|
}
|
|
return prov.DiffConfigF(urn, olds, news, ignoreChanges)
|
|
}
|
|
func (prov *Provider) Configure(inputs resource.PropertyMap) error {
|
|
contract.Assert(!prov.configured)
|
|
prov.configured = true
|
|
|
|
if prov.ConfigureF == nil {
|
|
prov.Config = inputs
|
|
return nil
|
|
}
|
|
return prov.ConfigureF(inputs)
|
|
}
|
|
|
|
func (prov *Provider) Check(urn resource.URN,
|
|
olds, news resource.PropertyMap, _ bool) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
|
if prov.CheckF == nil {
|
|
return news, nil, nil
|
|
}
|
|
return prov.CheckF(urn, olds, news)
|
|
}
|
|
func (prov *Provider) Create(urn resource.URN, props resource.PropertyMap, timeout float64,
|
|
preview bool) (resource.ID, resource.PropertyMap, resource.Status, error) {
|
|
|
|
if prov.CreateF == nil {
|
|
// generate a new uuid
|
|
uuid, err := uuid.NewV4()
|
|
if err != nil {
|
|
return "", nil, resource.StatusOK, err
|
|
}
|
|
return resource.ID(uuid.String()), resource.PropertyMap{}, resource.StatusOK, nil
|
|
}
|
|
return prov.CreateF(urn, props, timeout, preview)
|
|
}
|
|
func (prov *Provider) Diff(urn resource.URN, id resource.ID,
|
|
olds resource.PropertyMap, news resource.PropertyMap, _ bool, ignoreChanges []string) (plugin.DiffResult, error) {
|
|
if prov.DiffF == nil {
|
|
return plugin.DiffResult{}, nil
|
|
}
|
|
return prov.DiffF(urn, id, olds, news, ignoreChanges)
|
|
}
|
|
func (prov *Provider) Update(urn resource.URN, id resource.ID, olds resource.PropertyMap, news resource.PropertyMap,
|
|
timeout float64, ignoreChanges []string, preview bool) (resource.PropertyMap, resource.Status, error) {
|
|
if prov.UpdateF == nil {
|
|
return news, resource.StatusOK, nil
|
|
}
|
|
return prov.UpdateF(urn, id, olds, news, timeout, ignoreChanges, preview)
|
|
}
|
|
func (prov *Provider) Delete(urn resource.URN,
|
|
id resource.ID, props resource.PropertyMap, timeout float64) (resource.Status, error) {
|
|
if prov.DeleteF == nil {
|
|
return resource.StatusOK, nil
|
|
}
|
|
return prov.DeleteF(urn, id, props, timeout)
|
|
}
|
|
|
|
func (prov *Provider) Read(urn resource.URN, id resource.ID,
|
|
inputs, state resource.PropertyMap) (plugin.ReadResult, resource.Status, error) {
|
|
if prov.ReadF == nil {
|
|
return plugin.ReadResult{
|
|
Outputs: resource.PropertyMap{},
|
|
Inputs: resource.PropertyMap{},
|
|
}, resource.StatusUnknown, nil
|
|
}
|
|
return prov.ReadF(urn, id, inputs, state)
|
|
}
|
|
|
|
func (prov *Provider) Construct(info plugin.ConstructInfo, typ tokens.Type, name tokens.QName, parent resource.URN,
|
|
inputs resource.PropertyMap, options plugin.ConstructOptions) (plugin.ConstructResult, error) {
|
|
if prov.ConstructF == nil {
|
|
return plugin.ConstructResult{}, nil
|
|
}
|
|
monitor, err := dialMonitor(context.Background(), info.MonitorAddress)
|
|
if err != nil {
|
|
return plugin.ConstructResult{}, err
|
|
}
|
|
return prov.ConstructF(monitor, string(typ), string(name), parent, inputs, options)
|
|
}
|
|
|
|
func (prov *Provider) Invoke(tok tokens.ModuleMember,
|
|
args resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
|
if prov.InvokeF == nil {
|
|
return resource.PropertyMap{}, nil, nil
|
|
}
|
|
return prov.InvokeF(tok, args)
|
|
}
|
|
|
|
func (prov *Provider) StreamInvoke(
|
|
tok tokens.ModuleMember, args resource.PropertyMap,
|
|
onNext func(resource.PropertyMap) error) ([]plugin.CheckFailure, error) {
|
|
|
|
return nil, fmt.Errorf("not implemented")
|
|
}
|
|
|
|
func (prov *Provider) Call(tok tokens.ModuleMember, args resource.PropertyMap, info plugin.CallInfo,
|
|
options plugin.CallOptions) (plugin.CallResult, error) {
|
|
if prov.CallF == nil {
|
|
return plugin.CallResult{}, nil
|
|
}
|
|
monitor, err := dialMonitor(context.Background(), info.MonitorAddress)
|
|
if err != nil {
|
|
return plugin.CallResult{}, err
|
|
}
|
|
return prov.CallF(monitor, tok, args, info, options)
|
|
}
|