feat: print service endpoints on service creation

This commit is contained in:
Pavel Sviderski
2025-02-27 20:37:02 +10:00
parent 4c239ed79a
commit 58ecc17ac1
2 changed files with 59 additions and 1 deletions
+13 -1
View File
@@ -109,9 +109,21 @@ func run(ctx context.Context, uncli *cli.CLI, opts runOptions) error {
} }
defer client.Close() defer client.Close()
if _, err = client.RunService(ctx, spec); err != nil { resp, err := client.RunService(ctx, spec)
if err != nil {
return fmt.Errorf("run service: %w", err) return fmt.Errorf("run service: %w", err)
} }
svc, err := client.InspectService(ctx, resp.ID)
if err != nil {
return fmt.Errorf("inspect service: %w", err)
}
fmt.Println()
fmt.Printf("%s endpoints:\n", svc.Name)
for _, endpoint := range svc.Endpoints() {
fmt.Printf(" • %s\n", endpoint)
}
return nil return nil
} }
+46
View File
@@ -4,8 +4,10 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/distribution/reference" "github.com/distribution/reference"
"maps"
"reflect" "reflect"
"regexp" "regexp"
"slices"
"uncloud/internal/machine/api/pb" "uncloud/internal/machine/api/pb"
) )
@@ -79,6 +81,50 @@ type MachineContainer struct {
Container Container Container Container
} }
// Endpoints returns the exposed HTTP and HTTPS endpoints of the service.
func (s *Service) Endpoints() []string {
endpoints := make(map[string]struct{})
// Container specs may differ between containers in the same service, e.g. during a rolling update,
// so we need to collect all unique endpoints.
for _, ctr := range s.Containers {
ports, err := ctr.Container.ServicePorts()
if err != nil {
continue
}
for _, port := range ports {
protocol := ""
switch port.Protocol {
case ProtocolHTTP:
protocol = "http"
case ProtocolHTTPS:
protocol = "https"
default:
continue
}
if port.Hostname == "" {
// There shouldn't be http(s) ports without a hostname but just in case ignore them.
continue
}
endpoint := fmt.Sprintf("%s://%s", protocol, port.Hostname)
if port.PublishedPort != 0 {
// For non-standard ports (80/443), include the port in the URL.
if !(port.Protocol == ProtocolHTTP && port.PublishedPort == 80) &&
!(port.Protocol == ProtocolHTTPS && port.PublishedPort == 443) {
endpoint += fmt.Sprintf(":%d", port.PublishedPort)
}
}
endpoints[endpoint] = struct{}{}
}
}
return slices.Sorted(maps.Keys(endpoints))
}
func ServiceFromProto(s *pb.Service) (Service, error) { func ServiceFromProto(s *pb.Service) (Service, error) {
var err error var err error
containers := make([]MachineContainer, len(s.Containers)) containers := make([]MachineContainer, len(s.Containers))