property

package
v3.199.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 1, 2025 License: Apache-2.0 Imports: 6 Imported by: 17

README

Property Values

The Pulumi value system (formerly resource.PropertyValue).

property.Value

Normalization

property.Value, property.Map and property.Array are all normalized by construction, which means that you can't construct 2 values with the same semantic meaning but a different memory representation. Let's look at a couple of examples to understand what this means:

Null Values

property.New will always return a null value when given an input that compares as equal to nil. These all result in the same value in memory:

property.New(([]property.Value)(nil))
property.New((map[string]property.Value)(nil))
property.New(property.Null)
property.Value{}

That means that you can safely use these with reflect.DeepEquals and assert.Equal.

Empty Maps and Empty Arrays

In Pulumi's type system, there are empty maps and empty arrays, distinct from null values.

For maps, we have:

property.New(map[string]property.Value{})
property.New(property.Map{})

Constructing a non-empty map and then deleting the inner element will have the same result. This will return true:

reflect.DeepEquals(
    property.NewMap(map[string]property.Value{
        "a": property.Value{},
    }).Delete("a"),
    property.Map{},
)

For arrays, we have:

property.New([]property.Value{})
property.New(property.Array{})
Markers

Any property.Value can have 2 kinds of markers: secretness and resource dependencies.

It never matters how these are applied, only what's there. These values are the same:

property.New("a string").
    WithSecret(true).
    WithDependencies([]urn.URN{urn2, urn1, urn2})

property.WithGoValue(
    property.New(property.Null).
        WithDependencies([]urn.URN{urn1, urn2}).
        WithSecret(true),
    "a string",
)

Relationship to Pulumi's Protobuf Wire Format

