Files
osmedeus/internal/cloud/state.go
T
j3ssie 459d5939fb feat: add cloud infrastructure and nmap/tmux function support
- Implement cloud provider infrastructure (DigitalOcean, AWS, GCP, Linode, Azure) with Pulumi integration for distributed scanning
- Add nmap and tmux utility functions for port scanning results processing and long-running background session management
- Introduce webhook-triggered run execution with unique UUID and authentication key support for external integrations
2026-02-16 15:23:24 +07:00

108 lines
3.1 KiB
Go

package cloud
import (
"fmt"
"os"
"path/filepath"
"github.com/j3ssie/osmedeus/v5/internal/json"
)
// SaveInfrastructureState persists infrastructure state to disk
func SaveInfrastructureState(infra *Infrastructure, statePath string) error {
// Ensure state directory exists
stateDir := filepath.Join(statePath, "infrastructure")
if err := os.MkdirAll(stateDir, 0755); err != nil {
return fmt.Errorf("failed to create state directory: %w", err)
}
// Create state file path
stateFile := filepath.Join(stateDir, fmt.Sprintf("%s.json", infra.ID))
// Marshal infrastructure to JSON
data, err := json.Marshal(infra)
if err != nil {
return fmt.Errorf("failed to marshal infrastructure state: %w", err)
}
// Write state file
if err := os.WriteFile(stateFile, data, 0644); err != nil {
return fmt.Errorf("failed to write state file: %w", err)
}
return nil
}
// LoadInfrastructureState loads infrastructure state from disk
func LoadInfrastructureState(infraID, statePath string) (*Infrastructure, error) {
stateFile := filepath.Join(statePath, "infrastructure", fmt.Sprintf("%s.json", infraID))
// Read state file
data, err := os.ReadFile(stateFile)
if err != nil {
return nil, fmt.Errorf("failed to read state file: %w", err)
}
// Unmarshal infrastructure
var infra Infrastructure
if err := json.Unmarshal(data, &infra); err != nil {
return nil, fmt.Errorf("failed to unmarshal infrastructure state: %w", err)
}
return &infra, nil
}
// ListInfrastructures lists all saved infrastructure states
func ListInfrastructures(statePath string) ([]*Infrastructure, error) {
stateDir := filepath.Join(statePath, "infrastructure")
// Check if directory exists
if _, err := os.Stat(stateDir); os.IsNotExist(err) {
return []*Infrastructure{}, nil
}
// Read directory entries
entries, err := os.ReadDir(stateDir)
if err != nil {
return nil, fmt.Errorf("failed to read state directory: %w", err)
}
// Load each infrastructure state
var infrastructures []*Infrastructure
for _, entry := range entries {
if entry.IsDir() || filepath.Ext(entry.Name()) != ".json" {
continue
}
infraID := entry.Name()[:len(entry.Name())-5] // Remove .json extension
infra, err := LoadInfrastructureState(infraID, statePath)
if err != nil {
// Log warning but continue
fmt.Printf("Warning: failed to load infrastructure %s: %v\n", infraID, err)
continue
}
infrastructures = append(infrastructures, infra)
}
return infrastructures, nil
}
// RemoveInfrastructureState removes infrastructure state from disk
func RemoveInfrastructureState(infraID, statePath string) error {
stateFile := filepath.Join(statePath, "infrastructure", fmt.Sprintf("%s.json", infraID))
if err := os.Remove(stateFile); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("failed to remove state file: %w", err)
}
return nil
}
// InfrastructureExists checks if an infrastructure state exists
func InfrastructureExists(infraID, statePath string) bool {
stateFile := filepath.Join(statePath, "infrastructure", fmt.Sprintf("%s.json", infraID))
_, err := os.Stat(stateFile)
return err == nil
}