Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v16] Default BaseURL only for community / enterprise editions #51933

Merged
merged 2 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,14 @@ all: version
binaries:
$(MAKE) $(BINARIES)

# Appending new conditional settings for community build type for tools.
ifeq ("$(GITHUB_REPOSITORY_OWNER)","gravitational")
# TELEPORT_LDFLAGS and TOOLS_LDFLAGS if appended will overwrite the previous LDFLAGS set in the BUILDFLAGS.
# This is done here to prevent any changes to the (BUI)LDFLAGS passed to the other binaries
TELEPORT_LDFLAGS ?= -ldflags '$(GO_LDFLAGS) -X github.com/gravitational/teleport/lib/modules.teleportBuildType=community'
TOOLS_LDFLAGS ?= -ldflags '$(GO_LDFLAGS) -X github.com/gravitational/teleport/lib/modules.teleportBuildType=community'
endif

# By making these 3 targets below (tsh, tctl and teleport) PHONY we are solving
# several problems:
# * Build will rely on go build internal caching https://golang.org/doc/go1.10 at all times
Expand All @@ -343,15 +351,9 @@ $(BUILDDIR)/tctl:
@if [[ -z "$(LIBFIDO2_BUILD_TAG)" ]]; then \
echo 'Warning: Building tctl without libfido2. Install libfido2 to have access to MFA.' >&2; \
fi
GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go build -tags "$(PAM_TAG) $(FIPS_TAG) $(LIBFIDO2_BUILD_TAG) $(PIV_BUILD_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tctl $(BUILDFLAGS) ./tool/tctl
GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go build -tags "$(PAM_TAG) $(FIPS_TAG) $(LIBFIDO2_BUILD_TAG) $(PIV_BUILD_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tctl $(BUILDFLAGS) $(TOOLS_LDFLAGS) ./tool/tctl

.PHONY: $(BUILDDIR)/teleport
# Appending new conditional settings for community build type
ifeq ("$(GITHUB_REPOSITORY_OWNER)","gravitational")
# TELEPORT_LDFLAGS if appended will overwrite the previous LDFLAGS set in the BUILDFLAGS.
# This is done here to prevent any changes to the (BUI)LDFLAGS passed to the other binaries
TELEPORT_LDFLAGS ?= -ldflags '$(GO_LDFLAGS) -X github.com/gravitational/teleport/lib/modules.teleportBuildType=community'
endif
$(BUILDDIR)/teleport: ensure-webassets bpf-bytecode rdpclient
GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go build -tags "webassets_embed $(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(WEBASSETS_TAG) $(RDPCLIENT_TAG) $(PIV_BUILD_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/teleport $(BUILDFLAGS) $(TELEPORT_LDFLAGS) ./tool/teleport

Expand All @@ -364,15 +366,15 @@ $(BUILDDIR)/tsh:
@if [[ -z "$(LIBFIDO2_BUILD_TAG)" ]]; then \
echo 'Warning: Building tsh without libfido2. Install libfido2 to have access to MFA.' >&2; \
fi
GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG_TSH) go build -tags "$(FIPS_TAG) $(LIBFIDO2_BUILD_TAG) $(TOUCHID_TAG) $(PIV_BUILD_TAG) $(VNETDAEMON_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tsh $(BUILDFLAGS) ./tool/tsh
GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG_TSH) go build -tags "$(FIPS_TAG) $(LIBFIDO2_BUILD_TAG) $(TOUCHID_TAG) $(PIV_BUILD_TAG) $(VNETDAEMON_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tsh $(BUILDFLAGS) $(TOOLS_LDFLAGS) ./tool/tsh

.PHONY: $(BUILDDIR)/tbot
# tbot is CGO-less by default except on Windows because lib/client/terminal/ wants CGO on this OS
$(BUILDDIR)/tbot: TBOT_CGO_FLAGS ?= $(if $(filter windows,$(OS)),$(CGOFLAG))
# Build mode pie requires CGO
$(BUILDDIR)/tbot: BUILDFLAGS_TBOT += $(if $(TBOT_CGO_FLAGS), -buildmode=pie)
$(BUILDDIR)/tbot:
GOOS=$(OS) GOARCH=$(ARCH) $(TBOT_CGO_FLAGS) go build -tags "$(FIPS_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tbot $(BUILDFLAGS_TBOT) ./tool/tbot
GOOS=$(OS) GOARCH=$(ARCH) $(TBOT_CGO_FLAGS) go build -tags "$(FIPS_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tbot $(BUILDFLAGS_TBOT) $(TOOLS_LDFLAGS) ./tool/tbot

