2019-04-20 20:34:58 +00:00
|
|
|
// Copyright 2016-2018, Pulumi Corporation.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package display
|
|
|
|
|
|
|
|
import (
|
Lift context parameter to SerializeDeployment/Resource/Operations/Properties (#15929)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
SerializePropertyValue needed a `context.Context` object to pass to the
`config.Encrypter`. It was using `context.TODO()`, this change instead
accepts a context on the parameters and lifts that up to
SerializeProperties, SerializeResource, SerializeOperation, and
SerializeDeployment.
There were a few call sites for those methods that already had a context
on hand, and they now pass that context. The other calls sites now use
`context.TODO()`, we should continue to iterate in this area to ensure
everywhere that needs a context has one passed in.
## Checklist
- [x] I have run `make tidy` to update any new dependencies
- [x] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-04-15 07:45:46 +00:00
|
|
|
"context"
|
2019-04-20 20:34:58 +00:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2021-10-26 23:21:27 +00:00
|
|
|
"os"
|
2019-04-20 20:34:58 +00:00
|
|
|
|
2023-09-18 11:01:28 +00:00
|
|
|
"github.com/pulumi/pulumi/pkg/v3/display"
|
2021-03-17 13:20:05 +00:00
|
|
|
"github.com/pulumi/pulumi/pkg/v3/engine"
|
|
|
|
"github.com/pulumi/pulumi/pkg/v3/resource/stack"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/diag"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/diag/colors"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/config"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/util/logging"
|
2019-04-20 20:34:58 +00:00
|
|
|
)
|
|
|
|
|
2019-05-10 05:19:11 +00:00
|
|
|
// massagePropertyValue takes a property value and strips out the secrets annotations from it. If showSecrets is
|
|
|
|
// not true any secret values are replaced with "[secret]".
|
|
|
|
func massagePropertyValue(v resource.PropertyValue, showSecrets bool) resource.PropertyValue {
|
|
|
|
switch {
|
|
|
|
case v.IsArray():
|
|
|
|
new := make([]resource.PropertyValue, len(v.ArrayValue()))
|
|
|
|
for i, e := range v.ArrayValue() {
|
|
|
|
new[i] = massagePropertyValue(e, showSecrets)
|
|
|
|
}
|
|
|
|
return resource.NewArrayProperty(new)
|
|
|
|
case v.IsObject():
|
|
|
|
new := make(resource.PropertyMap, len(v.ObjectValue()))
|
|
|
|
for k, e := range v.ObjectValue() {
|
|
|
|
new[k] = massagePropertyValue(e, showSecrets)
|
|
|
|
}
|
2019-05-10 21:25:34 +00:00
|
|
|
return resource.NewObjectProperty(new)
|
2019-05-10 05:19:11 +00:00
|
|
|
case v.IsSecret() && showSecrets:
|
|
|
|
return massagePropertyValue(v.SecretValue().Element, showSecrets)
|
|
|
|
case v.IsSecret():
|
|
|
|
return resource.NewStringProperty("[secret]")
|
|
|
|
default:
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MassageSecrets takes a property map and returns a new map by transforming each value with massagePropertyValue
|
|
|
|
// This allows us to serialize the resulting map using our existing serialization logic we use for deployments, to
|
|
|
|
// produce sane output for stackOutputs. If we did not do this, SecretValues would be serialized as objects
|
|
|
|
// with the signature key and value.
|
|
|
|
func MassageSecrets(m resource.PropertyMap, showSecrets bool) resource.PropertyMap {
|
|
|
|
new := make(resource.PropertyMap, len(m))
|
|
|
|
for k, e := range m {
|
|
|
|
new[k] = massagePropertyValue(e, showSecrets)
|
|
|
|
}
|
|
|
|
return new
|
|
|
|
}
|
|
|
|
|
2019-05-25 10:10:38 +00:00
|
|
|
// stateForJSONOutput prepares some resource's state for JSON output. This includes filtering the output based
|
|
|
|
// on the supplied options, in addition to massaging secret fields.
|
|
|
|
func stateForJSONOutput(s *resource.State, opts Options) *resource.State {
|
|
|
|
var inputs resource.PropertyMap
|
|
|
|
var outputs resource.PropertyMap
|
|
|
|
if !isRootURN(s.URN) || !opts.SuppressOutputs {
|
|
|
|
// For now, replace any secret properties as the string [secret] and then serialize what we have.
|
|
|
|
inputs = MassageSecrets(s.Inputs, false)
|
|
|
|
outputs = MassageSecrets(s.Outputs, false)
|
|
|
|
} else {
|
|
|
|
// If we're suppressing outputs, don't show the root stack properties.
|
|
|
|
inputs = resource.PropertyMap{}
|
|
|
|
outputs = resource.PropertyMap{}
|
|
|
|
}
|
|
|
|
|
|
|
|
return resource.NewState(s.Type, s.URN, s.Custom, s.Delete, s.ID, inputs,
|
|
|
|
outputs, s.Parent, s.Protect, s.External, s.Dependencies, s.InitErrors, s.Provider,
|
2022-03-24 19:08:18 +00:00
|
|
|
s.PropertyDependencies, s.PendingReplacement, s.AdditionalSecretOutputs, s.Aliases, &s.CustomTimeouts,
|
[engine] Add support for source positions
These changes add support for passing source position information in
gRPC metadata and recording the source position that corresponds to a
resource registration in the statefile.
Enabling source position information in the resource model can provide
substantial benefits, including but not limited to:
- Better errors from the Pulumi CLI
- Go-to-defintion for resources in state
- Editor integration for errors, etc. from `pulumi preview`
Source positions are (file, line) or (file, line, column) tuples
represented as URIs. The line and column are stored in the fragment
portion of the URI as "line(,column)?". The scheme of the URI and the
form of its path component depends on the context in which it is
generated or used:
- During an active update, the URI's scheme is `file` and paths are
absolute filesystem paths. This allows consumers to easily access
arbitrary files that are available on the host.
- In a statefile, the URI's scheme is `project` and paths are relative
to the project root. This allows consumers to resolve source positions
relative to the project file in different contexts irrespective of the
location of the project itself (e.g. given a project-relative path and
the URL of the project's root on GitHub, one can build a GitHub URL for
the source position).
During an update, source position information may be attached to gRPC
calls as "source-position" metadata. This allows arbitrary calls to be
associated with source positions without changes to their protobuf
payloads. Modifying the protobuf payloads is also a viable approach, but
is somewhat more invasive than attaching metadata, and requires changes
to every call signature.
Source positions should reflect the position in user code that initiated
a resource model operation (e.g. the source position passed with
`RegisterResource` for `pet` in the example above should be the source
position in `index.ts`, _not_ the source position in the Pulumi SDK). In
general, the Pulumi SDK should be able to infer the source position of
the resource registration, as the relationship between a resource
registration and its corresponding user code should be static per SDK.
Source positions in state files will be stored as a new `registeredAt`
property on each resource. This property is optional.
2023-06-29 18:41:19 +00:00
|
|
|
s.ImportID, s.RetainOnDelete, s.DeletedWith, s.Created, s.Modified, s.SourcePosition)
|
2019-05-10 05:19:11 +00:00
|
|
|
}
|
|
|
|
|
2021-10-26 23:21:27 +00:00
|
|
|
// ShowJSONEvents renders incremental engine events to stdout.
|
|
|
|
func ShowJSONEvents(events <-chan engine.Event, done chan<- bool, opts Options) {
|
|
|
|
// Ensure we close the done channel before exiting.
|
|
|
|
defer func() { close(done) }()
|
|
|
|
|
|
|
|
sequence := 0
|
|
|
|
encoder := json.NewEncoder(os.Stdout)
|
|
|
|
encoder.SetEscapeHTML(false)
|
|
|
|
for e := range events {
|
|
|
|
if err := logJSONEvent(encoder, e, opts, sequence); err != nil {
|
|
|
|
logging.V(7).Infof("failed to log event: %v", err)
|
|
|
|
}
|
|
|
|
sequence++
|
|
|
|
|
|
|
|
// In the event of cancellation, break out of the loop.
|
|
|
|
if e.Type == engine.CancelEvent {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ShowPreviewDigest renders engine events from a preview into a well-formed JSON document. Note that this does not
|
2019-04-20 20:34:58 +00:00
|
|
|
// emit events incrementally so that it can guarantee anything emitted to stdout is well-formed. This means that,
|
|
|
|
// if used interactively, the experience will lead to potentially very long pauses. If run in CI, it is up to the
|
|
|
|
// end user to ensure that output is periodically printed to prevent tools from thinking preview has hung.
|
2021-10-26 23:21:27 +00:00
|
|
|
func ShowPreviewDigest(events <-chan engine.Event, done chan<- bool, opts Options) {
|
2019-04-20 20:34:58 +00:00
|
|
|
// Ensure we close the done channel before exiting.
|
|
|
|
defer func() { close(done) }()
|
|
|
|
|
|
|
|
// Now loop and accumulate our digest until the event stream is closed, or we hit a cancellation.
|
2022-06-27 14:08:06 +00:00
|
|
|
var digest display.PreviewDigest
|
2019-04-20 20:34:58 +00:00
|
|
|
for e := range events {
|
2021-10-26 23:21:27 +00:00
|
|
|
// In the event of cancellation, break out of the loop immediately.
|
2019-04-20 20:34:58 +00:00
|
|
|
if e.Type == engine.CancelEvent {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
// For all other events, use the payload to build up the JSON digest we'll emit later.
|
|
|
|
switch e.Type {
|
turn on the golangci-lint exhaustive linter (#15028)
Turn on the golangci-lint exhaustive linter. This is the first step
towards catching more missing cases during development rather than
in tests, or in production.
This might be best reviewed commit-by-commit, as the first commit turns
on the linter with the `default-signifies-exhaustive: true` option set,
which requires a lot less changes in the current codebase.
I think it's probably worth doing the second commit as well, as that
will get us the real benefits, even though we end up with a little bit
more churn. However it means all the `switch` statements are covered,
which isn't the case after the first commit, since we do have a lot of
`default` statements that just call `assert.Fail`.
Fixes #14601
## Checklist
- [x] I have run `make tidy` to update any new dependencies
- [x] I have run `make lint` to verify my code passes the lint check
- [x] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-17 16:50:41 +00:00
|
|
|
case engine.CancelEvent:
|
|
|
|
// Pacify the linter here, this is already handled beforehand
|
2021-10-26 23:21:27 +00:00
|
|
|
// Events occurring early:
|
2019-04-20 20:34:58 +00:00
|
|
|
case engine.PreludeEvent:
|
|
|
|
// Capture the config map from the prelude. Note that all secrets will remain blinded for safety.
|
2020-07-17 06:52:31 +00:00
|
|
|
digest.Config = e.Payload().(engine.PreludeEventPayload).Config
|
2019-04-20 20:34:58 +00:00
|
|
|
|
|
|
|
// Events throughout the execution:
|
|
|
|
case engine.DiagEvent:
|
|
|
|
// Skip any ephemeral or debug messages, and elide all colorization.
|
2020-07-17 06:52:31 +00:00
|
|
|
p := e.Payload().(engine.DiagEventPayload)
|
2019-04-20 20:34:58 +00:00
|
|
|
if !p.Ephemeral && p.Severity != diag.Debug {
|
2022-06-27 14:08:06 +00:00
|
|
|
digest.Diagnostics = append(digest.Diagnostics, display.PreviewDiagnostic{
|
2019-04-20 20:34:58 +00:00
|
|
|
URN: p.URN,
|
|
|
|
Message: colors.Never.Colorize(p.Prefix + p.Message),
|
|
|
|
Severity: p.Severity,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
case engine.StdoutColorEvent:
|
|
|
|
// Append stdout events as informational messages, and elide all colorization.
|
2020-07-17 06:52:31 +00:00
|
|
|
p := e.Payload().(engine.StdoutEventPayload)
|
2022-06-27 14:08:06 +00:00
|
|
|
digest.Diagnostics = append(digest.Diagnostics, display.PreviewDiagnostic{
|
2019-04-20 20:34:58 +00:00
|
|
|
Message: colors.Never.Colorize(p.Message),
|
|
|
|
Severity: diag.Info,
|
|
|
|
})
|
|
|
|
case engine.ResourcePreEvent:
|
|
|
|
// Create the detailed metadata for this step and the initial state of its resource. Later,
|
|
|
|
// if new outputs arrive, we'll search for and swap in those new values.
|
2020-07-17 06:52:31 +00:00
|
|
|
if m := e.Payload().(engine.ResourcePreEventPayload).Metadata; shouldShow(m, opts) || isRootStack(m) {
|
2022-06-27 14:08:06 +00:00
|
|
|
var detailedDiff map[string]display.PropertyDiff
|
2019-07-01 19:34:19 +00:00
|
|
|
if m.DetailedDiff != nil {
|
2022-06-27 14:08:06 +00:00
|
|
|
detailedDiff = make(map[string]display.PropertyDiff)
|
2019-07-01 19:34:19 +00:00
|
|
|
for k, v := range m.DetailedDiff {
|
2022-06-27 14:08:06 +00:00
|
|
|
detailedDiff[k] = display.PropertyDiff{
|
2019-07-01 19:34:19 +00:00
|
|
|
Kind: v.Kind.String(),
|
|
|
|
InputDiff: v.InputDiff,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-27 14:08:06 +00:00
|
|
|
step := &display.PreviewStep{
|
2019-04-23 22:55:18 +00:00
|
|
|
Op: m.Op,
|
2020-07-09 14:19:12 +00:00
|
|
|
URN: m.URN,
|
2019-04-23 22:55:18 +00:00
|
|
|
Provider: m.Provider,
|
|
|
|
DiffReasons: m.Diffs,
|
|
|
|
ReplaceReasons: m.Keys,
|
2019-07-01 19:34:19 +00:00
|
|
|
DetailedDiff: detailedDiff,
|
2019-04-23 22:55:18 +00:00
|
|
|
}
|
2019-05-25 10:10:38 +00:00
|
|
|
|
Lift context parameter to SerializeDeployment/Resource/Operations/Properties (#15929)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
SerializePropertyValue needed a `context.Context` object to pass to the
`config.Encrypter`. It was using `context.TODO()`, this change instead
accepts a context on the parameters and lifts that up to
SerializeProperties, SerializeResource, SerializeOperation, and
SerializeDeployment.
There were a few call sites for those methods that already had a context
on hand, and they now pass that context. The other calls sites now use
`context.TODO()`, we should continue to iterate in this area to ensure
everywhere that needs a context has one passed in.
## Checklist
- [x] I have run `make tidy` to update any new dependencies
- [x] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-04-15 07:45:46 +00:00
|
|
|
ctx := context.TODO()
|
2019-04-23 22:55:18 +00:00
|
|
|
if m.Old != nil {
|
2019-05-25 10:10:38 +00:00
|
|
|
oldState := stateForJSONOutput(m.Old.State, opts)
|
Lift context parameter to SerializeDeployment/Resource/Operations/Properties (#15929)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
SerializePropertyValue needed a `context.Context` object to pass to the
`config.Encrypter`. It was using `context.TODO()`, this change instead
accepts a context on the parameters and lifts that up to
SerializeProperties, SerializeResource, SerializeOperation, and
SerializeDeployment.
There were a few call sites for those methods that already had a context
on hand, and they now pass that context. The other calls sites now use
`context.TODO()`, we should continue to iterate in this area to ensure
everywhere that needs a context has one passed in.
## Checklist
- [x] I have run `make tidy` to update any new dependencies
- [x] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-04-15 07:45:46 +00:00
|
|
|
res, err := stack.SerializeResource(ctx, oldState, config.NewPanicCrypter(), false /* showSecrets */)
|
2019-05-10 23:04:12 +00:00
|
|
|
if err == nil {
|
2019-04-17 20:48:38 +00:00
|
|
|
step.OldState = &res
|
2019-05-10 23:04:12 +00:00
|
|
|
} else {
|
2021-10-26 23:21:27 +00:00
|
|
|
logging.V(7).Infof("not adding old state as there was an error serializing: %s", err)
|
2019-04-17 20:48:38 +00:00
|
|
|
}
|
2019-04-23 22:55:18 +00:00
|
|
|
}
|
|
|
|
if m.New != nil {
|
2019-05-25 10:10:38 +00:00
|
|
|
newState := stateForJSONOutput(m.New.State, opts)
|
Lift context parameter to SerializeDeployment/Resource/Operations/Properties (#15929)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
SerializePropertyValue needed a `context.Context` object to pass to the
`config.Encrypter`. It was using `context.TODO()`, this change instead
accepts a context on the parameters and lifts that up to
SerializeProperties, SerializeResource, SerializeOperation, and
SerializeDeployment.
There were a few call sites for those methods that already had a context
on hand, and they now pass that context. The other calls sites now use
`context.TODO()`, we should continue to iterate in this area to ensure
everywhere that needs a context has one passed in.
## Checklist
- [x] I have run `make tidy` to update any new dependencies
- [x] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-04-15 07:45:46 +00:00
|
|
|
res, err := stack.SerializeResource(ctx, newState, config.NewPanicCrypter(), false /* showSecrets */)
|
2019-05-10 23:04:12 +00:00
|
|
|
if err == nil {
|
2019-04-17 20:48:38 +00:00
|
|
|
step.NewState = &res
|
2019-05-10 23:04:12 +00:00
|
|
|
} else {
|
2021-10-26 23:21:27 +00:00
|
|
|
logging.V(7).Infof("not adding new state as there was an error serializing: %s", err)
|
2019-04-17 20:48:38 +00:00
|
|
|
}
|
2019-04-23 22:55:18 +00:00
|
|
|
}
|
2019-05-25 10:10:38 +00:00
|
|
|
|
2019-04-23 22:55:18 +00:00
|
|
|
digest.Steps = append(digest.Steps, step)
|
2019-04-20 20:34:58 +00:00
|
|
|
}
|
|
|
|
case engine.ResourceOutputsEvent, engine.ResourceOperationFailed:
|
2021-10-26 23:21:27 +00:00
|
|
|
// Because we are only JSON serializing previews, we don't need to worry about outputs
|
|
|
|
// resolving or operations failing.
|
2019-04-20 20:34:58 +00:00
|
|
|
|
2021-10-26 23:21:27 +00:00
|
|
|
// Events occurring late:
|
turn on the golangci-lint exhaustive linter (#15028)
Turn on the golangci-lint exhaustive linter. This is the first step
towards catching more missing cases during development rather than
in tests, or in production.
This might be best reviewed commit-by-commit, as the first commit turns
on the linter with the `default-signifies-exhaustive: true` option set,
which requires a lot less changes in the current codebase.
I think it's probably worth doing the second commit as well, as that
will get us the real benefits, even though we end up with a little bit
more churn. However it means all the `switch` statements are covered,
which isn't the case after the first commit, since we do have a lot of
`default` statements that just call `assert.Fail`.
Fixes #14601
## Checklist
- [x] I have run `make tidy` to update any new dependencies
- [x] I have run `make lint` to verify my code passes the lint check
- [x] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-17 16:50:41 +00:00
|
|
|
case engine.PolicyViolationEvent, engine.PolicyLoadEvent, engine.PolicyRemediationEvent:
|
2023-11-17 09:15:31 +00:00
|
|
|
// At this point in time, we don't handle policy events in JSON serialization
|
|
|
|
continue
|
2019-04-20 20:34:58 +00:00
|
|
|
case engine.SummaryEvent:
|
|
|
|
// At the end of the preview, a summary event indicates the final conclusions.
|
2020-07-17 06:52:31 +00:00
|
|
|
p := e.Payload().(engine.SummaryEventPayload)
|
2019-04-20 20:34:58 +00:00
|
|
|
digest.Duration = p.Duration
|
|
|
|
digest.ChangeSummary = p.ResourceChanges
|
|
|
|
digest.MaybeCorrupt = p.MaybeCorrupt
|
2024-04-12 15:55:06 +00:00
|
|
|
case engine.DownloadProgressEvent:
|
|
|
|
// It doesn't make sense to record these ephemeral events
|
|
|
|
continue
|
2019-04-20 20:34:58 +00:00
|
|
|
default:
|
|
|
|
contract.Failf("unknown event type '%s'", e.Type)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Finally, go ahead and render the JSON to stdout.
|
|
|
|
out, err := json.MarshalIndent(&digest, "", " ")
|
|
|
|
contract.Assertf(err == nil, "unexpected JSON error: %v", err)
|
|
|
|
fmt.Println(string(out))
|
|
|
|
}
|