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 }