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 }