Example suggestion for config middleware

This commit is contained in:
Ian Wahbe
2024-05-03 12:35:47 -10:00
parent 139d863b3d
commit 68085dfdc2
2 changed files with 38 additions and 74 deletions

View File

@@ -17,9 +17,6 @@ package deprecated
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"sort"
"google.golang.org/protobuf/types/known/structpb"
"github.com/pulumi/pulumi/pkg/v3/codegen/schema" "github.com/pulumi/pulumi/pkg/v3/codegen/schema"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource" "github.com/pulumi/pulumi/sdk/v3/go/common/resource"
@@ -120,15 +117,10 @@ func (enc *ConfigEncoding) unmarshalOpts() plugin.MarshalOptions {
// Like plugin.UnmarshalPropertyValue but overrides string parsing with convertStringToPropertyValue. // Like plugin.UnmarshalPropertyValue but overrides string parsing with convertStringToPropertyValue.
func (enc *ConfigEncoding) unmarshalPropertyValue(key resource.PropertyKey, func (enc *ConfigEncoding) unmarshalPropertyValue(key resource.PropertyKey,
v *structpb.Value, pv resource.PropertyValue,
) (*resource.PropertyValue, error) { ) (resource.PropertyValue, error) {
opts := enc.unmarshalOpts() opts := enc.unmarshalOpts()
pv, err := plugin.UnmarshalPropertyValue(key, v, enc.unmarshalOpts())
if err != nil {
return nil, fmt.Errorf("error unmarshalling property %q: %w", key, err)
}
prop, ok := enc.schema.Variables[string(key)] prop, ok := enc.schema.Variables[string(key)]
// Only apply JSON-encoded recognition for known fields. // Only apply JSON-encoded recognition for known fields.
@@ -136,8 +128,10 @@ func (enc *ConfigEncoding) unmarshalPropertyValue(key resource.PropertyKey,
return pv, nil return pv, nil
} }
var jsonString string var (
var jsonStringDetected, jsonStringSecret bool jsonString string
jsonStringDetected, jsonStringSecret bool
)
if pv.IsString() { if pv.IsString() {
jsonString = pv.StringValue() jsonString = pv.StringValue()
@@ -153,22 +147,21 @@ func (enc *ConfigEncoding) unmarshalPropertyValue(key resource.PropertyKey,
if jsonStringDetected { if jsonStringDetected {
v, err := enc.convertStringToPropertyValue(jsonString, prop) v, err := enc.convertStringToPropertyValue(jsonString, prop)
if err != nil { if err != nil {
return nil, fmt.Errorf("error unmarshalling property %q: %w", key, err) return resource.PropertyValue{}, fmt.Errorf("error unmarshalling property %q: %w", key, err)
} }
if jsonStringSecret { if jsonStringSecret {
s := resource.MakeSecret(v) return resource.MakeSecret(v), nil
return &s, nil
} }
return &v, nil return v, nil
} }
// Computed sentinels are coming in as always having an empty string, but the encoding coerses them to a zero // Computed sentinels are coming in as always having an empty string, but the encoding coerces them to a zero
// value of the appropriate type. // value of the appropriate type.
if pv.IsComputed() { if pv.IsComputed() {
el := pv.V.(resource.Computed).Element el := pv.V.(resource.Computed).Element
if el.IsString() && el.StringValue() == "" { if el.IsString() && el.StringValue() == "" {
res := resource.MakeComputed(enc.zeroValue(prop.Type)) res := resource.MakeComputed(enc.zeroValue(prop.Type))
return &res, nil return res, nil
} }
} }
@@ -177,36 +170,21 @@ func (enc *ConfigEncoding) unmarshalPropertyValue(key resource.PropertyKey,
// UnmarshalProperties is copied from plugin.UnmarshalProperties substituting plugin.UnmarshalPropertyValue. // UnmarshalProperties is copied from plugin.UnmarshalProperties substituting plugin.UnmarshalPropertyValue.
func (enc *ConfigEncoding) UnmarshalProperties( func (enc *ConfigEncoding) UnmarshalProperties(
props *structpb.Struct, props resource.PropertyMap,
) (resource.PropertyMap, error) { ) (resource.PropertyMap, error) {
opts := enc.unmarshalOpts()
result := make(resource.PropertyMap) result := make(resource.PropertyMap)
// First sort the keys so we enumerate them in order (in case errors happen, we want determinism). // First sort the keys so we enumerate them in order (in case errors happen, we want determinism).
var keys []string keys := props.StableKeys()
if props != nil {
for k := range props.Fields {
keys = append(keys, k)
}
sort.Strings(keys)
}
// And now unmarshal every field it into the map. // And now unmarshal every field it into the map.
for _, key := range keys { for _, key := range keys {
pk := resource.PropertyKey(key) pk := resource.PropertyKey(key)
v, err := enc.unmarshalPropertyValue(pk, props.Fields[key]) v, err := enc.unmarshalPropertyValue(pk, props[key])
if err != nil { if err != nil {
return nil, err return nil, err
} else if v != nil {
if opts.SkipNulls && v.IsNull() {
continue
}
if opts.SkipInternalKeys && resource.IsInternalPropertyKey(pk) {
continue
}
result[pk] = *v
} }
result[pk] = v
} }
return result, nil return result, nil

View File

@@ -17,15 +17,14 @@ package provider
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"github.com/pulumi/pulumi-docker-build/provider/internal"
"github.com/pulumi/pulumi-docker-build/provider/internal/deprecated"
gp "github.com/pulumi/pulumi-go-provider" gp "github.com/pulumi/pulumi-go-provider"
"github.com/pulumi/pulumi/pkg/v3/codegen/schema" "github.com/pulumi/pulumi/pkg/v3/codegen/schema"
"github.com/pulumi/pulumi/pkg/v3/resource/provider" "github.com/pulumi/pulumi/pkg/v3/resource/provider"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin"
rpc "github.com/pulumi/pulumi/sdk/v3/proto/go" rpc "github.com/pulumi/pulumi/sdk/v3/proto/go"
"github.com/pulumi/pulumi-docker-build/provider/internal"
"github.com/pulumi/pulumi-docker-build/provider/internal/deprecated"
) )
// Version is initialized by the Go linker to contain the semver of this build. // Version is initialized by the Go linker to contain the semver of this build.
@@ -41,11 +40,7 @@ func Serve() error {
// New creates a new provider. // New creates a new provider.
func New(host *provider.HostClient) (rpc.ResourceProviderServer, error) { func New(host *provider.HostClient) (rpc.ResourceProviderServer, error) {
server, err := gp.RawServer(Name, Version, internal.NewBuildxProvider())(host) return gp.RawServer(Name, Version, configurableProvider(internal.NewBuildxProvider()))(host)
if err != nil {
return nil, fmt.Errorf("building raw server: %w", err)
}
return &configurableProvider{ResourceProviderServer: server}, nil
} }
// configurableProvider is a workaround for // configurableProvider is a workaround for
@@ -56,35 +51,26 @@ func New(host *provider.HostClient) (rpc.ResourceProviderServer, error) {
// //
// If you find yourself in a position where you need to copy this -- STOP! // If you find yourself in a position where you need to copy this -- STOP!
// https://github.com/pulumi/pulumi/pull/15032 should be merged with this fix. // https://github.com/pulumi/pulumi/pull/15032 should be merged with this fix.
type configurableProvider struct { func configurableProvider(p gp.Provider) gp.Provider {
rpc.ResourceProviderServer configure := p.Configure
}
func (p configurableProvider) Configure( p.Configure = func(ctx context.Context, req gp.ConfigureRequest) error {
ctx context.Context, r, err := p.GetSchema(ctx, gp.GetSchemaRequest{Version: 0})
request *rpc.ConfigureRequest, if err != nil {
) (*rpc.ConfigureResponse, error) { return err
r, err := p.GetSchema(ctx, &rpc.GetSchemaRequest{Version: 0}) }
if err != nil { spec := schema.PackageSpec{}
return nil, err err = json.Unmarshal([]byte(r.Schema), &spec)
} if err != nil {
spec := schema.PackageSpec{} return err
err = json.Unmarshal([]byte(r.Schema), &spec) }
if err != nil {
return nil, err ce := deprecated.New(spec.Config)
if props, err := ce.UnmarshalProperties(req.Args); err == nil {
req.Args = props
}
return configure(ctx, req)
} }
ce := deprecated.New(spec.Config) return p
buildxReq := request
if props, err := ce.UnmarshalProperties(request.Args); err == nil {
args, _ := plugin.MarshalProperties(props, plugin.MarshalOptions{
Label: "config",
KeepUnknowns: true,
SkipNulls: true,
KeepSecrets: true,
RejectAssets: true,
})
buildxReq.Args = args
}
return p.ResourceProviderServer.Configure(ctx, buildxReq)
} }