Merge pull request #1134 from hashicorp/f-deprecation
helper/schema: allow Schema attrs to be Deprecated/Removed
This commit is contained in:
commit
e97b4803d6
|
@ -113,6 +113,21 @@ type Schema struct {
|
|||
//
|
||||
// NOTE: This currently does not work.
|
||||
ComputedWhen []string
|
||||
|
||||
// When Deprecated is set, this attribute is deprecated.
|
||||
//
|
||||
// A deprecated field still works, but will probably stop working in near
|
||||
// future. This string is the message shown to the user with instructions on
|
||||
// how to address the deprecation.
|
||||
Deprecated string
|
||||
|
||||
// When Removed is set, this attribute has been removed from the schema
|
||||
//
|
||||
// Removed attributes can be left in the Schema to generate informative error
|
||||
// messages for the user when they show up in resource configurations.
|
||||
// This string is the message shown to the user with instructions on
|
||||
// what do to about the removed attribute.
|
||||
Removed string
|
||||
}
|
||||
|
||||
// SchemaDefaultFunc is a function called to return a default value for
|
||||
|
@ -877,7 +892,7 @@ func (m schemaMap) validate(
|
|||
raw, err = schema.DefaultFunc()
|
||||
if err != nil {
|
||||
return nil, []error{fmt.Errorf(
|
||||
"%s, error loading default: %s", k, err)}
|
||||
"%q, error loading default: %s", k, err)}
|
||||
}
|
||||
|
||||
// We're okay as long as we had a value set
|
||||
|
@ -886,7 +901,7 @@ func (m schemaMap) validate(
|
|||
if !ok {
|
||||
if schema.Required {
|
||||
return nil, []error{fmt.Errorf(
|
||||
"%s: required field is not set", k)}
|
||||
"%q: required field is not set", k)}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
@ -895,7 +910,7 @@ func (m schemaMap) validate(
|
|||
if !schema.Required && !schema.Optional {
|
||||
// This is a computed-only field
|
||||
return nil, []error{fmt.Errorf(
|
||||
"%s: this field cannot be set", k)}
|
||||
"%q: this field cannot be set", k)}
|
||||
}
|
||||
|
||||
return m.validateType(k, raw, schema, c)
|
||||
|
@ -1066,16 +1081,30 @@ func (m schemaMap) validateType(
|
|||
raw interface{},
|
||||
schema *Schema,
|
||||
c *terraform.ResourceConfig) ([]string, []error) {
|
||||
var ws []string
|
||||
var es []error
|
||||
switch schema.Type {
|
||||
case TypeSet:
|
||||
fallthrough
|
||||
case TypeList:
|
||||
return m.validateList(k, raw, schema, c)
|
||||
ws, es = m.validateList(k, raw, schema, c)
|
||||
case TypeMap:
|
||||
return m.validateMap(k, raw, schema, c)
|
||||
ws, es = m.validateMap(k, raw, schema, c)
|
||||
default:
|
||||
return m.validatePrimitive(k, raw, schema, c)
|
||||
ws, es = m.validatePrimitive(k, raw, schema, c)
|
||||
}
|
||||
|
||||
if schema.Deprecated != "" {
|
||||
ws = append(ws, fmt.Sprintf(
|
||||
"%q: [DEPRECATED] %s", k, schema.Deprecated))
|
||||
}
|
||||
|
||||
if schema.Removed != "" {
|
||||
es = append(es, fmt.Errorf(
|
||||
"%q: [REMOVED] %s", k, schema.Removed))
|
||||
}
|
||||
|
||||
return ws, es
|
||||
}
|
||||
|
||||
// Zero returns the zero value for a type.
|
||||
|
|
|
@ -2584,11 +2584,12 @@ func TestSchemaMap_InternalValidate(t *testing.T) {
|
|||
|
||||
func TestSchemaMap_Validate(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Schema map[string]*Schema
|
||||
Config map[string]interface{}
|
||||
Vars map[string]string
|
||||
Warn bool
|
||||
Err bool
|
||||
Schema map[string]*Schema
|
||||
Config map[string]interface{}
|
||||
Vars map[string]string
|
||||
Err bool
|
||||
Errors []error
|
||||
Warnings []string
|
||||
}{
|
||||
"Good": {
|
||||
Schema: map[string]*Schema{
|
||||
|
@ -3019,6 +3020,71 @@ func TestSchemaMap_Validate(t *testing.T) {
|
|||
|
||||
Err: true,
|
||||
},
|
||||
|
||||
"Deprecated attribute usage generates warning, but not error": {
|
||||
Schema: map[string]*Schema{
|
||||
"old_news": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
Deprecated: "please use 'new_news' instead",
|
||||
},
|
||||
},
|
||||
|
||||
Config: map[string]interface{}{
|
||||
"old_news": "extra extra!",
|
||||
},
|
||||
|
||||
Err: false,
|
||||
|
||||
Warnings: []string{
|
||||
"\"old_news\": [DEPRECATED] please use 'new_news' instead",
|
||||
},
|
||||
},
|
||||
|
||||
"Deprecated generates no warnings if attr not used": {
|
||||
Schema: map[string]*Schema{
|
||||
"old_news": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
Deprecated: "please use 'new_news' instead",
|
||||
},
|
||||
},
|
||||
|
||||
Err: false,
|
||||
|
||||
Warnings: nil,
|
||||
},
|
||||
|
||||
"Removed attribute usage generates error": {
|
||||
Schema: map[string]*Schema{
|
||||
"long_gone": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
Removed: "no longer supported by Cloud API",
|
||||
},
|
||||
},
|
||||
|
||||
Config: map[string]interface{}{
|
||||
"long_gone": "still here!",
|
||||
},
|
||||
|
||||
Err: true,
|
||||
Errors: []error{
|
||||
fmt.Errorf("\"long_gone\": [REMOVED] no longer supported by Cloud API"),
|
||||
},
|
||||
},
|
||||
|
||||
"Removed generates no errors if attr not used": {
|
||||
Schema: map[string]*Schema{
|
||||
"long_gone": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
Removed: "no longer supported by Cloud API",
|
||||
},
|
||||
},
|
||||
|
||||
Err: false,
|
||||
},
|
||||
}
|
||||
|
||||
for tn, tc := range cases {
|
||||
|
@ -3050,8 +3116,14 @@ func TestSchemaMap_Validate(t *testing.T) {
|
|||
t.FailNow()
|
||||
}
|
||||
|
||||
if (len(ws) > 0) != tc.Warn {
|
||||
t.Fatalf("%q: ws: %#v", tn, ws)
|
||||
if !reflect.DeepEqual(ws, tc.Warnings) {
|
||||
t.Fatalf("%q: warnings:\n\nexpected: %#v\ngot:%#v", tn, tc.Warnings, ws)
|
||||
}
|
||||
|
||||
if tc.Errors != nil {
|
||||
if !reflect.DeepEqual(es, tc.Errors) {
|
||||
t.Fatalf("%q: errors:\n\nexpected: %q\ngot: %q", tn, tc.Errors, es)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue