Skip to content

Commit 200eb57

Browse files
authored
[v17] Client tools autoupdates (#48635)
* 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)
1 parent 11d0ffe commit 200eb57

File tree

33 files changed

+2384
-1254
lines changed

33 files changed

+2384
-1254
lines changed

api/client/webclient/webclient.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,8 @@ type ProxySettings struct {
334334
type AutoUpdateSettings struct {
335335
// ToolsVersion defines the version of {tsh, tctl} for client auto update.
336336
ToolsVersion string `json:"tools_version"`
337-
// ToolsMode defines mode client auto update feature `enabled|disabled`.
338-
ToolsMode string `json:"tools_mode"`
337+
// ToolsAutoUpdate indicates if the requesting tools client should be updated.
338+
ToolsAutoUpdate bool `json:"tools_auto_update"`
339339
}
340340

341341
// KubeProxySettings is kubernetes proxy settings

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6977,6 +6977,13 @@ message AutoUpdateConfigCreate {
69776977
(gogoproto.embed) = true,
69786978
(gogoproto.jsontag) = ""
69796979
];
6980+
6981+
// Status indicates whether the creation was successful.
6982+
Status Status = 5 [
6983+
(gogoproto.nullable) = false,
6984+
(gogoproto.embed) = true,
6985+
(gogoproto.jsontag) = ""
6986+
];
69806987
}
69816988

69826989
// AutoUpdateConfigUpdate is emitted when an auto update config is updated.
@@ -7008,6 +7015,13 @@ message AutoUpdateConfigUpdate {
70087015
(gogoproto.embed) = true,
70097016
(gogoproto.jsontag) = ""
70107017
];
7018+
7019+
// ResourceMetadata is a common resource event metadata
7020+
ResourceMetadata Resource = 5 [
7021+
(gogoproto.nullable) = false,
7022+
(gogoproto.embed) = true,
7023+
(gogoproto.jsontag) = ""
7024+
];
70117025
}
70127026

70137027
// AutoUpdateConfigDelete is emitted when an auto update config is deleted.
@@ -7039,6 +7053,13 @@ message AutoUpdateConfigDelete {
70397053
(gogoproto.embed) = true,
70407054
(gogoproto.jsontag) = ""
70417055
];
7056+
7057+
// Status indicates whether the deletion was successful.
7058+
Status Status = 5 [
7059+
(gogoproto.nullable) = false,
7060+
(gogoproto.embed) = true,
7061+
(gogoproto.jsontag) = ""
7062+
];
70427063
}
70437064

70447065
// AutoUpdateVersionCreate is emitted when an auto update version is created.
@@ -7070,6 +7091,13 @@ message AutoUpdateVersionCreate {
70707091
(gogoproto.embed) = true,
70717092
(gogoproto.jsontag) = ""
70727093
];
7094+
7095+
// Status indicates whether the creation was successful.
7096+
Status Status = 5 [
7097+
(gogoproto.nullable) = false,
7098+
(gogoproto.embed) = true,
7099+
(gogoproto.jsontag) = ""
7100+
];
70737101
}
70747102

70757103
// AutoUpdateVersionUpdate is emitted when an auto update version is updated.
@@ -7101,6 +7129,13 @@ message AutoUpdateVersionUpdate {
71017129
(gogoproto.embed) = true,
71027130
(gogoproto.jsontag) = ""
71037131
];
7132+
7133+
// ResourceMetadata is a common resource event metadata
7134+
ResourceMetadata Resource = 5 [
7135+
(gogoproto.nullable) = false,
7136+
(gogoproto.embed) = true,
7137+
(gogoproto.jsontag) = ""
7138+
];
71047139
}
71057140

71067141
// AutoUpdateVersionDelete is emitted when an auto update version is deleted.
@@ -7132,6 +7167,13 @@ message AutoUpdateVersionDelete {
71327167
(gogoproto.embed) = true,
71337168
(gogoproto.jsontag) = ""
71347169
];
7170+
7171+
// Status indicates whether the deletion was successful.
7172+
Status Status = 5 [
7173+
(gogoproto.nullable) = false,
7174+
(gogoproto.embed) = true,
7175+
(gogoproto.jsontag) = ""
7176+
];
71357177
}
71367178

71377179
// StaticHostUserCreate is emitted when a static host user is created.

