package main import ( "encoding/json" "fmt" "os" "path/filepath" "runtime" ) // InfraState persists infrastructure resource UUIDs between commands. type InfraState struct { Zone string `json:"zone"` ClientName string `json:"client_name,omitempty"` RepoBranch string `json:"repo_branch,omitempty"` Network StateRef `json:"network"` Appview ServerState `json:"appview"` Hold ServerState `json:"hold"` LB StateRef `json:"loadbalancer"` ObjectStorage ObjectStorageState `json:"object_storage"` ScannerEnabled bool `json:"scanner_enabled,omitempty"` ScannerSecret string `json:"scanner_secret,omitempty"` } // Naming returns a Naming helper, defaulting to "seamark" if ClientName is empty. func (s *InfraState) Naming() Naming { name := s.ClientName if name == "" { name = "seamark" } return Naming{ClientName: name} } // Branch returns the repo branch, defaulting to "main" if empty. func (s *InfraState) Branch() string { if s.RepoBranch == "" { return "main" } return s.RepoBranch } type StateRef struct { UUID string `json:"uuid"` } type ServerState struct { UUID string `json:"server_uuid"` PublicIP string `json:"public_ip"` PrivateIP string `json:"private_ip"` } type ObjectStorageState struct { UUID string `json:"uuid"` Endpoint string `json:"endpoint"` Region string `json:"region"` Bucket string `json:"bucket"` AccessKeyID string `json:"access_key_id"` } func statePath() string { _, thisFile, _, _ := runtime.Caller(0) return filepath.Join(filepath.Dir(thisFile), "state.json") } func loadState() (*InfraState, error) { data, err := os.ReadFile(statePath()) if err != nil { return nil, fmt.Errorf("read state.json: %w (run 'provision' first)", err) } var st InfraState if err := json.Unmarshal(data, &st); err != nil { return nil, fmt.Errorf("parse state.json: %w", err) } return &st, nil } func saveState(st *InfraState) error { data, err := json.MarshalIndent(st, "", " ") if err != nil { return fmt.Errorf("marshal state: %w", err) } if err := os.WriteFile(statePath(), data, 0644); err != nil { return fmt.Errorf("write state.json: %w", err) } return nil } func deleteState() error { if err := os.Remove(statePath()); err != nil && !os.IsNotExist(err) { return fmt.Errorf("remove state.json: %w", err) } return nil }