infra.go

77 lines
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
package internal

import (
	"encoding/json"
	"fmt"
)

// InfraConfig mirrors the CLI's infra.json structure for reading project deployment configs.
type InfraConfig struct {
	Platforms map[string]InfraPlatform    `json:"platforms"`
	Servers   map[string]InfraServer      `json:"servers"`
	Services  map[string]InfraService     `json:"services,omitempty"`
	Instances map[string][]InfraInstance   `json:"instances,omitempty"`
}

type InfraPlatform struct {
	Provider string `json:"provider"`
	Token    string `json:"token,omitempty"`
	Region   string `json:"region,omitempty"`
}

type InfraServer struct {
	Platform string   `json:"platform,omitempty"`
	Size     string   `json:"size"`
	Services []string `json:"services,omitempty"`
}

type InfraService struct {
	Image  string            `json:"image,omitempty"`
	Source string            `json:"source,omitempty"`
	Ports  []InfraPort       `json:"ports,omitempty"`
	Env    map[string]string `json:"env,omitempty"`
}

type InfraPort struct {
	Host      int `json:"host"`
	Container int `json:"container"`
}

type InfraInstance struct {
	ID     string `json:"id,omitempty"`
	Name   string `json:"name"`
	IP     string `json:"ip,omitempty"`
	Region string `json:"region,omitempty"`
}

// ReadProjectInfra reads a project's infra.json via the code-server container.
func ReadProjectInfra(repoName string) (*InfraConfig, error) {
	output, err := CoderExec(fmt.Sprintf("cat /home/coder/repos/%s/infra.json 2>/dev/null", repoName))
	if err != nil {
		return nil, fmt.Errorf("no infra.json found for %s", repoName)
	}

	var cfg InfraConfig
	if err := json.Unmarshal([]byte(output), &cfg); err != nil {
		return nil, fmt.Errorf("invalid infra.json: %w", err)
	}

	return &cfg, nil
}

// InfraSummary returns a brief human-readable summary of the infra config.
func InfraSummary(cfg *InfraConfig) string {
	platforms := len(cfg.Platforms)
	servers := len(cfg.Servers)
	services := len(cfg.Services)
	var instanceCount int
	for _, insts := range cfg.Instances {
		instanceCount += len(insts)
	}

	summary := fmt.Sprintf("%d platform(s), %d server type(s), %d service(s)", platforms, servers, services)
	if instanceCount > 0 {
		summary += fmt.Sprintf(", %d instance(s)", instanceCount)
	}
	return summary
}