Scrub example config of real credentials and internal hosts (closes #172)
check / check (pull_request) Successful in 2m26s

config.example.yml carried a real-looking 20-char S3 access key id and
40-char secret, a private-address http:// endpoint, and a storage_url
naming an internal rclone remote and pool path. Replace them with the
same neutral placeholders the `config init` template uses:
YOUR_ACCESS_KEY / YOUR_SECRET_KEY, a https://s3.example.com endpoint,
a mybucket bucket, and rclone://myremote/path/to/backups. No behavior
or other keys change.

The credentials live in the commented-out s3 block, which the loader
never parses, so the new test reads the file's raw text to assert the
placeholders are present and no http:// endpoint remains, and also
loads it to confirm the active storage_url still parses.

Model: opus-4-8
This commit is contained in:
2026-09-22 11:20:37 +00:00
parent 548a7ae156
commit 4d3949c1f2
2 changed files with 47 additions and 5 deletions
+5 -5
View File
@@ -257,16 +257,16 @@ exclude:
# Storage URL - use either this OR the s3 section below # Storage URL - use either this OR the s3 section below
# Supports: s3://bucket/prefix, file:///path, rclone://remote/path # Supports: s3://bucket/prefix, file:///path, rclone://remote/path
storage_url: "rclone://las1stor1//srv/pool.2024.04/backups/heraklion" storage_url: "rclone://myremote/path/to/backups"
# S3-compatible storage configuration # S3-compatible storage configuration
#s3: #s3:
# # S3-compatible endpoint URL # # S3-compatible endpoint URL
# # Examples: https://s3.amazonaws.com, https://storage.googleapis.com # # Examples: https://s3.amazonaws.com, https://storage.googleapis.com
# endpoint: http://10.100.205.122:8333 # endpoint: https://s3.example.com
# #
# # Bucket name where backups will be stored # # Bucket name where backups will be stored
# bucket: testbucket # bucket: mybucket
# #
# # Prefix (folder) within the bucket for this host's backups # # Prefix (folder) within the bucket for this host's backups
# # Useful for organizing backups from multiple hosts # # Useful for organizing backups from multiple hosts
@@ -274,8 +274,8 @@ storage_url: "rclone://las1stor1//srv/pool.2024.04/backups/heraklion"
# #prefix: "hosts/myserver/" # #prefix: "hosts/myserver/"
# #
# # S3 access credentials # # S3 access credentials
# access_key_id: Z9GT22M9YFU08WRMC5D4 # access_key_id: YOUR_ACCESS_KEY
# secret_access_key: Pi0tPKjFbN4rZlRhcA4zBtEkib04yy2WcIzI+AXk # secret_access_key: YOUR_SECRET_KEY
# #
# # S3 region # # S3 region
# # Default: us-east-1 # # Default: us-east-1
+42
View File
@@ -87,6 +87,48 @@ func TestConfigLoad(t *testing.T) {
} }
} }
// TestExampleConfigIsScrubbedAndLoads checks that the shipped
// config.example.yml carries only neutral placeholders (no real credentials,
// private addresses, or internal host names) and still parses.
func TestExampleConfigIsScrubbedAndLoads(t *testing.T) {
t.Parallel()
examplePath := filepath.Join("..", "..", "config.example.yml")
cfg, err := Load(examplePath)
if err != nil {
t.Fatalf("Failed to load config.example.yml: %v", err)
}
if cfg.StorageURL != "rclone://myremote/path/to/backups" {
t.Errorf("Expected neutral storage_url, got '%s'", cfg.StorageURL)
}
//nolint:gosec // G304: examplePath is a fixed in-repo path, not user input
raw, err := os.ReadFile(examplePath)
if err != nil {
t.Fatalf("Failed to read config.example.yml: %v", err)
}
text := string(raw)
wantSubstrings := []string{
"YOUR_ACCESS_KEY",
"YOUR_SECRET_KEY",
"endpoint: https://",
}
for _, want := range wantSubstrings {
if !strings.Contains(text, want) {
t.Errorf("Expected config.example.yml to contain %q", want)
}
}
// A raw "http://" scheme would mean a plaintext, likely private endpoint.
if strings.Contains(text, "http://") {
t.Error("config.example.yml should not contain an http:// endpoint")
}
}
// TestConfigFromEnv tests loading config path from environment variable // TestConfigFromEnv tests loading config path from environment variable
func TestConfigFromEnv(t *testing.T) { func TestConfigFromEnv(t *testing.T) {
t.Parallel() t.Parallel()