Example suggestion for config middleware
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user