As part of our efforts to remove the large snapshot of the legacy SDK that
we've been using, this replaces the uses of that package with our new
lightweight "backendbase" package, which is a collection of helpers that
can substitute for most of the parts of the legacy SDK that backends tend
to use.
For this backend for now we'll use the "SDK like" helpers which aim to
retain some of the legacy-SDK-specific assumptions that aren't technically
true anymore, such as the idea that null and empty string are equivalent.
Hopefully one day we'll be able to wean this backend off of that more
completely, but this is a pragmatic way to get away from the legacy SDK
without a large rewrite.
This also drew attention to the fact that this backend was previously
relying on the weird context.Context value that the SDK was passing in
to the configure method, even though that context isn't connected up to
anything particularly useful. In the long run we should change the backend
APIs to pass context.Context to each method that might make network
requests, but for now we're using context.TODO so that we can more easily
find these cases and update them later once there's a real context to use.
// Input(), Validate() and Configure() are implemented by embedding *schema.Backend.
// State(), DeleteState() and States() are implemented explicitly.
// Schema() and PrepareConfig() are implemented by embedding backendbase.Base.
// Configure(), State(), DeleteState() and States() are implemented explicitly.
typeBackendstruct{
*schema.Backend
backendbase.Base
storageClient*storage.Client
storageContextcontext.Context
storageClient*storage.Client
bucketNamestring
prefixstring
@ -38,104 +41,116 @@ type Backend struct {
}
funcNew()backend.Backend{
b:=&Backend{}
b.Backend=&schema.Backend{
ConfigureFunc:b.configure,
Schema:map[string]*schema.Schema{
"bucket":{
Type:schema.TypeString,
Required:true,
Description:"The name of the Google Cloud Storage bucket",
return&Backend{
Base:backendbase.Base{
Schema:&configschema.Block{
Attributes:map[string]*configschema.Attribute{
"bucket":{
Type:cty.String,
Required:true,
Description:"The name of the Google Cloud Storage bucket",
},
"prefix":{
Type:cty.String,
Optional:true,
Description:"The directory where state files will be saved inside the bucket",
},
"credentials":{
Type:cty.String,
Optional:true,
Description:"Google Cloud JSON Account Key",
},
"access_token":{
Type:cty.String,
Optional:true,
Description:"An OAuth2 token used for GCP authentication",
},
"impersonate_service_account":{
Type:cty.String,
Optional:true,
Description:"The service account to impersonate for all Google API Calls",
},
"impersonate_service_account_delegates":{
Type:cty.List(cty.String),
Optional:true,
Description:"The delegation chain for the impersonated service account",
},
"encryption_key":{
Type:cty.String,
Optional:true,
Description:"A 32 byte base64 encoded 'customer supplied encryption key' used when reading and writing state files in the bucket.",
},
"kms_encryption_key":{
Type:cty.String,
Optional:true,
Description:"A Cloud KMS key ('customer managed encryption key') used when reading and writing state files in the bucket. Format should be 'projects/{{project}}/locations/{{location}}/keyRings/{{keyRing}}/cryptoKeys/{{name}}'.",
},
"storage_custom_endpoint":{
Type:cty.String,
Optional:true,
},
},
},
"prefix":{
Type:schema.TypeString,
Optional:true,
Description:"The directory where state files will be saved inside the bucket",
},
"credentials":{
Type:schema.TypeString,
Optional:true,
Description:"Google Cloud JSON Account Key",
Default:"",
},
"access_token":{
Type:schema.TypeString,
Optional:true,
DefaultFunc:schema.MultiEnvDefaultFunc([]string{
"GOOGLE_OAUTH_ACCESS_TOKEN",
},nil),
Description:"An OAuth2 token used for GCP authentication",
},
"impersonate_service_account":{
Type:schema.TypeString,
Optional:true,
DefaultFunc:schema.MultiEnvDefaultFunc([]string{
"GOOGLE_BACKEND_IMPERSONATE_SERVICE_ACCOUNT",
"GOOGLE_IMPERSONATE_SERVICE_ACCOUNT",
},nil),
Description:"The service account to impersonate for all Google API Calls",
},
"impersonate_service_account_delegates":{
Type:schema.TypeList,
Optional:true,
Description:"The delegation chain for the impersonated service account",
Elem:&schema.Schema{Type:schema.TypeString},
},
"encryption_key":{
Type:schema.TypeString,
Optional:true,
DefaultFunc:schema.MultiEnvDefaultFunc([]string{
"GOOGLE_ENCRYPTION_KEY",
},nil),
Description:"A 32 byte base64 encoded 'customer supplied encryption key' used when reading and writing state files in the bucket.",
ConflictsWith:[]string{"kms_encryption_key"},
},
"kms_encryption_key":{
Type:schema.TypeString,
Optional:true,
DefaultFunc:schema.MultiEnvDefaultFunc([]string{
"GOOGLE_KMS_ENCRYPTION_KEY",
},nil),
Description:"A Cloud KMS key ('customer managed encryption key') used when reading and writing state files in the bucket. Format should be 'projects/{{project}}/locations/{{location}}/keyRings/{{keyRing}}/cryptoKeys/{{name}}'.",