TELEPORT_ARGS ?= start
.PHONY: teleport-hot-reload
Expand Down Expand Up @@ -1741,7 +1743,7 @@ changelog:
# does not match version set it will fail to create a release. If tag doesn't exist it
# will also fail to create a release.
#
# For more information on release notes generation see:
# For more information on release notes generation see:
# https://github.com/gravitational/shared-workflows/tree/gus/release-notes/tools/release-notes#readme
.PHONY: create-github-release
create-github-release: LATEST = false
Expand Down
16 changes: 12 additions & 4 deletions integration/autoupdate/tools/updater/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"context"
"crypto"
"fmt"
"os"
"time"

"github.com/gravitational/trace"
Expand All @@ -35,8 +36,12 @@ import (
"github.com/gravitational/teleport/lib/tlsca"
)

// TestPassword is password generated during the test to login in test cluster.
const TestPassword = "UPDATER_TEST_PASSWORD"
const (
// TestPassword is env var used for setting password generated during the test to login in test cluster.
TestPassword = "UPDATER_TEST_PASSWORD"
// TestBuild is env var for setting test build type during the test.
TestBuild = "UPDATER_TEST_BUILD"
)

var (
version = teleport.Version
Expand All @@ -54,17 +59,20 @@ func (p *TestModules) GetSuggestedAccessLists(ctx context.Context, identity *tls

// BuildType returns build type (OSS or Enterprise)
func (p *TestModules) BuildType() string {
if build := os.Getenv(TestBuild); build != "" {
return build
}
return "CLI"
}

// IsEnterpriseBuild returns false for [TestModules].
func (p *TestModules) IsEnterpriseBuild() bool {
return false
return os.Getenv(TestBuild) == modules.BuildEnterprise
}

// IsOSSBuild returns false for [TestModules].
func (p *TestModules) IsOSSBuild() bool {
return false
return os.Getenv(TestBuild) == modules.BuildOSS
}

// LicenseExpiry returns the expiry date of the enterprise license, if applicable.
Expand Down
49 changes: 49 additions & 0 deletions integration/autoupdate/tools/updater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ import (
"github.com/stretchr/testify/require"

"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/integration/autoupdate/tools/updater"
"github.com/gravitational/teleport/lib/autoupdate"
"github.com/gravitational/teleport/lib/autoupdate/tools"
"github.com/gravitational/teleport/lib/modules"
)

var (
Expand Down Expand Up @@ -216,3 +219,49 @@ func TestUpdateInterruptSignal(t *testing.T) {
}
assert.Contains(t, output.String(), "Update progress:")
}

// TestUpdateForOSSBuild verifies the update logic for AGPL editions of Teleport requires
// base URL environment variable.
func TestUpdateForOSSBuild(t *testing.T) {
t.Setenv(types.HomeEnvVar, t.TempDir())
ctx := context.Background()

// Enable OSS build.
t.Setenv(updater.TestBuild, modules.BuildOSS)

// Fetch compiled test binary with updater logic and install to $TELEPORT_HOME.
updater := tools.NewUpdater(
toolsDir,
testVersions[0],
tools.WithBaseURL(baseURL),
)
err := updater.Update(ctx, testVersions[0])
require.NoError(t, err)

// Verify that requested update is ignored by OSS build and version wasn't updated.
cmd := exec.CommandContext(ctx, filepath.Join(toolsDir, "tsh"), "version")
cmd.Env = append(
os.Environ(),
fmt.Sprintf("%s=%s", teleportToolsVersion, testVersions[1]),
)
out, err := cmd.Output()
require.NoError(t, err)

matches := pattern.FindStringSubmatch(string(out))
require.Len(t, matches, 2)
require.Equal(t, testVersions[0], matches[1])

// Next update is set with the base URL env variable, must download new version.
t.Setenv(autoupdate.BaseURLEnvVar, baseURL)
cmd = exec.CommandContext(ctx, filepath.Join(toolsDir, "tsh"), "version")
cmd.Env = append(
os.Environ(),
fmt.Sprintf("%s=%s", teleportToolsVersion, testVersions[1]),
)
out, err = cmd.Output()
require.NoError(t, err)

matches = pattern.FindStringSubmatch(string(out))
require.Len(t, matches, 2)
require.Equal(t, testVersions[1], matches[1])
}
3 changes: 2 additions & 1 deletion lib/autoupdate/tools/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func CheckAndUpdateRemote(ctx context.Context, proxy string, insecure bool, reEx
slog.WarnContext(ctx, "Client tools update is disabled", "error", err)
return nil
}

// Overrides default base URL for custom CDN for downloading updates.
if envBaseURL := os.Getenv(autoupdate.BaseURLEnvVar); envBaseURL != "" {
baseURL = envBaseURL
Expand All @@ -110,7 +111,7 @@ func updateAndReExec(ctx context.Context, updater *Updater, toolsVersion string,
// is required if the user passed in the TELEPORT_TOOLS_VERSION
// explicitly.
err := updater.UpdateWithLock(ctxUpdate, toolsVersion)
if err != nil && !errors.Is(err, context.Canceled) {
if err != nil && !errors.Is(err, context.Canceled) && !errors.Is(err, errNoBaseURL) {
return trace.Wrap(err)
}

Expand Down
9 changes: 3 additions & 6 deletions lib/autoupdate/tools/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func (u *Updater) UpdateWithLock(ctx context.Context, updateToolsVersion string)
// with defined updater directory suffix.
func (u *Updater) Update(ctx context.Context, toolsVersion string) error {
// Get platform specific download URLs.
packages, err := teleportPackageURLs(u.uriTemplate, u.baseURL, toolsVersion)
packages, err := teleportPackageURLs(ctx, u.uriTemplate, u.baseURL, toolsVersion)
if err != nil {
return trace.Wrap(err)
}
Expand Down Expand Up @@ -409,11 +409,6 @@ func (u *Updater) downloadHash(ctx context.Context, url string) ([]byte, error)
// downloadArchive downloads the archive package by `url` and writes content to the writer interface,
// return calculated sha256 hash sum of the content.
func (u *Updater) downloadArchive(ctx context.Context, url string, f io.Writer) ([]byte, error) {
// Display a progress bar before initiating the update request to inform the user that
// an update is in progress, allowing them the option to cancel before actual response
// which might be delayed with slow internet connection or complete isolation to CDN.
pw, finish := newProgressWriter(10)
defer finish()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, trace.Wrap(err)
Expand All @@ -429,6 +424,8 @@ func (u *Updater) downloadArchive(ctx context.Context, url string, f io.Writer)
if resp.StatusCode != http.StatusOK {
return nil, trace.BadParameter("bad status when downloading archive: %v", resp.StatusCode)
}
pw, finish := newProgressWriter(10)
defer finish()

if resp.ContentLength != -1 {
if err := checkFreeSpace(u.toolsDir, uint64(resp.ContentLength)); err != nil {
Expand Down
15 changes: 12 additions & 3 deletions lib/autoupdate/tools/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"bytes"
"context"
"errors"
"log/slog"
"os"
"os/exec"
"path/filepath"
Expand All @@ -40,6 +41,8 @@ import (
"github.com/gravitational/teleport/lib/utils"
)

var errNoBaseURL = errors.New("baseURL is not defined")

// Dir returns the path to client tools in $TELEPORT_HOME/bin.
func Dir() (string, error) {
home := os.Getenv(types.HomeEnvVar)
Expand Down Expand Up @@ -126,10 +129,16 @@ type packageURL struct {
Optional bool
}

// teleportPackageURLs returns the URL for the Teleport archive to download.
func teleportPackageURLs(uriTmpl string, baseURL, version string) ([]packageURL, error) {
var flags autoupdate.InstallFlags
// teleportPackageURLs returns URLs for the Teleport archives to download.
func teleportPackageURLs(ctx context.Context, uriTmpl string, baseURL, version string) ([]packageURL, error) {
m := modules.GetModules()
envBaseURL := os.Getenv(autoupdate.BaseURLEnvVar)
if m.BuildType() == modules.BuildOSS && envBaseURL == "" {
slog.WarnContext(ctx, "Client tools updates are disabled as they are licensed under AGPL. To use Community Edition builds or custom binaries, set the 'TELEPORT_CDN_BASE_URL' environment variable.")
return nil, errNoBaseURL
}

var flags autoupdate.InstallFlags
if m.IsBoringBinary() {
flags |= autoupdate.FlagFIPS
}
Expand Down
Loading