The two more strongly-typed Pulumi SDKs curently fail with an error during unmarshaling when attempting to marshal a value that is not an asset into an asset-typed location (e.g. an asset-typed resource output property). While this behavior is reasonable on its face, it gives rise to practical challenges when dealing with TF-provider-backed resources that have asset-typed properties. When such a resource is refreshed, the values of its asset-typed properties are replaced with non-asset values, as the TF bridge can't currently create a resonable stand-in asset value. For example, consider an S3 bucket object: ``` import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; const bucket = new aws.s3.Bucket("my-bucket"); new aws.s3.BucketObject("my-object", { source: new pulumi.FileAsset("some/file"), }); ``` Upon creation, the value of the input property `source` will be a file asset backed by the path `some/file`. The bridge will propagate this value to the `source` output property; this propagation is safe because the resource was just created and so the output property must have the value that was passed by the program. Now, let some actor apply out-of-band changes to the contents of the bucket object s.t. the `source` property changes when the object is refreshed. In that case, the `source` property will be a string value which the bridge is unable to interpret as an asset. The next time the Pulumi program is run, the Go or .NET SDK will attempt to deserialize the string into an asset-typed property and will fail. With these changes, the deserialization would not fail, and would instead create an asset or archive value that will fail to marshal if passed to another resource. Users can avoid these errors by not passing asset or archive outputs to other resources/stack outputs. These changes unblock users who are hitting https://github.com/pulumi/pulumi-aws/issues/1521.
64 lines
2 KiB
C#
64 lines
2 KiB
C#
// Copyright 2016-2019, Pulumi Corporation
|
|
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using Pulumi.Serialization;
|
|
|
|
namespace Pulumi
|
|
{
|
|
/// <summary>
|
|
/// An Archive represents a collection of named assets.
|
|
/// </summary>
|
|
public abstract class Archive : AssetOrArchive
|
|
{
|
|
private protected Archive(string propName, object value)
|
|
: base(Constants.SpecialArchiveSig, propName, value)
|
|
{
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// An AssetArchive is an archive created from an in-memory collection of named assets or other
|
|
/// archives.
|
|
/// </summary>
|
|
public sealed class AssetArchive : Archive
|
|
{
|
|
public AssetArchive(IDictionary<string, AssetOrArchive> assets)
|
|
: base(Constants.ArchiveAssetsName, assets.ToImmutableDictionary())
|
|
{
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A FileArchive is a file-based archive, or a collection of file-based assets. This can be a
|
|
/// raw directory or a single archive file in one of the supported formats(.tar, .tar.gz,
|
|
/// or.zip).
|
|
/// </summary>
|
|
public sealed class FileArchive : Archive
|
|
{
|
|
public FileArchive(string path) : base(Constants.AssetOrArchivePathName, path)
|
|
{
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A RemoteArchive is a file-based archive fetched from a remote location. The URI's scheme
|
|
/// dictates the protocol for fetching the archive's contents: <c>file://</c> is a local file
|
|
/// (just like a FileArchive), <c>http://</c> and <c>https://</c> specify HTTP and HTTPS,
|
|
/// respectively, and specific providers may recognize custom schemes.
|
|
/// </summary>
|
|
public sealed class RemoteArchive : Archive
|
|
{
|
|
public RemoteArchive(string uri) : base(Constants.AssetOrArchiveUriName, uri)
|
|
{
|
|
}
|
|
}
|
|
|
|
sealed class InvalidArchive : Archive
|
|
{
|
|
public InvalidArchive() : base(Constants.ArchiveAssetsName, ImmutableDictionary<string, AssetOrArchive>.Empty)
|
|
{
|
|
}
|
|
}
|
|
}
|