readysite / pkg / platform / providers / mock / mock.go
4.5 KB
mock.go
package mock

import (
	"fmt"
	"sync"

	"github.com/google/uuid"
	"github.com/readysite/readysite/pkg/platform"
)

// backend is a mock implementation for testing
type backend struct {
	mu       sync.RWMutex
	servers  map[string]*platform.Server
	volumes  map[string]*platform.Volume
	zones    map[string]*platform.DNSZone
	records  map[string][]platform.DNSRecord
	ipCount  int
}

// New creates a mock platform for testing
func New() *platform.Platform {
	return &platform.Platform{
		Backend: &backend{
			servers: make(map[string]*platform.Server),
			volumes: make(map[string]*platform.Volume),
			zones:   make(map[string]*platform.DNSZone),
			records: make(map[string][]platform.DNSRecord),
		},
	}
}

// CreateServer creates a mock server
func (b *backend) CreateServer(opts platform.ServerOptions) (*platform.Server, error) {
	b.mu.Lock()
	defer b.mu.Unlock()

	// Check if server with this name already exists
	for _, s := range b.servers {
		if s.Name == opts.Name {
			return nil, fmt.Errorf("server with name %q already exists", opts.Name)
		}
	}

	b.ipCount++
	server := &platform.Server{
		ID:     uuid.New().String(),
		Name:   opts.Name,
		Size:   string(opts.Size),
		Region: string(opts.Region),
		IP:     fmt.Sprintf("10.0.0.%d", b.ipCount),
		Status: "active",
	}

	b.servers[server.ID] = server
	return server, nil
}

// GetServer retrieves a server by name
func (b *backend) GetServer(name string) (*platform.Server, error) {
	b.mu.RLock()
	defer b.mu.RUnlock()

	for _, s := range b.servers {
		if s.Name == name {
			return s, nil
		}
	}
	return nil, platform.ErrNotFound
}

// DeleteServer removes a server by ID
func (b *backend) DeleteServer(id string) error {
	b.mu.Lock()
	defer b.mu.Unlock()

	if _, ok := b.servers[id]; !ok {
		return platform.ErrNotFound
	}
	delete(b.servers, id)
	return nil
}

// CreateVolume creates a mock volume
func (b *backend) CreateVolume(name string, sizeGB int, region platform.Region) (*platform.Volume, error) {
	b.mu.Lock()
	defer b.mu.Unlock()

	// Check if volume with this name already exists
	for _, v := range b.volumes {
		if v.Name == name {
			return nil, fmt.Errorf("volume with name %q already exists", name)
		}
	}

	volume := &platform.Volume{
		ID:     uuid.New().String(),
		Name:   name,
		Size:   sizeGB,
		Region: string(region),
	}

	b.volumes[volume.ID] = volume
	return volume, nil
}

// GetVolume retrieves a volume by name
func (b *backend) GetVolume(name string) (*platform.Volume, error) {
	b.mu.RLock()
	defer b.mu.RUnlock()

	for _, v := range b.volumes {
		if v.Name == name {
			return v, nil
		}
	}
	return nil, platform.ErrNotFound
}

// AttachVolume attaches a volume to a server
func (b *backend) AttachVolume(volumeID, serverID string) error {
	b.mu.Lock()
	defer b.mu.Unlock()

	volume, ok := b.volumes[volumeID]
	if !ok {
		return platform.ErrNotFound
	}
	if _, ok := b.servers[serverID]; !ok {
		return platform.ErrNotFound
	}
	volume.ServerID = serverID
	return nil
}

// DetachVolume detaches a volume from its server
func (b *backend) DetachVolume(volumeID string) error {
	b.mu.Lock()
	defer b.mu.Unlock()

	volume, ok := b.volumes[volumeID]
	if !ok {
		return platform.ErrNotFound
	}
	volume.ServerID = ""
	return nil
}

// CreateDNSZone creates a mock DNS zone
func (b *backend) CreateDNSZone(domain string) (*platform.DNSZone, error) {
	b.mu.Lock()
	defer b.mu.Unlock()

	if _, ok := b.zones[domain]; ok {
		return nil, fmt.Errorf("zone %q already exists", domain)
	}

	zone := &platform.DNSZone{
		Name: domain,
		TTL:  300,
	}
	b.zones[domain] = zone
	b.records[domain] = []platform.DNSRecord{}
	return zone, nil
}

// GetDNSZone retrieves a DNS zone by domain
func (b *backend) GetDNSZone(domain string) (*platform.DNSZone, error) {
	b.mu.RLock()
	defer b.mu.RUnlock()

	zone, ok := b.zones[domain]
	if !ok {
		return nil, platform.ErrNotFound
	}
	return zone, nil
}

// AddDNSRecord adds a DNS record to a zone
func (b *backend) AddDNSRecord(zone string, record platform.DNSRecord) error {
	b.mu.Lock()
	defer b.mu.Unlock()

	if _, ok := b.zones[zone]; !ok {
		return platform.ErrNotFound
	}
	record.ID = uuid.New().String()
	b.records[zone] = append(b.records[zone], record)
	return nil
}

// DeleteDNSRecord removes a DNS record from a zone
func (b *backend) DeleteDNSRecord(zone, recordID string) error {
	b.mu.Lock()
	defer b.mu.Unlock()

	records, ok := b.records[zone]
	if !ok {
		return platform.ErrNotFound
	}

	for i, r := range records {
		if r.ID == recordID {
			b.records[zone] = append(records[:i], records[i+1:]...)
			return nil
		}
	}
	return platform.ErrNotFound
}
← Back