api/types/events/events.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,3 +2328,27 @@ func (m *SFTPSummary) TrimToMaxSize(maxSize int) AuditEvent {
23282328

23292329
return out
23302330
}
2331+
2332+
func (m *AutoUpdateConfigCreate) TrimToMaxSize(_ int) AuditEvent {
2333+
return m
2334+
}
2335+
2336+
func (m *AutoUpdateConfigUpdate) TrimToMaxSize(_ int) AuditEvent {
2337+
return m
2338+
}
2339+
2340+
func (m *AutoUpdateConfigDelete) TrimToMaxSize(_ int) AuditEvent {
2341+
return m
2342+
}
2343+
2344+
func (m *AutoUpdateVersionCreate) TrimToMaxSize(_ int) AuditEvent {
2345+
return m
2346+
}
2347+
2348+
func (m *AutoUpdateVersionUpdate) TrimToMaxSize(_ int) AuditEvent {
2349+
return m
2350+
}
2351+
2352+
func (m *AutoUpdateVersionDelete) TrimToMaxSize(_ int) AuditEvent {
2353+
return m
2354+
}

api/types/events/events.pb.go

Lines changed: 1342 additions & 1059 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/types/events/oneof.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,31 @@ func ToOneOf(in AuditEvent) (*OneOf, error) {
765765
out.Event = &OneOf_SFTPSummary{
766766
SFTPSummary: e,
767767
}
768+
case *AutoUpdateConfigCreate:
769+
out.Event = &OneOf_AutoUpdateConfigCreate{
770+
AutoUpdateConfigCreate: e,
771+
}
772+
case *AutoUpdateConfigUpdate:
773+
out.Event = &OneOf_AutoUpdateConfigUpdate{
774+
AutoUpdateConfigUpdate: e,
775+
}
776+
case *AutoUpdateConfigDelete:
777+
out.Event = &OneOf_AutoUpdateConfigDelete{
778+
AutoUpdateConfigDelete: e,
779+
}
780+
781+
case *AutoUpdateVersionCreate:
782+
out.Event = &OneOf_AutoUpdateVersionCreate{
783+
AutoUpdateVersionCreate: e,
784+
}
785+
case *AutoUpdateVersionUpdate:
786+
out.Event = &OneOf_AutoUpdateVersionUpdate{
787+
AutoUpdateVersionUpdate: e,
788+
}
789+
case *AutoUpdateVersionDelete:
790+
out.Event = &OneOf_AutoUpdateVersionDelete{
791+
AutoUpdateVersionDelete: e,
792+
}
768793
default:
769794
slog.ErrorContext(context.Background(), "Attempted to convert dynamic event of unknown type into protobuf event.", "event_type", in.GetType())
770795
unknown := &Unknown{}

integration/autoupdate/tools/main_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ import (
3737

3838
"github.com/gravitational/trace"
3939

40-
"github.com/gravitational/teleport/integration/helpers"
40+
"github.com/gravitational/teleport/api/constants"
41+
"github.com/gravitational/teleport/integration/helpers/archive"
4142
)
4243

4344
const (
@@ -133,25 +134,25 @@ func buildAndArchiveApps(ctx context.Context, path string, toolsDir string, vers
133134
for _, app := range []string{"tsh", "tctl"} {
134135
output := filepath.Join(versionPath, app)
135136
switch runtime.GOOS {
136-
case "windows":
137+
case constants.WindowsOS:
137138
output = filepath.Join(versionPath, app+".exe")
138-
case "darwin":
139+
case constants.DarwinOS:
139140
output = filepath.Join(versionPath, app+".app", "Contents", "MacOS", app)
140141
}
141142
if err := buildBinary(output, toolsDir, version, baseURL); err != nil {
142143
return trace.Wrap(err)
143144
}
144145
}
145146
switch runtime.GOOS {
146-
case "darwin":
147+
case constants.DarwinOS:
147148
archivePath := filepath.Join(path, fmt.Sprintf("teleport-%s.pkg", version))
148-
return trace.Wrap(helpers.CompressDirToPkgFile(ctx, versionPath, archivePath, "com.example.pkgtest"))
149-
case "windows":
149+
return trace.Wrap(archive.CompressDirToPkgFile(ctx, versionPath, archivePath, "com.example.pkgtest"))
150+
case constants.WindowsOS:
150151
archivePath := filepath.Join(path, fmt.Sprintf("teleport-v%s-windows-amd64-bin.zip", version))
151-
return trace.Wrap(helpers.CompressDirToZipFile(ctx, versionPath, archivePath))
152+
return trace.Wrap(archive.CompressDirToZipFile(ctx, versionPath, archivePath))
152153
default:
153154
archivePath := filepath.Join(path, fmt.Sprintf("teleport-v%s-linux-%s-bin.tar.gz", version, runtime.GOARCH))
154-
return trace.Wrap(helpers.CompressDirToTarGzFile(ctx, versionPath, archivePath))
155+
return trace.Wrap(archive.CompressDirToTarGzFile(ctx, versionPath, archivePath))
155156
}
156157
}
157158

integration/autoupdate/tools/updater/main.go

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,9 @@ import (
2525
"log"
2626
"os"
2727
"os/signal"
28-
"runtime"
2928
"syscall"
3029
"time"
3130

32-
"github.com/gravitational/teleport/api/constants"
3331
"github.com/gravitational/teleport/lib/autoupdate/tools"
3432
)
3533

@@ -40,17 +38,20 @@ var (
4038
)
4139

4240
func main() {
43-
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
41+
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
4442
defer cancel()
4543
ctx, _ = signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
4644

4745
updater := tools.NewUpdater(
48-
clientTools(),
46+
tools.DefaultClientTools(),
4947
toolsDir,
5048
version,
5149
tools.WithBaseURL(baseURL),
5250
)
53-
toolsVersion, reExec := updater.CheckLocal()
51+
toolsVersion, reExec, err := updater.CheckLocal()
52+
if err != nil {
53+
log.Fatal(err)
54+
}
5455
if reExec {
5556
// Download and update the version of client tools required by the cluster.
5657
// This is required if the user passed in the TELEPORT_TOOLS_VERSION explicitly.
@@ -76,13 +77,3 @@ func main() {
7677
fmt.Printf("Teleport v%v git\n", version)
7778
}
7879
}
79-
80-
// clientTools list of the client tools needs to be updated.
81-
func clientTools() []string {
82-
switch runtime.GOOS {
83-
case constants.WindowsOS:
84-
return []string{"tsh.exe", "tctl.exe"}
85-
default:
86-
return []string{"tsh", "tctl"}
87-
}
88-
}

integration/autoupdate/tools/updater_test.go

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,13 @@ import (
2626
"os/exec"
2727
"path/filepath"
2828
"regexp"
29-
"runtime"
3029
"strings"
3130
"testing"
3231
"time"
3332

3433
"github.com/stretchr/testify/assert"
3534
"github.com/stretchr/testify/require"
3635

37-
"github.com/gravitational/teleport/api/constants"
3836
"github.com/gravitational/teleport/lib/autoupdate/tools"
3937
)
4038

@@ -51,7 +49,7 @@ func TestUpdate(t *testing.T) {
5149

5250
// Fetch compiled test binary with updater logic and install to $TELEPORT_HOME.
5351
updater := tools.NewUpdater(
54-
clientTools(),
52+
tools.DefaultClientTools(),
5553
toolsDir,
5654
testVersions[0],
5755
tools.WithBaseURL(baseURL),
@@ -93,7 +91,7 @@ func TestParallelUpdate(t *testing.T) {
9391

9492
// Initial fetch the updater binary un-archive and replace.
9593
updater := tools.NewUpdater(
96-
clientTools(),
94+
tools.DefaultClientTools(),
9795
toolsDir,
9896
testVersions[0],
9997
tools.WithBaseURL(baseURL),
@@ -167,7 +165,7 @@ func TestUpdateInterruptSignal(t *testing.T) {
167165

168166
// Initial fetch the updater binary un-archive and replace.
169167
updater := tools.NewUpdater(
170-
clientTools(),
168+
tools.DefaultClientTools(),
171169
toolsDir,
172170
testVersions[0],
173171
tools.WithBaseURL(baseURL),
@@ -220,12 +218,3 @@ func TestUpdateInterruptSignal(t *testing.T) {
220218
}
221219
assert.Contains(t, output.String(), "Update progress:")
222220
}
223-
224-
func clientTools() []string {
225-
switch runtime.GOOS {
226-
case constants.WindowsOS:
227-
return []string{"tsh.exe", "tctl.exe"}
228-
default:
229-
return []string{"tsh", "tctl"}
230-
}
231-
}

integration/helpers/archive.go renamed to integration/helpers/archive/packaging.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
*/
1818

19-
package helpers
19+
package archive
2020

2121
import (
2222
"archive/tar"

integrations/event-handler/go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,10 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe
11331133
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
11341134
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM=
11351135
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
1136+
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
11361137
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
1138+
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
1139+
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
11371140
github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
11381141
github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=
11391142
github.com/google/safetext v0.0.0-20240104143208-7a7d9b3d812f h1:o2yGZLlsOj5H5uvtQNEdi6DeA0GbUP3lm0gWW5RvY0s=

integrations/terraform/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ require (
187187
github.com/google/go-tspi v0.3.0 // indirect
188188
github.com/google/gofuzz v1.2.0 // indirect
189189
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect
190+
github.com/google/renameio/v2 v2.0.0 // indirect
190191
github.com/google/s2a-go v0.1.8 // indirect
191192
github.com/google/safetext v0.0.0-20240104143208-7a7d9b3d812f // indirect
192193
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect

integrations/terraform/go.sum

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1260,7 +1260,6 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe
12601260
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
12611261
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM=
12621262
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
1263-
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
12641263
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
12651264
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
12661265
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=

0 commit comments

Comments
 (0)