github.com/opentofu/opentofu@v1.7.1/internal/legacy/helper/schema/data_source_resource_shim.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package schema
     7  
     8  import (
     9  	"fmt"
    10  )
    11  
    12  // DataSourceResourceShim takes a Resource instance describing a data source
    13  // (with a Read implementation and a Schema, at least) and returns a new
    14  // Resource instance with additional Create and Delete implementations that
    15  // allow the data source to be used as a resource.
    16  //
    17  // This is a backward-compatibility layer for data sources that were formerly
    18  // read-only resources before the data source concept was added. It should not
    19  // be used for any *new* data sources.
    20  //
    21  // The Read function for the data source *must* call d.SetId with a non-empty
    22  // id in order for this shim to function as expected.
    23  //
    24  // The provided Resource instance, and its schema, will be modified in-place
    25  // to make it suitable for use as a full resource.
    26  func DataSourceResourceShim(name string, dataSource *Resource) *Resource {
    27  	// Recursively, in-place adjust the schema so that it has ForceNew
    28  	// on any user-settable resource.
    29  	dataSourceResourceShimAdjustSchema(dataSource.Schema)
    30  
    31  	dataSource.Create = CreateFunc(dataSource.Read)
    32  	dataSource.Delete = func(d *ResourceData, meta interface{}) error {
    33  		d.SetId("")
    34  		return nil
    35  	}
    36  	dataSource.Update = nil // should already be nil, but let's make sure
    37  
    38  	// FIXME: Link to some further docs either on the website or in the
    39  	// changelog, once such a thing exists.
    40  	dataSource.DeprecationMessage = fmt.Sprintf(
    41  		"using %s as a resource is deprecated; consider using the data source instead",
    42  		name,
    43  	)
    44  
    45  	return dataSource
    46  }
    47  
    48  func dataSourceResourceShimAdjustSchema(schema map[string]*Schema) {
    49  	for _, s := range schema {
    50  		// If the attribute is configurable then it must be ForceNew,
    51  		// since we have no Update implementation.
    52  		if s.Required || s.Optional {
    53  			s.ForceNew = true
    54  		}
    55  
    56  		// If the attribute is a nested resource, we need to recursively
    57  		// apply these same adjustments to it.
    58  		if s.Elem != nil {
    59  			if r, ok := s.Elem.(*Resource); ok {
    60  				dataSourceResourceShimAdjustSchema(r.Schema)
    61  			}
    62  		}
    63  	}
    64  }