add secret versioning support

This commit is contained in:
2025-06-08 22:07:19 -07:00
parent f59ee4d2d6
commit fbda2d91af
16 changed files with 2451 additions and 1608 deletions

View File

@@ -3,6 +3,7 @@ package secret
import (
"os"
"path/filepath"
"strings"
"testing"
"filippo.io/age"
@@ -23,12 +24,33 @@ func (m *MockVault) GetDirectory() (string, error) {
}
func (m *MockVault) AddSecret(name string, value []byte, force bool) error {
// Simplified implementation for testing
secretDir := filepath.Join(m.directory, "secrets.d", name)
if err := m.fs.MkdirAll(secretDir, DirPerms); err != nil {
// Create versioned structure for testing
storageName := strings.ReplaceAll(name, "/", "%")
secretDir := filepath.Join(m.directory, "secrets.d", storageName)
// Generate version name
versionName, err := GenerateVersionName(m.fs, secretDir)
if err != nil {
return err
}
return afero.WriteFile(m.fs, filepath.Join(secretDir, "value.age"), value, FilePerms)
// Create version directory
versionDir := filepath.Join(secretDir, "versions", versionName)
if err := m.fs.MkdirAll(versionDir, DirPerms); err != nil {
return err
}
// Write encrypted value (simplified for testing)
if err := afero.WriteFile(m.fs, filepath.Join(versionDir, "value.age"), value, FilePerms); err != nil {
return err
}
// Set current symlink
if err := SetCurrentVersion(m.fs, secretDir, versionName); err != nil {
return err
}
return nil
}
func (m *MockVault) GetName() string {
@@ -122,16 +144,30 @@ func TestPerSecretKeyFunctionality(t *testing.T) {
// Verify that all expected files were created
secretDir := filepath.Join(vaultDir, "secrets.d", secretName)
// Check value.age exists (the new per-secret key architecture format)
secretExists, err := afero.Exists(
fs,
filepath.Join(secretDir, "value.age"),
)
if err != nil || !secretExists {
t.Fatalf("value.age file was not created")
// Check versions directory exists
versionsDir := filepath.Join(secretDir, "versions")
versionsDirExists, err := afero.DirExists(fs, versionsDir)
if err != nil || !versionsDirExists {
t.Fatalf("versions directory was not created")
}
t.Logf("All expected files created successfully")
// Check current symlink exists
currentVersion, err := GetCurrentVersion(fs, secretDir)
if err != nil {
t.Fatalf("Failed to get current version: %v", err)
}
// Check value.age exists in the version directory
versionDir := filepath.Join(versionsDir, currentVersion)
valueExists, err := afero.Exists(
fs,
filepath.Join(versionDir, "value.age"),
)
if err != nil || !valueExists {
t.Fatalf("value.age file was not created in version directory")
}
t.Logf("All expected files created successfully with versioning")
})
// Create a Secret object to test with