Skip to content

Commit fcea2c6

Browse files
vapopovravicious
andauthored
[v14] Client tools managed updates (#52025)
* [v15] Client tools autoupdates (#48648) * Expose client tools auto update for find endpoint (#46785) * Expose client tools auto update for find endpoint * Group auto update settings in find response Log error instead returning error Add tests auto update settings in find endpoint Add check for not implemented error * Add more test cases * Client AutoUpdate proto structure changes (#47532) * Update client autoupdate proto structure * Replace with reserved * Fix unit tests * Add more info in proto * Rename proto to be aligned RFD namings * Replace enum type for ToolsMode to string * Add packaging utility for client tools auto updates (#47060) * Add packaging utility for client tools auto updates * Add error handling for close functions * Move archive to existing utils package * Move archive helpers to integration/helper CR changes * CR changes * CR changes * CR changes Replace creating directory with extract path as argument * CR changes * Validate full size before un-archive Extract files to extractDir with ignore dir structure * Change compressing with relative paths Add test for cleanup and fix skip logic * CR changes * CR changes * Fix linter * Client tools auto update (#47466) * Add client tools auto update * Replace fork for posix platform for re-exec Move integration tests to client tools specific dir Use context cancellation with SIGTERM, SIGINT Remove cancelable tee reader with context replacement Renaming * Fix syscall path execution Fix archive cleanup if hash is not valid Limit the archive write bytes * Cover the case with single package for darwin platform after v17 * Move updater logic to tools package * Move context out from the library Base URL renaming * Add more context in comments * Changes in find endpoint * Replace test http server with `httptest` Replace hash for bytes matching Proper temp file close for archive download * Add more context to comments * Move feature flag to main package to be reused * Constant rename * Replace build tag with lib/modules to identify enterprise build * Replace fips tag with modules flag * Client auto updates integration for {tctl,tsh} (#47815) * Client auto updates integration for tctl/tsh * Add version validation Fix recursive version check for darwin platform Fix cleanup for multi-package support * Fix identifying tools removal from home directory * Replace ToolsMode with ToolsAutoUpdate * Reuse insecure flag for tests * Fix CheckRemote with login * Fix windows administrative access requirement Update must be able to be canceled, re-execute with latest version or last updated Show progress bar before request is made * Fix update cancellation for login action Address review comments * Add signal handler with stack context cancellation * Use copy instead of hard link for windows Fix progress bar if we can't receive size of package * Replace with list in order to support manual cancel * Download archive package to temp directory * Decrease timeout for client tools proxy call * Add audit logs for auto update resources (#48218) * Connect: Make sure tsh auto-updates are turned off * Add dir for code shared between Node.js processes * Connect: Make sure tsh auto-updates are turned off * Pass TELEPORT_TOOLS_VERSION=off to tsh vnet-daemon * Disable client tools auto update disabled if there are no home dir (#49159) Move updater to general tools package * Move client auto update helper to lib package (#49247) * Restrict AutoUpdateVersion to be created/updated for cloud (#49008) (#50244) * Restrict AutoUpdateVersion to be created/updated for cloud * Check builtin Admin role and Cloud feature * More informative error message * Remove KindAutoUpdateAgentRollout from editor role preset * Add remove tctl command for AutoUpdateConfig and AutoUpdateVersion (#49532) (#49676) * Fix auto-update re-exec arguments modified by aliases (#50228) (#51183) * Fix auto-update re-exec arguments modified by aliases * Make arguments to be required to set * Restore progress bar show before request * Improve integration tests to execute with `tsh` and `tctl` Added a full-cycle integration test to verify client tools auto-updates within a test cluster by modifying AutoUpdateConfig and AutoUpdateVersion resources. The test executes the login command using alias configurations to ensure no recursive re-execution occurs. The updater binary used in integration tests has been replaced with the `Run` logic of tctl and tsh. * Set generated test password by env variable instead of constant value * Restore priority of env check over remote check In case of double re-execution case we should stop second one to prevent loop re-execution Drop localDir set during compilation * Add client tools auto update tctl commands (#47692) * Add client tools auto update tctl commands * Always print version for watch command Restrict update empty target version Rename command to upsert * Add alias on/off for tools mode Rename update command to configure * Add semantic version validation * Drop watch command for autoupdate * Replace Upsert with Update/Create Add format option for output json/yaml * Change update message * Use get/set naming for client-tools * Add mode to response * Change sub-command help messages Leave only aliases for enabled/disabled * Reorganize tctl commands to have commands not required auth client * Propagate insecure flag with global config to commands by context * Fix autoupdate command without auth client * Change commands to enable/disable/target * Add retry in case of the parallel request * Add more than one retry Code review changes * Add template for client tools auto-update download url (#51210) * Add templates for client tools auto-update download url * Change to base url setting by env MakeURL moved to common function to be general for both, agent and client tools * Add godoc for common function and constant for default package * Use flags and version arguments instead of revision * Move base url env to shared constant * Fix tests after backporting * Pass TELEPORT_TOOLS_VERSION=off when starting tshd * Prevent keystore cleanup to remove bin directory (#52331) * Don't show the progress bar until the request to the CDN is made * Fix Windows permission error with self remove (#52316) * Fix windows permission error with self replace * Aggregate errors * Update comments --------- Co-authored-by: Rafał Cieślak <rafal.cieslak@goteleport.com>
1 parent 333c530 commit fcea2c6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+5508
-1002
lines changed

api/client/webclient/webclient.go

+10
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ type PingResponse struct {
296296
ServerVersion string `json:"server_version"`
297297
// MinClientVersion is the minimum client version required by the server.
298298
MinClientVersion string `json:"min_client_version"`
299+
// AutoUpdateSettings contains the auto update settings.
300+
AutoUpdate AutoUpdateSettings `json:"auto_update"`
299301
// ClusterName contains the name of the Teleport cluster.
300302
ClusterName string `json:"cluster_name"`
301303

@@ -329,6 +331,14 @@ type ProxySettings struct {
329331
AssistEnabled bool `json:"assist_enabled"`
330332
}
331333

334+
// AutoUpdateSettings contains information about the auto update requirements.
335+
type AutoUpdateSettings struct {
336+
// ToolsVersion defines the version of {tsh, tctl} for client auto update.
337+
ToolsVersion string `json:"tools_version"`
338+
// ToolsAutoUpdate indicates if the requesting tools client should be updated.
339+
ToolsAutoUpdate bool `json:"tools_auto_update"`
340+
}
341+
332342
// KubeProxySettings is kubernetes proxy settings
333343
type KubeProxySettings struct {
334344
// Enabled is true when kubernetes proxy is enabled

api/gen/proto/go/teleport/autoupdate/v1/autoupdate.pb.go

+199-59
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/proto/teleport/autoupdate/v1/autoupdate.proto

+19-4
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,15 @@ message AutoUpdateConfig {
3333

3434
// AutoUpdateConfigSpec encodes the parameters of the autoupdate config object.
3535
message AutoUpdateConfigSpec {
36-
// ToolsAutoupdate encodes the feature flag to enable/disable tools autoupdates.
37-
bool tools_autoupdate = 1;
36+
reserved 1;
37+
reserved "tools_autoupdate"; // ToolsAutoupdate is replaced by tools.mode.
38+
AutoUpdateConfigSpecTools tools = 2;
39+
}
40+
41+
// AutoUpdateConfigSpecTools encodes the parameters for client tools auto updates.
42+
message AutoUpdateConfigSpecTools {
43+
// Mode defines state of the client tools auto update.
44+
string mode = 1;
3845
}
3946

4047
// AutoUpdateVersion is a resource singleton with version required for
@@ -50,6 +57,14 @@ message AutoUpdateVersion {
5057

5158
// AutoUpdateVersionSpec encodes the parameters of the autoupdate versions.
5259
message AutoUpdateVersionSpec {
53-
// ToolsVersion is the semantic version required for tools autoupdates.
54-
string tools_version = 1;
60+
reserved 1;
61+
reserved "tools_version"; // ToolsVersion is replaced by tools.target_version.
62+
AutoUpdateVersionSpecTools tools = 2;
63+
}
64+
65+
// AutoUpdateVersionSpecTools encodes the parameters for client tools auto updates.
66+
message AutoUpdateVersionSpecTools {
67+
// TargetVersion specifies the semantic version required for tools to establish a connection with the cluster.
68+
// Client tools after connection to the cluster going to be updated to this version automatically.
69+
string target_version = 1;
5570
}

api/proto/teleport/legacy/types/events/events.proto

+42
Original file line numberDiff line numberDiff line change
@@ -5865,6 +5865,13 @@ message AutoUpdateConfigCreate {
58655865
(gogoproto.embed) = true,
58665866
(gogoproto.jsontag) = ""
58675867
];
5868+
5869+
// Status indicates whether the creation was successful.
5870+
Status Status = 5 [
5871+
(gogoproto.nullable) = false,
5872+
(gogoproto.embed) = true,
5873+
(gogoproto.jsontag) = ""
5874+
];
58685875
}
58695876

58705877
// AutoUpdateConfigUpdate is emitted when an auto update config is updated.
@@ -5896,6 +5903,13 @@ message AutoUpdateConfigUpdate {
58965903
(gogoproto.embed) = true,
58975904
(gogoproto.jsontag) = ""
58985905
];
5906+
5907+
// ResourceMetadata is a common resource event metadata
5908+
ResourceMetadata Resource = 5 [
5909+
(gogoproto.nullable) = false,
5910+
(gogoproto.embed) = true,
5911+
(gogoproto.jsontag) = ""
5912+
];
58995913
}
59005914

59015915
// AutoUpdateConfigDelete is emitted when an auto update config is deleted.
@@ -5927,6 +5941,13 @@ message AutoUpdateConfigDelete {
59275941
(gogoproto.embed) = true,
59285942
(gogoproto.jsontag) = ""
59295943
];
5944+
5945+
// Status indicates whether the deletion was successful.
5946+
Status Status = 5 [
5947+
(gogoproto.nullable) = false,
5948+
(gogoproto.embed) = true,
5949+
(gogoproto.jsontag) = ""
5950+
];
59305951
}
59315952

59325953
// AutoUpdateVersionCreate is emitted when an auto update version is created.
@@ -5958,6 +5979,13 @@ message AutoUpdateVersionCreate {
59585979
(gogoproto.embed) = true,
59595980
(gogoproto.jsontag) = ""
59605981
];
5982+
5983+
// Status indicates whether the creation was successful.
5984+
Status Status = 5 [
5985+
(gogoproto.nullable) = false,
5986+
(gogoproto.embed) = true,
5987+
(gogoproto.jsontag) = ""
5988+
];
59615989
}
59625990

59635991
// AutoUpdateVersionUpdate is emitted when an auto update version is updated.
@@ -5989,6 +6017,13 @@ message AutoUpdateVersionUpdate {
59896017
(gogoproto.embed) = true,
59906018
(gogoproto.jsontag) = ""
59916019
];
6020+
6021+
// ResourceMetadata is a common resource event metadata
6022+
ResourceMetadata Resource = 5 [
6023+
(gogoproto.nullable) = false,
6024+
(gogoproto.embed) = true,
6025+
(gogoproto.jsontag) = ""
6026+
];
59926027
}
59936028

59946029
// AutoUpdateVersionDelete is emitted when an auto update version is deleted.
@@ -6020,4 +6055,11 @@ message AutoUpdateVersionDelete {
60206055
(gogoproto.embed) = true,
60216056
(gogoproto.jsontag) = ""
60226057
];
6058+
6059+
// Status indicates whether the deletion was successful.
6060+
Status Status = 5 [
6061+
(gogoproto.nullable) = false,
6062+
(gogoproto.embed) = true,
6063+
(gogoproto.jsontag) = ""
6064+
];
60236065
}

