Skip to content

Commit

Permalink
Cloud Installation Commands (#4024)
Browse files Browse the repository at this point in the history
Added `earthly cloud` commands for managing BYOC configurations. Also
tweaked some connection logic so that custom TLS certs can be used for
any satellites instead of just Self-Hosted.
  • Loading branch information
brandonSc authored Apr 29, 2024
1 parent 23000c0 commit 1c27529
Show file tree
Hide file tree
Showing 9 changed files with 388 additions and 33 deletions.
82 changes: 82 additions & 0 deletions cloud/cloud_installation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package cloud

import (
"context"

pb "github.com/earthly/cloud-api/compute"
"github.com/pkg/errors"
)

const (
CloudStatusConnected = "Connected"
CloudStatusActive = "Active"
CloudStatusProblem = "Problem"
)

type Installation struct {
Name string
Org string
Status string
NumSatellites int
IsDefault bool
}

func (c *Client) ConfigureCloud(ctx context.Context, orgID, cloudName string, setDefault bool) (*Installation, error) {
resp, err := c.compute.ConfigureCloud(c.withAuth(ctx), &pb.ConfigureCloudRequest{
OrgId: orgID,
Name: cloudName,
SetDefault: setDefault,
})
if err != nil {
return nil, errors.Wrap(err, "error from ConfigureCloud API")
}
return &Installation{
Name: cloudName,
Org: orgID,
Status: installationStatus(resp.Status),
}, nil
}

func (c *Client) ListClouds(ctx context.Context, orgID string) ([]Installation, error) {
resp, err := c.compute.ListClouds(c.withAuth(ctx), &pb.ListCloudsRequest{
OrgId: orgID,
})
if err != nil {
return nil, errors.Wrap(err, "error from ListCloud API")
}
var installations []Installation
for _, i := range resp.Clouds {
installations = append(installations, Installation{
Name: i.CloudName,
Org: orgID,
Status: installationStatus(i.Status),
NumSatellites: int(i.NumSatellites),
IsDefault: i.IsDefault,
})
}
return installations, nil
}

func (c *Client) DeleteCloud(ctx context.Context, orgID, cloudName string) error {
_, err := c.compute.DeleteCloud(c.withAuth(ctx), &pb.DeleteCloudRequest{
Name: cloudName,
OrgId: orgID,
})
if err != nil {
return errors.Wrap(err, "error from DeleteCloud API")
}
return nil
}

func installationStatus(status pb.CloudStatus) string {
internalStatus := "UNKNOWN"
switch status {
case pb.CloudStatus_CLOUD_STATUS_ACCOUNT_ACTIVE:
internalStatus = CloudStatusActive
case pb.CloudStatus_CLOUD_STATUS_ACCOUNT_CONNECTED:
internalStatus = CloudStatusConnected
case pb.CloudStatus_CLOUD_STATUS_PROBLEM:
internalStatus = CloudStatusProblem
}
return internalStatus
}
6 changes: 5 additions & 1 deletion cloud/satellite.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type SatelliteInstance struct {
Address string
IsManaged bool
Certificate *pb.TLSCertificate
CloudName string
}

func (c *Client) ListSatellites(ctx context.Context, orgName string, includeHidden bool) ([]SatelliteInstance, error) {
Expand All @@ -106,6 +107,7 @@ func (c *Client) ListSatellites(ctx context.Context, orgName string, includeHidd
Hidden: s.Hidden,
LastUsed: s.LastUsed.AsTime(),
CacheRetention: s.CacheRetention.AsDuration(),
CloudName: s.CloudName,
}
}
return instances, nil
Expand Down Expand Up @@ -140,7 +142,7 @@ func (c *Client) GetSatellite(ctx context.Context, name, orgName string) (*Satel
LastUsed: resp.LastUsed.AsTime(),
CacheRetention: resp.CacheRetention.AsDuration(),
IsManaged: resp.IsManaged,
Address: resp.PrivateDns,
Address: resp.SatelliteAddress,
Certificate: resp.Certificate,
}, nil
}
Expand Down Expand Up @@ -170,6 +172,7 @@ type LaunchSatelliteOpt struct {
MaintenanceWindowStart string
MaintenanceWeekendsOnly bool
FeatureFlags []string
CloudName string
}

