provider.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. // GetPreviewInstance gets a specific instance by ID
  82. GetPreviewInstance(ctx context.Context) (*Instance, error)
  83. // DeleteInstance deletes an instance
  84. ResetInstance(ctx context.Context, id string) error
  85. // StartInstance starts an instance
  86. StartInstance(ctx context.Context, id string) error
  87. // StopInstance stops an instance
  88. StopInstance(ctx context.Context, id string) error
  89. // RestartInstance restarts an instance
  90. RestartInstance(ctx context.Context, id string) error
  91. // WaitForInstanceStatus waits for an instance to reach a specific status
  92. WaitForInstanceStatus(ctx context.Context, id, status string, timeout time.Duration) error
  93. }
  94. // // ProviderFactory is a function that creates a new provider instance
  95. type ProviderFactory func() Provider
  96. // providerRegistry manages provider factories and initialized instances
  97. type providerRegistry struct {
  98. factories map[string]ProviderFactory
  99. instances map[string]Provider
  100. mu sync.RWMutex
  101. }
  102. // global registry instance
  103. var registry = &providerRegistry{
  104. factories: make(map[string]ProviderFactory),
  105. instances: make(map[string]Provider),
  106. }
  107. // RegisterProvider registers a new provider factory
  108. func RegisterProvider(name string, factory ProviderFactory) {
  109. registry.mu.Lock()
  110. defer registry.mu.Unlock()
  111. registry.factories[name] = factory
  112. }
  113. // InitializeProvider initializes a provider with config and stores the instance
  114. func InitializeProvider(name string, config map[string]string) error {
  115. registry.mu.Lock()
  116. defer registry.mu.Unlock()
  117. factory, ok := registry.factories[name]
  118. if !ok {
  119. return fmt.Errorf("provider %s not found", name)
  120. }
  121. provider := factory()
  122. err := provider.Initialize(config)
  123. if err != nil {
  124. return err
  125. }
  126. // Store the initialized provider instance
  127. registry.instances[name] = provider
  128. return nil
  129. }
  130. // GetProvider returns an initialized provider by name
  131. func GetProvider(name string) (Provider, bool) {
  132. registry.mu.RLock()
  133. defer registry.mu.RUnlock()
  134. // Return the initialized instance if it exists
  135. if provider, ok := registry.instances[name]; ok {
  136. return provider, true
  137. }
  138. // If there's no initialized instance but there's a factory,
  139. // return false to indicate it needs initialization
  140. _, ok := registry.factories[name]
  141. return nil, ok
  142. }
  143. // GetSupportedProviders returns a list of supported provider names
  144. func GetSupportedProviders() []string {
  145. registry.mu.RLock()
  146. defer registry.mu.RUnlock()
  147. var names []string
  148. for name := range registry.factories {
  149. names = append(names, name)
  150. }
  151. return names
  152. }