github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/states/statemgr/persistent.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package statemgr
     5  
     6  import (
     7  	version "github.com/hashicorp/go-version"
     8  
     9  	"github.com/terramate-io/tf/states"
    10  	"github.com/terramate-io/tf/terraform"
    11  )
    12  
    13  // Persistent is a union of the Refresher and Persistent interfaces, for types
    14  // that deal with persistent snapshots.
    15  //
    16  // Persistent snapshots are ones that are retained in storage that will
    17  // outlive a particular Terraform process, and are shared with other Terraform
    18  // processes that have a similarly-configured state manager.
    19  //
    20  // A manager may also choose to retain historical persistent snapshots, but
    21  // that is an implementation detail and not visible via this API.
    22  type Persistent interface {
    23  	Refresher
    24  	Persister
    25  	OutputReader
    26  }
    27  
    28  // OutputReader is the interface for managers that fetches output values from state
    29  // or another source. This is a refinement of fetching the entire state and digging
    30  // the output values from it because enhanced backends can apply special permissions
    31  // to differentiate reading the state and reading the outputs within the state.
    32  type OutputReader interface {
    33  	// GetRootOutputValues fetches the root module output values from state or another source
    34  	GetRootOutputValues() (map[string]*states.OutputValue, error)
    35  }
    36  
    37  // Refresher is the interface for managers that can read snapshots from
    38  // persistent storage.
    39  //
    40  // Refresher is usually implemented in conjunction with Reader, with
    41  // RefreshState copying the latest persistent snapshot into the latest
    42  // transient snapshot.
    43  //
    44  // For a type that implements both Refresher and Persister, RefreshState must
    45  // return the result of the most recently completed successful call to
    46  // PersistState, unless another concurrently-running process has persisted
    47  // another snapshot in the mean time.
    48  //
    49  // The Refresher implementation must guarantee that the snapshot is read
    50  // from persistent storage in a way that is safe under concurrent calls to
    51  // PersistState that may be happening in other processes.
    52  type Refresher interface {
    53  	// RefreshState retrieves a snapshot of state from persistent storage,
    54  	// returning an error if this is not possible.
    55  	//
    56  	// Types that implement RefreshState generally also implement a State
    57  	// method that returns the result of the latest successful refresh.
    58  	//
    59  	// Since only a subset of the data in a state is included when persisting,
    60  	// a round-trip through PersistState and then RefreshState will often
    61  	// return only a subset of what was written. Callers must assume that
    62  	// ephemeral portions of the state may be unpopulated after calling
    63  	// RefreshState.
    64  	RefreshState() error
    65  }
    66  
    67  // Persister is the interface for managers that can write snapshots to
    68  // persistent storage.
    69  //
    70  // Persister is usually implemented in conjunction with Writer, with
    71  // PersistState copying the latest transient snapshot to be the new latest
    72  // persistent snapshot.
    73  //
    74  // A Persister implementation must detect updates made by other processes
    75  // that may be running concurrently and avoid destroying those changes. This
    76  // is most commonly achieved by making use of atomic write capabilities on
    77  // the remote storage backend in conjunction with book-keeping with the
    78  // Serial and Lineage fields in the standard state file formats.
    79  //
    80  // Some implementations may optionally utilize config schema to persist
    81  // state. For example, when representing state in an external JSON
    82  // representation.
    83  type Persister interface {
    84  	PersistState(*terraform.Schemas) error
    85  }
    86  
    87  // PersistentMeta is an optional extension to Persistent that allows inspecting
    88  // the metadata associated with the snapshot that was most recently either
    89  // read by RefreshState or written by PersistState.
    90  type PersistentMeta interface {
    91  	// StateSnapshotMeta returns metadata about the state snapshot most
    92  	// recently created either by a call to PersistState or read by a call
    93  	// to RefreshState.
    94  	//
    95  	// If no persistent snapshot is yet available in the manager then
    96  	// the return value is meaningless. This method is primarily available
    97  	// for testing and logging purposes, and is of little use otherwise.
    98  	StateSnapshotMeta() SnapshotMeta
    99  }
   100  
   101  // SnapshotMeta contains metadata about a persisted state snapshot.
   102  //
   103  // This metadata is usually (but not necessarily) included as part of the
   104  // "header" of a state file, which is then written to a raw blob storage medium
   105  // by a persistent state manager.
   106  //
   107  // Not all state managers will have useful values for all fields in this
   108  // struct, so SnapshotMeta values are of little use beyond testing and logging
   109  // use-cases.
   110  type SnapshotMeta struct {
   111  	// Lineage and Serial can be used to understand the relationships between
   112  	// snapshots.
   113  	//
   114  	// If two snapshots both have an identical, non-empty Lineage
   115  	// then the one with the higher Serial is newer than the other.
   116  	// If the Lineage values are different or empty then the two snapshots
   117  	// are unrelated and cannot be compared for relative age.
   118  	Lineage string
   119  	Serial  uint64
   120  
   121  	// TerraformVersion is the number of the version of Terraform that created
   122  	// the snapshot.
   123  	TerraformVersion *version.Version
   124  }