property.Value represents the semantics of properties sent over the wire. It does not attempt to faithfully replicate the wire format. This means that a parsing function func(*struct.Struct) property.Value will be surjective relation from *struct.Struct (Pulumi's wire format for property values) to property.Value. The function cannot be injective, since it intentionally unifies elements with equivalent semantics. For example, consider the following wire values, all of which represent the secret number 42:

{
    "4dabf18193072939515e22adb298388d": "1b47061264138c4ac30d75fd1eb44270", # Mark as a secret value
    "plaintext": {
        "4dabf18193072939515e22adb298388d": "d0e6a833031e9bbcd3f4e8bde6ca49a4", # Mark as an output value
        "value": 42
    }
}
{
    "4dabf18193072939515e22adb298388d": "d0e6a833031e9bbcd3f4e8bde6ca49a4", # Mark as an output value
    "secret": true,
    "value": 42
}
{
    "4dabf18193072939515e22adb298388d": "1b47061264138c4ac30d75fd1eb44270", # Mark as a secret value
    "plaintext": 42
}

Because there isn't a semantic difference between them, property.Value will represent all 3 values in the same way:

property.New(42.0).WithSecret(true)

The goal here is to make life easier for both provider authors and engine maintainers by lifting the value space above what the wire can represent. This does mean that you cannot roundtrip the wire format through property.Value. Given the above example, property.New(42.0).WithSecret(true) would be converted into it's "canonical" wire format representation:

{
    "4dabf18193072939515e22adb298388d": "1b47061264138c4ac30d75fd1eb44270", # Mark this as secret
    "plaintext": 42
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// Mark a property as an untyped computed value.
	//
	//	value := property.New(property.Computed)
	Computed computed
	// Mark a property as an untyped null value.
	//
	//	value := property.New(property.Null)
	//
	// [Value]s can be null, and a null value *is not* equivalent to the absence of a
	// value.
	Null null
)

Computed and Null are marker values of distinct singleton types.

Because the type of the variable is a singleton, it is not possible to mutate these values (there is no other value to mutate to).

Functions

func EqualRelaxComputed

func EqualRelaxComputed(opts *eqOpts)

See the doc comment for Value.Equals for the effect of EqualRelaxComputed.

Types

type Archive

type Archive = *archive.Archive

type Array

type Array struct {
	// contains filtered or unexported fields
}

An immutable Array of [Value]s.

An Array is not itself a Value, but it can be cheaply converted into a Value with New.

func NewArray added in v3.161.0

func NewArray(slice []Value) Array

NewArray creates a new Array from a slice of [Value]s. It is the inverse of Array.AsSlice.

func (Array) All added in v3.161.0

func (a Array) All(yield func(int, Value) bool)

All calls yield for each element of the list.

If yield returns false, then the iteration terminates.

arr := property.NewArray([]property.Value{
	property.New(1),
	property.New(2),
	property.New(3),
})

arr.All(func(i int, v Value) bool {
	fmt.Printf("Index: %d, value: %s\n", i, v)
	return true
})

With Go 1.23, you can use iterator syntax to access each element:

for i, v := range arr.All {
	fmt.Printf("Index: %d, value: %s\n", i, v)
}

func (Array) Append added in v3.161.0

func (a Array) Append(v ...Value) Array

Append a new value to the end of the Array.

func (Array) AsSlice added in v3.161.0

func (a Array) AsSlice() []Value

AsSlice copies the Array into a slice.

AsSlice will return nil for an empty slice.

func (Array) Get added in v3.161.0

func (a Array) Get(idx int) Value

Get the value from an Array at an index.

If idx is negative or if idx is greater then or equal to the length of the Array, then this function will panic.

func (Array) GoString added in v3.165.0

func (a Array) GoString() string

func (Array) Len added in v3.161.0

func (a Array) Len() int

The length of the Array.

type Asset

type Asset = *asset.Asset

type EqualOption

type EqualOption func(*eqOpts)

type GoValue

type GoValue interface {
	bool | float64 | string |
		Map | map[string]Value |
		Array | []Value |
		Asset | Archive |
		ResourceReference |
		computed | null // marker singletons
}

GoValue defines the set of go values that can be contained inside a Value.

Value can also be a null value.

type IndexSegment added in v3.161.0

type IndexSegment struct {
	// contains filtered or unexported fields
}

IndexSegment represents an index into an Array.

To create an IndexSegment, use NewSegment.

type KeySegment added in v3.161.0

type KeySegment struct {
	// contains filtered or unexported fields
}

KeySegment represents a traversal into a Map by a key.

KeySegment does not support glob ("*") expansion. Values are treated as is.

To create an KeySegment, use NewSegment.

type Map

type Map struct {
	// contains filtered or unexported fields
}

An immutable Map of [Value]s.

func NewMap added in v3.161.0

func NewMap(m map[string]Value) Map

NewMap creates a new map from m.

func (Map) All added in v3.161.0

func (m Map) All(yield func(string, Value) bool)

All calls yield for each key value pair in the Map. All iterates in random order, just like Go's native maps. For stable iteration order, use Map.AllStable.

If yield returns false, then the iteration terminates.

m := property.NewMap(map[]property.Value{
	"one": property.New(1),
	"two": property.New(2),
	"three": property.New(3),
})

m.All(func(k string, v Value) bool {
	fmt.Printf("Key: %s, value: %s\n", k, v)
	return true
})

With Go 1.23, you can use iterator syntax to access each element:

for k, v := range arr.All {
	fmt.Printf("Index: %s, value: %s\n", k, v)
}

func (Map) AllStable added in v3.161.0

func (m Map) AllStable(yield func(string, Value) bool)

AllStable calls yield for each key value pair in the Map in sorted key order.

For usage, see Map.All.

func (Map) AsMap added in v3.161.0

func (m Map) AsMap() map[string]Value

AsMap converts the Map into a native Go map from strings to [Values].

AsMap always returns a non-nil map.

func (Map) Delete added in v3.168.0

func (m Map) Delete(keys ...string) Map

Delete produces a new map identical to the receiver with given keys removed.

func (Map) Get added in v3.161.0

func (m Map) Get(key string) Value

Get retrieves the Value associated with key in the Map. If key is not in Map, then a Null value is returned.

To distinguish between a zero value and no value, use Map.GetOk.

func (Map) GetOk added in v3.161.0

func (m Map) GetOk(key string) (Value, bool)

func (Map) GoString added in v3.165.0

func (a Map) GoString() string

func (Map) Len added in v3.161.0

func (m Map) Len() int

The number of elements in the Map.

func (Map) Set added in v3.161.0

func (m Map) Set(key string, value Value) Map

Set produces a new map identical to the receiver with key mapped to value.

Set does not mutate it's receiver.

type Path added in v3.161.0

type Path []PathSegment

Path provides access and alteration methods on [Value]s.

Paths are composed of [PathSegment]s, which can be one of:

- KeySegment: For indexing into [Map]s. - IndexSegment: For indexing into [Array]s.

func (Path) Alter added in v3.161.0

func (p Path) Alter(v Value, f func(v Value) Value) (Value, error)

Alter changes the value at p by applying f.

To preserve metadata, use WithGoValue in conjunction with Alter:

p.Alter(v, func(v Value) Value) {
	return property.WithGoValue(v, "new-value")
})

This will preserve any secrets or dependencies encoded in `v`.

Any returned error will implement PathApplyFailure.

func (Path) Get added in v3.161.0

func (p Path) Get(v Value) (Value, error)

Get the Value from v by applying the Path.

value := property.New(map[string]property.Value{
	"cities": property.New([]property.Value{
		property.New("Seattle"),
		property.New("London"),
	}),
})

firstCity := property.Path{
	property.NewSegment("cities"),
	property.NewSegment(0),
}

city, _ := firstCity.Get(value) // Seattle

If the Path does not describe a value in v, then an error will be returned. The returned error can be safely cast to PathApplyFailure.

func (Path) Set added in v3.161.0

func (p Path) Set(src, newValue Value) (Value, error)

Set the value described by the path in src to newValue.

Set does not mutate src, instead a copy of src with the change applied is returned. is returned that holds the change.

