diff --git a/api/client/webclient/webclient.go b/api/client/webclient/webclient.go index 7a30ea67ea5d9..166182e51f3bd 100644 --- a/api/client/webclient/webclient.go +++ b/api/client/webclient/webclient.go @@ -296,6 +296,8 @@ type PingResponse struct { ServerVersion string `json:"server_version"` // MinClientVersion is the minimum client version required by the server. MinClientVersion string `json:"min_client_version"` + // AutoUpdateSettings contains the auto update settings. + AutoUpdate AutoUpdateSettings `json:"auto_update"` // ClusterName contains the name of the Teleport cluster. ClusterName string `json:"cluster_name"` @@ -329,6 +331,14 @@ type ProxySettings struct { AssistEnabled bool `json:"assist_enabled"` } +// AutoUpdateSettings contains information about the auto update requirements. +type AutoUpdateSettings struct { + // ToolsVersion defines the version of {tsh, tctl} for client auto update. + ToolsVersion string `json:"tools_version"` + // ToolsMode defines mode client auto update feature `enabled|disabled`. + ToolsMode string `json:"tools_mode"` +} + // KubeProxySettings is kubernetes proxy settings type KubeProxySettings struct { // Enabled is true when kubernetes proxy is enabled diff --git a/api/gen/proto/go/teleport/autoupdate/v1/autoupdate.pb.go b/api/gen/proto/go/teleport/autoupdate/v1/autoupdate.pb.go index eff70443d2f28..ffc36aeb70163 100644 --- a/api/gen/proto/go/teleport/autoupdate/v1/autoupdate.pb.go +++ b/api/gen/proto/go/teleport/autoupdate/v1/autoupdate.pb.go @@ -122,8 +122,7 @@ type AutoUpdateConfigSpec struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // ToolsAutoupdate encodes the feature flag to enable/disable tools autoupdates. - ToolsAutoupdate bool `protobuf:"varint,1,opt,name=tools_autoupdate,json=toolsAutoupdate,proto3" json:"tools_autoupdate,omitempty"` + Tools *AutoUpdateConfigSpecTools `protobuf:"bytes,2,opt,name=tools,proto3" json:"tools,omitempty"` } func (x *AutoUpdateConfigSpec) Reset() { @@ -158,11 +157,60 @@ func (*AutoUpdateConfigSpec) Descriptor() ([]byte, []int) { return file_teleport_autoupdate_v1_autoupdate_proto_rawDescGZIP(), []int{1} } -func (x *AutoUpdateConfigSpec) GetToolsAutoupdate() bool { +func (x *AutoUpdateConfigSpec) GetTools() *AutoUpdateConfigSpecTools { if x != nil { - return x.ToolsAutoupdate + return x.Tools } - return false + return nil +} + +// AutoUpdateConfigSpecTools encodes the parameters for client tools auto updates. +type AutoUpdateConfigSpecTools struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Mode defines state of the client tools auto update. + Mode string `protobuf:"bytes,1,opt,name=mode,proto3" json:"mode,omitempty"` +} + +func (x *AutoUpdateConfigSpecTools) Reset() { + *x = AutoUpdateConfigSpecTools{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AutoUpdateConfigSpecTools) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AutoUpdateConfigSpecTools) ProtoMessage() {} + +func (x *AutoUpdateConfigSpecTools) ProtoReflect() protoreflect.Message { + mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AutoUpdateConfigSpecTools.ProtoReflect.Descriptor instead. +func (*AutoUpdateConfigSpecTools) Descriptor() ([]byte, []int) { + return file_teleport_autoupdate_v1_autoupdate_proto_rawDescGZIP(), []int{2} +} + +func (x *AutoUpdateConfigSpecTools) GetMode() string { + if x != nil { + return x.Mode + } + return "" } // AutoUpdateVersion is a resource singleton with version required for @@ -182,7 +230,7 @@ type AutoUpdateVersion struct { func (x *AutoUpdateVersion) Reset() { *x = AutoUpdateVersion{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[2] + mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -195,7 +243,7 @@ func (x *AutoUpdateVersion) String() string { func (*AutoUpdateVersion) ProtoMessage() {} func (x *AutoUpdateVersion) ProtoReflect() protoreflect.Message { - mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[2] + mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -208,7 +256,7 @@ func (x *AutoUpdateVersion) ProtoReflect() protoreflect.Message { // Deprecated: Use AutoUpdateVersion.ProtoReflect.Descriptor instead. func (*AutoUpdateVersion) Descriptor() ([]byte, []int) { - return file_teleport_autoupdate_v1_autoupdate_proto_rawDescGZIP(), []int{2} + return file_teleport_autoupdate_v1_autoupdate_proto_rawDescGZIP(), []int{3} } func (x *AutoUpdateVersion) GetKind() string { @@ -252,14 +300,13 @@ type AutoUpdateVersionSpec struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // ToolsVersion is the semantic version required for tools autoupdates. - ToolsVersion string `protobuf:"bytes,1,opt,name=tools_version,json=toolsVersion,proto3" json:"tools_version,omitempty"` + Tools *AutoUpdateVersionSpecTools `protobuf:"bytes,2,opt,name=tools,proto3" json:"tools,omitempty"` } func (x *AutoUpdateVersionSpec) Reset() { *x = AutoUpdateVersionSpec{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[3] + mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -272,7 +319,7 @@ func (x *AutoUpdateVersionSpec) String() string { func (*AutoUpdateVersionSpec) ProtoMessage() {} func (x *AutoUpdateVersionSpec) ProtoReflect() protoreflect.Message { - mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[3] + mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -285,12 +332,62 @@ func (x *AutoUpdateVersionSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use AutoUpdateVersionSpec.ProtoReflect.Descriptor instead. func (*AutoUpdateVersionSpec) Descriptor() ([]byte, []int) { - return file_teleport_autoupdate_v1_autoupdate_proto_rawDescGZIP(), []int{3} + return file_teleport_autoupdate_v1_autoupdate_proto_rawDescGZIP(), []int{4} +} + +func (x *AutoUpdateVersionSpec) GetTools() *AutoUpdateVersionSpecTools { + if x != nil { + return x.Tools + } + return nil } -func (x *AutoUpdateVersionSpec) GetToolsVersion() string { +// AutoUpdateVersionSpecTools encodes the parameters for client tools auto updates. +type AutoUpdateVersionSpecTools struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // TargetVersion specifies the semantic version required for tools to establish a connection with the cluster. + // Client tools after connection to the cluster going to be updated to this version automatically. + TargetVersion string `protobuf:"bytes,1,opt,name=target_version,json=targetVersion,proto3" json:"target_version,omitempty"` +} + +func (x *AutoUpdateVersionSpecTools) Reset() { + *x = AutoUpdateVersionSpecTools{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AutoUpdateVersionSpecTools) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AutoUpdateVersionSpecTools) ProtoMessage() {} + +func (x *AutoUpdateVersionSpecTools) ProtoReflect() protoreflect.Message { + mi := &file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AutoUpdateVersionSpecTools.ProtoReflect.Descriptor instead. +func (*AutoUpdateVersionSpecTools) Descriptor() ([]byte, []int) { + return file_teleport_autoupdate_v1_autoupdate_proto_rawDescGZIP(), []int{5} +} + +func (x *AutoUpdateVersionSpecTools) GetTargetVersion() string { if x != nil { - return x.ToolsVersion + return x.TargetVersion } return "" } @@ -317,35 +414,50 @@ var file_teleport_autoupdate_v1_autoupdate_proto_rawDesc = []byte{ 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x41, + 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x77, 0x0a, 0x14, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x5f, - 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x41, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x22, 0xd9, 0x01, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, - 0x75, 0x62, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, - 0x75, 0x62, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x04, 0x73, 0x70, - 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x3c, 0x0a, - 0x15, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x5f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, - 0x6f, 0x6f, 0x6c, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x56, 0x5a, 0x54, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, - 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x47, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, + 0x70, 0x65, 0x63, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x4a, + 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x10, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x5f, 0x61, 0x75, 0x74, + 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0x2f, 0x0a, 0x19, 0x41, 0x75, 0x74, 0x6f, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x54, + 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0xd9, 0x01, 0x0a, 0x11, 0x41, 0x75, 0x74, + 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, + 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x41, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, + 0x73, 0x70, 0x65, 0x63, 0x22, 0x76, 0x0a, 0x15, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x48, 0x0a, + 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x54, 0x6f, 0x6f, 0x6c, 0x73, + 0x52, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x0d, 0x74, + 0x6f, 0x6f, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x43, 0x0a, 0x1a, + 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x53, 0x70, 0x65, 0x63, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x42, 0x56, 0x5a, 0x54, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x61, + 0x75, 0x74, 0x6f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -360,24 +472,28 @@ func file_teleport_autoupdate_v1_autoupdate_proto_rawDescGZIP() []byte { return file_teleport_autoupdate_v1_autoupdate_proto_rawDescData } -var file_teleport_autoupdate_v1_autoupdate_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_teleport_autoupdate_v1_autoupdate_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_teleport_autoupdate_v1_autoupdate_proto_goTypes = []interface{}{ - (*AutoUpdateConfig)(nil), // 0: teleport.autoupdate.v1.AutoUpdateConfig - (*AutoUpdateConfigSpec)(nil), // 1: teleport.autoupdate.v1.AutoUpdateConfigSpec - (*AutoUpdateVersion)(nil), // 2: teleport.autoupdate.v1.AutoUpdateVersion - (*AutoUpdateVersionSpec)(nil), // 3: teleport.autoupdate.v1.AutoUpdateVersionSpec - (*v1.Metadata)(nil), // 4: teleport.header.v1.Metadata + (*AutoUpdateConfig)(nil), // 0: teleport.autoupdate.v1.AutoUpdateConfig + (*AutoUpdateConfigSpec)(nil), // 1: teleport.autoupdate.v1.AutoUpdateConfigSpec + (*AutoUpdateConfigSpecTools)(nil), // 2: teleport.autoupdate.v1.AutoUpdateConfigSpecTools + (*AutoUpdateVersion)(nil), // 3: teleport.autoupdate.v1.AutoUpdateVersion + (*AutoUpdateVersionSpec)(nil), // 4: teleport.autoupdate.v1.AutoUpdateVersionSpec + (*AutoUpdateVersionSpecTools)(nil), // 5: teleport.autoupdate.v1.AutoUpdateVersionSpecTools + (*v1.Metadata)(nil), // 6: teleport.header.v1.Metadata } var file_teleport_autoupdate_v1_autoupdate_proto_depIdxs = []int32{ - 4, // 0: teleport.autoupdate.v1.AutoUpdateConfig.metadata:type_name -> teleport.header.v1.Metadata + 6, // 0: teleport.autoupdate.v1.AutoUpdateConfig.metadata:type_name -> teleport.header.v1.Metadata 1, // 1: teleport.autoupdate.v1.AutoUpdateConfig.spec:type_name -> teleport.autoupdate.v1.AutoUpdateConfigSpec - 4, // 2: teleport.autoupdate.v1.AutoUpdateVersion.metadata:type_name -> teleport.header.v1.Metadata - 3, // 3: teleport.autoupdate.v1.AutoUpdateVersion.spec:type_name -> teleport.autoupdate.v1.AutoUpdateVersionSpec - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 2, // 2: teleport.autoupdate.v1.AutoUpdateConfigSpec.tools:type_name -> teleport.autoupdate.v1.AutoUpdateConfigSpecTools + 6, // 3: teleport.autoupdate.v1.AutoUpdateVersion.metadata:type_name -> teleport.header.v1.Metadata + 4, // 4: teleport.autoupdate.v1.AutoUpdateVersion.spec:type_name -> teleport.autoupdate.v1.AutoUpdateVersionSpec + 5, // 5: teleport.autoupdate.v1.AutoUpdateVersionSpec.tools:type_name -> teleport.autoupdate.v1.AutoUpdateVersionSpecTools + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_teleport_autoupdate_v1_autoupdate_proto_init() } @@ -411,7 +527,7 @@ func file_teleport_autoupdate_v1_autoupdate_proto_init() { } } file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AutoUpdateVersion); i { + switch v := v.(*AutoUpdateConfigSpecTools); i { case 0: return &v.state case 1: @@ -423,6 +539,18 @@ func file_teleport_autoupdate_v1_autoupdate_proto_init() { } } file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AutoUpdateVersion); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AutoUpdateVersionSpec); i { case 0: return &v.state @@ -434,6 +562,18 @@ func file_teleport_autoupdate_v1_autoupdate_proto_init() { return nil } } + file_teleport_autoupdate_v1_autoupdate_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AutoUpdateVersionSpecTools); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -441,7 +581,7 @@ func file_teleport_autoupdate_v1_autoupdate_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_teleport_autoupdate_v1_autoupdate_proto_rawDesc, NumEnums: 0, - NumMessages: 4, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/api/proto/teleport/autoupdate/v1/autoupdate.proto b/api/proto/teleport/autoupdate/v1/autoupdate.proto index 1987407fe7d81..b4e557549b316 100644 --- a/api/proto/teleport/autoupdate/v1/autoupdate.proto +++ b/api/proto/teleport/autoupdate/v1/autoupdate.proto @@ -33,8 +33,15 @@ message AutoUpdateConfig { // AutoUpdateConfigSpec encodes the parameters of the autoupdate config object. message AutoUpdateConfigSpec { - // ToolsAutoupdate encodes the feature flag to enable/disable tools autoupdates. - bool tools_autoupdate = 1; + reserved 1; + reserved "tools_autoupdate"; // ToolsAutoupdate is replaced by tools.mode. + AutoUpdateConfigSpecTools tools = 2; +} + +// AutoUpdateConfigSpecTools encodes the parameters for client tools auto updates. +message AutoUpdateConfigSpecTools { + // Mode defines state of the client tools auto update. + string mode = 1; } // AutoUpdateVersion is a resource singleton with version required for @@ -50,6 +57,14 @@ message AutoUpdateVersion { // AutoUpdateVersionSpec encodes the parameters of the autoupdate versions. message AutoUpdateVersionSpec { - // ToolsVersion is the semantic version required for tools autoupdates. - string tools_version = 1; + reserved 1; + reserved "tools_version"; // ToolsVersion is replaced by tools.target_version. + AutoUpdateVersionSpecTools tools = 2; +} + +// AutoUpdateVersionSpecTools encodes the parameters for client tools auto updates. +message AutoUpdateVersionSpecTools { + // TargetVersion specifies the semantic version required for tools to establish a connection with the cluster. + // Client tools after connection to the cluster going to be updated to this version automatically. + string target_version = 1; } diff --git a/api/types/autoupdate/config.go b/api/types/autoupdate/config.go index 5be3db89fd0c5..d61c35eccf0c2 100644 --- a/api/types/autoupdate/config.go +++ b/api/types/autoupdate/config.go @@ -26,6 +26,13 @@ import ( "github.com/gravitational/teleport/api/types" ) +const ( + // ToolsUpdateModeEnabled enables client tools automatic updates. + ToolsUpdateModeEnabled = "enabled" + // ToolsUpdateModeDisabled disables client tools automatic updates. + ToolsUpdateModeDisabled = "disabled" +) + // NewAutoUpdateConfig creates a new auto update configuration resource. func NewAutoUpdateConfig(spec *autoupdate.AutoUpdateConfigSpec) (*autoupdate.AutoUpdateConfig, error) { config := &autoupdate.AutoUpdateConfig{ @@ -58,6 +65,11 @@ func ValidateAutoUpdateConfig(c *autoupdate.AutoUpdateConfig) error { if c.Spec == nil { return trace.BadParameter("Spec is nil") } + if c.Spec.Tools != nil { + if c.Spec.Tools.Mode != ToolsUpdateModeDisabled && c.Spec.Tools.Mode != ToolsUpdateModeEnabled { + return trace.BadParameter("ToolsMode is not valid") + } + } return nil } diff --git a/api/types/autoupdate/config_test.go b/api/types/autoupdate/config_test.go index 2ee33dc5bf2b3..443d6f246fa56 100644 --- a/api/types/autoupdate/config_test.go +++ b/api/types/autoupdate/config_test.go @@ -41,7 +41,9 @@ func TestNewAutoUpdateConfig(t *testing.T) { { name: "success tools autoupdate disabled", spec: &autoupdate.AutoUpdateConfigSpec{ - ToolsAutoupdate: false, + Tools: &autoupdate.AutoUpdateConfigSpecTools{ + Mode: ToolsUpdateModeDisabled, + }, }, assertErr: func(t *testing.T, err error, a ...any) { require.NoError(t, err) @@ -53,14 +55,18 @@ func TestNewAutoUpdateConfig(t *testing.T) { Name: types.MetaNameAutoUpdateConfig, }, Spec: &autoupdate.AutoUpdateConfigSpec{ - ToolsAutoupdate: false, + Tools: &autoupdate.AutoUpdateConfigSpecTools{ + Mode: ToolsUpdateModeDisabled, + }, }, }, }, { name: "success tools autoupdate enabled", spec: &autoupdate.AutoUpdateConfigSpec{ - ToolsAutoupdate: true, + Tools: &autoupdate.AutoUpdateConfigSpecTools{ + Mode: ToolsUpdateModeEnabled, + }, }, assertErr: func(t *testing.T, err error, a ...any) { require.NoError(t, err) @@ -72,7 +78,9 @@ func TestNewAutoUpdateConfig(t *testing.T) { Name: types.MetaNameAutoUpdateConfig, }, Spec: &autoupdate.AutoUpdateConfigSpec{ - ToolsAutoupdate: true, + Tools: &autoupdate.AutoUpdateConfigSpecTools{ + Mode: ToolsUpdateModeEnabled, + }, }, }, }, @@ -83,6 +91,17 @@ func TestNewAutoUpdateConfig(t *testing.T) { require.ErrorContains(t, err, "Spec is nil") }, }, + { + name: "invalid tools mode", + spec: &autoupdate.AutoUpdateConfigSpec{ + Tools: &autoupdate.AutoUpdateConfigSpecTools{ + Mode: "invalid-mode", + }, + }, + assertErr: func(t *testing.T, err error, a ...any) { + require.ErrorContains(t, err, "ToolsMode is not valid") + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/api/types/autoupdate/version.go b/api/types/autoupdate/version.go index 088171a072ae3..ad2d12f265949 100644 --- a/api/types/autoupdate/version.go +++ b/api/types/autoupdate/version.go @@ -60,11 +60,13 @@ func ValidateAutoUpdateVersion(v *autoupdate.AutoUpdateVersion) error { return trace.BadParameter("Spec is nil") } - if v.Spec.ToolsVersion == "" { - return trace.BadParameter("ToolsVersion is unset") - } - if _, err := semver.NewVersion(v.Spec.ToolsVersion); err != nil { - return trace.BadParameter("ToolsVersion is not a valid semantic version") + if v.Spec.Tools != nil { + if v.Spec.Tools.TargetVersion == "" { + return trace.BadParameter("TargetVersion is unset") + } + if _, err := semver.NewVersion(v.Spec.Tools.TargetVersion); err != nil { + return trace.BadParameter("TargetVersion is not a valid semantic version") + } } return nil diff --git a/api/types/autoupdate/version_test.go b/api/types/autoupdate/version_test.go index 5fe4f167a037e..70790a204b219 100644 --- a/api/types/autoupdate/version_test.go +++ b/api/types/autoupdate/version_test.go @@ -41,7 +41,9 @@ func TestNewAutoUpdateVersion(t *testing.T) { { name: "success tools autoupdate version", spec: &autoupdate.AutoUpdateVersionSpec{ - ToolsVersion: "1.2.3-dev", + Tools: &autoupdate.AutoUpdateVersionSpecTools{ + TargetVersion: "1.2.3-dev", + }, }, assertErr: func(t *testing.T, err error, a ...any) { require.NoError(t, err) @@ -53,26 +55,32 @@ func TestNewAutoUpdateVersion(t *testing.T) { Name: types.MetaNameAutoUpdateVersion, }, Spec: &autoupdate.AutoUpdateVersionSpec{ - ToolsVersion: "1.2.3-dev", + Tools: &autoupdate.AutoUpdateVersionSpecTools{ + TargetVersion: "1.2.3-dev", + }, }, }, }, { name: "invalid empty tools version", spec: &autoupdate.AutoUpdateVersionSpec{ - ToolsVersion: "", + Tools: &autoupdate.AutoUpdateVersionSpecTools{ + TargetVersion: "", + }, }, assertErr: func(t *testing.T, err error, a ...any) { - require.ErrorContains(t, err, "ToolsVersion is unset") + require.ErrorContains(t, err, "TargetVersion is unset") }, }, { name: "invalid semantic tools version", spec: &autoupdate.AutoUpdateVersionSpec{ - ToolsVersion: "17-0-0", + Tools: &autoupdate.AutoUpdateVersionSpecTools{ + TargetVersion: "17-0-0", + }, }, assertErr: func(t *testing.T, err error, a ...any) { - require.ErrorContains(t, err, "ToolsVersion is not a valid semantic version") + require.ErrorContains(t, err, "TargetVersion is not a valid semantic version") }, }, { diff --git a/lib/cache/cache_test.go b/lib/cache/cache_test.go index 57706bacca209..9f1384bb27d42 100644 --- a/lib/cache/cache_test.go +++ b/lib/cache/cache_test.go @@ -3563,7 +3563,9 @@ func newAutoUpdateConfig(t *testing.T) *autoupdate.AutoUpdateConfig { t.Helper() r, err := update.NewAutoUpdateConfig(&autoupdate.AutoUpdateConfigSpec{ - ToolsAutoupdate: true, + Tools: &autoupdate.AutoUpdateConfigSpecTools{ + Mode: update.ToolsUpdateModeEnabled, + }, }) require.NoError(t, err) return r @@ -3573,7 +3575,9 @@ func newAutoUpdateVersion(t *testing.T) *autoupdate.AutoUpdateVersion { t.Helper() r, err := update.NewAutoUpdateVersion(&autoupdate.AutoUpdateVersionSpec{ - ToolsVersion: "1.2.3", + Tools: &autoupdate.AutoUpdateVersionSpecTools{ + TargetVersion: "1.2.3", + }, }) require.NoError(t, err) return r diff --git a/lib/services/local/autoupdate_test.go b/lib/services/local/autoupdate_test.go index d46a40b75647b..92ec037fbc5a6 100644 --- a/lib/services/local/autoupdate_test.go +++ b/lib/services/local/autoupdate_test.go @@ -51,7 +51,11 @@ func TestAutoUpdateServiceConfigCRUD(t *testing.T) { Kind: types.KindAutoUpdateConfig, Version: types.V1, Metadata: &headerv1.Metadata{Name: types.MetaNameAutoUpdateConfig}, - Spec: &autoupdatev1pb.AutoUpdateConfigSpec{ToolsAutoupdate: true}, + Spec: &autoupdatev1pb.AutoUpdateConfigSpec{ + Tools: &autoupdatev1pb.AutoUpdateConfigSpecTools{ + Mode: autoupdate.ToolsUpdateModeEnabled, + }, + }, } created, err := service.CreateAutoUpdateConfig(ctx, config) @@ -71,10 +75,12 @@ func TestAutoUpdateServiceConfigCRUD(t *testing.T) { require.Empty(t, diff) require.Equal(t, created.GetMetadata().GetRevision(), got.GetMetadata().GetRevision()) - config.Spec.ToolsAutoupdate = false + config.Spec.Tools = &autoupdatev1pb.AutoUpdateConfigSpecTools{ + Mode: autoupdate.ToolsUpdateModeDisabled, + } updated, err := service.UpdateAutoUpdateConfig(ctx, config) require.NoError(t, err) - require.NotEqual(t, got.GetSpec().GetToolsAutoupdate(), updated.GetSpec().GetToolsAutoupdate()) + require.NotEqual(t, got.GetSpec().GetTools(), updated.GetSpec().GetTools()) _, err = service.UpsertAutoUpdateConfig(ctx, config) require.NoError(t, err) @@ -106,7 +112,11 @@ func TestAutoUpdateServiceVersionCRUD(t *testing.T) { Kind: types.KindAutoUpdateVersion, Version: types.V1, Metadata: &headerv1.Metadata{Name: types.MetaNameAutoUpdateVersion}, - Spec: &autoupdatev1pb.AutoUpdateVersionSpec{ToolsVersion: "1.2.3"}, + Spec: &autoupdatev1pb.AutoUpdateVersionSpec{ + Tools: &autoupdatev1pb.AutoUpdateVersionSpecTools{ + TargetVersion: "1.2.3", + }, + }, } created, err := service.CreateAutoUpdateVersion(ctx, version) @@ -126,10 +136,12 @@ func TestAutoUpdateServiceVersionCRUD(t *testing.T) { require.Empty(t, diff) require.Equal(t, created.GetMetadata().GetRevision(), got.GetMetadata().GetRevision()) - version.Spec.ToolsVersion = "3.2.1" + version.Spec.Tools = &autoupdatev1pb.AutoUpdateVersionSpecTools{ + TargetVersion: "3.2.1", + } updated, err := service.UpdateAutoUpdateVersion(ctx, version) require.NoError(t, err) - require.NotEqual(t, got.GetSpec().GetToolsVersion(), updated.GetSpec().GetToolsVersion()) + require.NotEqual(t, got.GetSpec().GetTools().GetTargetVersion(), updated.GetSpec().GetTools().GetTargetVersion()) _, err = service.UpsertAutoUpdateVersion(ctx, version) require.NoError(t, err) @@ -161,7 +173,11 @@ func TestAutoUpdateServiceInvalidNameCreate(t *testing.T) { Kind: types.KindAutoUpdateConfig, Version: types.V1, Metadata: &headerv1.Metadata{Name: "invalid-auto-update-config-name"}, - Spec: &autoupdatev1pb.AutoUpdateConfigSpec{ToolsAutoupdate: true}, + Spec: &autoupdatev1pb.AutoUpdateConfigSpec{ + Tools: &autoupdatev1pb.AutoUpdateConfigSpecTools{ + Mode: autoupdate.ToolsUpdateModeEnabled, + }, + }, } createdConfig, err := service.CreateAutoUpdateConfig(ctx, config) @@ -172,7 +188,11 @@ func TestAutoUpdateServiceInvalidNameCreate(t *testing.T) { Kind: types.KindAutoUpdateVersion, Version: types.V1, Metadata: &headerv1.Metadata{Name: "invalid-auto-update-version-name"}, - Spec: &autoupdatev1pb.AutoUpdateVersionSpec{ToolsVersion: "1.2.3"}, + Spec: &autoupdatev1pb.AutoUpdateVersionSpec{ + Tools: &autoupdatev1pb.AutoUpdateVersionSpecTools{ + TargetVersion: "1.2.3", + }, + }, } createdVersion, err := service.CreateAutoUpdateVersion(ctx, version) @@ -194,7 +214,11 @@ func TestAutoUpdateServiceInvalidNameUpdate(t *testing.T) { ctx := context.Background() // Validate the config update restriction. - config, err := autoupdate.NewAutoUpdateConfig(&autoupdatev1pb.AutoUpdateConfigSpec{ToolsAutoupdate: true}) + config, err := autoupdate.NewAutoUpdateConfig(&autoupdatev1pb.AutoUpdateConfigSpec{ + Tools: &autoupdatev1pb.AutoUpdateConfigSpecTools{ + Mode: autoupdate.ToolsUpdateModeEnabled, + }, + }) require.NoError(t, err) createdConfig, err := service.UpsertAutoUpdateConfig(ctx, config) @@ -207,7 +231,11 @@ func TestAutoUpdateServiceInvalidNameUpdate(t *testing.T) { require.Nil(t, createdConfig) // Validate the version update restriction. - version, err := autoupdate.NewAutoUpdateVersion(&autoupdatev1pb.AutoUpdateVersionSpec{ToolsVersion: "1.2.3"}) + version, err := autoupdate.NewAutoUpdateVersion(&autoupdatev1pb.AutoUpdateVersionSpec{ + Tools: &autoupdatev1pb.AutoUpdateVersionSpecTools{ + TargetVersion: "1.2.3", + }, + }) require.NoError(t, err) createdVersion, err := service.UpsertAutoUpdateVersion(ctx, version) diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index d9faba3cfca37..28797d5e0d64b 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -1415,12 +1415,30 @@ func (h *Handler) find(w http.ResponseWriter, r *http.Request, p httprouter.Para if err != nil { return nil, trace.Wrap(err) } - return webclient.PingResponse{ + response := webclient.PingResponse{ Proxy: *proxyConfig, ServerVersion: teleport.Version, MinClientVersion: teleport.MinClientVersion, ClusterName: h.auth.clusterName, - }, nil + } + + autoUpdateConfig, err := h.cfg.AccessPoint.GetAutoUpdateConfig(r.Context()) + // TODO(vapopov) DELETE IN v18.0.0 check of IsNotImplemented, must be backported to all latest supported versions. + if err != nil && !trace.IsNotFound(err) && !trace.IsNotImplemented(err) { + h.log.WithError(err).Error("failed to receive AutoUpdateConfig") + } else if err == nil { + response.AutoUpdate.ToolsMode = autoUpdateConfig.GetSpec().GetTools().GetMode() + } + + autoUpdateVersion, err := h.cfg.AccessPoint.GetAutoUpdateVersion(r.Context()) + // TODO(vapopov) DELETE IN v18.0.0 check of IsNotImplemented, must be backported to all latest supported versions. + if err != nil && !trace.IsNotFound(err) && !trace.IsNotImplemented(err) { + h.log.WithError(err).Error("failed to receive AutoUpdateVersion") + } else if err == nil { + response.AutoUpdate.ToolsVersion = autoUpdateVersion.GetSpec().GetTools().GetTargetVersion() + } + + return response, nil } func (h *Handler) pingWithConnector(w http.ResponseWriter, r *http.Request, p httprouter.Params) (interface{}, error) { diff --git a/lib/web/apiserver_ping_test.go b/lib/web/apiserver_ping_test.go index 330aebcacd954..a248cc22d198f 100644 --- a/lib/web/apiserver_ping_test.go +++ b/lib/web/apiserver_ping_test.go @@ -22,12 +22,15 @@ import ( "testing" "github.com/gravitational/roundtrip" + "github.com/gravitational/trace" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/gravitational/teleport/api/client/webclient" "github.com/gravitational/teleport/api/constants" + autoupdatev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/autoupdate" "github.com/gravitational/teleport/lib/client" "github.com/gravitational/teleport/lib/modules" ) @@ -231,5 +234,110 @@ func TestPing_minimalAPI(t *testing.T) { require.NoError(t, resp.Body.Close()) }) } +} + +// TestPing_autoUpdateResources tests that find endpoint return correct data related to auto updates. +func TestPing_autoUpdateResources(t *testing.T) { + env := newWebPack(t, 1, func(cfg *proxyConfig) { + cfg.minimalHandler = true + }) + proxy := env.proxies[0] + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + req, err := http.NewRequest(http.MethodGet, proxy.newClient(t).Endpoint("webapi", "find"), nil) + require.NoError(t, err) + req.Host = proxy.handler.handler.cfg.ProxyPublicAddrs[0].Host() + + tests := []struct { + name string + config *autoupdatev1pb.AutoUpdateConfigSpec + version *autoupdatev1pb.AutoUpdateVersionSpec + cleanup bool + expected webclient.AutoUpdateSettings + }{ + { + name: "resources not defined", + expected: webclient.AutoUpdateSettings{}, + }, + { + name: "enable auto update", + config: &autoupdatev1pb.AutoUpdateConfigSpec{ + Tools: &autoupdatev1pb.AutoUpdateConfigSpecTools{ + Mode: autoupdate.ToolsUpdateModeEnabled, + }, + }, + expected: webclient.AutoUpdateSettings{ToolsMode: "enabled"}, + cleanup: true, + }, + { + name: "set auto update version", + version: &autoupdatev1pb.AutoUpdateVersionSpec{ + Tools: &autoupdatev1pb.AutoUpdateVersionSpecTools{ + TargetVersion: "1.2.3", + }, + }, + expected: webclient.AutoUpdateSettings{ToolsVersion: "1.2.3"}, + cleanup: true, + }, + { + name: "enable auto update and set version", + config: &autoupdatev1pb.AutoUpdateConfigSpec{ + Tools: &autoupdatev1pb.AutoUpdateConfigSpecTools{ + Mode: autoupdate.ToolsUpdateModeEnabled, + }, + }, + version: &autoupdatev1pb.AutoUpdateVersionSpec{ + Tools: &autoupdatev1pb.AutoUpdateVersionSpecTools{ + TargetVersion: "1.2.3", + }, + }, + expected: webclient.AutoUpdateSettings{ToolsMode: "enabled", ToolsVersion: "1.2.3"}, + }, + { + name: "modify auto update config and version", + config: &autoupdatev1pb.AutoUpdateConfigSpec{ + Tools: &autoupdatev1pb.AutoUpdateConfigSpecTools{ + Mode: autoupdate.ToolsUpdateModeDisabled, + }, + }, + version: &autoupdatev1pb.AutoUpdateVersionSpec{ + Tools: &autoupdatev1pb.AutoUpdateVersionSpecTools{ + TargetVersion: "3.2.1", + }, + }, + expected: webclient.AutoUpdateSettings{ToolsMode: "disabled", ToolsVersion: "3.2.1"}, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + if tc.config != nil { + config, err := autoupdate.NewAutoUpdateConfig(tc.config) + require.NoError(t, err) + _, err = env.server.Auth().UpsertAutoUpdateConfig(ctx, config) + require.NoError(t, err) + } + if tc.version != nil { + version, err := autoupdate.NewAutoUpdateVersion(tc.version) + require.NoError(t, err) + _, err = env.server.Auth().UpsertAutoUpdateVersion(ctx, version) + require.NoError(t, err) + } + + resp, err := client.NewInsecureWebClient().Do(req) + require.NoError(t, err) + pr := &webclient.PingResponse{} + require.NoError(t, json.NewDecoder(resp.Body).Decode(pr)) + require.NoError(t, resp.Body.Close()) + + assert.Equal(t, tc.expected, pr.AutoUpdate) + + if tc.cleanup { + require.NotErrorIs(t, env.server.Auth().DeleteAutoUpdateConfig(ctx), &trace.NotFoundError{}) + require.NotErrorIs(t, env.server.Auth().DeleteAutoUpdateVersion(ctx), &trace.NotFoundError{}) + } + }) + } } diff --git a/tool/tctl/common/collection.go b/tool/tctl/common/collection.go index 0880de26016b9..f92370cfd2033 100644 --- a/tool/tctl/common/collection.go +++ b/tool/tctl/common/collection.go @@ -1398,7 +1398,7 @@ func (c *autoUpdateConfigCollection) writeText(w io.Writer, verbose bool) error t := asciitable.MakeTable([]string{"Name", "Tools AutoUpdate Enabled"}) t.AddRow([]string{ c.config.GetMetadata().GetName(), - fmt.Sprintf("%v", c.config.GetSpec().GetToolsAutoupdate()), + fmt.Sprintf("%v", c.config.GetSpec().GetTools().GetMode()), }) _, err := t.AsBuffer().WriteTo(w) return trace.Wrap(err) @@ -1416,7 +1416,7 @@ func (c *autoUpdateVersionCollection) writeText(w io.Writer, verbose bool) error t := asciitable.MakeTable([]string{"Name", "Tools AutoUpdate Version"}) t.AddRow([]string{ c.version.GetMetadata().GetName(), - fmt.Sprintf("%v", c.version.GetSpec().GetToolsVersion()), + fmt.Sprintf("%v", c.version.GetSpec().GetTools().TargetVersion), }) _, err := t.AsBuffer().WriteTo(w) return trace.Wrap(err) diff --git a/tool/tctl/common/resource_command_test.go b/tool/tctl/common/resource_command_test.go index 2ef10964f1f7b..3f73e8b88d76a 100644 --- a/tool/tctl/common/resource_command_test.go +++ b/tool/tctl/common/resource_command_test.go @@ -1436,7 +1436,8 @@ metadata: name: autoupdate-config revision: 3a43b44a-201e-4d7f-aef1-ae2f6d9811ed spec: - tools_autoupdate: true + tools: + mode: enabled version: v1 ` _, err := runResourceCommand(t, fc, []string{"get", types.KindAutoUpdateConfig, "--format=json"}) @@ -1471,7 +1472,8 @@ metadata: name: autoupdate-version revision: 3a43b44a-201e-4d7f-aef1-ae2f6d9811ed spec: - tools_version: 1.2.3 + tools: + target_version: 1.2.3 version: v1 ` _, err := runResourceCommand(t, fc, []string{"get", types.KindAutoUpdateVersion, "--format=json"})