provider.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. package cloud
  2. import (
  3. "context"
  4. "fmt"
  5. "sync"
  6. "time"
  7. "git.linuxforward.com/byop/byop-engine/models"
  8. )
  9. // InstanceSize represents the size configuration for a VM instance
  10. type InstanceSize struct {
  11. ID string `json:"id"`
  12. Name string `json:"name"`
  13. CPUCores int `json:"cpu_cores"`
  14. MemoryGB int `json:"memory_gb"`
  15. DiskGB int `json:"disk_gb"`
  16. Price float64 `json:"price"` // Hourly price
  17. }
  18. // Region represents a geographic region
  19. type Region struct {
  20. ID string `json:"id"`
  21. Name string `json:"name"`
  22. Zone string `json:"zone"`
  23. }
  24. // Instance represents a virtual machine instance
  25. type Instance struct {
  26. ID string `json:"id"`
  27. Name string `json:"name"`
  28. Region string `json:"region"`
  29. Size string `json:"size"`
  30. ImageID string `json:"image_id"`
  31. IPAddress string `json:"ip_address"`
  32. PrivateIP string `json:"private_ip,omitempty"`
  33. Status string `json:"status"` // Creating, Running, Stopping, Stopped, Restarting, Terminated
  34. CreatedAt time.Time `json:"created_at"`
  35. Tags map[string]string `json:"tags,omitempty"`
  36. SecurityGroups []string `json:"security_groups,omitempty"`
  37. }
  38. // InstanceCreateOpts are options to configure a new instance
  39. type InstanceCreateOpts struct {
  40. Name string `json:"name"`
  41. Region string `json:"region"`
  42. Size string `json:"size"`
  43. ImageID string `json:"image_id"`
  44. SSHKeyIDs []string `json:"ssh_key_ids,omitempty"`
  45. UserData string `json:"user_data,omitempty"`
  46. Tags map[string]string `json:"tags,omitempty"`
  47. SecurityGroups []string `json:"security_groups,omitempty"`
  48. Components []models.Component `json:"components,omitempty"`
  49. }
  50. // SSHKey represents an SSH key
  51. type SSHKey struct {
  52. ID string `json:"id"`
  53. Name string `json:"name"`
  54. Fingerprint string `json:"fingerprint"`
  55. PublicKey string `json:"public_key"`
  56. CreatedAt time.Time `json:"created_at"`
  57. }
  58. // Image represents an operating system image
  59. type Image struct {
  60. ID string `json:"id"`
  61. Name string `json:"name"`
  62. Description string `json:"description"`
  63. Type string `json:"type"` // base, snapshot, backup
  64. Status string `json:"status"`
  65. CreatedAt time.Time `json:"created_at"`
  66. MinDiskGB int `json:"min_disk_gb,omitempty"`
  67. SizeGB int `json:"size_gb,omitempty"`
  68. }
  69. // Provider defines the interface that all cloud providers must implement
  70. type Provider interface {
  71. // Initialize sets up the provider with credentials and configuration
  72. Initialize(config map[string]string) error
  73. // ListRegions lists all available regions
  74. ListRegions(ctx context.Context) ([]Region, error)
  75. // ListInstanceSizes lists available VM sizes
  76. ListInstanceSizes(ctx context.Context, region string) ([]InstanceSize, error)
  77. // ListInstances lists all instances
  78. ListInstances(ctx context.Context) ([]Instance, error)
  79. // GetInstance gets a specific instance by ID
  80. GetFirstFreeInstance(ctx context.Context) (*Instance, error)
  81. // DeleteInstance deletes an instance
  82. ResetInstance(ctx context.Context, id string) error
  83. // StartInstance starts an instance
  84. StartInstance(ctx context.Context, id string) error
  85. // StopInstance stops an instance
  86. StopInstance(ctx context.Context, id string) error
  87. // RestartInstance restarts an instance
  88. RestartInstance(ctx context.Context, id string) error
  89. // WaitForInstanceStatus waits for an instance to reach a specific status
  90. WaitForInstanceStatus(ctx context.Context, id, status string, timeout time.Duration) error
  91. }
  92. // // ProviderFactory is a function that creates a new provider instance
  93. type ProviderFactory func() Provider
  94. // providerRegistry manages provider factories and initialized instances
  95. type providerRegistry struct {
  96. factories map[string]ProviderFactory
  97. instances map[string]Provider
  98. mu sync.RWMutex
  99. }
  100. // global registry instance
  101. var registry = &providerRegistry{
  102. factories: make(map[string]ProviderFactory),
  103. instances: make(map[string]Provider),
  104. }
  105. // RegisterProvider registers a new provider factory
  106. func RegisterProvider(name string, factory ProviderFactory) {
  107. registry.mu.Lock()
  108. defer registry.mu.Unlock()
  109. registry.factories[name] = factory
  110. }
  111. // InitializeProvider initializes a provider with config and stores the instance
  112. func InitializeProvider(name string, config map[string]string) error {
  113. registry.mu.Lock()
  114. defer registry.mu.Unlock()
  115. factory, ok := registry.factories[name]
  116. if !ok {
  117. return fmt.Errorf("provider %s not found", name)
  118. }
  119. provider := factory()
  120. err := provider.Initialize(config)
  121. if err != nil {
  122. return err
  123. }
  124. // Store the initialized provider instance
  125. registry.instances[name] = provider
  126. return nil
  127. }
  128. // GetProvider returns an initialized provider by name
  129. func GetProvider(name string) (Provider, bool) {
  130. registry.mu.RLock()
  131. defer registry.mu.RUnlock()
  132. // Return the initialized instance if it exists
  133. if provider, ok := registry.instances[name]; ok {
  134. return provider, true
  135. }
  136. // If there's no initialized instance but there's a factory,
  137. // return false to indicate it needs initialization
  138. _, ok := registry.factories[name]
  139. return nil, ok
  140. }
  141. // GetSupportedProviders returns a list of supported provider names
  142. func GetSupportedProviders() []string {
  143. registry.mu.RLock()
  144. defer registry.mu.RUnlock()
  145. var names []string
  146. for name := range registry.factories {
  147. names = append(names, name)
  148. }
  149. return names
  150. }