github.com/kanishk98/terraform@v1.3.0-dev.0.20220917174235-661ca8088a6a/internal/configs/configschema/marks.go (about)

     1  package configschema
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/terraform/internal/lang/marks"
     7  	"github.com/zclconf/go-cty/cty"
     8  )
     9  
    10  // ValueMarks returns a set of path value marks for a given value and path,
    11  // based on the sensitive flag for each attribute within the schema. Nested
    12  // blocks are descended (if present in the given value).
    13  func (b *Block) ValueMarks(val cty.Value, path cty.Path) []cty.PathValueMarks {
    14  	var pvm []cty.PathValueMarks
    15  
    16  	// We can mark attributes as sensitive even if the value is null
    17  	for name, attrS := range b.Attributes {
    18  		if attrS.Sensitive {
    19  			// Create a copy of the path, with this step added, to add to our PathValueMarks slice
    20  			attrPath := make(cty.Path, len(path), len(path)+1)
    21  			copy(attrPath, path)
    22  			attrPath = append(path, cty.GetAttrStep{Name: name})
    23  			pvm = append(pvm, cty.PathValueMarks{
    24  				Path:  attrPath,
    25  				Marks: cty.NewValueMarks(marks.Sensitive),
    26  			})
    27  		}
    28  	}
    29  
    30  	// If the value is null, no other marks are possible
    31  	if val.IsNull() {
    32  		return pvm
    33  	}
    34  
    35  	// Extract marks for nested attribute type values
    36  	for name, attrS := range b.Attributes {
    37  		// If the attribute has no nested type, or the nested type doesn't
    38  		// contain any sensitive attributes, skip inspecting it
    39  		if attrS.NestedType == nil || !attrS.NestedType.ContainsSensitive() {
    40  			continue
    41  		}
    42  
    43  		// Create a copy of the path, with this step added, to add to our PathValueMarks slice
    44  		attrPath := make(cty.Path, len(path), len(path)+1)
    45  		copy(attrPath, path)
    46  		attrPath = append(path, cty.GetAttrStep{Name: name})
    47  
    48  		pvm = append(pvm, attrS.NestedType.ValueMarks(val.GetAttr(name), attrPath)...)
    49  	}
    50  
    51  	// Extract marks for nested blocks
    52  	for name, blockS := range b.BlockTypes {
    53  		// If our block doesn't contain any sensitive attributes, skip inspecting it
    54  		if !blockS.Block.ContainsSensitive() {
    55  			continue
    56  		}
    57  
    58  		blockV := val.GetAttr(name)
    59  		if blockV.IsNull() || !blockV.IsKnown() {
    60  			continue
    61  		}
    62  
    63  		// Create a copy of the path, with this step added, to add to our PathValueMarks slice
    64  		blockPath := make(cty.Path, len(path), len(path)+1)
    65  		copy(blockPath, path)
    66  		blockPath = append(path, cty.GetAttrStep{Name: name})
    67  
    68  		switch blockS.Nesting {
    69  		case NestingSingle, NestingGroup:
    70  			pvm = append(pvm, blockS.Block.ValueMarks(blockV, blockPath)...)
    71  		case NestingList, NestingMap, NestingSet:
    72  			for it := blockV.ElementIterator(); it.Next(); {
    73  				idx, blockEV := it.Element()
    74  				morePaths := blockS.Block.ValueMarks(blockEV, append(blockPath, cty.IndexStep{Key: idx}))
    75  				pvm = append(pvm, morePaths...)
    76  			}
    77  		default:
    78  			panic(fmt.Sprintf("unsupported nesting mode %s", blockS.Nesting))
    79  		}
    80  	}
    81  	return pvm
    82  }
    83  
    84  // ValueMarks returns a set of path value marks for a given value and path,
    85  // based on the sensitive flag for each attribute within the nested attribute.
    86  // Attributes with nested types are descended (if present in the given value).
    87  func (o *Object) ValueMarks(val cty.Value, path cty.Path) []cty.PathValueMarks {
    88  	var pvm []cty.PathValueMarks
    89  
    90  	if val.IsNull() || !val.IsKnown() {
    91  		return pvm
    92  	}
    93  
    94  	for name, attrS := range o.Attributes {
    95  		// Skip attributes which can never produce sensitive path value marks
    96  		if !attrS.Sensitive && (attrS.NestedType == nil || !attrS.NestedType.ContainsSensitive()) {
    97  			continue
    98  		}
    99  
   100  		switch o.Nesting {
   101  		case NestingSingle, NestingGroup:
   102  			// Create a path to this attribute
   103  			attrPath := make(cty.Path, len(path), len(path)+1)
   104  			copy(attrPath, path)
   105  			attrPath = append(path, cty.GetAttrStep{Name: name})
   106  
   107  			if attrS.Sensitive {
   108  				// If the entire attribute is sensitive, mark it so
   109  				pvm = append(pvm, cty.PathValueMarks{
   110  					Path:  attrPath,
   111  					Marks: cty.NewValueMarks(marks.Sensitive),
   112  				})
   113  			} else {
   114  				// The attribute has a nested type which contains sensitive
   115  				// attributes, so recurse
   116  				pvm = append(pvm, attrS.NestedType.ValueMarks(val.GetAttr(name), attrPath)...)
   117  			}
   118  		case NestingList, NestingMap, NestingSet:
   119  			// For nested attribute types which have a non-single nesting mode,
   120  			// we add path value marks for each element of the collection
   121  			for it := val.ElementIterator(); it.Next(); {
   122  				idx, attrEV := it.Element()
   123  				attrV := attrEV.GetAttr(name)
   124  
   125  				// Create a path to this element of the attribute's collection. Note
   126  				// that the path is extended in opposite order to the iteration order
   127  				// of the loops: index into the collection, then the contained
   128  				// attribute name. This is because we have one type
   129  				// representing multiple collection elements.
   130  				attrPath := make(cty.Path, len(path), len(path)+2)
   131  				copy(attrPath, path)
   132  				attrPath = append(path, cty.IndexStep{Key: idx}, cty.GetAttrStep{Name: name})
   133  
   134  				if attrS.Sensitive {
   135  					// If the entire attribute is sensitive, mark it so
   136  					pvm = append(pvm, cty.PathValueMarks{
   137  						Path:  attrPath,
   138  						Marks: cty.NewValueMarks(marks.Sensitive),
   139  					})
   140  				} else {
   141  					// The attribute has a nested type which contains sensitive
   142  					// attributes, so recurse
   143  					pvm = append(pvm, attrS.NestedType.ValueMarks(attrV, attrPath)...)
   144  				}
   145  			}
   146  		default:
   147  			panic(fmt.Sprintf("unsupported nesting mode %s", attrS.NestedType.Nesting))
   148  		}
   149  	}
   150  	return pvm
   151  }