From 0e49d40db827263aeab91439c6a9ff06e30cf477 Mon Sep 17 00:00:00 2001 From: CarambarLoL <108605785+ChrisFromCnC@users.noreply.github.com> Date: Thu, 11 Apr 2024 17:22:33 +0200 Subject: [PATCH] Add secrets file support for docker I propose to add support to dockerfile secrets for PBS_USERNAME, PBS_API_TOKEN_NAME and PBS_API_TOKEN. Idea is to move secrets outside of docker-compose file for instance for security purpose. As example a docker-compose file can be created like this: proxmoxbackup: image: ghcr.io/natrontech/pbs-exporter:0.1.5 container_name: proxmoxbackup restart: always secrets: - proxmoxbackup-username - proxmoxbackup-api-token-name - proxmoxbackup-api-token environment: PBS_USERNAME_FILE: /run/secrets/proxmoxbackup-username PBS_API_TOKEN_NAME_FILE: /run/secrets/proxmoxbackup-api-token-name PBS_API_TOKEN_FILE: /run/secrets/proxmoxbackup-api-token secrets: proxmoxbackup-username: file: "./.secrets/proxmoxbackup_username.secret" proxmoxbackup-api-token-name: file: "./.secrets/proxmoxbackup_api_token_name.secret" proxmoxbackup-api-token: file: "./.secrets/proxmoxbackup_api_token.secret" All secrets are now stored in a folder .secrets. Convention naming for secrets in docker is to add _FILE to regular environnement variable. In our case we need to manage PBS_USERNAME_FILE, PBS_API_TOKEN_NAME_FILE and PBS_API_TOKEN_FILE env variables. I just adapt the main.go to read the new env variable for the secret file name and read the first line from the file. --- main.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/main.go b/main.go index 1e6686d..cd8cd88 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "crypto/tls" "encoding/json" "flag" @@ -234,6 +235,24 @@ type Exporter struct { authorizationHeader string } +func ReadSecretFile(secretfilename string) string { + file, err := os.Open(secretfilename) + // flag to check the file format + if err != nil { + log.Fatal(err) + } + // Close the file + defer func() { + if err = file.Close(); err != nil { + log.Fatal(err) + } + }() + // Read the first line + line := bufio.NewScanner(file) + line.Scan() + return line.Text() +} + func NewExporter(endpoint string, username string, apitoken string, apitokenname string) *Exporter { return &Exporter{ endpoint: endpoint, @@ -660,12 +679,24 @@ func main() { } if os.Getenv("PBS_USERNAME") != "" { *username = os.Getenv("PBS_USERNAME") + } else { + if os.Getenv("PBS_USERNAME_FILE") != "" { + *username = ReadSecretFile(os.Getenv("PBS_USERNAME_FILE")) + } } if os.Getenv("PBS_API_TOKEN_NAME") != "" { *apitokenname = os.Getenv("PBS_API_TOKEN_NAME") + } else { + if os.Getenv("PBS_API_TOKEN_NAME_FILE") != "" { + *apitokenname = ReadSecretFile(os.Getenv("PBS_API_TOKEN_NAME_FILE")) + } } if os.Getenv("PBS_API_TOKEN") != "" { *apitoken = os.Getenv("PBS_API_TOKEN") + } else { + if os.Getenv("PBS_API_TOKEN_FILE") != "" { + *apitoken = ReadSecretFile(os.Getenv("PBS_API_TOKEN_FILE")) + } } if os.Getenv("PBS_TIMEOUT") != "" { *timeout = os.Getenv("PBS_TIMEOUT")