Skip to content
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
4 changes: 4 additions & 0 deletions api/client/webclient/webconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ type WebConfig struct {
IsUsageBasedBilling bool `json:"isUsageBasedBilling,omitempty"`
// AutomaticUpgrades describes whether agents should automatically upgrade.
AutomaticUpgrades bool `json:"automaticUpgrades"`
// AutomaticUpgradesTargetVersion is the agents version (eg kube agent helm chart) that should be installed.
// Eg, v13.4.3
// Only present when AutomaticUpgrades are enabled.
AutomaticUpgradesTargetVersion string `json:"automaticUpgradesTargetVersion,omitempty"`
// AssistEnabled is true when Teleport Assist is enabled.
AssistEnabled bool `json:"assistEnabled"`
// HideInaccessibleFeatures is true when features should be undiscoverable to users without the necessary permissions.
Expand Down
52 changes: 40 additions & 12 deletions lib/web/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import (
apisshutils "github.com/gravitational/teleport/api/utils/sshutils"
"github.com/gravitational/teleport/lib/auth"
wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/automaticupgrades"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/defaults"
dtconfig "github.com/gravitational/teleport/lib/devicetrust/config"
Expand All @@ -78,6 +79,7 @@ import (
"github.com/gravitational/teleport/lib/limiter"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/multiplexer"
"github.com/gravitational/teleport/lib/observability/tracing"
"github.com/gravitational/teleport/lib/plugin"
"github.com/gravitational/teleport/lib/proxy"
"github.com/gravitational/teleport/lib/reversetunnelclient"
Expand Down Expand Up @@ -266,6 +268,22 @@ type Config struct {
// NodeWatcher is a services.NodeWatcher used by Assist to lookup nodes from
// the proxy's cache and get nodes in real time.
NodeWatcher *services.NodeWatcher

// AutomaticUpgradesVersionURL is the URL which returns the target agent version.
// This URL must returns a valid version string.
// Eg, v13.4.3
// Optional: uses cloud/stable channel when omitted.
AutomaticUpgradesVersionURL string
}

// SetDefaults ensures proper default values are set if
// not provided.
func (c *Config) SetDefaults() {
c.ProxyClient = auth.WithGithubConnectorConversions(c.ProxyClient)

if c.TracerProvider == nil {
c.TracerProvider = tracing.NoopProvider()
}
}

type APIHandler struct {
Expand Down Expand Up @@ -1455,19 +1473,29 @@ func (h *Handler) getWebConfig(w http.ResponseWriter, r *http.Request, p httprou
canJoinSessions = !services.IsRecordAtProxy(recCfg.GetMode())
}

automaticUpgradesEnabled := clusterFeatures.GetAutomaticUpgrades()
var automaticUpgradesTargetVersion string
if automaticUpgradesEnabled {
automaticUpgradesTargetVersion, err = automaticupgrades.Version(r.Context(), h.cfg.AutomaticUpgradesVersionURL)
if err != nil {
return nil, trace.Wrap(err)
}
}

webCfg := webclient.WebConfig{
Auth: authSettings,
CanJoinSessions: canJoinSessions,
IsCloud: clusterFeatures.GetCloud(),
TunnelPublicAddress: tunnelPublicAddr,
RecoveryCodesEnabled: clusterFeatures.GetRecoveryCodes(),
UI: h.getUIConfig(r.Context()),
IsDashboard: isDashboard(clusterFeatures),
IsUsageBasedBilling: clusterFeatures.GetIsUsageBased(),
AutomaticUpgrades: clusterFeatures.GetAutomaticUpgrades(),
AssistEnabled: assistEnabled,
HideInaccessibleFeatures: clusterFeatures.GetFeatureHiding(),
CustomTheme: clusterFeatures.GetCustomTheme(),
Auth: authSettings,
CanJoinSessions: canJoinSessions,
IsCloud: clusterFeatures.GetCloud(),
TunnelPublicAddress: tunnelPublicAddr,
RecoveryCodesEnabled: clusterFeatures.GetRecoveryCodes(),
UI: h.getUIConfig(r.Context()),
IsDashboard: isDashboard(clusterFeatures),
IsUsageBasedBilling: clusterFeatures.GetIsUsageBased(),
AutomaticUpgrades: automaticUpgradesEnabled,
AutomaticUpgradesTargetVersion: automaticUpgradesTargetVersion,
AssistEnabled: assistEnabled,
HideInaccessibleFeatures: clusterFeatures.GetFeatureHiding(),
CustomTheme: clusterFeatures.GetCustomTheme(),
}

resource, err := h.cfg.ProxyClient.GetClusterName()
Expand Down
11 changes: 11 additions & 0 deletions lib/web/apiserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4588,9 +4588,20 @@ func TestGetWebConfig(t *testing.T) {
}
env.proxies[0].handler.handler.cfg.ProxySettings = mockProxySetting

httpTestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.URL.Path, "/v1/stable/cloud/version")
w.WriteHeader(http.StatusOK)
w.Write([]byte("v99.0.1"))
}))
defer httpTestServer.Close()
versionURL, err := url.JoinPath(httpTestServer.URL, "/v1/stable/cloud/version")
require.NoError(t, err)
env.proxies[0].handler.handler.cfg.AutomaticUpgradesVersionURL = versionURL