Any returned error will implement PathApplyFailure.

type PathApplyFailure added in v3.161.0

type PathApplyFailure interface {
	error

	// The last value in a path traversal successfully reached.
	Found() Value
}

type PathSegment added in v3.161.0

type PathSegment interface {
	// contains filtered or unexported methods
}

func NewSegment added in v3.161.0

func NewSegment[T interface{ string | int }](v T) PathSegment

NewSegment creates a new PathSegment suitable for use in Path.

type ResourceReference

type ResourceReference struct {
	URN            urn.URN
	ID             Value
	PackageVersion string
}

ResourceReference is a property value that represents a reference to a Resource. The reference captures the resource's URN, ID, and the version of its containing package. Note that there are several cases to consider with respect to the ID:

  • The reference may not contain an ID if the referenced resource is a component resource. In this case, the ID will be Null.
  • The ID may be unknown (in which case it will be the Computed property value)
  • Otherwise, the ID must be a string.

func (ResourceReference) Equal

func (ref ResourceReference) Equal(other ResourceReference) bool

func (ResourceReference) IDString

func (ref ResourceReference) IDString() (value string, hasID bool)

type Value

type Value struct {
	// contains filtered or unexported fields
}

Value is an imitable representation of a Pulumi property value. To create a new Value from a typed Go value, see New. To create a new Value from an untyped any value, see Any.

It may represent any type in GoValue, included the Computed value. In addition, values may be secret and/or have resource dependencies.

The zero value of Value is null, and is valid for use.

func Any

func Any(goValue any) (Value, error)

Any creates a new Value from a GoValue of unknown type. An error is returned if goValue is not a member of GoValue.

func New

func New[T GoValue](goValue T) Value

New creates a new Value from a GoValue.

To create a new value from an unknown type, use Any.

func WithGoValue

func WithGoValue[T GoValue](value Value, newGoValue T) Value

WithGoValue creates a new Value with the inner value newGoValue.

To set a Value to a null or computed value, pass Null or Computed as the new value.

func (Value) AsArchive

func (v Value) AsArchive() Archive

func (Value) AsArray

func (v Value) AsArray() Array

func (Value) AsAsset

func (v Value) AsAsset() Asset

func (Value) AsBool

func (v Value) AsBool() bool

func (Value) AsMap

func (v Value) AsMap() Map

func (Value) AsNumber

func (v Value) AsNumber() float64

func (Value) AsResourceReference

func (v Value) AsResourceReference() ResourceReference

func (Value) AsString

func (v Value) AsString() string

func (Value) Dependencies

func (v Value) Dependencies() []urn.URN

Dependencies returns the dependency set of v.

To set the dependencies of a value, use Value.WithDependencies.

func (Value) Equals

func (v Value) Equals(other Value, opts ...EqualOption) bool

Check if two Values are equal.

There are two corner cases that need to be called out here:

  • Secret equality is enforced. That means that:

    {"a", secret: false} == {"a", secret: false}

    {"a", secret: true} != {"a", secret: false}

    {"b", secret: false} != {"c", secret: false}

  • Computed value equality has two different modes. By default, it works like Null equality: a.IsComputed() => (a.Equals(b) <=> b.IsComputed()) (up to secrets and dependencies).

    If EqualRelaxComputed is passed, then computed values are considered equal to all other values. (up to secrets and dependencies)

func (Value) GoString added in v3.165.0

func (v Value) GoString() string

func (Value) HasComputed

func (v Value) HasComputed() bool

HasComputed returns true if the Value or any nested Value is computed.

To check if the receiver is itself computed, use Value.IsComputed.

func (Value) HasSecrets

func (v Value) HasSecrets() bool

HasSecrets returns true if the Value or any nested Value is secret.

func (Value) IsArchive

func (v Value) IsArchive() bool

func (Value) IsArray

func (v Value) IsArray() bool

func (Value) IsAsset

func (v Value) IsAsset() bool

func (Value) IsBool

func (v Value) IsBool() bool

func (Value) IsComputed

func (v Value) IsComputed() bool

func (Value) IsMap

func (v Value) IsMap() bool

func (Value) IsNull

func (v Value) IsNull() bool

func (Value) IsNumber

func (v Value) IsNumber() bool

func (Value) IsResourceReference

func (v Value) IsResourceReference() bool

func (Value) IsString

func (v Value) IsString() bool

func (Value) Secret

func (v Value) Secret() bool

Secret returns true if the Value is secret.

It does not check if there are nested values that are secret. To recursively check if the Value contains a secret, use Value.HasSecrets.

func (Value) WithDependencies

func (v Value) WithDependencies(dependencies []urn.URN) Value

WithDependencies returns a new value identical to the receiver, except that it has as it's dependencies the passed in value.

func (Value) WithSecret

func (v Value) WithSecret(isSecret bool) Value

WithSecret produces a new Value identical to it's receiver except that it's secret market is set to isSecret.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL