/
stack_reference.go
199 lines (175 loc) 路 5.81 KB
/
stack_reference.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package pulumi
import (
"fmt"
"reflect"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
)
// StackReference manages a reference to a Pulumi stack.
type StackReference struct {
CustomResourceState
// Name is in the form "Org/Program/Stack"
Name StringOutput `pulumi:"name"`
// Outputs resolves with exports from the named stack
Outputs MapOutput `pulumi:"outputs"`
// ctx is a reference to the context used to create the stack reference. It must be
// valid and non-nil to call `GetOutput`.
ctx *Context
}
// GetOutput returns a stack output keyed by the given name as an AnyOutput
// If the given name is not present in the StackReference, Output<nil> is returned.
func (s *StackReference) GetOutput(name StringInput) AnyOutput {
return All(name, s.rawOutputs).
ApplyT(func(args []interface{}) (interface{}, error) {
n, stack := args[0].(string), args[1].(resource.PropertyMap)
if !stack["outputs"].IsObject() {
return Any(nil), fmt.Errorf("failed to convert %T to object", stack)
}
outs := stack["outputs"].ObjectValue()
v, ok := outs[resource.PropertyKey(n)]
if !ok {
if s.ctx.DryRun() {
// It is a dry run, so it is safe to return an unknown output.
return UnsafeUnknownOutput([]Resource{s}), nil
}
// We don't return an error to remain consistent with other SDKs regarding missing keys.
return nil, nil
}
ret, secret, _ := unmarshalPropertyValue(s.ctx, v)
if secret {
ret = ToSecret(ret)
}
return ret, nil
}).(AnyOutput)
}
// StackReferenceOutputDetails holds a stack output value.
// At most one of the Value and SecretValue fields will be set.
//
// You can build a StackReferenceOutputDetails with
// the [StackReference.GetOutputDetails] method.
type StackReferenceOutputDetails struct {
// Output value returned by the StackReference.
// This field is nil if the value is a secret
// or it does not exist.
Value interface{}
// Secret output value returned by the StackReference.
// This field is nil if the value is not a secret
// or it does not exist.
SecretValue interface{}
}
// GetOutputDetails retrieves a stack output keyed by the given name
// and returns the value inside a [StackReferenceOutputDetails] object.
//
// It sets the Value or the SecretValue fields of StackReferenceOutputDetails
// depending on whether the stack output is a secret.
// If the given name is not present in the StackReference,
// both fields are nil.
func (s *StackReference) GetOutputDetails(name string) (*StackReferenceOutputDetails, error) {
value, _, secret, _, err := awaitWithContext(s.ctx.Context(), s.GetOutput(String(name)))
if err != nil {
return nil, err
}
var d StackReferenceOutputDetails
if secret {
d.SecretValue = value
} else {
d.Value = value
}
return &d, nil
}
// GetStringOutput returns a stack output keyed by the given name as an StringOutput
func (s *StackReference) GetStringOutput(name StringInput) StringOutput {
return All(name, s.GetOutput(name)).ApplyT(func(args []interface{}) (string, error) {
name, out := args[0].(string), args[1]
if out == nil {
return "", fmt.Errorf(
"stack reference output %q does not exist on stack %q",
name,
s.name)
}
str, ok := out.(string)
if !ok {
return "", fmt.Errorf(
"getting stack reference output %q on stack %q, failed to convert %T to string",
name,
s.name,
out)
}
return str, nil
}).(StringOutput)
}
// GetIDOutput returns a stack output keyed by the given name as an IDOutput
func (s *StackReference) GetIDOutput(name StringInput) IDOutput {
return s.GetStringOutput(name).ApplyT(func(out string) ID {
return ID(out)
}).(IDOutput)
}
// GetFloat64Output returns a stack output keyed by the given name as an Float64Output
func (s *StackReference) GetFloat64Output(name StringInput) Float64Output {
return All(name, s.GetOutput(name)).ApplyT(func(args []interface{}) (float64, error) {
name, out := args[0].(string), args[1]
if out == nil {
return 0.0, fmt.Errorf(
"stack reference output %q does not exist on stack %q",
name,
s.name)
}
numf, ok := out.(float64)
if !ok {
return 0.0, fmt.Errorf(
"getting stack reference output %q on stack %q, failed to convert %T to float64",
name,
s.name,
out)
}
return numf, nil
}).(Float64Output)
}
// GetIntOutput returns a stack output keyed by the given name as an IntOutput
func (s *StackReference) GetIntOutput(name StringInput) IntOutput {
return All(name, s.GetOutput(name)).ApplyT(func(args []interface{}) (int, error) {
name, out := args[0].(string), args[1]
if out == nil {
return 0, fmt.Errorf(
"stack reference output %q does not exist on stack %q",
name,
s.name)
}
numf, ok := out.(float64)
if !ok {
return 0, fmt.Errorf(
"getting stack reference output %q on stack %q, failed to convert %T to int",
name,
s.name,
out)
}
return int(numf), nil
}).(IntOutput)
}
type stackReferenceArgs struct {
Name string `pulumi:"name"`
}
// StackReferenceArgs is the input to NewStackReference that allows specifying a stack name
type StackReferenceArgs struct {
// Name is in the form "Org/Program/Stack"
Name StringInput
}
func (StackReferenceArgs) ElementType() reflect.Type {
return reflect.TypeOf((*stackReferenceArgs)(nil)).Elem()
}
// NewStackReference creates a stack reference that makes available outputs from the specified stack
func NewStackReference(ctx *Context, name string, args *StackReferenceArgs,
opts ...ResourceOption,
) (*StackReference, error) {
if args == nil {
args = &StackReferenceArgs{}
}
if args.Name == nil {
args.Name = StringInput(String(name))
}
id := args.Name.ToStringOutput().ApplyT(func(s string) ID { return ID(s) }).(IDOutput)
ref := StackReference{ctx: ctx}
if err := ctx.ReadResource("pulumi:pulumi:StackReference", name, id, args, &ref, opts...); err != nil {
return nil, err
}
return &ref, nil
}