func (c *Client) LaunchSatellite(ctx context.Context, opt LaunchSatelliteOpt) error {
Expand All @@ -186,6 +189,7 @@ func (c *Client) LaunchSatellite(ctx context.Context, opt LaunchSatelliteOpt) er
Version: opt.PinnedVersion,
MaintenanceWindowStart: opt.MaintenanceWindowStart,
MaintenanceWeekendsOnly: opt.MaintenanceWeekendsOnly,
CloudName: opt.CloudName,
}
_, err = c.compute.LaunchSatellite(c.withAuth(ctx), req)
if err != nil {
Expand Down
30 changes: 13 additions & 17 deletions cmd/earthly/base/buildkit.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/earthly/earthly/analytics"
"github.com/earthly/earthly/buildkitd"
"github.com/earthly/earthly/cloud"
"github.com/earthly/earthly/util/containerutil"
)

func (cli *CLI) GetBuildkitClient(cliCtx *cli.Context, cloudClient *cloud.Client) (c *client.Client, cleanupTLS func(), err error) {
Expand Down Expand Up @@ -67,43 +66,40 @@ func (cli *CLI) ConfigureSatellite(cliCtx *cli.Context, cloudClient *cloud.Clien
return nil, errors.New("self-hosted satellite is not operational")
}

cli.Flags().BuildkitdSettings.UseTCP = true
if cli.Cfg().Global.TLSEnabled {
if sat.IsManaged {
// satellites on earthly-cloud do not use custom certificates
cli.Flags().BuildkitdSettings.ClientTLSCert = ""
cli.Flags().BuildkitdSettings.ClientTLSKey = ""
cli.Flags().BuildkitdSettings.TLSCA = ""
cli.Flags().BuildkitdSettings.ServerTLSCert = ""
cli.Flags().BuildkitdSettings.ServerTLSKey = ""
} else if sat.Certificate != nil {
if sat.Certificate != nil {
t := time.Now()
cleanupTLS, err = buildkitd.ConfigureSatelliteTLS(&cli.Flags().BuildkitdSettings, sat)
if err != nil {
return nil, fmt.Errorf("failed configuring certificates for satellite: %w", err)
}
cli.Console().WithPrefix("satellite").
DebugPrintf("TLS certificates configured in: %s", time.Since(t).String())
} else {
cli.Flags().BuildkitdSettings.ClientTLSCert = ""
cli.Flags().BuildkitdSettings.ClientTLSKey = ""
cli.Flags().BuildkitdSettings.TLSCA = ""
cli.Flags().BuildkitdSettings.ServerTLSCert = ""
cli.Flags().BuildkitdSettings.ServerTLSKey = ""
}
} else {
cli.Console().Warnf("TLS has been disabled; this should never be done when connecting to Earthly's production API\n")
}

cli.Flags().BuildkitdSettings.UseTCP = true
cli.Flags().BuildkitdSettings.SatelliteName = satelliteName
cli.Flags().BuildkitdSettings.SatelliteDisplayName = cli.Flags().SatelliteName
cli.Flags().BuildkitdSettings.SatelliteOrgID = orgID
cli.Flags().BuildkitdSettings.SatelliteIsManaged = sat.IsManaged
satelliteAddress := cli.Flags().SatelliteAddress
if !sat.IsManaged && satelliteAddress == "" {
if satelliteAddress == "" {
// A self-hosted satellite uses its own address
satelliteAddress = fmt.Sprintf("tcp://%s", sat.Address)
}
if satelliteAddress != "" {
cli.Flags().BuildkitdSettings.BuildkitAddress = satelliteAddress
} else {
cli.Flags().BuildkitdSettings.BuildkitAddress = containerutil.SatelliteAddress
}
cli.Flags().BuildkitdSettings.BuildkitAddress = satelliteAddress

cli.SetAnaMetaIsSat(true)
cli.SetAnaMetaSatCurrentVersion("") // TODO
cli.SetAnaMetaSatCurrentVersion(sat.Version)

if cli.Flags().FeatureFlagOverrides != "" {
cli.Flags().FeatureFlagOverrides += ","
Expand Down
2 changes: 1 addition & 1 deletion cmd/earthly/flag/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type Global struct {
NoSatellite bool
ProjectName string
OrgName string
CloudName string
EarthlyCIRunner bool
ArtifactMode bool
ImageMode bool
Expand Down Expand Up @@ -233,7 +234,6 @@ func (global *Global) RootFlags(installName string, bkImage string) []cli.Flag {
},
&cli.StringFlag{
Name: "satellite-address",
Value: containerutil.SatelliteAddress,
EnvVars: []string{"EARTHLY_SATELLITE_ADDRESS"},
Usage: "Satellite address override for dev purposes",
Destination: &global.SatelliteAddress,
Expand Down
Loading

0 comments on commit 1c27529

Please sign in to comment.