expectedCfg.IsCloud = true
expectedCfg.IsUsageBasedBilling = true
expectedCfg.AutomaticUpgrades = true
expectedCfg.AutomaticUpgradesTargetVersion = "v99.0.1"
expectedCfg.AssistEnabled = true

// request and verify enabled features are enabled.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,10 @@ const generateCmd = (data: {
isEnterprise: boolean;
isCloud: boolean;
automaticUpgradesEnabled: boolean;
automaticUpgradesTargetVersion: string;
}) => {
let extraYAMLConfig = '';
let deployVersion = data.clusterVersion;

if (data.isEnterprise) {
extraYAMLConfig += 'enterprise: true\n';
Expand All @@ -334,6 +336,11 @@ const generateCmd = (data: {
extraYAMLConfig += ' podDisruptionBudget:\n';
extraYAMLConfig += ' enabled: true\n';
extraYAMLConfig += ' minAvailable: 1\n';

// Replace the helm version to deploy with the one coming from the AutomaticUpgrades Version URL.
// AutomaticUpgradesTargetVersion contains a v, eg, v13.4.2.
// However, helm chart expects no 'v', eg, 13.4.2.
deployVersion = data.automaticUpgradesTargetVersion.replace(/^v/, '');
}

return `cat << EOF > prod-cluster-values.yaml
Expand All @@ -345,7 +352,7 @@ labels:
teleport.internal/resource-id: ${data.resourceId}
${extraYAMLConfig}EOF

helm install teleport-agent teleport/teleport-kube-agent -f prod-cluster-values.yaml --version ${data.clusterVersion} --create-namespace --namespace ${data.namespace}`;
helm install teleport-agent teleport/teleport-kube-agent -f prod-cluster-values.yaml --version ${deployVersion} --create-namespace --namespace ${data.namespace}`;
};

const InstallHelmChart = ({
Expand Down Expand Up @@ -440,6 +447,7 @@ const InstallHelmChart = ({
isEnterprise: ctx.isEnterprise,
isCloud: ctx.isCloud,
automaticUpgradesEnabled: ctx.automaticUpgradesEnabled,
automaticUpgradesTargetVersion: ctx.automaticUpgradesTargetVersion,
});

return (
Expand Down
1 change: 1 addition & 0 deletions web/packages/teleport/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const cfg = {
isCloud: false,
assistEnabled: false,
automaticUpgrades: false,
automaticUpgradesTargetVersion: '',
isDashboard: false,
tunnelPublicAddress: '',
recoveryCodesEnabled: false,
Expand Down
1 change: 1 addition & 0 deletions web/packages/teleport/src/teleportContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class TeleportContext implements types.Context {
isEnterprise = cfg.isEnterprise;
isCloud = cfg.isCloud;
automaticUpgradesEnabled = cfg.automaticUpgrades;
automaticUpgradesTargetVersion = cfg.automaticUpgradesTargetVersion;
assistEnabled = cfg.assistEnabled;
agentService = agentService;

Expand Down