From fb262d0dbe6690e8c71881e4bb2b132ed7c4c81b Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Sat, 16 Apr 2016 17:30:40 -0700 Subject: [PATCH] helper/schema: shim for making data sources act like resources Historically we've had some "read-only" and "logical" resources. With the addition of the data source concept these will gradually become data sources, but we need to retain backward compatibility with existing configurations that use the now-deprecated resources. This shim is intended to allow us to easily create a resource from a data source implementation. It adjusts the schema as needed and adds stub Create and Delete implementations. This would ideally also produce a deprecation warning whenever such a shimmed resource is used, but the schema system doesn't currently have a mechanism for resource-specific validation, so that remains just a TODO for the moment. --- helper/schema/data_source_resource_shim.go | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 helper/schema/data_source_resource_shim.go diff --git a/helper/schema/data_source_resource_shim.go b/helper/schema/data_source_resource_shim.go new file mode 100644 index 000000000..7394990e1 --- /dev/null +++ b/helper/schema/data_source_resource_shim.go @@ -0,0 +1,52 @@ +package schema + +// DataSourceResourceShim takes a Resource instance describing a data source +// (with a Read implementation and a Schema, at least) and returns a new +// Resource instance with additional Create and Delete implementations that +// allow the data source to be used as a resource. +// +// This is a backward-compatibility layer for data sources that were formerly +// read-only resources before the data source concept was added. It should not +// be used for any *new* data sources. +// +// The Read function for the data source *must* call d.SetId with a non-empty +// id in order for this shim to function as expected. +// +// The provided Resource instance, and its schema, will be modified in-place +// to make it suitable for use as a full resource. +func DataSourceResourceShim(dataSource *Resource) *Resource { + // TODO: Somehow emit a warning when a shim resource is used, + // recommending that the user switch to using the data source + // instead. + + // Recursively, in-place adjust the schema so that it has ForceNew + // on any user-settable resource. + dataSourceResourceShimAdjustSchema(dataSource.Schema) + + dataSource.Create = CreateFunc(dataSource.Read) + dataSource.Delete = func(d *ResourceData, meta interface{}) error { + d.SetId("") + return nil + } + dataSource.Update = nil // should already be nil, but let's make sure + + return dataSource +} + +func dataSourceResourceShimAdjustSchema(schema map[string]*Schema) { + for _, s := range schema { + // If the attribute is configurable then it must be ForceNew, + // since we have no Update implementation. + if s.Required || s.Optional { + s.ForceNew = true + } + + // If the attribute is a nested resource, we need to recursively + // apply these same adjustments to it. + if s.Elem != nil { + if r, ok := s.Elem.(*Resource); ok { + dataSourceResourceShimAdjustSchema(r.Schema) + } + } + } +}