github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/backend/init/init.go (about) 1 // Package init contains the list of backends that can be initialized and 2 // basic helper functions for initializing those backends. 3 package init 4 5 import ( 6 "sync" 7 8 "github.com/hashicorp/terraform-svchost/disco" 9 "github.com/hashicorp/terraform/internal/backend" 10 "github.com/hashicorp/terraform/internal/tfdiags" 11 "github.com/zclconf/go-cty/cty" 12 13 backendLocal "github.com/hashicorp/terraform/internal/backend/local" 14 backendRemote "github.com/hashicorp/terraform/internal/backend/remote" 15 backendAzure "github.com/hashicorp/terraform/internal/backend/remote-state/azure" 16 backendConsul "github.com/hashicorp/terraform/internal/backend/remote-state/consul" 17 backendCos "github.com/hashicorp/terraform/internal/backend/remote-state/cos" 18 backendGCS "github.com/hashicorp/terraform/internal/backend/remote-state/gcs" 19 backendHTTP "github.com/hashicorp/terraform/internal/backend/remote-state/http" 20 backendInmem "github.com/hashicorp/terraform/internal/backend/remote-state/inmem" 21 backendKubernetes "github.com/hashicorp/terraform/internal/backend/remote-state/kubernetes" 22 backendOSS "github.com/hashicorp/terraform/internal/backend/remote-state/oss" 23 backendPg "github.com/hashicorp/terraform/internal/backend/remote-state/pg" 24 backendS3 "github.com/hashicorp/terraform/internal/backend/remote-state/s3" 25 backendCloud "github.com/hashicorp/terraform/internal/cloud" 26 ) 27 28 // backends is the list of available backends. This is a global variable 29 // because backends are currently hardcoded into Terraform and can't be 30 // modified without recompilation. 31 // 32 // To read an available backend, use the Backend function. This ensures 33 // safe concurrent read access to the list of built-in backends. 34 // 35 // Backends are hardcoded into Terraform because the API for backends uses 36 // complex structures and supporting that over the plugin system is currently 37 // prohibitively difficult. For those wanting to implement a custom backend, 38 // they can do so with recompilation. 39 var backends map[string]backend.InitFn 40 var backendsLock sync.Mutex 41 42 // RemovedBackends is a record of previously supported backends which have 43 // since been deprecated and removed. 44 var RemovedBackends map[string]string 45 46 // Init initializes the backends map with all our hardcoded backends. 47 func Init(services *disco.Disco) { 48 backendsLock.Lock() 49 defer backendsLock.Unlock() 50 51 backends = map[string]backend.InitFn{ 52 "local": func() backend.Backend { return backendLocal.New() }, 53 "remote": func() backend.Backend { return backendRemote.New(services) }, 54 55 // Remote State backends. 56 "azurerm": func() backend.Backend { return backendAzure.New() }, 57 "consul": func() backend.Backend { return backendConsul.New() }, 58 "cos": func() backend.Backend { return backendCos.New() }, 59 "gcs": func() backend.Backend { return backendGCS.New() }, 60 "http": func() backend.Backend { return backendHTTP.New() }, 61 "inmem": func() backend.Backend { return backendInmem.New() }, 62 "kubernetes": func() backend.Backend { return backendKubernetes.New() }, 63 "oss": func() backend.Backend { return backendOSS.New() }, 64 "pg": func() backend.Backend { return backendPg.New() }, 65 "s3": func() backend.Backend { return backendS3.New() }, 66 67 // Terraform Cloud 'backend' 68 // This is an implementation detail only, used for the cloud package 69 "cloud": func() backend.Backend { return backendCloud.New(services) }, 70 } 71 72 RemovedBackends = map[string]string{ 73 "artifactory": `The "artifactory" backend is not supported in Terraform v1.3 or later.`, 74 "azure": `The "azure" backend name has been removed, please use "azurerm".`, 75 "etcd": `The "etcd" backend is not supported in Terraform v1.3 or later.`, 76 "etcdv3": `The "etcdv3" backend is not supported in Terraform v1.3 or later.`, 77 "manta": `The "manta" backend is not supported in Terraform v1.3 or later.`, 78 "swift": `The "swift" backend is not supported in Terraform v1.3 or later.`, 79 } 80 } 81 82 // Backend returns the initialization factory for the given backend, or 83 // nil if none exists. 84 func Backend(name string) backend.InitFn { 85 backendsLock.Lock() 86 defer backendsLock.Unlock() 87 return backends[name] 88 } 89 90 // Set sets a new backend in the list of backends. If f is nil then the 91 // backend will be removed from the map. If this backend already exists 92 // then it will be overwritten. 93 // 94 // This method sets this backend globally and care should be taken to do 95 // this only before Terraform is executing to prevent odd behavior of backends 96 // changing mid-execution. 97 func Set(name string, f backend.InitFn) { 98 backendsLock.Lock() 99 defer backendsLock.Unlock() 100 101 if f == nil { 102 delete(backends, name) 103 return 104 } 105 106 backends[name] = f 107 } 108 109 // deprecatedBackendShim is used to wrap a backend and inject a deprecation 110 // warning into the Validate method. 111 type deprecatedBackendShim struct { 112 backend.Backend 113 Message string 114 } 115 116 // PrepareConfig delegates to the wrapped backend to validate its config 117 // and then appends shim's deprecation warning. 118 func (b deprecatedBackendShim) PrepareConfig(obj cty.Value) (cty.Value, tfdiags.Diagnostics) { 119 newObj, diags := b.Backend.PrepareConfig(obj) 120 return newObj, diags.Append(tfdiags.SimpleWarning(b.Message)) 121 } 122 123 // DeprecateBackend can be used to wrap a backend to retrun a deprecation 124 // warning during validation. 125 func deprecateBackend(b backend.Backend, message string) backend.Backend { 126 // Since a Backend wrapped by deprecatedBackendShim can no longer be 127 // asserted as an Enhanced or Local backend, disallow those types here 128 // entirely. If something other than a basic backend.Backend needs to be 129 // deprecated, we can add that functionality to schema.Backend or the 130 // backend itself. 131 if _, ok := b.(backend.Enhanced); ok { 132 panic("cannot use DeprecateBackend on an Enhanced Backend") 133 } 134 135 if _, ok := b.(backend.Local); ok { 136 panic("cannot use DeprecateBackend on a Local Backend") 137 } 138 139 return deprecatedBackendShim{ 140 Backend: b, 141 Message: message, 142 } 143 }