mirror of
https://github.com/hashicorp/terraform.git
synced 2026-03-22 02:20:07 -04:00
This new field will be consumed in order to redact sensitive values referenced in a list block's input configuration from the query logs. We simply pipe the config schema and the marked values, and include the paths in the query_start log output.
120 lines
3.9 KiB
Go
120 lines
3.9 KiB
Go
// Copyright IBM Corp. 2014, 2026
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package json
|
|
|
|
import (
|
|
"encoding/json"
|
|
"sort"
|
|
|
|
"github.com/hashicorp/terraform/internal/addrs"
|
|
"github.com/hashicorp/terraform/internal/configs/configschema"
|
|
"github.com/hashicorp/terraform/internal/genconfig"
|
|
"github.com/hashicorp/terraform/internal/lang/format"
|
|
"github.com/hashicorp/terraform/internal/lang/marks"
|
|
"github.com/zclconf/go-cty/cty"
|
|
ctyjson "github.com/zclconf/go-cty/cty/json"
|
|
)
|
|
|
|
type QueryStart struct {
|
|
Address string `json:"address"`
|
|
ResourceType string `json:"resource_type"`
|
|
InputConfig map[string]json.RawMessage `json:"input_config,omitempty"`
|
|
SensitiveAttributePaths []string `json:"sensitive_attribute_paths,omitempty"`
|
|
}
|
|
|
|
type QueryResult struct {
|
|
Address string `json:"address"`
|
|
DisplayName string `json:"display_name"`
|
|
Identity map[string]json.RawMessage `json:"identity"`
|
|
IdentityVersion int64 `json:"identity_version"`
|
|
ResourceType string `json:"resource_type"`
|
|
ResourceObject map[string]json.RawMessage `json:"resource_object,omitempty"`
|
|
Config string `json:"config,omitempty"`
|
|
ImportConfig string `json:"import_config,omitempty"`
|
|
}
|
|
|
|
type QueryComplete struct {
|
|
Address string `json:"address"`
|
|
ResourceType string `json:"resource_type"`
|
|
Total int `json:"total"`
|
|
}
|
|
|
|
func NewQueryStart(addr addrs.AbsResourceInstance, inputConfig cty.Value, configSchema *configschema.Block) QueryStart {
|
|
unmarkVal, valPaths := inputConfig.UnmarkDeepWithPaths()
|
|
|
|
// We only want a unique set of attribute paths. A path
|
|
// can either be defined as sensitive by the provider or
|
|
// marked by configuration.
|
|
uniquePaths := make(map[string]struct{})
|
|
|
|
// Search for any marked sensitive paths, irrespective
|
|
// of the schema
|
|
for _, pvm := range valPaths {
|
|
if _, ok := pvm.Marks[marks.Sensitive]; ok {
|
|
uniquePaths[format.CtyPath(pvm.Path)] = struct{}{}
|
|
}
|
|
}
|
|
|
|
// Now let's loop through the resource schema defined by
|
|
// the provider
|
|
schemaPaths := configSchema.SensitivePaths(inputConfig, nil)
|
|
for _, path := range schemaPaths {
|
|
uniquePaths[format.CtyPath(path)] = struct{}{}
|
|
}
|
|
|
|
sensitiveAttributePaths := make([]string, 0, len(uniquePaths))
|
|
for p := range uniquePaths {
|
|
sensitiveAttributePaths = append(sensitiveAttributePaths, p)
|
|
}
|
|
|
|
sort.Strings(sensitiveAttributePaths)
|
|
|
|
return QueryStart{
|
|
Address: addr.String(),
|
|
ResourceType: addr.Resource.Resource.Type,
|
|
InputConfig: marshalValues(unmarkVal),
|
|
SensitiveAttributePaths: sensitiveAttributePaths,
|
|
}
|
|
}
|
|
|
|
func NewQueryResult(listAddr addrs.AbsResourceInstance, value cty.Value, identityVersion int64, generated *genconfig.ResourceImport) QueryResult {
|
|
result := QueryResult{
|
|
Address: listAddr.String(),
|
|
DisplayName: value.GetAttr("display_name").AsString(),
|
|
Identity: marshalValues(value.GetAttr("identity")),
|
|
IdentityVersion: identityVersion,
|
|
ResourceType: listAddr.Resource.Resource.Type,
|
|
ResourceObject: marshalValues(value.GetAttr("state")),
|
|
}
|
|
|
|
if generated != nil {
|
|
result.Config = generated.Resource.String()
|
|
result.ImportConfig = string(generated.ImportBody)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func NewQueryComplete(addr addrs.AbsResourceInstance, total int) QueryComplete {
|
|
return QueryComplete{
|
|
Address: addr.String(),
|
|
ResourceType: addr.Resource.Resource.Type,
|
|
Total: total,
|
|
}
|
|
}
|
|
|
|
func marshalValues(value cty.Value) map[string]json.RawMessage {
|
|
if value == cty.NilVal || value.IsNull() {
|
|
return nil
|
|
}
|
|
|
|
ret := make(map[string]json.RawMessage)
|
|
it := value.ElementIterator()
|
|
|
|
for it.Next() {
|
|
k, v := it.Element()
|
|
vJSON, _ := ctyjson.Marshal(v, v.Type())
|
|
ret[k.AsString()] = json.RawMessage(vJSON)
|
|
}
|
|
return ret
|
|
}
|