Introduce MarshalOptions.{RejectAsset, RejectArchive}

Not all resource providers support Pulumi's Asset and Archive types. In
particular, the Kubernetes provider should reject any resource
definition that contains either of these types.

This commit will introduce two MarshalOptions that will make it easy for
the Kubernetes provider to guarantee that no properties of this type are
in a resource request, as it's deserializing the request from the
engine.
This commit is contained in:
Alex Clemmer 2019-08-24 12:27:39 -07:00
parent 5188232afa
commit 99d70e4610
3 changed files with 53 additions and 0 deletions

View file

@ -7,6 +7,8 @@ CHANGELOG
- Fix a crash when using StackReference from the `1.0.0-beta.3` version of
`@pulumi/pulumi` and `1.0.0-beta.2` or earlier of the CLI.
- Allow Un/MashalProperties to reject Asset and AssetArchive types. (partial fix
for https://github.com/pulumi/pulumi-kubernetes/issues/737)
## 1.0.0-beta.3 (2019-08-21)

View file

@ -35,6 +35,7 @@ type MarshalOptions struct {
ElideAssetContents bool // true if we are eliding the contents of assets.
ComputeAssetHashes bool // true if we are computing missing asset hashes on the fly.
KeepSecrets bool // true if we are keeping secrets (otherwise we replace them with their underlying value).
RejectAssets bool // true if we should return errors on Asset and Archive values.
}
const (
@ -118,8 +119,14 @@ func MarshalPropertyValue(v resource.PropertyValue, opts MarshalOptions) (*struc
},
}, nil
} else if v.IsAsset() {
if opts.RejectAssets {
return nil, errors.New("unexpected Asset property value")
}
return MarshalAsset(v.AssetValue(), opts)
} else if v.IsArchive() {
if opts.RejectAssets {
return nil, errors.New("unexpected Asset Archive property value")
}
return MarshalArchive(v.ArchiveValue(), opts)
} else if v.IsObject() {
obj, err := MarshalProperties(v.ObjectValue(), opts)
@ -287,6 +294,9 @@ func UnmarshalPropertyValue(v *structpb.Value, opts MarshalOptions) (*resource.P
switch sig {
case resource.AssetSig:
if opts.RejectAssets {
return nil, errors.New("unexpected Asset property value")
}
asset, isasset, err := resource.DeserializeAsset(objmap)
if err != nil {
return nil, err
@ -302,6 +312,9 @@ func UnmarshalPropertyValue(v *structpb.Value, opts MarshalOptions) (*resource.P
m := resource.NewAssetProperty(asset)
return &m, nil
case resource.ArchiveSig:
if opts.RejectAssets {
return nil, errors.New("unexpected Asset Archive property value")
}
archive, isarchive, err := resource.DeserializeArchive(objmap)
if err != nil {
return nil, err

View file

@ -185,6 +185,44 @@ func TestComputedReject(t *testing.T) {
}
}
func TestAssetReject(t *testing.T) {
// Ensure that asset and archive properties produce errors when RejectAssets == true.
opts := MarshalOptions{RejectAssets: true}
text := "a test asset"
asset, err := resource.NewTextAsset(text)
assert.Nil(t, err)
{
assetProps, err := MarshalPropertyValue(resource.NewAssetProperty(asset), opts)
assert.NotNil(t, err)
assert.Nil(t, assetProps)
}
{
assetProps, err := MarshalPropertyValue(resource.NewAssetProperty(asset), MarshalOptions{})
assert.Nil(t, err)
assetPropU, err := UnmarshalPropertyValue(assetProps, opts)
assert.NotNil(t, err)
assert.Nil(t, assetPropU)
}
arch, err := resource.NewAssetArchive(map[string]interface{}{"foo": asset})
assert.Nil(t, err)
{
archProps, err := MarshalPropertyValue(resource.NewArchiveProperty(arch), opts)
assert.NotNil(t, err)
assert.Nil(t, archProps)
}
{
archProps, err := MarshalPropertyValue(resource.NewArchiveProperty(arch), MarshalOptions{})
assert.Nil(t, err)
archValue, err := UnmarshalPropertyValue(archProps, opts)
assert.NotNil(t, err)
assert.Nil(t, archValue)
}
}
func TestUnsupportedSecret(t *testing.T) {
rawProp := resource.NewObjectProperty(resource.NewPropertyMapFromMap(map[string]interface{}{
resource.SigKey: resource.SecretSig,