package cloud import ( "context" "fmt" "sync" "time" "git.linuxforward.com/byop/byop-engine/models" ) // InstanceSize represents the size configuration for a VM instance type InstanceSize struct { ID string `json:"id"` Name string `json:"name"` CPUCores int `json:"cpu_cores"` MemoryGB int `json:"memory_gb"` DiskGB int `json:"disk_gb"` Price float64 `json:"price"` // Hourly price } // Region represents a geographic region type Region struct { ID string `json:"id"` Name string `json:"name"` Zone string `json:"zone"` } // Instance represents a virtual machine instance type Instance struct { ID string `json:"id"` Name string `json:"name"` Region string `json:"region"` Size string `json:"size"` ImageID string `json:"image_id"` IPAddress string `json:"ip_address"` PrivateIP string `json:"private_ip,omitempty"` Status string `json:"status"` // Creating, Running, Stopping, Stopped, Restarting, Terminated CreatedAt time.Time `json:"created_at"` Tags map[string]string `json:"tags,omitempty"` SecurityGroups []string `json:"security_groups,omitempty"` } // InstanceCreateOpts are options to configure a new instance type InstanceCreateOpts struct { Name string `json:"name"` Region string `json:"region"` Size string `json:"size"` ImageID string `json:"image_id"` SSHKeyIDs []string `json:"ssh_key_ids,omitempty"` UserData string `json:"user_data,omitempty"` Tags map[string]string `json:"tags,omitempty"` SecurityGroups []string `json:"security_groups,omitempty"` Components []models.Component `json:"components,omitempty"` } // SSHKey represents an SSH key type SSHKey struct { ID string `json:"id"` Name string `json:"name"` Fingerprint string `json:"fingerprint"` PublicKey string `json:"public_key"` CreatedAt time.Time `json:"created_at"` } // Image represents an operating system image type Image struct { ID string `json:"id"` Name string `json:"name"` Description string `json:"description"` Type string `json:"type"` // base, snapshot, backup Status string `json:"status"` CreatedAt time.Time `json:"created_at"` MinDiskGB int `json:"min_disk_gb,omitempty"` SizeGB int `json:"size_gb,omitempty"` } // Provider defines the interface that all cloud providers must implement type Provider interface { // Initialize sets up the provider with credentials and configuration Initialize(config map[string]string) error // ListRegions lists all available regions ListRegions(ctx context.Context) ([]Region, error) // ListInstanceSizes lists available VM sizes ListInstanceSizes(ctx context.Context, region string) ([]InstanceSize, error) // ListInstances lists all instances ListInstances(ctx context.Context) ([]Instance, error) // GetInstance gets a specific instance by ID GetFirstFreeInstance(ctx context.Context) (*Instance, error) // DeleteInstance deletes an instance ResetInstance(ctx context.Context, id string) error // StartInstance starts an instance StartInstance(ctx context.Context, id string) error // StopInstance stops an instance StopInstance(ctx context.Context, id string) error // RestartInstance restarts an instance RestartInstance(ctx context.Context, id string) error // WaitForInstanceStatus waits for an instance to reach a specific status WaitForInstanceStatus(ctx context.Context, id, status string, timeout time.Duration) error } // // ProviderFactory is a function that creates a new provider instance type ProviderFactory func() Provider // providerRegistry manages provider factories and initialized instances type providerRegistry struct { factories map[string]ProviderFactory instances map[string]Provider mu sync.RWMutex } // global registry instance var registry = &providerRegistry{ factories: make(map[string]ProviderFactory), instances: make(map[string]Provider), } // RegisterProvider registers a new provider factory func RegisterProvider(name string, factory ProviderFactory) { registry.mu.Lock() defer registry.mu.Unlock() registry.factories[name] = factory } // InitializeProvider initializes a provider with config and stores the instance func InitializeProvider(name string, config map[string]string) error { registry.mu.Lock() defer registry.mu.Unlock() factory, ok := registry.factories[name] if !ok { return fmt.Errorf("provider %s not found", name) } provider := factory() err := provider.Initialize(config) if err != nil { return err } // Store the initialized provider instance registry.instances[name] = provider return nil } // GetProvider returns an initialized provider by name func GetProvider(name string) (Provider, bool) { registry.mu.RLock() defer registry.mu.RUnlock() // Return the initialized instance if it exists if provider, ok := registry.instances[name]; ok { return provider, true } // If there's no initialized instance but there's a factory, // return false to indicate it needs initialization _, ok := registry.factories[name] return nil, ok } // GetSupportedProviders returns a list of supported provider names func GetSupportedProviders() []string { registry.mu.RLock() defer registry.mu.RUnlock() var names []string for name := range registry.factories { names = append(names, name) } return names }