From 5f8951c4dc80fda76d1dbfd5b0b493441eb9b822 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Mon, 16 Dec 2019 09:57:54 -0800 Subject: [PATCH] Serialize resource states the right way (#3574) --- pkg/backend/display/display.go | 4 ++++ pkg/backend/display/events.go | 26 +++++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/pkg/backend/display/display.go b/pkg/backend/display/display.go index 7cb9d6dfb..44cc319f8 100644 --- a/pkg/backend/display/display.go +++ b/pkg/backend/display/display.go @@ -19,6 +19,7 @@ import ( "fmt" "io" "os" + "time" "github.com/pulumi/pulumi/pkg/apitype" "github.com/pulumi/pulumi/pkg/engine" @@ -77,12 +78,15 @@ func startEventLogger(events <-chan engine.Event, done chan<- bool, path string) contract.IgnoreError(logFile.Close()) }() + sequence := 0 encoder := json.NewEncoder(logFile) logEvent := func(e engine.Event) error { apiEvent, err := ConvertEngineEvent(e) if err != nil { return err } + apiEvent.Sequence, sequence = sequence, sequence+1 + apiEvent.Timestamp = int(time.Now().Unix()) return encoder.Encode(apiEvent) } diff --git a/pkg/backend/display/events.go b/pkg/backend/display/events.go index 5d675a58f..fffb37ef0 100644 --- a/pkg/backend/display/events.go +++ b/pkg/backend/display/events.go @@ -4,13 +4,18 @@ import ( "github.com/pkg/errors" "github.com/pulumi/pulumi/pkg/apitype" "github.com/pulumi/pulumi/pkg/engine" + "github.com/pulumi/pulumi/pkg/resource/config" "github.com/pulumi/pulumi/pkg/resource/plugin" + "github.com/pulumi/pulumi/pkg/resource/stack" "github.com/pulumi/pulumi/pkg/util/contract" ) -// convertEngineEvent converts a raw engine.Event into an apitype.EngineEvent used in the Pulumi +// ConvertEngineEvent converts a raw engine.Event into an apitype.EngineEvent used in the Pulumi // REST API. Returns an error if the engine event is unknown or not in an expected format. // EngineEvent.{ Sequence, Timestamp } are expected to be set by the caller. +// +// IMPORTANT: Any resource secret data stored in the engine event will be encrypted using the +// blinding encrypter, and unrecoverable. So this operation is inherently lossy. func ConvertEngineEvent(e engine.Event) (apitype.EngineEvent, error) { var apiEvent apitype.EngineEvent @@ -182,19 +187,22 @@ func convertStepEventMetadata(md engine.StepEventMetadata) apitype.StepEventMeta } } +// convertStepEventStateMetadata converts the internal StepEventStateMetadata to the API type +// we send over the wire. +// +// IMPORTANT: Any secret values are encrypted using the blinding encrypter. So any secret data +// in the resource state will be lost and unrecoverable. func convertStepEventStateMetadata(md *engine.StepEventStateMetadata) *apitype.StepEventStateMetadata { if md == nil { return nil } - inputs := make(map[string]interface{}) - for k, v := range md.Inputs { - inputs[string(k)] = v - } - outputs := make(map[string]interface{}) - for k, v := range md.Outputs { - outputs[string(k)] = v - } + encrypter := config.BlindingCrypter + inputs, err := stack.SerializeProperties(md.Inputs, encrypter) + contract.IgnoreError(err) + + outputs, err := stack.SerializeProperties(md.Outputs, encrypter) + contract.IgnoreError(err) return &apitype.StepEventStateMetadata{ Type: string(md.Type),