kubeform.dev/terraform-backend-sdk@v0.0.0-20220310143633-45f07fe731c5/experiments/experiment.go (about)

     1  package experiments
     2  
     3  // Experiment represents a particular experiment, which can be activated
     4  // independently of all other experiments.
     5  type Experiment string
     6  
     7  // All active and defunct experiments must be represented by constants whose
     8  // internal string values are unique.
     9  //
    10  // Each of these declared constants must also be registered as either a
    11  // current or a defunct experiment in the init() function below.
    12  //
    13  // Each experiment is represented by a string that must be a valid HCL
    14  // identifier so that it can be specified in configuration.
    15  const (
    16  	VariableValidation             = Experiment("variable_validation")
    17  	ModuleVariableOptionalAttrs    = Experiment("module_variable_optional_attrs")
    18  	SuppressProviderSensitiveAttrs = Experiment("provider_sensitive_attrs")
    19  	ConfigDrivenMove               = Experiment("config_driven_move")
    20  )
    21  
    22  func init() {
    23  	// Each experiment constant defined above must be registered here as either
    24  	// a current or a concluded experiment.
    25  	registerConcludedExperiment(VariableValidation, "Custom variable validation can now be used by default, without enabling an experiment.")
    26  	registerConcludedExperiment(SuppressProviderSensitiveAttrs, "Provider-defined sensitive attributes are now redacted by default, without enabling an experiment.")
    27  	registerCurrentExperiment(ModuleVariableOptionalAttrs)
    28  	registerCurrentExperiment(ConfigDrivenMove)
    29  }
    30  
    31  // GetCurrent takes an experiment name and returns the experiment value
    32  // representing that expression if and only if it is a current experiment.
    33  //
    34  // If the selected experiment is concluded, GetCurrent will return an
    35  // error of type ConcludedError whose message hopefully includes some guidance
    36  // for users of the experiment on how to migrate to a stable feature that
    37  // succeeded it.
    38  //
    39  // If the selected experiment is not known at all, GetCurrent will return an
    40  // error of type UnavailableError.
    41  func GetCurrent(name string) (Experiment, error) {
    42  	exp := Experiment(name)
    43  	if currentExperiments.Has(exp) {
    44  		return exp, nil
    45  	}
    46  
    47  	if msg, concluded := concludedExperiments[exp]; concluded {
    48  		return Experiment(""), ConcludedError{ExperimentName: name, Message: msg}
    49  	}
    50  
    51  	return Experiment(""), UnavailableError{ExperimentName: name}
    52  }
    53  
    54  // Keyword returns the keyword that would be used to activate this experiment
    55  // in the configuration.
    56  func (e Experiment) Keyword() string {
    57  	return string(e)
    58  }
    59  
    60  // IsCurrent returns true if the receiver is considered a currently-selectable
    61  // experiment.
    62  func (e Experiment) IsCurrent() bool {
    63  	return currentExperiments.Has(e)
    64  }
    65  
    66  // IsConcluded returns true if the receiver is a concluded experiment.
    67  func (e Experiment) IsConcluded() bool {
    68  	_, exists := concludedExperiments[e]
    69  	return exists
    70  }
    71  
    72  // currentExperiments are those which are available to activate in the current
    73  // version of Terraform.
    74  //
    75  // Members of this set are registered in the init function above.
    76  var currentExperiments = make(Set)
    77  
    78  // concludedExperiments are those which were available to activate in an earlier
    79  // version of Terraform but are no longer available, either because the feature
    80  // in question has been implemented or because the experiment failed and the
    81  // feature was abandoned. Each experiment maps to a message describing the
    82  // outcome, so we can give users feedback about what they might do in modules
    83  // using concluded experiments.
    84  //
    85  // After an experiment has been concluded for a whole major release span it can
    86  // be removed, since we expect users to perform upgrades one major release at
    87  // at time without skipping and thus they will see the concludedness error
    88  // message as they upgrade through a prior major version.
    89  //
    90  // Members of this map are registered in the init function above.
    91  var concludedExperiments = make(map[Experiment]string)
    92  
    93  func registerCurrentExperiment(exp Experiment) {
    94  	currentExperiments.Add(exp)
    95  }
    96  
    97  func registerConcludedExperiment(exp Experiment, message string) {
    98  	concludedExperiments[exp] = message
    99  }