Skip to content

Commit a4e71f6

Browse files
committed
fix append bugs of cty.Path
make Error string of Diagnostic include detail introduce MapKey to associate diag to proper attribute for maps during validation
1 parent 97ce108 commit a4e71f6

File tree

2 files changed

+33
-18
lines changed

2 files changed

+33
-18
lines changed

diag/diagnostic.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ type Diagnostic struct {
4242
Summary string
4343
Detail string
4444
AttributePath cty.Path
45+
MapKey string
4546
}
4647

4748
func (d *Diagnostic) Error() string {
48-
return fmt.Sprintf("%s: %s", d.Severity, d.Summary)
49+
return fmt.Sprintf("%s: %s: %s", d.Severity, d.Summary, d.Detail)
4950
}
5051

5152
type Severity int

helper/schema/schema.go

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -410,13 +410,19 @@ func (s *Schema) finalizeDiff(d *terraform.ResourceAttrDiff, customized bool) *t
410410
return d
411411
}
412412

413-
func (s *Schema) validateFunc(decoded interface{}, k string, path cty.Path) diag.Diagnostics {
413+
func (s *Schema) validateFunc(decoded interface{}, k string, path cty.Path, isTypeMap bool) diag.Diagnostics {
414414
var diags diag.Diagnostics
415415

416416
if s.ValidateDiagFunc != nil {
417417
diags = s.ValidateDiagFunc(decoded, k)
418418
for _, d := range diags {
419-
d.AttributePath = path
419+
p := path.Copy()
420+
if len(d.AttributePath) == 0 {
421+
if isTypeMap && d.MapKey != "" {
422+
p = append(p, cty.IndexStep{Key: cty.StringVal(d.MapKey)})
423+
}
424+
d.AttributePath = p
425+
}
420426
}
421427
} else if s.ValidateFunc != nil {
422428
ws, es := s.ValidateFunc(decoded, k)
@@ -1611,7 +1617,8 @@ func (m schemaMap) validateList(
16111617
raw interface{},
16121618
schema *Schema,
16131619
c *terraform.ResourceConfig,
1614-
path cty.Path) diag.Diagnostics {
1620+
path cty.Path,
1621+
isTypeSet bool) diag.Diagnostics {
16151622

16161623
var diags diag.Diagnostics
16171624

@@ -1675,7 +1682,12 @@ func (m schemaMap) validateList(
16751682

16761683
for i, raw := range raws {
16771684
key := fmt.Sprintf("%s.%d", k, i)
1678-
path = append(path, cty.IndexStep{Key: cty.NumberIntVal(int64(i))})
1685+
1686+
// TODO: figure out cty.Path for TypeSet
1687+
// if isTypeSet {
1688+
// } else {
1689+
// }
1690+
p := append(path.Copy(), cty.IndexStep{Key: cty.NumberIntVal(int64(i))})
16791691

16801692
// Reify the key value from the ResourceConfig.
16811693
// If the list was computed we have all raw values, but some of these
@@ -1687,9 +1699,9 @@ func (m schemaMap) validateList(
16871699
switch t := schema.Elem.(type) {
16881700
case *Resource:
16891701
// This is a sub-resource
1690-
diags = append(diags, m.validateObject(key, t.Schema, c, path)...)
1702+
diags = append(diags, m.validateObject(key, t.Schema, c, p)...)
16911703
case *Schema:
1692-
diags = append(diags, m.validateType(key, raw, t, c, path)...)
1704+
diags = append(diags, m.validateType(key, raw, t, c, p)...)
16931705
}
16941706

16951707
}
@@ -1752,7 +1764,7 @@ func (m schemaMap) validateMap(
17521764
return diags
17531765
}
17541766

1755-
return schema.validateFunc(mapIface, k, path)
1767+
return schema.validateFunc(mapIface, k, path, true)
17561768
}
17571769

17581770
// It is a slice, verify that all the elements are maps
@@ -1784,7 +1796,7 @@ func (m schemaMap) validateMap(
17841796
}
17851797
}
17861798

1787-
return schema.validateFunc(validatableMap, k, path)
1799+
return schema.validateFunc(validatableMap, k, path, true)
17881800
}
17891801

17901802
func validateMapValues(k string, m map[string]interface{}, schema *Schema, path cty.Path) diag.Diagnostics {
@@ -1793,12 +1805,12 @@ func validateMapValues(k string, m map[string]interface{}, schema *Schema, path
17931805

17941806
for key, raw := range m {
17951807
valueType, err := getValueType(k, schema)
1796-
path = append(path, cty.GetAttrStep{Name: key})
1808+
p := append(path.Copy(), cty.IndexStep{Key: cty.StringVal(key)})
17971809
if err != nil {
17981810
return append(diags, &diag.Diagnostic{
17991811
Severity: diag.Error,
18001812
Summary: err.Error(),
1801-
AttributePath: path,
1813+
AttributePath: p,
18021814
})
18031815
}
18041816

@@ -1809,7 +1821,7 @@ func validateMapValues(k string, m map[string]interface{}, schema *Schema, path
18091821
return append(diags, &diag.Diagnostic{
18101822
Severity: diag.Error,
18111823
Summary: err.Error(),
1812-
AttributePath: path,
1824+
AttributePath: p,
18131825
})
18141826
}
18151827
case TypeInt:
@@ -1818,7 +1830,7 @@ func validateMapValues(k string, m map[string]interface{}, schema *Schema, path
18181830
return append(diags, &diag.Diagnostic{
18191831
Severity: diag.Error,
18201832
Summary: err.Error(),
1821-
AttributePath: path,
1833+
AttributePath: p,
18221834
})
18231835
}
18241836
case TypeFloat:
@@ -1827,7 +1839,7 @@ func validateMapValues(k string, m map[string]interface{}, schema *Schema, path
18271839
return append(diags, &diag.Diagnostic{
18281840
Severity: diag.Error,
18291841
Summary: err.Error(),
1830-
AttributePath: path,
1842+
AttributePath: p,
18311843
})
18321844
}
18331845
case TypeString:
@@ -1836,7 +1848,7 @@ func validateMapValues(k string, m map[string]interface{}, schema *Schema, path
18361848
return append(diags, &diag.Diagnostic{
18371849
Severity: diag.Error,
18381850
Summary: err.Error(),
1839-
AttributePath: path,
1851+
AttributePath: p,
18401852
})
18411853
}
18421854
default:
@@ -2014,7 +2026,7 @@ func (m schemaMap) validatePrimitive(
20142026
panic(fmt.Sprintf("Unknown validation type: %#v", schema.Type))
20152027
}
20162028

2017-
return append(diags, schema.validateFunc(decoded, k, path)...)
2029+
return append(diags, schema.validateFunc(decoded, k, path, false)...)
20182030
}
20192031

20202032
func (m schemaMap) validateType(
@@ -2027,8 +2039,10 @@ func (m schemaMap) validateType(
20272039
var diags diag.Diagnostics
20282040

20292041
switch schema.Type {
2030-
case TypeSet, TypeList:
2031-
diags = m.validateList(k, raw, schema, c, path)
2042+
case TypeList:
2043+
diags = m.validateList(k, raw, schema, c, path, false)
2044+
case TypeSet:
2045+
diags = m.validateList(k, raw, schema, c, path, true)
20322046
case TypeMap:
20332047
diags = m.validateMap(k, raw, schema, c, path)
20342048
default:

0 commit comments

Comments
 (0)