api/types/autoupdate/config.go

+12
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ import (
2626
"github.com/gravitational/teleport/api/types"
2727
)
2828

29+
const (
30+
// ToolsUpdateModeEnabled enables client tools automatic updates.
31+
ToolsUpdateModeEnabled = "enabled"
32+
// ToolsUpdateModeDisabled disables client tools automatic updates.
33+
ToolsUpdateModeDisabled = "disabled"
34+
)
35+
2936
// NewAutoUpdateConfig creates a new auto update configuration resource.
3037
func NewAutoUpdateConfig(spec *autoupdate.AutoUpdateConfigSpec) (*autoupdate.AutoUpdateConfig, error) {
3138
config := &autoupdate.AutoUpdateConfig{
@@ -58,6 +65,11 @@ func ValidateAutoUpdateConfig(c *autoupdate.AutoUpdateConfig) error {
5865
if c.Spec == nil {
5966
return trace.BadParameter("Spec is nil")
6067
}
68+
if c.Spec.Tools != nil {
69+
if c.Spec.Tools.Mode != ToolsUpdateModeDisabled && c.Spec.Tools.Mode != ToolsUpdateModeEnabled {
70+
return trace.BadParameter("ToolsMode is not valid")
71+
}
72+
}
6173

6274
return nil
6375
}

api/types/autoupdate/config_test.go

+23-4
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ func TestNewAutoUpdateConfig(t *testing.T) {
4141
{
4242
name: "success tools autoupdate disabled",
4343
spec: &autoupdate.AutoUpdateConfigSpec{
44-
ToolsAutoupdate: false,
44+
Tools: &autoupdate.AutoUpdateConfigSpecTools{
45+
Mode: ToolsUpdateModeDisabled,
46+
},
4547
},
4648
assertErr: func(t *testing.T, err error, a ...any) {
4749
require.NoError(t, err)
@@ -53,14 +55,18 @@ func TestNewAutoUpdateConfig(t *testing.T) {
5355
Name: types.MetaNameAutoUpdateConfig,
5456
},
5557
Spec: &autoupdate.AutoUpdateConfigSpec{
56-
ToolsAutoupdate: false,
58+
Tools: &autoupdate.AutoUpdateConfigSpecTools{
59+
Mode: ToolsUpdateModeDisabled,
60+
},
5761
},
5862
},
5963
},
6064
{
6165
name: "success tools autoupdate enabled",
6266
spec: &autoupdate.AutoUpdateConfigSpec{
63-
ToolsAutoupdate: true,
67+
Tools: &autoupdate.AutoUpdateConfigSpecTools{
68+
Mode: ToolsUpdateModeEnabled,
69+
},
6470
},
6571
assertErr: func(t *testing.T, err error, a ...any) {
6672
require.NoError(t, err)
@@ -72,7 +78,9 @@ func TestNewAutoUpdateConfig(t *testing.T) {
7278
Name: types.MetaNameAutoUpdateConfig,
7379
},
7480
Spec: &autoupdate.AutoUpdateConfigSpec{
75-
ToolsAutoupdate: true,
81+
Tools: &autoupdate.AutoUpdateConfigSpecTools{
82+
Mode: ToolsUpdateModeEnabled,
83+
},
7684
},
7785
},
7886
},
@@ -83,6 +91,17 @@ func TestNewAutoUpdateConfig(t *testing.T) {
8391
require.ErrorContains(t, err, "Spec is nil")
8492
},
8593
},
94+
{
95+
name: "invalid tools mode",
96+
spec: &autoupdate.AutoUpdateConfigSpec{
97+
Tools: &autoupdate.AutoUpdateConfigSpecTools{
98+
Mode: "invalid-mode",
99+
},
100+
},
101+
assertErr: func(t *testing.T, err error, a ...any) {
102+
require.ErrorContains(t, err, "ToolsMode is not valid")
103+
},
104+
},
86105
}
87106
for _, tt := range tests {
88107
t.Run(tt.name, func(t *testing.T) {

api/types/autoupdate/version.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,13 @@ func ValidateAutoUpdateVersion(v *autoupdate.AutoUpdateVersion) error {
6060
return trace.BadParameter("Spec is nil")
6161
}
6262

63-
if v.Spec.ToolsVersion == "" {
64-
return trace.BadParameter("ToolsVersion is unset")
65-
}
66-
if _, err := semver.NewVersion(v.Spec.ToolsVersion); err != nil {
67-
return trace.BadParameter("ToolsVersion is not a valid semantic version")
63+
if v.Spec.Tools != nil {
64+
if v.Spec.Tools.TargetVersion == "" {
65+
return trace.BadParameter("TargetVersion is unset")
66+
}
67+
if _, err := semver.NewVersion(v.Spec.Tools.TargetVersion); err != nil {
68+
return trace.BadParameter("TargetVersion is not a valid semantic version")
69+
}
6870
}
6971

7072
return nil

api/types/autoupdate/version_test.go

+14-6
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ func TestNewAutoUpdateVersion(t *testing.T) {
4141
{
4242
name: "success tools autoupdate version",
4343
spec: &autoupdate.AutoUpdateVersionSpec{
44-
ToolsVersion: "1.2.3-dev",
44+
Tools: &autoupdate.AutoUpdateVersionSpecTools{
45+
TargetVersion: "1.2.3-dev",
46+
},
4547
},
4648
assertErr: func(t *testing.T, err error, a ...any) {
4749
require.NoError(t, err)
@@ -53,26 +55,32 @@ func TestNewAutoUpdateVersion(t *testing.T) {
5355
Name: types.MetaNameAutoUpdateVersion,
5456
},
5557
Spec: &autoupdate.AutoUpdateVersionSpec{
56-
ToolsVersion: "1.2.3-dev",
58+
Tools: &autoupdate.AutoUpdateVersionSpecTools{
59+
TargetVersion: "1.2.3-dev",
60+
},
5761
},
5862
},
5963
},
6064
{
6165
name: "invalid empty tools version",
6266
spec: &autoupdate.AutoUpdateVersionSpec{
63-
ToolsVersion: "",
67+
Tools: &autoupdate.AutoUpdateVersionSpecTools{
68+
TargetVersion: "",
69+
},
6470
},
6571
assertErr: func(t *testing.T, err error, a ...any) {
66-
require.ErrorContains(t, err, "ToolsVersion is unset")
72+
require.ErrorContains(t, err, "TargetVersion is unset")
6773
},
6874
},
6975
{
7076
name: "invalid semantic tools version",
7177
spec: &autoupdate.AutoUpdateVersionSpec{
72-
ToolsVersion: "17-0-0",
78+
Tools: &autoupdate.AutoUpdateVersionSpecTools{
79+
TargetVersion: "17-0-0",
80+
},
7381
},
7482
assertErr: func(t *testing.T, err error, a ...any) {
75-
require.ErrorContains(t, err, "ToolsVersion is not a valid semantic version")
83+
require.ErrorContains(t, err, "TargetVersion is not a valid semantic version")
7684
},
7785
},
7886
{

api/types/events/events.go

+24
Original file line numberDiff line numberDiff line change
@@ -1980,3 +1980,27 @@ func (m *IntegrationUpdate) TrimToMaxSize(maxSize int) AuditEvent {
19801980
func (m *IntegrationDelete) TrimToMaxSize(maxSize int) AuditEvent {
19811981
return m
19821982
}
1983+
1984+
func (m *AutoUpdateConfigCreate) TrimToMaxSize(_ int) AuditEvent {
1985+
return m
1986+
}
1987+
1988+
func (m *AutoUpdateConfigUpdate) TrimToMaxSize(_ int) AuditEvent {
1989+
return m
1990+
}
1991+
1992+
func (m *AutoUpdateConfigDelete) TrimToMaxSize(_ int) AuditEvent {
1993+
return m
1994+
}
1995+
1996+
func (m *AutoUpdateVersionCreate) TrimToMaxSize(_ int) AuditEvent {
1997+
return m
1998+
}
1999+
2000+
func (m *AutoUpdateVersionUpdate) TrimToMaxSize(_ int) AuditEvent {
2001+
return m
2002+
}
2003+
2004+
func (m *AutoUpdateVersionDelete) TrimToMaxSize(_ int) AuditEvent {
2005+
return m
2006+
}

0 commit comments

Comments
 (0)