No One Can Stop Me Now
This commit is contained in:
107
services/setec-manager/internal/hosting/config.go
Normal file
107
services/setec-manager/internal/hosting/config.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package hosting
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ProviderConfigStore manages saved provider configurations on disk.
|
||||
// Each provider's config is stored as a separate JSON file with restrictive
|
||||
// permissions (0600) since the files contain API keys.
|
||||
type ProviderConfigStore struct {
|
||||
configDir string
|
||||
}
|
||||
|
||||
// NewConfigStore creates a new store rooted at configDir. The directory is
|
||||
// created on first write if it does not already exist.
|
||||
func NewConfigStore(configDir string) *ProviderConfigStore {
|
||||
return &ProviderConfigStore{configDir: configDir}
|
||||
}
|
||||
|
||||
// configPath returns the file path for a provider's config file.
|
||||
func (s *ProviderConfigStore) configPath(providerName string) string {
|
||||
return filepath.Join(s.configDir, providerName+".json")
|
||||
}
|
||||
|
||||
// ensureDir creates the config directory if it does not exist.
|
||||
func (s *ProviderConfigStore) ensureDir() error {
|
||||
return os.MkdirAll(s.configDir, 0700)
|
||||
}
|
||||
|
||||
// Save writes a provider configuration to disk. It overwrites any existing
|
||||
// config for the same provider.
|
||||
func (s *ProviderConfigStore) Save(providerName string, cfg ProviderConfig) error {
|
||||
if providerName == "" {
|
||||
return fmt.Errorf("hosting: provider name must not be empty")
|
||||
}
|
||||
if err := s.ensureDir(); err != nil {
|
||||
return fmt.Errorf("hosting: create config dir: %w", err)
|
||||
}
|
||||
|
||||
data, err := json.MarshalIndent(cfg, "", " ")
|
||||
if err != nil {
|
||||
return fmt.Errorf("hosting: marshal config for %s: %w", providerName, err)
|
||||
}
|
||||
|
||||
path := s.configPath(providerName)
|
||||
if err := os.WriteFile(path, data, 0600); err != nil {
|
||||
return fmt.Errorf("hosting: write config for %s: %w", providerName, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Load reads a provider configuration from disk.
|
||||
func (s *ProviderConfigStore) Load(providerName string) (*ProviderConfig, error) {
|
||||
path := s.configPath(providerName)
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("hosting: no config found for provider %q", providerName)
|
||||
}
|
||||
return nil, fmt.Errorf("hosting: read config for %s: %w", providerName, err)
|
||||
}
|
||||
|
||||
var cfg ProviderConfig
|
||||
if err := json.Unmarshal(data, &cfg); err != nil {
|
||||
return nil, fmt.Errorf("hosting: parse config for %s: %w", providerName, err)
|
||||
}
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
// Delete removes a provider's saved configuration.
|
||||
func (s *ProviderConfigStore) Delete(providerName string) error {
|
||||
path := s.configPath(providerName)
|
||||
if err := os.Remove(path); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil // already gone
|
||||
}
|
||||
return fmt.Errorf("hosting: delete config for %s: %w", providerName, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListConfigured returns the names of all providers that have saved configs.
|
||||
func (s *ProviderConfigStore) ListConfigured() ([]string, error) {
|
||||
entries, err := os.ReadDir(s.configDir)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil // no directory means no configs
|
||||
}
|
||||
return nil, fmt.Errorf("hosting: list configs: %w", err)
|
||||
}
|
||||
|
||||
var names []string
|
||||
for _, e := range entries {
|
||||
if e.IsDir() {
|
||||
continue
|
||||
}
|
||||
name := e.Name()
|
||||
if strings.HasSuffix(name, ".json") {
|
||||
names = append(names, strings.TrimSuffix(name, ".json"))
|
||||
}
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
Reference in New Issue
Block a user