Skip to content

Commit

Permalink
feat(config): switch to HCLOUD_TOKEN_FILE variable
Browse files Browse the repository at this point in the history
  • Loading branch information
simonostendorf committed Jun 5, 2024
1 parent 4d1cac1 commit 15a43f4
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 24 deletions.
30 changes: 22 additions & 8 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,30 @@ type HCCMConfiguration struct {
Route RouteConfiguration
}

// read values from environment variables or from file set via _FILE env var
// values set directly via env var take precedence over values set via file

Check failure on line 101 in internal/config/config.go

View workflow job for this annotation

GitHub Actions / Lint

Comment should end in a period (godot)
func readFromEnvOrFile(envVar string) (string, error) {
value := os.Getenv(envVar)
if strings.HasPrefix(value, "file:") {
valueBytes, err := os.ReadFile(strings.TrimPrefix(value, "file:"))
if err != nil {
return "", fmt.Errorf("failed to read %s from file: %w", envVar, err)
}
return strings.TrimSpace(string(valueBytes)), nil
// check if the value is set directly via env (e.g. HCLOUD_TOKEN)
value, ok := os.LookupEnv(envVar)
if ok {
return value, nil
}

// check if the value is set via a file (e.g. HCLOUD_TOKEN_FILE)
value, ok = os.LookupEnv(envVar + "_FILE")
if !ok {
// return no error here, the values could be optional
// and the function "Validate()" below checks that all required variables are set
return "", nil
}
return value, nil

// read file content
valueBytes, err := os.ReadFile(value)
if err != nil {
return "", fmt.Errorf("failed to read %s: %w", envVar+"_FILE", err)
}

return strings.TrimSpace(string(valueBytes)), nil
}

// Read evaluates all environment variables and returns a [HCCMConfiguration]. It only validates as far as
Expand Down
19 changes: 10 additions & 9 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ func TestRead(t *testing.T) {
{
name: "secrets from file",
env: []string{
"HCLOUD_TOKEN", "file:hetzner-token",
"ROBOT_USER", "file:hetzner-user",
"ROBOT_PASSWORD", "file:hetzner-password",
"HCLOUD_TOKEN_FILE", "/tmp/hetzner-token",
"ROBOT_USER_FILE", "/tmp/hetzner-user",
"ROBOT_PASSWORD_FILE", "/tmp/hetzner-password",
},
files: map[string]string{
"hetzner-token": "jr5g7ZHpPptyhJzZyHw2Pqu4g9gTqDvEceYpngPf79jN_NOT_VALID_dzhepnahq",
Expand All @@ -80,10 +80,11 @@ func TestRead(t *testing.T) {
{
name: "secrets from unknown file",
env: []string{
"HCLOUD_TOKEN", "file:/etc/hetzner/token",
"ROBOT_USER", "file:/etc/hetzner/user",
"ROBOT_PASSWORD", "file:/etc/hetzner/password",
"HCLOUD_TOKEN_FILE", "/tmp/hetzner-token",
"ROBOT_USER_FILE", "/tmp/hetzner-user",
"ROBOT_PASSWORD_FILE", "/tmp/hetzner-password",
},
files: map[string]string{}, // don't create files
want: HCCMConfiguration{
HCloudClient: HCloudClientConfiguration{Token: ""},
Robot: RobotConfiguration{User: "", Password: "", CacheTimeout: 0},
Expand All @@ -92,9 +93,9 @@ func TestRead(t *testing.T) {
LoadBalancer: LoadBalancerConfiguration{Enabled: false},
Route: RouteConfiguration{Enabled: false},
},
wantErr: errors.New(`failed to read HCLOUD_TOKEN from file: open /etc/hetzner/token: no such file or directory
failed to read ROBOT_USER from file: open /etc/hetzner/user: no such file or directory
failed to read ROBOT_PASSWORD from file: open /etc/hetzner/password: no such file or directory`),
wantErr: errors.New(`failed to read HCLOUD_TOKEN_FILE: open /tmp/hetzner-token: no such file or directory
failed to read ROBOT_USER_FILE: open /tmp/hetzner-user: no such file or directory
failed to read ROBOT_PASSWORD_FILE: open /tmp/hetzner-password: no such file or directory`),
},
{
name: "client",
Expand Down
19 changes: 12 additions & 7 deletions internal/testsupport/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,28 @@ import (
"testing"
)

// SetFiles can be used to temporarily create files on the local file system.
// It returns a function that will clean up all files it created.
func Setfiles(t *testing.T, files map[string]string) func() {
for file, content := range files {
filepath := os.TempDir() + "/" + file

// check if file exists
_, err := os.Stat(file)
_, err := os.Stat(filepath)
if err == nil {
t.Fatalf("Trying to set file %s, but it already exists. Please choose another filepath for the test.", file)
t.Fatalf("Trying to set file %s, but it already exists. Please choose another filepath for the test.", filepath)
}

// create file
f, err := os.Create(file)
f, err := os.Create(filepath)
if err != nil {
t.Fatalf("Failed to create file %s: %v", file, err)
t.Fatalf("Failed to create file %s: %v", filepath, err)
}

// write content to file
_, err = f.WriteString(content)
if err != nil {
t.Fatalf("Failed to write to file %s: %v", file, err)
t.Fatalf("Failed to write to file %s: %v", filepath, err)
}

// close file
Expand All @@ -31,9 +35,10 @@ func Setfiles(t *testing.T, files map[string]string) func() {

return func() {
for file := range files {
err := os.Remove(file)
filepath := os.TempDir() + "/" + file
err := os.Remove(filepath)
if err != nil {
t.Fatalf("Failed to remove file %s: %v", file, err)
t.Fatalf("Failed to remove file %s: %v", filepath, err)
}
}
}
Expand Down

0 comments on commit 15a43f4

Please sign in to comment.