32: systemd-vaultd-update-secrets: do not depend on CREDENTIALS_DIRECTORY… r=Mic92 a=Mic92



Co-authored-by: Jörg Thalheim <joerg@thalheim.io>
main
bors[bot] 2 years ago committed by GitHub
commit ad3af48a81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,6 +3,7 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"log"
"os" "os"
"path" "path"
"syscall" "syscall"
@ -13,20 +14,37 @@ const (
systemdVaultdir = "/run/systemd-vaultd/secrets" systemdVaultdir = "/run/systemd-vaultd/secrets"
) )
func updateSecrets(credentialsDirectory, target string) error { func updateSecrets(serviceName, target string) error {
// get systemd service name from credentials directory // get systemd service name from credentials directory
serviceName := path.Base(credentialsDirectory) stat, err := os.Stat(target)
stat, err := os.Stat(credentialsDirectory)
if err != nil { if err != nil {
return fmt.Errorf("failed to stat %s: %w", credentialsDirectory, err) return fmt.Errorf("failed to stat target %s: %w", target, err)
} }
// inherit the owner and group of the credentials directory // inherit the owner and group of the credentials directory
uid := stat.Sys().(*syscall.Stat_t).Uid uid := stat.Sys().(*syscall.Stat_t).Uid
gid := stat.Sys().(*syscall.Stat_t).Gid gid := stat.Sys().(*syscall.Stat_t).Gid
jsonPath := path.Join(credentialsDirectory, fmt.Sprintf("%s.json", serviceName)) jsonPath := path.Join(systemdVaultdir, fmt.Sprintf("%s.json", serviceName))
var content []byte var content []byte
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
jsonStat, err := os.Stat(jsonPath)
if err != nil {
if os.IsNotExist(err) {
// wait for the file to be created
fmt.Printf("waiting for %s to be created", jsonPath)
time.Sleep(1 * time.Second)
continue
}
return fmt.Errorf("failed to stat vault json file %s: %w", serviceName, err)
}
if jsonStat.ModTime().Before(stat.ModTime()) {
// wait for the file to be updated
fmt.Printf("waiting for %s to be updated", jsonPath)
time.Sleep(1 * time.Second)
continue
}
content, err = os.ReadFile(jsonPath) content, err = os.ReadFile(jsonPath)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
@ -45,14 +63,23 @@ func updateSecrets(credentialsDirectory, target string) error {
} }
for key, value := range data { for key, value := range data {
targetPath := path.Join(target, key) targetPath := path.Join(target, key)
err := os.MkdirAll(path.Dir(targetPath), 0o700) tempPath := targetPath + ".tmp"
os.Chown(path.Dir(targetPath), int(uid), int(gid)) err = os.WriteFile(tempPath, []byte(value.(string)), 0o400)
if err != nil {
return fmt.Errorf("failed to write file %s: %w", targetPath, err)
}
err = os.Chown(tempPath, int(uid), int(gid))
if err != nil {
return fmt.Errorf("failed to chown file %s: %w", targetPath, err)
}
err = os.Rename(tempPath, targetPath)
if err != nil { if err != nil {
return fmt.Errorf("failed to create directory %s: %w", path.Dir(targetPath), err) return fmt.Errorf("failed to rename file %s: %w", targetPath, err)
} }
os.WriteFile(targetPath, []byte(value.(string)), 0o400) }
os.Chown(targetPath, int(uid), int(gid)) err = os.Chtimes(target, time.Now(), time.Now())
if err != nil {
log.Printf("failed to update modification time of %s: %v", target, err)
} }
return nil return nil
@ -63,14 +90,14 @@ func main() {
fmt.Println("Usage: systemd-vaultd-update-secrets <target>") fmt.Println("Usage: systemd-vaultd-update-secrets <target>")
os.Exit(1) os.Exit(1)
} }
credentialsDirectory := os.Getenv("CREDENTIALS_DIRECTORY") serviceName := os.Getenv("SYSTEMD_ACTIVATION_UNIT")
if credentialsDirectory == "" { if serviceName == "" {
fmt.Println("CREDENTIALS_DIRECTORY environment variable must be set") fmt.Println("SYSTEMD_ACTIVATION_UNIT not set")
os.Exit(1) os.Exit(1)
} }
target := os.Args[1] target := os.Args[1]
if err := updateSecrets(credentialsDirectory, target); err != nil { if err := updateSecrets(serviceName, target); err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
} }

Loading…
Cancel
Save