-
Notifications
You must be signed in to change notification settings - Fork 0
/
victor.go
132 lines (117 loc) · 2.81 KB
/
victor.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
package victor
import (
"context"
"io"
"strings"
"github.com/pkg/errors"
"github.com/pulumi/pulumi/sdk/v3/go/auto"
"github.com/pulumi/pulumi/sdk/v3/go/auto/optup"
"go.uber.org/multierr"
"go.uber.org/zap"
)
type VictorArgs struct {
Verbose bool
Version string
Statefile string
Username *string
Password *string
Passphrase string
Context string
Server *string
Resources []string
Configuration []string
Outputs *string
}
func Victor(ctx context.Context, args *VictorArgs) error {
if args == nil {
args = &VictorArgs{
Verbose: false,
}
}
logger := Log()
// Build Victor's client
client := NewClient(args.Version, args.Verbose, args.Username, args.Password)
// Create the workspace
if args.Verbose {
logger.Info("creating the local workspace")
}
ws, err := auto.NewLocalWorkspace(ctx,
auto.WorkDir(args.Context),
auto.EnvVars(map[string]string{
"PULUMI_CONFIG_PASSPHRASE": args.Passphrase,
}),
)
if err != nil {
return errors.Wrap(err, "creating the local workspace")
}
// Install resources
var merr error
for _, res := range args.Resources {
name, version, _ := strings.Cut(res, " ")
if args.Server == nil {
merr = multierr.Append(merr, ws.InstallPlugin(ctx, name, version))
continue
}
merr = multierr.Append(merr, ws.InstallPluginFromServer(ctx, name, version, *args.Server))
}
if merr != nil {
return errors.Wrap(merr, "pulumi resources install, failing fast")
}
// Get stack
if args.Verbose {
logger.Info("getting the stack")
}
stack, err := GetStack(ctx, client, ws, args.Statefile, args.Verbose)
if err != nil {
return err
}
// Set stack configuration
for _, conf := range args.Configuration {
k, v, _ := strings.Cut(conf, " ")
merr = multierr.Append(merr, stack.SetConfig(ctx, k, auto.ConfigValue{
Value: v,
}))
}
if merr != nil {
return merr
}
// Refresh and update
upopts := []optup.Option{}
if args.Verbose {
logger.Info("refreshing and updating Pulumi stack")
zw := &ZapWriter{logger: logger}
upopts = append(upopts, optup.ProgressStreams(zw))
}
_, err = stack.Refresh(ctx)
if err != nil {
return errors.Wrap(err, "refreshing Pulumi stack")
}
res, err := stack.Up(ctx, upopts...)
if err != nil {
return errors.Wrap(err, "stack up")
}
// Export outputs
if args.Outputs != nil {
if err := ExportOutputs(res.Outputs, *args.Outputs); err != nil {
logger.Error("exporting outputs",
zap.Error(err),
)
}
}
// Export stack
if args.Verbose {
logger.Info("pushing the stack")
}
return PushStack(ctx, client, stack, args.Statefile)
}
type ZapWriter struct {
logger *zap.Logger
}
var _ io.Writer = (*ZapWriter)(nil)
func (zw *ZapWriter) Write(p []byte) (n int, err error) {
msg := string(p)
zw.logger.Info("pulumi output",
zap.String("msg", msg),
)
return len(p), nil
}