gcs: Adopt the "ReadPathOrContents" helper function

Package backend previously had a ReadPathOrContents helper that takes a
string that could represent either a filename or some literal content, and
then reads the given file if it's a filename or just returns the literal
content otherwise.

We originally used variations of this helper to shim a number of different
situations that had originally accepted filenames but later changed to
accept literal content, but over time we've eliminated all of those and so
the only remaining caller is the gcs backend which uses it to accept
GCP credentials either as literal content or as a file containing the
credentials.

Therefore here we move that helper function to be just an unexported part
of the gcs backend package. This is part of an ongoing effort to minimize
what each remote state backend depends on (either directly or indirectly)
so that we can make gradual progress towards these remote state backends
being self-contained enough to move into other codebases. In the short
term though, it just puts this helper function closer to its caller so it's
easier to maintain them both together if needed.
pull/34827/head
Martin Atkins 2 years ago
parent a2a982206c
commit 914618b061

@ -9,10 +9,7 @@ package backend
import (
"errors"
"io/ioutil"
"os"
"github.com/mitchellh/go-homedir"
"github.com/zclconf/go-cty/cty"
"github.com/hashicorp/terraform/internal/configs/configschema"
@ -107,31 +104,3 @@ type Backend interface {
// in this backend.
Workspaces() ([]string, error)
}
// If the argument is a path, Read loads it and returns the contents,
// otherwise the argument is assumed to be the desired contents and is simply
// returned.
func ReadPathOrContents(poc string) (string, error) {
if len(poc) == 0 {
return poc, nil
}
path := poc
if path[0] == '~' {
var err error
path, err = homedir.Expand(path)
if err != nil {
return path, err
}
}
if _, err := os.Stat(path); err == nil {
contents, err := ioutil.ReadFile(path)
if err != nil {
return string(contents), err
}
return string(contents), nil
}
return poc, nil
}

@ -164,7 +164,7 @@ func (b *Backend) configure(ctx context.Context) error {
} else if creds != "" {
// to mirror how the provider works, we accept the file path or the contents
contents, err := backend.ReadPathOrContents(creds)
contents, err := readPathOrContents(creds)
if err != nil {
return fmt.Errorf("Error loading credentials: %s", err)
}
@ -224,7 +224,7 @@ func (b *Backend) configure(ctx context.Context) error {
// Customer-supplied encryption
key := data.Get("encryption_key").(string)
if key != "" {
kc, err := backend.ReadPathOrContents(key)
kc, err := readPathOrContents(key)
if err != nil {
return fmt.Errorf("Error loading encryption key: %s", err)
}

@ -429,7 +429,7 @@ func testGetClientOptions(t *testing.T) ([]option.ClientOption, error) {
var opts []option.ClientOption
var credOptions []option.ClientOption
contents, err := backend.ReadPathOrContents(creds)
contents, err := readPathOrContents(creds)
if err != nil {
return nil, fmt.Errorf("error loading credentials: %s", err)
}

@ -7,6 +7,7 @@ require (
cloud.google.com/go/storage v1.30.1
github.com/hashicorp/terraform v0.0.0-00010101000000-000000000000
github.com/hashicorp/terraform/internal/legacy v0.0.0-00010101000000-000000000000
github.com/mitchellh/go-homedir v1.1.0
golang.org/x/net v0.21.0
golang.org/x/oauth2 v0.17.0
google.golang.org/api v0.126.0
@ -46,7 +47,6 @@ require (
github.com/klauspost/compress v1.15.11 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect

@ -0,0 +1,39 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package gcs
import (
"io/ioutil"
"os"
"github.com/mitchellh/go-homedir"
)
// If the argument is a path, Read loads it and returns the contents,
// otherwise the argument is assumed to be the desired contents and is simply
// returned.
func readPathOrContents(poc string) (string, error) {
if len(poc) == 0 {
return poc, nil
}
path := poc
if path[0] == '~' {
var err error
path, err = homedir.Expand(path)
if err != nil {
return path, err
}
}
if _, err := os.Stat(path); err == nil {
contents, err := ioutil.ReadFile(path)
if err != nil {
return string(contents), err
}
return string(contents), nil
}
return poc, nil
}

@ -1,7 +1,7 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package backend
package gcs
import (
"io"
@ -23,7 +23,7 @@ func TestReadPathOrContents_Path(t *testing.T) {
}
f.Close()
contents, err := ReadPathOrContents(f.Name())
contents, err := readPathOrContents(f.Name())
if err != nil {
t.Fatalf("err: %s", err)
@ -48,7 +48,7 @@ func TestReadPathOrContents_TildePath(t *testing.T) {
r := strings.NewReplacer(home, "~")
homePath := r.Replace(f.Name())
contents, err := ReadPathOrContents(homePath)
contents, err := readPathOrContents(homePath)
if err != nil {
t.Fatalf("err: %s", err)
@ -79,7 +79,7 @@ func TestRead_PathNoPermission(t *testing.T) {
t.Fatalf("err: %s", err)
}
contents, err := ReadPathOrContents(f.Name())
contents, err := readPathOrContents(f.Name())
if err == nil {
t.Fatal("Expected error, got none!")
@ -92,7 +92,7 @@ func TestRead_PathNoPermission(t *testing.T) {
func TestReadPathOrContents_Contents(t *testing.T) {
input := "hello"
contents, err := ReadPathOrContents(input)
contents, err := readPathOrContents(input)
if err != nil {
t.Fatalf("err: %s", err)
@ -105,7 +105,7 @@ func TestReadPathOrContents_Contents(t *testing.T) {
func TestReadPathOrContents_TildeContents(t *testing.T) {
input := "~/hello/notafile"
contents, err := ReadPathOrContents(input)
contents, err := readPathOrContents(input)
if err != nil {
t.Fatalf("err: %s", err)
Loading…
Cancel
Save