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