~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
150 lines · 4.4 KB Raw History
package guestcontrolplane

import (
	"cmp"
	"errors"
	"fmt"
	"log/slog"
	"strings"
	"time"

	"k8s.io/utils/ptr"

	commonv1 "github.com/johnandersen777/socialweb-computer-kcp/api/common/v1alpha1"
	pdsv1alpha1 "github.com/johnandersen777/socialweb-computer-kcp/api/pds/v1alpha1"
	"github.com/johnandersen777/socialweb-computer-kcp/api/v1alpha1"
	"github.com/johnandersen777/socialweb-computer-kcp/internal/component"
	"github.com/johnandersen777/socialweb-computer-kcp/internal/guestseed"
	"github.com/johnandersen777/socialweb-computer-kcp/internal/kit/pinneddownloads"
)

const Kind = "GuestControlPlane"

const (
	DefaultOpenBaoTimeout = 10 * time.Second

	kindPds = "Pds"

	kindRemotePDS = "RemotePDS"

	DownloadsRoute = "GET /v1/downloads/{sha256}/{name}"

	GuestAgentDownloadPrefix = "socialweb-guest-agent-"

	OpentunnelDownloadPrefix = "opentunnel-"

	WoottyDownloadPrefix = "wootty-"
)

var RequiredDownloads = []string{
	GuestAgentDownloadPrefix + "x86_64", GuestAgentDownloadPrefix + "aarch64",
	OpentunnelDownloadPrefix + "x86_64", OpentunnelDownloadPrefix + "aarch64",
	WoottyDownloadPrefix + "x86_64", WoottyDownloadPrefix + "aarch64",
}

type Deps struct {
	component.Instance

	Hosts component.NetworkHosts
}

func New(spec v1alpha1.GuestControlPlaneSpec, deps Deps) (*Service, error) {
	s := &Service{
		spec:        spec,
		deps:        deps,
		stateDir:    deps.StateDir,
		grantSync:   time.Duration(ptr.Deref(spec.GrantSyncSeconds, 0)) * time.Second,
		issuerRetry: time.Duration(ptr.Deref(spec.IssuerRetrySeconds, 0)) * time.Second,
		trust:       component.NewTrust(spec.TLS.CA(), deps.Log),
	}
	if spec.Storage != nil && spec.Storage.DataDir != "" {
		s.stateDir = spec.Storage.DataDir
	}
	if s.handle() == "" {
		return nil, errors.New("guestcontrolplane: the component names no bidder handle")
	}
	log := deps.Log
	if log == nil {
		log = slog.New(slog.DiscardHandler)
	}
	s.log = log.With("component", "guestcontrolplane", "handle", s.handle())
	if dir := s.downloadsDir(); dir != "" {
		set, err := pinneddownloads.LoadRequired(dir, RequiredDownloads)
		if err != nil {
			return nil, fmt.Errorf("guestcontrolplane: the downloads dir: %w", err)
		}
		s.downloads = set
	}
	self, err := guestseed.SelfDownloadOf()
	if err != nil {
		s.log.Warn("the GuestControlPlane does not serve its own binary to guests", "err", err.Error())
		return s, nil
	}
	if s.downloads, err = s.downloads.WithFile(self.Name, self.Sha256, self.Path, self.Size); err != nil {
		return nil, fmt.Errorf("guestcontrolplane: serving its own binary: %w", err)
	}
	return s, nil
}

func (s *Service) downloadsDir() string {
	if s.spec.Storage == nil {
		return ""
	}
	return strings.TrimSpace(s.spec.Storage.BlobsDir)
}

func (s *Service) network() v1alpha1.MarketNetworkValue {
	if s.spec.Network == nil {
		return v1alpha1.MarketNetworkValue{}
	}
	return *s.spec.Network
}

func (s *Service) workspace() string {
	return cmp.Or(s.deps.Self.Workspace, "root")
}

func (s *Service) self() commonv1.ObjectRef {
	return commonv1.ObjectRef{Group: v1alpha1.GroupName, Kind: Kind, Name: s.deps.Self.Name, Workspace: s.workspace()}
}

func (s *Service) handle() string {
	if s.spec.Identity == nil {
		return ""
	}
	return s.spec.Identity.Handle
}

func (s *Service) did() string {
	if s.spec.Identity == nil {
		return ""
	}
	return strings.TrimSpace(s.spec.Identity.Did)
}

func (s *Service) pdsRef() (commonv1.ObjectRef, error) {
	ref := s.spec.PdsRef
	if ref == nil || strings.TrimSpace(ref.Name) == "" {
		return commonv1.ObjectRef{}, errors.New("guestcontrolplane: the relay names no pdsRef to mint service auth with")
	}
	out := commonv1.ObjectRef{Group: strings.TrimSpace(ref.Group), Kind: cmp.Or(strings.TrimSpace(ref.Kind), kindPds),
		Name: strings.TrimSpace(ref.Name), Workspace: cmp.Or(strings.TrimSpace(ref.Workspace), s.workspace())}
	switch {
	case strings.EqualFold(out.Kind, kindPds):
		out.Kind, out.Group = kindPds, cmp.Or(out.Group, v1alpha1.GroupName)
	case strings.EqualFold(out.Kind, kindRemotePDS):
		out.Kind, out.Group = kindRemotePDS, cmp.Or(out.Group, pdsv1alpha1.GroupName)
	default:
		return commonv1.ObjectRef{}, errors.New("guestcontrolplane: the pdsRef names neither a Pds nor a RemotePDS")
	}
	return out, nil
}

func (s *Service) relayHost() string {
	return strings.TrimSpace(s.network().IngressProxyHost)
}

func (s *Service) relayTLS() bool {
	network := s.network()
	return strings.HasPrefix(strings.ToLower(strings.TrimSpace(network.GuestTLSURL())), "https://")
}