Skip to content

Commit 57d4cc0

Browse files
committed
Add a warning/error option to schema validation
Add new schema options to configure the warning/error level of validation functions. This allows the following functions to be used as a warning-level diag instead of a fatal error: "ConflictsWith", "AtLeastOneOf", "ExactlyOneOf", "RequiredWith". The ConditionsMode allows provider developers to toggle between "warning" and "error" level messages. The ConditionsMessage is an optional additional message to be displayed to users at run time.
1 parent 112e216 commit 57d4cc0

File tree

2 files changed

+55
-14
lines changed

2 files changed

+55
-14
lines changed

helper/schema/schema.go

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,14 @@ type Schema struct {
198198
AtLeastOneOf []string
199199
RequiredWith []string
200200

201+
// ConditionsMode specifies the behavior of the SDK when one of the
202+
// above conditions are met. (ConflictsWith, ExactlyOneOf, etc).
203+
// When set to WARNING, a warning message is displayed to the user.
204+
// When set to ERROR (default), a fatal error is returned.
205+
// Optionally, a message can be returned with the warning or error.
206+
ConditionsMode string
207+
ConditionsMessage string
208+
201209
// When Deprecated is set, this attribute is deprecated.
202210
//
203211
// A deprecated field still works, but will probably stop working in near
@@ -1449,22 +1457,29 @@ func (m schemaMap) validate(
14491457
ok = raw != nil
14501458
}
14511459

1460+
var conditionsMode diag.Severity
1461+
if schema.ConditionsMode == strings.ToLower("warning") {
1462+
conditionsMode = diag.Warning
1463+
} else {
1464+
conditionsMode = diag.Error
1465+
}
1466+
14521467
err := validateExactlyOneAttribute(k, schema, c)
14531468
if err != nil {
14541469
return append(diags, diag.Diagnostic{
1455-
Severity: diag.Error,
1470+
Severity: conditionsMode,
14561471
Summary: "ExactlyOne",
1457-
Detail: err.Error(),
1472+
Detail: fmt.Sprintf("%s %s", schema.ConditionsMessage, err.Error()),
14581473
AttributePath: path,
14591474
})
14601475
}
14611476

14621477
err = validateAtLeastOneAttribute(k, schema, c)
14631478
if err != nil {
14641479
return append(diags, diag.Diagnostic{
1465-
Severity: diag.Error,
1480+
Severity: conditionsMode,
14661481
Summary: "AtLeastOne",
1467-
Detail: err.Error(),
1482+
Detail: fmt.Sprintf("%s %s", schema.ConditionsMessage, err.Error()),
14681483
AttributePath: path,
14691484
})
14701485
}
@@ -1494,9 +1509,9 @@ func (m schemaMap) validate(
14941509
err = validateRequiredWithAttribute(k, schema, c)
14951510
if err != nil {
14961511
return append(diags, diag.Diagnostic{
1497-
Severity: diag.Error,
1512+
Severity: conditionsMode,
14981513
Summary: "RequiredWith",
1499-
Detail: err.Error(),
1514+
Detail: fmt.Sprintf("%s %s", schema.ConditionsMessage, err.Error()),
15001515
AttributePath: path,
15011516
})
15021517
}
@@ -1521,9 +1536,9 @@ func (m schemaMap) validate(
15211536
err = validateConflictingAttributes(k, schema, c)
15221537
if err != nil {
15231538
return append(diags, diag.Diagnostic{
1524-
Severity: diag.Error,
1539+
Severity: conditionsMode,
15251540
Summary: "ConflictsWith",
1526-
Detail: err.Error(),
1541+
Detail: fmt.Sprintf("%s %s", schema.ConditionsMessage, err.Error()),
15271542
AttributePath: path,
15281543
})
15291544
}

helper/schema/schema_test.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5991,7 +5991,33 @@ func TestSchemaMap_Validate(t *testing.T) {
59915991

59925992
Err: true,
59935993
Errors: []error{
5994-
fmt.Errorf(`Error: ConflictsWith: "blacklist": conflicts with whitelist`),
5994+
fmt.Errorf(`Error: ConflictsWith: "blacklist": conflicts with whitelist`),
5995+
},
5996+
},
5997+
5998+
"Conflicting attributes generate warning": {
5999+
Schema: map[string]*Schema{
6000+
"whitelist": {
6001+
Type: TypeString,
6002+
Optional: true,
6003+
},
6004+
"blacklist": {
6005+
Type: TypeString,
6006+
Optional: true,
6007+
ConflictsWith: []string{"whitelist"},
6008+
ConditionsMode: "warning",
6009+
ConditionsMessage: "This functionality will be removed in a later release.",
6010+
},
6011+
},
6012+
6013+
Config: map[string]interface{}{
6014+
"whitelist": "white-val",
6015+
"blacklist": "black-val",
6016+
},
6017+
6018+
Err: false,
6019+
Warnings: []string{
6020+
`Warning: ConflictsWith: This functionality will be removed in a later release. "blacklist": conflicts with whitelist`,
59956021
},
59966022
},
59976023

@@ -6087,8 +6113,8 @@ func TestSchemaMap_Validate(t *testing.T) {
60876113

60886114
Err: true,
60896115
Errors: []error{
6090-
fmt.Errorf(`Error: ConflictsWith: "blacklist": conflicts with greenlist`),
6091-
fmt.Errorf(`Error: ConflictsWith: "greenlist": conflicts with blacklist`),
6116+
fmt.Errorf(`Error: ConflictsWith: "blacklist": conflicts with greenlist`),
6117+
fmt.Errorf(`Error: ConflictsWith: "greenlist": conflicts with blacklist`),
60926118
},
60936119
},
60946120

@@ -6132,7 +6158,7 @@ func TestSchemaMap_Validate(t *testing.T) {
61326158

61336159
Err: true,
61346160
Errors: []error{
6135-
fmt.Errorf(`Error: ConflictsWith: "optional_att": conflicts with required_att`),
6161+
fmt.Errorf(`Error: ConflictsWith: "optional_att": conflicts with required_att`),
61366162
},
61376163
},
61386164

@@ -6159,8 +6185,8 @@ func TestSchemaMap_Validate(t *testing.T) {
61596185

61606186
Err: true,
61616187
Errors: []error{
6162-
fmt.Errorf(`Error: ConflictsWith: "bar_att": conflicts with foo_att`),
6163-
fmt.Errorf(`Error: ConflictsWith: "foo_att": conflicts with bar_att`),
6188+
fmt.Errorf(`Error: ConflictsWith: "bar_att": conflicts with foo_att`),
6189+
fmt.Errorf(`Error: ConflictsWith: "foo_att": conflicts with bar_att`),
61646190
},
61656191
},
61666192

0 commit comments

Comments
 (0)