Convert (Upsert/Delete)Proxy RPC from HTTP to gRPC (#66124)

* Convert DeleteProxy RPC from HTTP to gRPC

* Use `t.Context()`

* Add more greppable TODO

* Fix usage of deprecated rpc

* Upsert RPC

* Use wrapper message for UpsertResponse

* gofmt

* Simplify godoc

* Update response message

* Update method names on public api client

* fix tests

* Introduce UpsertProxyWithoutServer

* Edoardo comments

* separate

* Change to UpsertProxyServer RPC handler
This commit is contained in:
Noah Stride
2026-05-28 07:59:00 +00:00
committed by GitHub
parent 22bac96447
commit 1bb374784b
33 changed files with 960 additions and 141 deletions
@@ -1012,6 +1012,181 @@ func (x *ListProxyServersResponse) GetNextPageToken() string {
return ""
}
// Request message for the PresenceService.UpsertProxyServer rpc.
type UpsertProxyServerRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Server is the Proxy server heartbeat to upsert.
Server *types.ServerV2 `protobuf:"bytes,1,opt,name=server,proto3" json:"server,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UpsertProxyServerRequest) Reset() {
*x = UpsertProxyServerRequest{}
mi := &file_teleport_presence_v1_service_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UpsertProxyServerRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpsertProxyServerRequest) ProtoMessage() {}
func (x *UpsertProxyServerRequest) ProtoReflect() protoreflect.Message {
mi := &file_teleport_presence_v1_service_proto_msgTypes[19]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpsertProxyServerRequest.ProtoReflect.Descriptor instead.
func (*UpsertProxyServerRequest) Descriptor() ([]byte, []int) {
return file_teleport_presence_v1_service_proto_rawDescGZIP(), []int{19}
}
func (x *UpsertProxyServerRequest) GetServer() *types.ServerV2 {
if x != nil {
return x.Server
}
return nil
}
// Response message for the PresenceService.UpsertProxyServer rpc.
type UpsertProxyServerResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Server is the upserted Proxy server.
Server *types.ServerV2 `protobuf:"bytes,1,opt,name=server,proto3" json:"server,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UpsertProxyServerResponse) Reset() {
*x = UpsertProxyServerResponse{}
mi := &file_teleport_presence_v1_service_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UpsertProxyServerResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpsertProxyServerResponse) ProtoMessage() {}
func (x *UpsertProxyServerResponse) ProtoReflect() protoreflect.Message {
mi := &file_teleport_presence_v1_service_proto_msgTypes[20]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpsertProxyServerResponse.ProtoReflect.Descriptor instead.
func (*UpsertProxyServerResponse) Descriptor() ([]byte, []int) {
return file_teleport_presence_v1_service_proto_rawDescGZIP(), []int{20}
}
func (x *UpsertProxyServerResponse) GetServer() *types.ServerV2 {
if x != nil {
return x.Server
}
return nil
}
// Request message for the PresenceService.DeleteProxyServer rpc.
type DeleteProxyServerRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Name is the name (host UUID) of the Proxy server to delete.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DeleteProxyServerRequest) Reset() {
*x = DeleteProxyServerRequest{}
mi := &file_teleport_presence_v1_service_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DeleteProxyServerRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteProxyServerRequest) ProtoMessage() {}
func (x *DeleteProxyServerRequest) ProtoReflect() protoreflect.Message {
mi := &file_teleport_presence_v1_service_proto_msgTypes[21]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteProxyServerRequest.ProtoReflect.Descriptor instead.
func (*DeleteProxyServerRequest) Descriptor() ([]byte, []int) {
return file_teleport_presence_v1_service_proto_rawDescGZIP(), []int{21}
}
func (x *DeleteProxyServerRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
// Response message for the PresenceService.DeleteProxyServer rpc.
type DeleteProxyServerResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DeleteProxyServerResponse) Reset() {
*x = DeleteProxyServerResponse{}
mi := &file_teleport_presence_v1_service_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DeleteProxyServerResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DeleteProxyServerResponse) ProtoMessage() {}
func (x *DeleteProxyServerResponse) ProtoReflect() protoreflect.Message {
mi := &file_teleport_presence_v1_service_proto_msgTypes[22]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DeleteProxyServerResponse.ProtoReflect.Descriptor instead.
func (*DeleteProxyServerResponse) Descriptor() ([]byte, []int) {
return file_teleport_presence_v1_service_proto_rawDescGZIP(), []int{22}
}
var File_teleport_presence_v1_service_proto protoreflect.FileDescriptor
const file_teleport_presence_v1_service_proto_rawDesc = "" +
@@ -1070,8 +1245,14 @@ const file_teleport_presence_v1_service_proto_rawDesc = "" +
"page_token\x18\x02 \x01(\tR\tpageToken\"m\n" +
"\x18ListProxyServersResponse\x12)\n" +
"\aservers\x18\x01 \x03(\v2\x0f.types.ServerV2R\aservers\x12&\n" +
"\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken2\x9b\n" +
"\n" +
"\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"C\n" +
"\x18UpsertProxyServerRequest\x12'\n" +
"\x06server\x18\x01 \x01(\v2\x0f.types.ServerV2R\x06server\"D\n" +
"\x19UpsertProxyServerResponse\x12'\n" +
"\x06server\x18\x01 \x01(\v2\x0f.types.ServerV2R\x06server\".\n" +
"\x18DeleteProxyServerRequest\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\"\x1b\n" +
"\x19DeleteProxyServerResponse2\x87\f\n" +
"\x0fPresenceService\x12Y\n" +
"\x10GetRemoteCluster\x12-.teleport.presence.v1.GetRemoteClusterRequest\x1a\x16.types.RemoteClusterV3\x12w\n" +
"\x12ListRemoteClusters\x12/.teleport.presence.v1.ListRemoteClustersRequest\x1a0.teleport.presence.v1.ListRemoteClustersResponse\x12_\n" +
@@ -1084,7 +1265,9 @@ const file_teleport_presence_v1_service_proto_rawDesc = "" +
"\x10ListRelayServers\x12-.teleport.presence.v1.ListRelayServersRequest\x1a..teleport.presence.v1.ListRelayServersResponse\x12t\n" +
"\x11DeleteRelayServer\x12..teleport.presence.v1.DeleteRelayServerRequest\x1a/.teleport.presence.v1.DeleteRelayServerResponse\x12n\n" +
"\x0fListAuthServers\x12,.teleport.presence.v1.ListAuthServersRequest\x1a-.teleport.presence.v1.ListAuthServersResponse\x12q\n" +
"\x10ListProxyServers\x12-.teleport.presence.v1.ListProxyServersRequest\x1a..teleport.presence.v1.ListProxyServersResponseBTZRgithub.com/gravitational/teleport/api/gen/proto/go/teleport/presence/v1;presencev1b\x06proto3"
"\x10ListProxyServers\x12-.teleport.presence.v1.ListProxyServersRequest\x1a..teleport.presence.v1.ListProxyServersResponse\x12t\n" +
"\x11UpsertProxyServer\x12..teleport.presence.v1.UpsertProxyServerRequest\x1a/.teleport.presence.v1.UpsertProxyServerResponse\x12t\n" +
"\x11DeleteProxyServer\x12..teleport.presence.v1.DeleteProxyServerRequest\x1a/.teleport.presence.v1.DeleteProxyServerResponseBTZRgithub.com/gravitational/teleport/api/gen/proto/go/teleport/presence/v1;presencev1b\x06proto3"
var (
file_teleport_presence_v1_service_proto_rawDescOnce sync.Once
@@ -1098,7 +1281,7 @@ func file_teleport_presence_v1_service_proto_rawDescGZIP() []byte {
return file_teleport_presence_v1_service_proto_rawDescData
}
var file_teleport_presence_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 19)
var file_teleport_presence_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
var file_teleport_presence_v1_service_proto_goTypes = []any{
(*GetRemoteClusterRequest)(nil), // 0: teleport.presence.v1.GetRemoteClusterRequest
(*ListRemoteClustersRequest)(nil), // 1: teleport.presence.v1.ListRemoteClustersRequest
@@ -1119,52 +1302,62 @@ var file_teleport_presence_v1_service_proto_goTypes = []any{
(*ListAuthServersResponse)(nil), // 16: teleport.presence.v1.ListAuthServersResponse
(*ListProxyServersRequest)(nil), // 17: teleport.presence.v1.ListProxyServersRequest
(*ListProxyServersResponse)(nil), // 18: teleport.presence.v1.ListProxyServersResponse
(*types.RemoteClusterV3)(nil), // 19: types.RemoteClusterV3
(*fieldmaskpb.FieldMask)(nil), // 20: google.protobuf.FieldMask
(*types.ReverseTunnelV2)(nil), // 21: types.ReverseTunnelV2
(*RelayServer)(nil), // 22: teleport.presence.v1.RelayServer
(*types.ServerV2)(nil), // 23: types.ServerV2
(*emptypb.Empty)(nil), // 24: google.protobuf.Empty
(*UpsertProxyServerRequest)(nil), // 19: teleport.presence.v1.UpsertProxyServerRequest
(*UpsertProxyServerResponse)(nil), // 20: teleport.presence.v1.UpsertProxyServerResponse
(*DeleteProxyServerRequest)(nil), // 21: teleport.presence.v1.DeleteProxyServerRequest
(*DeleteProxyServerResponse)(nil), // 22: teleport.presence.v1.DeleteProxyServerResponse
(*types.RemoteClusterV3)(nil), // 23: types.RemoteClusterV3
(*fieldmaskpb.FieldMask)(nil), // 24: google.protobuf.FieldMask
(*types.ReverseTunnelV2)(nil), // 25: types.ReverseTunnelV2
(*RelayServer)(nil), // 26: teleport.presence.v1.RelayServer
(*types.ServerV2)(nil), // 27: types.ServerV2
(*emptypb.Empty)(nil), // 28: google.protobuf.Empty
}
var file_teleport_presence_v1_service_proto_depIdxs = []int32{
19, // 0: teleport.presence.v1.ListRemoteClustersResponse.remote_clusters:type_name -> types.RemoteClusterV3
19, // 1: teleport.presence.v1.UpdateRemoteClusterRequest.remote_cluster:type_name -> types.RemoteClusterV3
20, // 2: teleport.presence.v1.UpdateRemoteClusterRequest.update_mask:type_name -> google.protobuf.FieldMask
21, // 3: teleport.presence.v1.ListReverseTunnelsResponse.reverse_tunnels:type_name -> types.ReverseTunnelV2
21, // 4: teleport.presence.v1.UpsertReverseTunnelRequest.reverse_tunnel:type_name -> types.ReverseTunnelV2
22, // 5: teleport.presence.v1.GetRelayServerResponse.relay_server:type_name -> teleport.presence.v1.RelayServer
22, // 6: teleport.presence.v1.ListRelayServersResponse.relays:type_name -> teleport.presence.v1.RelayServer
23, // 7: teleport.presence.v1.ListAuthServersResponse.servers:type_name -> types.ServerV2
23, // 8: teleport.presence.v1.ListProxyServersResponse.servers:type_name -> types.ServerV2
0, // 9: teleport.presence.v1.PresenceService.GetRemoteCluster:input_type -> teleport.presence.v1.GetRemoteClusterRequest
1, // 10: teleport.presence.v1.PresenceService.ListRemoteClusters:input_type -> teleport.presence.v1.ListRemoteClustersRequest
3, // 11: teleport.presence.v1.PresenceService.UpdateRemoteCluster:input_type -> teleport.presence.v1.UpdateRemoteClusterRequest
4, // 12: teleport.presence.v1.PresenceService.DeleteRemoteCluster:input_type -> teleport.presence.v1.DeleteRemoteClusterRequest
5, // 13: teleport.presence.v1.PresenceService.ListReverseTunnels:input_type -> teleport.presence.v1.ListReverseTunnelsRequest
7, // 14: teleport.presence.v1.PresenceService.UpsertReverseTunnel:input_type -> teleport.presence.v1.UpsertReverseTunnelRequest
8, // 15: teleport.presence.v1.PresenceService.DeleteReverseTunnel:input_type -> teleport.presence.v1.DeleteReverseTunnelRequest
9, // 16: teleport.presence.v1.PresenceService.GetRelayServer:input_type -> teleport.presence.v1.GetRelayServerRequest
11, // 17: teleport.presence.v1.PresenceService.ListRelayServers:input_type -> teleport.presence.v1.ListRelayServersRequest
13, // 18: teleport.presence.v1.PresenceService.DeleteRelayServer:input_type -> teleport.presence.v1.DeleteRelayServerRequest
15, // 19: teleport.presence.v1.PresenceService.ListAuthServers:input_type -> teleport.presence.v1.ListAuthServersRequest
17, // 20: teleport.presence.v1.PresenceService.ListProxyServers:input_type -> teleport.presence.v1.ListProxyServersRequest
19, // 21: teleport.presence.v1.PresenceService.GetRemoteCluster:output_type -> types.RemoteClusterV3
2, // 22: teleport.presence.v1.PresenceService.ListRemoteClusters:output_type -> teleport.presence.v1.ListRemoteClustersResponse
19, // 23: teleport.presence.v1.PresenceService.UpdateRemoteCluster:output_type -> types.RemoteClusterV3
24, // 24: teleport.presence.v1.PresenceService.DeleteRemoteCluster:output_type -> google.protobuf.Empty
6, // 25: teleport.presence.v1.PresenceService.ListReverseTunnels:output_type -> teleport.presence.v1.ListReverseTunnelsResponse
21, // 26: teleport.presence.v1.PresenceService.UpsertReverseTunnel:output_type -> types.ReverseTunnelV2
24, // 27: teleport.presence.v1.PresenceService.DeleteReverseTunnel:output_type -> google.protobuf.Empty
10, // 28: teleport.presence.v1.PresenceService.GetRelayServer:output_type -> teleport.presence.v1.GetRelayServerResponse
12, // 29: teleport.presence.v1.PresenceService.ListRelayServers:output_type -> teleport.presence.v1.ListRelayServersResponse
14, // 30: teleport.presence.v1.PresenceService.DeleteRelayServer:output_type -> teleport.presence.v1.DeleteRelayServerResponse
16, // 31: teleport.presence.v1.PresenceService.ListAuthServers:output_type -> teleport.presence.v1.ListAuthServersResponse
18, // 32: teleport.presence.v1.PresenceService.ListProxyServers:output_type -> teleport.presence.v1.ListProxyServersResponse
21, // [21:33] is the sub-list for method output_type
9, // [9:21] is the sub-list for method input_type
9, // [9:9] is the sub-list for extension type_name
9, // [9:9] is the sub-list for extension extendee
0, // [0:9] is the sub-list for field type_name
23, // 0: teleport.presence.v1.ListRemoteClustersResponse.remote_clusters:type_name -> types.RemoteClusterV3
23, // 1: teleport.presence.v1.UpdateRemoteClusterRequest.remote_cluster:type_name -> types.RemoteClusterV3
24, // 2: teleport.presence.v1.UpdateRemoteClusterRequest.update_mask:type_name -> google.protobuf.FieldMask
25, // 3: teleport.presence.v1.ListReverseTunnelsResponse.reverse_tunnels:type_name -> types.ReverseTunnelV2
25, // 4: teleport.presence.v1.UpsertReverseTunnelRequest.reverse_tunnel:type_name -> types.ReverseTunnelV2
26, // 5: teleport.presence.v1.GetRelayServerResponse.relay_server:type_name -> teleport.presence.v1.RelayServer
26, // 6: teleport.presence.v1.ListRelayServersResponse.relays:type_name -> teleport.presence.v1.RelayServer
27, // 7: teleport.presence.v1.ListAuthServersResponse.servers:type_name -> types.ServerV2
27, // 8: teleport.presence.v1.ListProxyServersResponse.servers:type_name -> types.ServerV2
27, // 9: teleport.presence.v1.UpsertProxyServerRequest.server:type_name -> types.ServerV2
27, // 10: teleport.presence.v1.UpsertProxyServerResponse.server:type_name -> types.ServerV2
0, // 11: teleport.presence.v1.PresenceService.GetRemoteCluster:input_type -> teleport.presence.v1.GetRemoteClusterRequest
1, // 12: teleport.presence.v1.PresenceService.ListRemoteClusters:input_type -> teleport.presence.v1.ListRemoteClustersRequest
3, // 13: teleport.presence.v1.PresenceService.UpdateRemoteCluster:input_type -> teleport.presence.v1.UpdateRemoteClusterRequest
4, // 14: teleport.presence.v1.PresenceService.DeleteRemoteCluster:input_type -> teleport.presence.v1.DeleteRemoteClusterRequest
5, // 15: teleport.presence.v1.PresenceService.ListReverseTunnels:input_type -> teleport.presence.v1.ListReverseTunnelsRequest
7, // 16: teleport.presence.v1.PresenceService.UpsertReverseTunnel:input_type -> teleport.presence.v1.UpsertReverseTunnelRequest
8, // 17: teleport.presence.v1.PresenceService.DeleteReverseTunnel:input_type -> teleport.presence.v1.DeleteReverseTunnelRequest
9, // 18: teleport.presence.v1.PresenceService.GetRelayServer:input_type -> teleport.presence.v1.GetRelayServerRequest
11, // 19: teleport.presence.v1.PresenceService.ListRelayServers:input_type -> teleport.presence.v1.ListRelayServersRequest
13, // 20: teleport.presence.v1.PresenceService.DeleteRelayServer:input_type -> teleport.presence.v1.DeleteRelayServerRequest
15, // 21: teleport.presence.v1.PresenceService.ListAuthServers:input_type -> teleport.presence.v1.ListAuthServersRequest
17, // 22: teleport.presence.v1.PresenceService.ListProxyServers:input_type -> teleport.presence.v1.ListProxyServersRequest
19, // 23: teleport.presence.v1.PresenceService.UpsertProxyServer:input_type -> teleport.presence.v1.UpsertProxyServerRequest
21, // 24: teleport.presence.v1.PresenceService.DeleteProxyServer:input_type -> teleport.presence.v1.DeleteProxyServerRequest
23, // 25: teleport.presence.v1.PresenceService.GetRemoteCluster:output_type -> types.RemoteClusterV3
2, // 26: teleport.presence.v1.PresenceService.ListRemoteClusters:output_type -> teleport.presence.v1.ListRemoteClustersResponse
23, // 27: teleport.presence.v1.PresenceService.UpdateRemoteCluster:output_type -> types.RemoteClusterV3
28, // 28: teleport.presence.v1.PresenceService.DeleteRemoteCluster:output_type -> google.protobuf.Empty
6, // 29: teleport.presence.v1.PresenceService.ListReverseTunnels:output_type -> teleport.presence.v1.ListReverseTunnelsResponse
25, // 30: teleport.presence.v1.PresenceService.UpsertReverseTunnel:output_type -> types.ReverseTunnelV2
28, // 31: teleport.presence.v1.PresenceService.DeleteReverseTunnel:output_type -> google.protobuf.Empty
10, // 32: teleport.presence.v1.PresenceService.GetRelayServer:output_type -> teleport.presence.v1.GetRelayServerResponse
12, // 33: teleport.presence.v1.PresenceService.ListRelayServers:output_type -> teleport.presence.v1.ListRelayServersResponse
14, // 34: teleport.presence.v1.PresenceService.DeleteRelayServer:output_type -> teleport.presence.v1.DeleteRelayServerResponse
16, // 35: teleport.presence.v1.PresenceService.ListAuthServers:output_type -> teleport.presence.v1.ListAuthServersResponse
18, // 36: teleport.presence.v1.PresenceService.ListProxyServers:output_type -> teleport.presence.v1.ListProxyServersResponse
20, // 37: teleport.presence.v1.PresenceService.UpsertProxyServer:output_type -> teleport.presence.v1.UpsertProxyServerResponse
22, // 38: teleport.presence.v1.PresenceService.DeleteProxyServer:output_type -> teleport.presence.v1.DeleteProxyServerResponse
25, // [25:39] is the sub-list for method output_type
11, // [11:25] is the sub-list for method input_type
11, // [11:11] is the sub-list for extension type_name
11, // [11:11] is the sub-list for extension extendee
0, // [0:11] is the sub-list for field type_name
}
func init() { file_teleport_presence_v1_service_proto_init() }
@@ -1179,7 +1372,7 @@ func file_teleport_presence_v1_service_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_teleport_presence_v1_service_proto_rawDesc), len(file_teleport_presence_v1_service_proto_rawDesc)),
NumEnums: 0,
NumMessages: 19,
NumMessages: 23,
NumExtensions: 0,
NumServices: 1,
},
@@ -47,6 +47,8 @@ const (
PresenceService_DeleteRelayServer_FullMethodName = "/teleport.presence.v1.PresenceService/DeleteRelayServer"
PresenceService_ListAuthServers_FullMethodName = "/teleport.presence.v1.PresenceService/ListAuthServers"
PresenceService_ListProxyServers_FullMethodName = "/teleport.presence.v1.PresenceService/ListProxyServers"
PresenceService_UpsertProxyServer_FullMethodName = "/teleport.presence.v1.PresenceService/UpsertProxyServer"
PresenceService_DeleteProxyServer_FullMethodName = "/teleport.presence.v1.PresenceService/DeleteProxyServer"
)
// PresenceServiceClient is the client API for PresenceService service.
@@ -79,6 +81,10 @@ type PresenceServiceClient interface {
ListAuthServers(ctx context.Context, in *ListAuthServersRequest, opts ...grpc.CallOption) (*ListAuthServersResponse, error)
// ListProxyServers returns a page of Proxy servers.
ListProxyServers(ctx context.Context, in *ListProxyServersRequest, opts ...grpc.CallOption) (*ListProxyServersResponse, error)
// UpsertProxyServer upserts a Proxy server heartbeat.
UpsertProxyServer(ctx context.Context, in *UpsertProxyServerRequest, opts ...grpc.CallOption) (*UpsertProxyServerResponse, error)
// DeleteProxyServer removes an existing Proxy server heartbeat by name.
DeleteProxyServer(ctx context.Context, in *DeleteProxyServerRequest, opts ...grpc.CallOption) (*DeleteProxyServerResponse, error)
}
type presenceServiceClient struct {
@@ -209,6 +215,26 @@ func (c *presenceServiceClient) ListProxyServers(ctx context.Context, in *ListPr
return out, nil
}
func (c *presenceServiceClient) UpsertProxyServer(ctx context.Context, in *UpsertProxyServerRequest, opts ...grpc.CallOption) (*UpsertProxyServerResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(UpsertProxyServerResponse)
err := c.cc.Invoke(ctx, PresenceService_UpsertProxyServer_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *presenceServiceClient) DeleteProxyServer(ctx context.Context, in *DeleteProxyServerRequest, opts ...grpc.CallOption) (*DeleteProxyServerResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(DeleteProxyServerResponse)
err := c.cc.Invoke(ctx, PresenceService_DeleteProxyServer_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// PresenceServiceServer is the server API for PresenceService service.
// All implementations must embed UnimplementedPresenceServiceServer
// for forward compatibility.
@@ -239,6 +265,10 @@ type PresenceServiceServer interface {
ListAuthServers(context.Context, *ListAuthServersRequest) (*ListAuthServersResponse, error)
// ListProxyServers returns a page of Proxy servers.
ListProxyServers(context.Context, *ListProxyServersRequest) (*ListProxyServersResponse, error)
// UpsertProxyServer upserts a Proxy server heartbeat.
UpsertProxyServer(context.Context, *UpsertProxyServerRequest) (*UpsertProxyServerResponse, error)
// DeleteProxyServer removes an existing Proxy server heartbeat by name.
DeleteProxyServer(context.Context, *DeleteProxyServerRequest) (*DeleteProxyServerResponse, error)
mustEmbedUnimplementedPresenceServiceServer()
}
@@ -285,6 +315,12 @@ func (UnimplementedPresenceServiceServer) ListAuthServers(context.Context, *List
func (UnimplementedPresenceServiceServer) ListProxyServers(context.Context, *ListProxyServersRequest) (*ListProxyServersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListProxyServers not implemented")
}
func (UnimplementedPresenceServiceServer) UpsertProxyServer(context.Context, *UpsertProxyServerRequest) (*UpsertProxyServerResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpsertProxyServer not implemented")
}
func (UnimplementedPresenceServiceServer) DeleteProxyServer(context.Context, *DeleteProxyServerRequest) (*DeleteProxyServerResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteProxyServer not implemented")
}
func (UnimplementedPresenceServiceServer) mustEmbedUnimplementedPresenceServiceServer() {}
func (UnimplementedPresenceServiceServer) testEmbeddedByValue() {}
@@ -522,6 +558,42 @@ func _PresenceService_ListProxyServers_Handler(srv interface{}, ctx context.Cont
return interceptor(ctx, in, info, handler)
}
func _PresenceService_UpsertProxyServer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpsertProxyServerRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PresenceServiceServer).UpsertProxyServer(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: PresenceService_UpsertProxyServer_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PresenceServiceServer).UpsertProxyServer(ctx, req.(*UpsertProxyServerRequest))
}
return interceptor(ctx, in, info, handler)
}
func _PresenceService_DeleteProxyServer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteProxyServerRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PresenceServiceServer).DeleteProxyServer(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: PresenceService_DeleteProxyServer_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PresenceServiceServer).DeleteProxyServer(ctx, req.(*DeleteProxyServerRequest))
}
return interceptor(ctx, in, info, handler)
}
// PresenceService_ServiceDesc is the grpc.ServiceDesc for PresenceService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -577,6 +649,14 @@ var PresenceService_ServiceDesc = grpc.ServiceDesc{
MethodName: "ListProxyServers",
Handler: _PresenceService_ListProxyServers_Handler,
},
{
MethodName: "UpsertProxyServer",
Handler: _PresenceService_UpsertProxyServer_Handler,
},
{
MethodName: "DeleteProxyServer",
Handler: _PresenceService_DeleteProxyServer_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "teleport/presence/v1/service.proto",
@@ -50,8 +50,13 @@ service PresenceService {
// ListAuthServers returns a page of Auth servers.
rpc ListAuthServers(ListAuthServersRequest) returns (ListAuthServersResponse);
// ListProxyServers returns a page of Proxy servers.
rpc ListProxyServers(ListProxyServersRequest) returns (ListProxyServersResponse);
// UpsertProxyServer upserts a Proxy server heartbeat.
rpc UpsertProxyServer(UpsertProxyServerRequest) returns (UpsertProxyServerResponse);
// DeleteProxyServer removes an existing Proxy server heartbeat by name.
rpc DeleteProxyServer(DeleteProxyServerRequest) returns (DeleteProxyServerResponse);
}
// Request for GetRemoteCluster
@@ -202,3 +207,24 @@ message ListProxyServersResponse {
// more results in the list.
string next_page_token = 2;
}
// Request message for the PresenceService.UpsertProxyServer rpc.
message UpsertProxyServerRequest {
// Server is the Proxy server heartbeat to upsert.
types.ServerV2 server = 1;
}
// Response message for the PresenceService.UpsertProxyServer rpc.
message UpsertProxyServerResponse {
// Server is the upserted Proxy server.
types.ServerV2 server = 1;
}
// Request message for the PresenceService.DeleteProxyServer rpc.
message DeleteProxyServerRequest {
// Name is the name (host UUID) of the Proxy server to delete.
string name = 1;
}
// Response message for the PresenceService.DeleteProxyServer rpc.
message DeleteProxyServerResponse {}
+9 -3
View File
@@ -133,9 +133,11 @@ func NewAPIServer(config *APIConfig) (http.Handler, error) {
// Servers and presence heartbeat
// TODO(kiosion) DELETE IN 21.0.0
srv.GET("/:version/authservers", srv.WithScopedAuth(srv.getAuthServers))
// TODO(noah): DELETE IN 20.0.0 - move to httpMigratedHandler
srv.POST("/:version/proxies", srv.WithAuth(srv.upsertProxy))
// TODO(kiosion) DELETE IN 21.0.0
srv.GET("/:version/proxies", srv.WithScopedAuth(srv.getProxies))
// TODO(noah): DELETE IN 20.0.0 - move to httpMigratedHandler
srv.DELETE("/:version/proxies/:name", srv.WithAuth(srv.deleteProxy))
srv.POST("/:version/tunnelconnections", srv.WithAuth(srv.upsertTunnelConnection))
srv.GET("/:version/tunnelconnections/:cluster", srv.WithAuth(srv.getTunnelConnections))
@@ -245,7 +247,7 @@ type upsertServerRawReq struct {
// presenceForAPIServer is a subset of [services.Presence].
type presenceForAPIServer interface {
UpsertNode(ctx context.Context, s types.Server) (*types.KeepAlive, error)
UpsertProxy(ctx context.Context, s types.Server) error
UpsertProxyServer(ctx context.Context, s types.Server) (types.Server, error)
}
// upsertServer is a common utility function
@@ -286,7 +288,7 @@ func (s *APIServer) upsertServer(auth presenceForAPIServer, role types.SystemRol
}
return handle, nil
case types.RoleProxy:
if err := auth.UpsertProxy(r.Context(), server); err != nil {
if _, err := auth.UpsertProxyServer(r.Context(), server); err != nil {
return nil, trace.Wrap(err)
}
default:
@@ -296,6 +298,8 @@ func (s *APIServer) upsertServer(auth presenceForAPIServer, role types.SystemRol
}
// upsertProxy is called by remote SSH nodes when they ping back into the auth service
//
// TODO(noah): move to httpMigratedHandler in v20.0.0
func (s *APIServer) upsertProxy(auth *ServerWithRoles, w http.ResponseWriter, r *http.Request, p httprouter.Params, version string) (any, error) {
return s.upsertServer(auth, types.RoleProxy, r, p)
}
@@ -313,12 +317,14 @@ func (s *APIServer) getProxies(auth *ServerWithRoles, w http.ResponseWriter, r *
}
// deleteProxy deletes proxy
//
// TODO(noah): move to httpMigratedHandler in v20.0.0
func (s *APIServer) deleteProxy(auth *ServerWithRoles, w http.ResponseWriter, r *http.Request, p httprouter.Params, version string) (any, error) {
name := p.ByName("name")
if name == "" {
return nil, trace.BadParameter("missing proxy name")
}
err := auth.DeleteProxy(r.Context(), name)
err := auth.DeleteProxyServer(r.Context(), name)
if err != nil {
return nil, trace.Wrap(err)
}
+2
View File
@@ -37,6 +37,8 @@ import (
"github.com/gravitational/teleport/lib/services"
)
// TODO(noah): In a separate PR soon, nuke this test. We cover this elsewhere
// much better. This test awkwardly skips some important layers.
func TestUpsertServer(t *testing.T) {
t.Parallel()
+11
View File
@@ -6676,6 +6676,17 @@ func restoreSanitizedHostname(server types.Server) error {
return nil
}
// UpsertProxyServerWithoutReturn exists to satisfy the Announcer interface.
// It is never called directly by the heartbeater that consumes the Announcer as
// for proxies this occurs over gRPC/HTTP API client.
//
// TODO(noah): DELETE IN v20.0.0 - once the HTTP fallback is removed the
// Announcer interface can call a returning variant directly.
func (a *Server) UpsertProxyServerWithoutReturn(ctx context.Context, server types.Server) error {
_, err := a.Services.UpsertProxyServer(ctx, server)
return trace.Wrap(err)
}
// UpsertNode implements [services.Presence] by delegating to [Server.Services]
// and potentially emitting a [usagereporter] event.
func (a *Server) UpsertNode(ctx context.Context, server types.Server) (*types.KeepAlive, error) {
+11 -6
View File
@@ -2702,11 +2702,12 @@ func (a *ServerWithRoles) DeleteAuthServer(name string) error {
return a.authServer.DeleteAuthServer(name)
}
func (a *ServerWithRoles) UpsertProxy(ctx context.Context, s types.Server) error {
// UpsertProxyServer registers proxy server presence.
func (a *ServerWithRoles) UpsertProxyServer(ctx context.Context, s types.Server) (types.Server, error) {
if err := a.authorizeAction(types.KindProxy, types.VerbCreate, types.VerbUpdate); err != nil {
return trace.Wrap(err)
return nil, trace.Wrap(err)
}
return a.authServer.UpsertProxy(ctx, s)
return a.authServer.UpsertProxyServer(ctx, s)
}
// Deprecated: Prefer paginated variant [ListProxyServers].
@@ -2756,12 +2757,16 @@ func (a *ServerWithRoles) ListProxyServers(ctx context.Context, pageSize int, pa
return a.authServer.ListProxyServers(ctx, pageSize, pageToken)
}
// DeleteProxy deletes proxy by name
func (a *ServerWithRoles) DeleteProxy(ctx context.Context, name string) error {
// DeleteProxyServer deletes proxy by name
//
// Deprecated: Use PresenceService.DeleteProxyServer instead.
//
// TODO(noah): DELETE IN v20.0.0
func (a *ServerWithRoles) DeleteProxyServer(ctx context.Context, name string) error {
if err := a.authorizeAction(types.KindProxy, types.VerbDelete); err != nil {
return trace.Wrap(err)
}
return a.authServer.DeleteProxy(ctx, name)
return a.authServer.DeleteProxyServer(ctx, name)
}
func (a *ServerWithRoles) DeleteToken(ctx context.Context, token string) error {
+8 -3
View File
@@ -59,9 +59,14 @@ type Announcer interface {
// for the specified duration with second resolution if it's >= 1 second
UpsertNode(ctx context.Context, s types.Server) (*types.KeepAlive, error)
// UpsertProxy registers proxy presence, permanently if ttl is 0 or
// for the specified duration with second resolution if it's >= 1 second
UpsertProxy(ctx context.Context, s types.Server) error
// UpsertProxyServerWithoutReturn registers proxy presence, permanently if
// ttl is 0 or for the specified duration with second resolution if it's
// >= 1 second. The upserted server is not returned because the HTTP
// fallback path cannot provide it.
//
// TODO(noah): DELETE IN v20.0.0 — replace with a returning variant once the
// HTTP fallback is removed.
UpsertProxyServerWithoutReturn(ctx context.Context, s types.Server) error
// UpsertAuthServer registers auth server presence, permanently if ttl is 0 or
// for the specified duration with second resolution if it's >= 1 second
+8
View File
@@ -1654,6 +1654,14 @@ type ClientI interface {
// ListUnifiedInstances returns a paginated list of unified instances (teleport instances and bot instances).
ListUnifiedInstances(ctx context.Context, req *inventoryv1.ListUnifiedInstancesRequest) (*inventoryv1.ListUnifiedInstancesResponse, error)
// UpsertProxyServerWithoutReturn registers a proxy server heartbeat.
// The upserted server is not returned because the HTTP fallback path
// cannot provide it.
//
// TODO(noah): DELETE IN v20.0.0 — replace with a returning variant once
// the HTTP fallback is removed.
UpsertProxyServerWithoutReturn(ctx context.Context, s types.Server) error
types.WebSessionsGetter
services.WebToken
-26
View File
@@ -394,32 +394,6 @@ type upsertServerRawReq struct {
TTL time.Duration `json:"ttl"`
}
// UpsertProxy is used by proxies to report their presence
// to other auth servers in form of heartbeat expiring after ttl period.
func (c *HTTPClient) UpsertProxy(ctx context.Context, s types.Server) error {
data, err := services.MarshalServer(s)
if err != nil {
return trace.Wrap(err)
}
args := &upsertServerRawReq{
Server: data,
}
_, err = c.PostJSON(ctx, c.Endpoint("proxies"), args)
return trace.Wrap(err)
}
// DeleteProxy deletes proxy by name
func (c *HTTPClient) DeleteProxy(ctx context.Context, name string) error {
if name == "" {
return trace.BadParameter("missing parameter name")
}
_, err := c.Delete(ctx, c.Endpoint("proxies", name))
if err != nil {
return trace.Wrap(err)
}
return nil
}
// ExtendWebSession creates a new web session for a user based on another
// valid web session
func (c *HTTPClient) ExtendWebSession(ctx context.Context, req WebSessionReq) (types.WebSession, error) {
+74
View File
@@ -25,6 +25,7 @@ import (
"github.com/gravitational/trace"
presencev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/presence/v1"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/services"
)
@@ -100,6 +101,79 @@ func (c *HTTPClient) GetAuthServers() ([]types.Server, error) {
return re, nil
}
// UpsertProxyServerWithoutReturn registers a proxy server heartbeat. It calls
// the gRPC PresenceService and falls back to the legacy HTTP endpoint if the
// server does not yet implement the gRPC RPC. The upserted proxy server is not
// returned because the HTTP fallback path cannot provide it; once the fallback
// is removed in v20 this can be replaced with a method that returns the
// upserted server.
//
// TODO(noah): DELETE IN v20.0.0
func (c *Client) UpsertProxyServerWithoutReturn(ctx context.Context, s types.Server) error {
serverV2, ok := s.(*types.ServerV2)
if !ok {
return trace.BadParameter("unsupported proxy server type %T", s)
}
_, err := c.APIClient.PresenceServiceClient().UpsertProxyServer(ctx, &presencev1.UpsertProxyServerRequest{
Server: serverV2,
})
if err == nil {
return nil
}
if !trace.IsNotImplemented(err) {
return trace.Wrap(err)
}
return c.HTTPClient.upsertProxyServerLegacy(ctx, s)
}
// upsertProxyServerLegacy registers a proxy server heartbeat via the legacy
// HTTP endpoint.
//
// TODO(noah): DELETE IN v20.0.0
func (c *HTTPClient) upsertProxyServerLegacy(ctx context.Context, s types.Server) error {
data, err := services.MarshalServer(s)
if err != nil {
return trace.Wrap(err)
}
args := &upsertServerRawReq{
Server: data,
}
_, err = c.PostJSON(ctx, c.Endpoint("proxies"), args)
return trace.Wrap(err)
}
// DeleteProxyServer deletes a proxy server heartbeat by name. It calls the
// gRPC PresenceService and falls back to the legacy HTTP endpoint if the
// server does not yet implement the gRPC RPC.
//
// TODO(noah): DELETE IN v20.0.0
func (c *Client) DeleteProxyServer(ctx context.Context, name string) error {
_, err := c.APIClient.PresenceServiceClient().DeleteProxyServer(ctx, &presencev1.DeleteProxyServerRequest{
Name: name,
})
if err == nil {
return nil
}
if !trace.IsNotImplemented(err) {
return trace.Wrap(err)
}
return c.HTTPClient.deleteProxyServerLegacy(ctx, name)
}
// deleteProxyServerLegacy deletes proxy by name via the legacy HTTP endpoint.
//
// TODO(noah): DELETE IN v20.0.0
func (c *HTTPClient) deleteProxyServerLegacy(ctx context.Context, name string) error {
if name == "" {
return trace.BadParameter("missing parameter name")
}
_, err := c.Delete(ctx, c.Endpoint("proxies", name))
if err != nil {
return trace.Wrap(err)
}
return nil
}
// GetProxies returns the list of auth servers registered in the cluster.
//
// Deprecated: Prefer paginated variant [APIClient.ListProxyServers].
+1 -1
View File
@@ -80,7 +80,7 @@ func newBrowserMFATestEnv(t *testing.T) testEnv {
PublicAddrs: []string{"proxy.example.com:443"},
})
require.NoError(t, err)
err = a.UpsertProxy(ctx, proxy)
_, err = a.UpsertProxyServer(ctx, proxy)
require.NoError(t, err)
// Enable WebAuthn support.
+2 -2
View File
@@ -3966,7 +3966,7 @@ func TestAppsCRUD(t *testing.T) {
}
require.Empty(t, iterOut)
err = srv.Auth().UpsertProxy(ctx, &types.ServerV2{
_, err = srv.Auth().UpsertProxyServer(ctx, &types.ServerV2{
Kind: types.KindProxy,
Metadata: types.Metadata{
Name: "proxy",
@@ -4104,7 +4104,7 @@ func TestAppServersCRUD(t *testing.T) {
require.Empty(t, resources.Resources)
t.Run("App server with an app that has a public address matching a proxy address should fail", func(t *testing.T) {
err = srv.Auth().UpsertProxy(ctx, &types.ServerV2{
_, err = srv.Auth().UpsertProxyServer(ctx, &types.ServerV2{
Kind: types.KindProxy,
Metadata: types.Metadata{
Name: "proxy",
@@ -295,7 +295,7 @@ func TestWorkloadIdentityService_SignJWTSVIDs(t *testing.T) {
PublicAddrs: []string{"teleport.example.com"},
})
require.NoError(t, err)
err = srv.Auth().UpsertProxy(ctx, proxy)
_, err = srv.Auth().UpsertProxyServer(ctx, proxy)
require.NoError(t, err)
wantIssuer := "https://teleport.example.com/workload-identity"
@@ -143,7 +143,7 @@ func newIssuanceTestPack(t *testing.T, ctx context.Context) *issuanceTestPack {
PublicAddrs: []string{"teleport.example.com"},
})
require.NoError(t, err)
err = srv.Auth().UpsertProxy(ctx, proxy)
_, err = srv.Auth().UpsertProxyServer(ctx, proxy)
require.NoError(t, err)
wantIssuer := "https://teleport.example.com/workload-identity"
+70
View File
@@ -24,6 +24,7 @@ import (
"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
"google.golang.org/grpc/peer"
"google.golang.org/protobuf/types/known/emptypb"
"github.com/gravitational/teleport"
@@ -48,6 +49,9 @@ type Backend interface {
DeleteReverseTunnel(ctx context.Context, tunnelName string) error
DeleteRelayServer(ctx context.Context, name string) error
UpsertProxyServer(ctx context.Context, server types.Server) (types.Server, error)
DeleteProxyServer(ctx context.Context, name string) error
}
type Cache interface {
@@ -477,3 +481,69 @@ func (s *Service) DeleteRelayServer(ctx context.Context, req *presencepb.DeleteR
return &presencepb.DeleteRelayServerResponse{}, nil
}
// UpsertProxyServer upserts a proxy server heartbeat.
func (s *Service) UpsertProxyServer(
ctx context.Context, req *presencepb.UpsertProxyServerRequest,
) (*presencepb.UpsertProxyServerResponse, error) {
srv := req.GetServer()
if srv == nil {
return nil, trace.BadParameter("server: must be specified")
}
// nb(noah): This forced overwrite of kind is load-bearing. You will be
// surprised to learn that in its current state the Proxy heartbeater will
// upsert the Server with Kind=Node.
// See https://github.com/gravitational/teleport/issues/66997
srv.Kind = types.KindProxy
if err := srv.CheckAndSetDefaults(); err != nil {
return nil, trace.Wrap(err)
}
authCtx, err := s.authorizer.Authorize(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
if err := authCtx.CheckAccessToKind(types.KindProxy, types.VerbCreate, types.VerbUpdate); err != nil {
return nil, trace.Wrap(err)
}
// If the proxy advertised a local/unspecified address, replace the host
// component with the peer address observed on the socket.
if p, ok := peer.FromContext(ctx); ok {
srv.SetAddr(utils.ReplaceLocalhost(srv.GetAddr(), p.Addr.String()))
}
upserted, err := s.backend.UpsertProxyServer(ctx, srv)
if err != nil {
return nil, trace.Wrap(err)
}
upsertedV2, ok := upserted.(*types.ServerV2)
if !ok {
return nil, trace.BadParameter("unsupported proxy server type %T", upserted)
}
return &presencepb.UpsertProxyServerResponse{
Server: upsertedV2,
}, nil
}
// DeleteProxyServer deletes a proxy server heartbeat by name.
func (s *Service) DeleteProxyServer(
ctx context.Context, req *presencepb.DeleteProxyServerRequest,
) (*presencepb.DeleteProxyServerResponse, error) {
authCtx, err := s.authorizer.Authorize(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
if err := authCtx.CheckAccessToKind(types.KindProxy, types.VerbDelete); err != nil {
return nil, trace.Wrap(err)
}
if req.Name == "" {
return nil, trace.BadParameter("name: must be specified")
}
if err := s.backend.DeleteProxyServer(ctx, req.GetName()); err != nil {
return nil, trace.Wrap(err)
}
return &presencepb.DeleteProxyServerResponse{}, nil
}
@@ -40,7 +40,9 @@ import (
"github.com/gravitational/teleport/api/trail"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/utils"
"github.com/gravitational/teleport/api/utils/clientutils"
"github.com/gravitational/teleport/lib/auth/authtest"
"github.com/gravitational/teleport/lib/itertools/stream"
"github.com/gravitational/teleport/lib/modules"
)
@@ -878,6 +880,204 @@ func TestDeleteReverseTunnel(t *testing.T) {
}
}
// TestDeleteProxyServer is an integration test that uses a real gRPC client/server.
func TestDeleteProxyServer(t *testing.T) {
t.Parallel()
srv := newTestTLSServer(t)
ctx := t.Context()
user, _, err := authtest.CreateUserAndRole(
srv.Auth(),
"proxy-deleter",
[]string{},
[]types.Rule{
{
Resources: []string{types.KindProxy},
Verbs: []string{types.VerbDelete},
},
})
require.NoError(t, err)
unprivilegedUser, _, err := authtest.CreateUserAndRole(
srv.Auth(),
"proxy-no-perms",
[]string{},
[]types.Rule{},
)
require.NoError(t, err)
proxy, err := types.NewServer("proxy-1", types.KindProxy, types.ServerSpecV2{})
require.NoError(t, err)
_, err = srv.Auth().UpsertProxyServer(ctx, proxy)
require.NoError(t, err)
tests := []struct {
name string
user string
req *presencev1pb.DeleteProxyServerRequest
assertError require.ErrorAssertionFunc
checkResourcesDeleted bool
}{
{
name: "success",
user: user.GetName(),
req: &presencev1pb.DeleteProxyServerRequest{
Name: proxy.GetName(),
},
assertError: require.NoError,
checkResourcesDeleted: true,
},
{
name: "no permissions",
user: unprivilegedUser.GetName(),
req: &presencev1pb.DeleteProxyServerRequest{
Name: proxy.GetName(),
},
assertError: func(t require.TestingT, err error, i ...any) {
require.True(t, trace.IsAccessDenied(err), "error should be access denied")
},
},
{
name: "non existent",
user: user.GetName(),
req: &presencev1pb.DeleteProxyServerRequest{
Name: proxy.GetName(),
},
assertError: func(t require.TestingT, err error, i ...any) {
require.True(t, trace.IsNotFound(err), "error should be not found")
},
},
{
name: "missing name",
user: user.GetName(),
req: &presencev1pb.DeleteProxyServerRequest{},
assertError: func(t require.TestingT, err error, i ...any) {
require.True(t, trace.IsBadParameter(err), "error should be bad parameter")
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client, err := srv.NewClient(authtest.TestUser(tt.user))
require.NoError(t, err)
_, err = client.PresenceServiceClient().DeleteProxyServer(ctx, tt.req)
tt.assertError(t, err)
if tt.checkResourcesDeleted {
proxies, err := stream.Collect(clientutils.Resources(ctx, srv.Auth().ListProxyServers))
require.NoError(t, err)
for _, p := range proxies {
require.NotEqual(t, tt.req.Name, p.GetName(), "proxy should be deleted")
}
}
})
}
}
// TestUpsertProxyServer is an integration test that uses a real gRPC client/server.
func TestUpsertProxyServer(t *testing.T) {
t.Parallel()
srv := newTestTLSServer(t)
ctx := t.Context()
user, _, err := authtest.CreateUserAndRole(
srv.Auth(),
"proxy-upserter",
[]string{},
[]types.Rule{
{
Resources: []string{types.KindProxy},
Verbs: []string{types.VerbCreate, types.VerbUpdate},
},
})
require.NoError(t, err)
unprivilegedUser, _, err := authtest.CreateUserAndRole(
srv.Auth(),
"proxy-upsert-no-perms",
[]string{},
[]types.Rule{},
)
require.NoError(t, err)
proxy, err := types.NewServer("proxy-1", types.KindProxy, types.ServerSpecV2{
Addr: "127.0.0.1:2023",
Hostname: "proxy.llama",
})
require.NoError(t, err)
tests := []struct {
name string
user string
req *presencev1pb.UpsertProxyServerRequest
assertError require.ErrorAssertionFunc
checkResourceUpserted bool
}{
{
name: "success",
user: user.GetName(),
req: &presencev1pb.UpsertProxyServerRequest{
Server: proxy.(*types.ServerV2),
},
assertError: require.NoError,
checkResourceUpserted: true,
},
{
name: "no permissions",
user: unprivilegedUser.GetName(),
req: &presencev1pb.UpsertProxyServerRequest{
Server: proxy.(*types.ServerV2),
},
assertError: func(t require.TestingT, err error, i ...any) {
require.True(t, trace.IsAccessDenied(err), "error should be access denied")
},
},
{
name: "missing server",
user: user.GetName(),
req: &presencev1pb.UpsertProxyServerRequest{},
assertError: func(t require.TestingT, err error, i ...any) {
require.True(t, trace.IsBadParameter(err), "error should be bad parameter")
},
},
{
name: "validation failure - blank name",
user: user.GetName(),
req: &presencev1pb.UpsertProxyServerRequest{
Server: &types.ServerV2{
Kind: types.KindProxy,
Version: types.V2,
Metadata: types.Metadata{
Name: "",
},
},
},
assertError: func(t require.TestingT, err error, i ...any) {
require.True(t, trace.IsBadParameter(err), "error should be bad parameter")
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client, err := srv.NewClient(authtest.TestUser(tt.user))
require.NoError(t, err)
_, err = client.PresenceServiceClient().UpsertProxyServer(ctx, tt.req)
tt.assertError(t, err)
if tt.checkResourceUpserted {
proxies, err := stream.Collect(clientutils.Resources(ctx, srv.Auth().ListProxyServers))
require.NoError(t, err)
var found bool
for _, p := range proxies {
if p.GetName() == tt.req.Server.GetName() {
found = true
break
}
}
require.True(t, found, "proxy should have been upserted")
}
})
}
}
func TestUpsertReverseTunnel(t *testing.T) {
t.Parallel()
srv := newTestTLSServer(t)
+155 -6
View File
@@ -24,6 +24,7 @@ import (
"crypto/tls"
"crypto/x509"
"encoding/base32"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
@@ -53,6 +54,7 @@ import (
"github.com/gravitational/teleport/api/constants"
apidefaults "github.com/gravitational/teleport/api/defaults"
headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
presencev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/presence/v1"
scopedaccessv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/scopes/access/v1"
trustpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/trust/v1"
userspb "github.com/gravitational/teleport/api/gen/proto/go/teleport/users/v1"
@@ -1006,7 +1008,7 @@ func TestOIDCIdPTokenRotation(t *testing.T) {
})
require.NoError(t, err)
err = clt.UpsertProxy(ctx, proxyServer)
err = clt.UpsertProxyServerWithoutReturn(ctx, proxyServer)
require.NoError(t, err)
integrationName := "my-integration"
@@ -1735,7 +1737,7 @@ func TestServersCRUD(t *testing.T) {
proxy := NewServer(types.KindProxy, "proxy1", "127.0.0.1:2023", apidefaults.Namespace)
proxy.Spec.Hostname = "proxy.llama"
require.NoError(t, clt.UpsertProxy(ctx, proxy))
require.NoError(t, clt.UpsertProxyServerWithoutReturn(ctx, proxy))
//nolint:staticcheck // TODO(kiosion) DELETE IN 21.0.0
out, err = clt.GetProxies()
@@ -1743,7 +1745,7 @@ func TestServersCRUD(t *testing.T) {
require.Len(t, out, 1)
require.Empty(t, cmp.Diff(out, []types.Server{proxy}, cmpopts.IgnoreFields(types.Metadata{}, "Revision")))
err = clt.DeleteProxy(ctx, proxy.GetName())
err = clt.DeleteProxyServer(ctx, proxy.GetName())
require.NoError(t, err)
//nolint:staticcheck // TODO(kiosion) DELETE IN 21.0.0
@@ -1768,6 +1770,153 @@ func TestServersCRUD(t *testing.T) {
require.Empty(t, cmp.Diff(out, []types.Server{auth}, cmpopts.IgnoreFields(types.Metadata{}, "Revision")))
}
// TestDeleteProxy exercises both wire paths that coexist during the
// HTTP-to-gRPC migration window: the direct gRPC RPC on *APIClient and the
// legacy HTTP endpoint invoked via the raw HTTP client.
//
// TODO(noah): DELETE IN v20.0.0 - once the legacy HTTP endpoint is removed,
// the DeleteProxy call in TestServersCRUD is sufficient.
func TestDeleteProxy(t *testing.T) {
t.Parallel()
testSrv := newTestTLSServer(t)
clt, err := testSrv.NewClient(authtest.TestAdmin())
require.NoError(t, err)
ctx := t.Context()
newProxy := func(name string) types.Server {
return &types.ServerV2{
Kind: types.KindProxy,
Version: types.V2,
Metadata: types.Metadata{
Name: name,
Namespace: apidefaults.Namespace,
},
Spec: types.ServerSpecV2{
Addr: "127.0.0.1:2023",
Hostname: "proxy.llama",
},
}
}
proxyNames := func(t *testing.T) []string {
proxies, _, err := testSrv.Auth().ListProxyServers(ctx, 0, "")
require.NoError(t, err)
names := make([]string, 0, len(proxies))
for _, p := range proxies {
names = append(names, p.GetName())
}
return names
}
t.Run("direct gRPC RPC", func(t *testing.T) {
proxy := newProxy("proxy-grpc")
require.NoError(t, clt.UpsertProxyServerWithoutReturn(ctx, proxy))
_, err := clt.APIClient.PresenceServiceClient().DeleteProxyServer(
ctx, &presencev1.DeleteProxyServerRequest{
Name: proxy.GetName(),
},
)
require.NoError(t, err)
require.NotContains(t, proxyNames(t), proxy.GetName())
})
t.Run("through fallback abstraction", func(t *testing.T) {
proxy := newProxy("proxy-through-fallback-grpc")
require.NoError(t, clt.UpsertProxyServerWithoutReturn(ctx, proxy))
require.NoError(t, clt.DeleteProxyServer(ctx, proxy.GetName()))
require.NotContains(t, proxyNames(t), proxy.GetName())
})
t.Run("legacy HTTP endpoint", func(t *testing.T) {
proxy := newProxy("proxy-http")
require.NoError(t, clt.UpsertProxyServerWithoutReturn(ctx, proxy))
_, err := clt.HTTPClient.Delete(ctx, clt.HTTPClient.Endpoint("proxies", proxy.GetName()))
require.NoError(t, err)
require.NotContains(t, proxyNames(t), proxy.GetName())
})
}
// TestUpsertProxy exercises both wire paths that coexist during the
// HTTP-to-gRPC migration window: the direct gRPC RPC on *APIClient and the
// legacy HTTP endpoint invoked via the raw HTTP client.
//
// TODO(noah): DELETE IN v20.0.0 - once the legacy HTTP endpoint is removed,
// the UpsertProxy call in TestServersCRUD is sufficient.
func TestUpsertProxy(t *testing.T) {
t.Parallel()
testSrv := newTestTLSServer(t)
clt, err := testSrv.NewClient(authtest.TestAdmin())
require.NoError(t, err)
ctx := t.Context()
newProxy := func(name string) types.Server {
return &types.ServerV2{
Kind: types.KindProxy,
Version: types.V2,
Metadata: types.Metadata{
Name: name,
Namespace: apidefaults.Namespace,
},
Spec: types.ServerSpecV2{
Addr: "127.0.0.1:2023",
Hostname: "proxy.llama",
},
}
}
proxyNames := func(t *testing.T) []string {
proxies, _, err := testSrv.Auth().ListProxyServers(ctx, 0, "")
require.NoError(t, err)
names := make([]string, 0, len(proxies))
for _, p := range proxies {
names = append(names, p.GetName())
}
return names
}
t.Run("direct gRPC RPC", func(t *testing.T) {
proxy := newProxy("proxy-grpc").(*types.ServerV2)
_, err := clt.APIClient.PresenceServiceClient().UpsertProxyServer(
ctx, &presencev1.UpsertProxyServerRequest{
Server: proxy,
},
)
require.NoError(t, err)
require.Contains(t, proxyNames(t), proxy.GetName())
})
t.Run("through fallback abstraction", func(t *testing.T) {
proxy := newProxy("proxy-through-fallback-grpc")
require.NoError(t, clt.UpsertProxyServerWithoutReturn(ctx, proxy))
require.Contains(t, proxyNames(t), proxy.GetName())
})
t.Run("legacy HTTP endpoint", func(t *testing.T) {
proxy := newProxy("proxy-http")
data, err := services.MarshalServer(proxy)
require.NoError(t, err)
body := map[string]any{"server": json.RawMessage(data)}
_, err = clt.HTTPClient.PostJSON(ctx, clt.HTTPClient.Endpoint("proxies"), body)
require.NoError(t, err)
require.Contains(t, proxyNames(t), proxy.GetName())
})
}
// TestAppServerCRUD tests CRUD functionality for services.App using an auth client.
func TestAppServerCRUD(t *testing.T) {
t.Parallel()
@@ -3333,7 +3482,7 @@ func TestGenerateAppToken(t *testing.T) {
PublicAddrs: []string{"https://teleport.example.com"},
})
require.NoError(t, err)
require.NoError(t, authClient.UpsertProxy(ctx, proxyServer))
require.NoError(t, authClient.UpsertProxyServerWithoutReturn(ctx, proxyServer))
tests := []struct {
inMachineRole types.SystemRole
@@ -4822,7 +4971,7 @@ func TestEvents(t *testing.T) {
},
}
err := testSrv.Auth().UpsertProxy(ctx, srv)
_, err := testSrv.Auth().UpsertProxyServer(ctx, srv)
require.NoError(t, err)
//nolint:staticcheck // TODO(kiosion) DELETE IN 21.0.0
@@ -4830,7 +4979,7 @@ func TestEvents(t *testing.T) {
require.NoError(t, err)
for _, p := range out {
require.NoError(t, testSrv.Auth().DeleteProxy(ctx, p.GetName()))
require.NoError(t, testSrv.Auth().DeleteProxyServer(ctx, p.GetName()))
}
return out[0]
+9 -3
View File
@@ -45,17 +45,23 @@ func TestProxies(t *testing.T) {
},
}, nil
},
create: p.presenceS.UpsertProxy,
create: func(ctx context.Context, s types.Server) error {
_, err := p.presenceS.UpsertProxyServer(ctx, s)
return err
},
list: p.presenceS.ListProxyServers,
cacheList: p.cache.ListProxyServers,
update: p.presenceS.UpsertProxy,
update: func(ctx context.Context, s types.Server) error {
_, err := p.presenceS.UpsertProxyServer(ctx, s)
return err
},
deleteAll: func(ctx context.Context) error {
proxies, err := stream.Collect(clientutils.Resources(ctx, p.presenceS.ListProxyServers))
if err != nil {
return err
}
for _, proxy := range proxies {
if err := p.presenceS.DeleteProxy(ctx, proxy.GetName()); err != nil {
if err := p.presenceS.DeleteProxyServer(ctx, proxy.GetName()); err != nil {
return err
}
}
+2 -2
View File
@@ -642,11 +642,11 @@ func TestHostUniqueCheck(t *testing.T) {
Namespace: defaults.Namespace,
},
}
err := a.UpsertProxy(context.Background(), proxy)
_, err := a.UpsertProxyServer(context.Background(), proxy)
require.NoError(t, err)
},
deleter: func(t *testing.T, hostID string) {
require.NoError(t, a.DeleteProxy(t.Context(), hostID))
require.NoError(t, a.DeleteProxyServer(t.Context(), hostID))
},
},
{
+1 -1
View File
@@ -5249,7 +5249,7 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error {
// reverse tunnel agents during rollouts, as otherwise they'll keep
// trying to reach proxies until the heartbeats expire.
if services.ShouldDeleteServerHeartbeatsOnShutdown(ctx) {
if err := conn.Client.DeleteProxy(ctx, conn.HostUUID()); err != nil {
if err := conn.Client.DeleteProxyServer(ctx, conn.HostUUID()); err != nil {
if !trace.IsNotFound(err) {
logger.WarnContext(ctx, "Failed to delete heartbeat", "error", err)
} else {
+15 -10
View File
@@ -202,19 +202,23 @@ func (s *PresenceService) getServers(ctx context.Context, kind, prefix string) (
return servers, nil
}
func (s *PresenceService) upsertServer(ctx context.Context, prefix string, server types.Server) error {
func (s *PresenceService) upsertServer(ctx context.Context, prefix string, server types.Server) (types.Server, error) {
rev := server.GetRevision()
value, err := services.MarshalServer(server)
if err != nil {
return trace.Wrap(err)
return nil, trace.Wrap(err)
}
_, err = s.Put(ctx, backend.Item{
lease, err := s.Put(ctx, backend.Item{
Key: backend.NewKey(prefix, server.GetName()),
Value: value,
Expires: server.Expiry(),
Revision: rev,
})
return trace.Wrap(err)
if err != nil {
return nil, trace.Wrap(err)
}
server.SetRevision(lease.Revision)
return server, nil
}
// DeleteAllNodes deletes all nodes in a namespace
@@ -446,7 +450,8 @@ func (s *PresenceService) ListAuthServers(ctx context.Context, pageSize int, pag
// UpsertAuthServer registers auth server presence, permanently if ttl is 0 or
// for the specified duration with second resolution if it's >= 1 second
func (s *PresenceService) UpsertAuthServer(ctx context.Context, server types.Server) error {
return s.upsertServer(ctx, authServersPrefix, server)
_, err := s.upsertServer(ctx, authServersPrefix, server)
return trace.Wrap(err)
}
// DeleteAllAuthServers deletes all auth servers
@@ -461,9 +466,9 @@ func (s *PresenceService) DeleteAuthServer(name string) error {
return s.Delete(context.TODO(), key)
}
// UpsertProxy registers proxy server presence, permanently if ttl is 0 or
// for the specified duration with second resolution if it's >= 1 second
func (s *PresenceService) UpsertProxy(ctx context.Context, server types.Server) error {
// UpsertProxyServer registers proxy server presence, permanently if ttl is 0
// or for the specified duration with second resolution if it's >= 1 second.
func (s *PresenceService) UpsertProxyServer(ctx context.Context, server types.Server) (types.Server, error) {
return s.upsertServer(ctx, proxiesPrefix, server)
}
@@ -481,8 +486,8 @@ func (s *PresenceService) ListProxyServers(ctx context.Context, pageSize int, pa
return generic.CollectPageAndCursor(s.rangeProxyServers(ctx, pageToken, ""), pageSize, serverToPaginationKey)
}
// DeleteProxy deletes proxy
func (s *PresenceService) DeleteProxy(ctx context.Context, name string) error {
// DeleteProxyServer deletes proxy
func (s *PresenceService) DeleteProxyServer(ctx context.Context, name string) error {
key := backend.NewKey(proxiesPrefix, name)
return s.Delete(ctx, key)
}
+6 -5
View File
@@ -63,7 +63,7 @@ type ServicesTestSuite struct {
Access services.Access
TrustS services.Trust
TrustInternalS services.TrustInternal
PresenceS services.Presence
PresenceS services.PresenceInternal
ProvisioningS services.Provisioner
WebS services.Identity
ConfigS services.ClusterConfiguration
@@ -395,7 +395,8 @@ func (s *ServicesTestSuite) ServerCRUD(t *testing.T) {
proxy := NewServer(types.KindProxy, "proxy1", "127.0.0.1:2023", apidefaults.Namespace)
proxy.Spec.Hostname = "proxy.llama"
require.NoError(t, s.PresenceS.UpsertProxy(ctx, proxy))
_, err = s.PresenceS.UpsertProxyServer(ctx, proxy)
require.NoError(t, err)
//nolint:staticcheck // TODO(kiosion) DELETE IN 21.0.0
out, err = s.PresenceS.GetProxies()
@@ -403,7 +404,7 @@ func (s *ServicesTestSuite) ServerCRUD(t *testing.T) {
require.Len(t, out, 1)
require.Empty(t, cmp.Diff(out, []types.Server{proxy}, cmpopts.IgnoreFields(types.Metadata{}, "Revision")))
err = s.PresenceS.DeleteProxy(ctx, proxy.GetName())
err = s.PresenceS.DeleteProxyServer(ctx, proxy.GetName())
require.NoError(t, err)
//nolint:staticcheck // TODO(kiosion) DELETE IN 21.0.0
@@ -2220,7 +2221,7 @@ func (s *ServicesTestSuite) Events(t *testing.T) {
crud: func(context.Context) types.Resource {
srv := NewServer(types.KindProxy, "srv1", "127.0.0.1:2022", apidefaults.Namespace)
err := s.PresenceS.UpsertProxy(ctx, srv)
_, err := s.PresenceS.UpsertProxyServer(ctx, srv)
require.NoError(t, err)
//nolint:staticcheck // TODO(kiosion) DELETE IN 21.0.0
@@ -2228,7 +2229,7 @@ func (s *ServicesTestSuite) Events(t *testing.T) {
require.NoError(t, err)
for _, p := range out {
require.NoError(t, s.PresenceS.DeleteProxy(ctx, p.GetName()))
require.NoError(t, s.PresenceS.DeleteProxyServer(ctx, p.GetName()))
}
return out[0]
+7 -6
View File
@@ -108,15 +108,11 @@ type Presence interface {
// DeleteAuthServer deletes auth server by name
DeleteAuthServer(name string) error
// UpsertProxy registers proxy server presence, permanently if ttl is 0 or
// for the specified duration with second resolution if it's >= 1 second
UpsertProxy(ctx context.Context, server types.Server) error
// ProxyGetter gets a list of proxies
ProxyGetter
// DeleteProxy deletes proxy by name
DeleteProxy(ctx context.Context, name string) error
// DeleteProxyServer deletes proxy by name
DeleteProxyServer(ctx context.Context, name string) error
// UpsertReverseTunnel upserts reverse tunnel entry temporarily or permanently
UpsertReverseTunnel(ctx context.Context, tunnel types.ReverseTunnel) (types.ReverseTunnel, error)
@@ -205,6 +201,11 @@ type PresenceInternal interface {
Presence
InventoryInternal
// UpsertProxyServer registers proxy server presence, permanently if ttl is
// 0 or for the specified duration with second resolution if it's >= 1
// second. It returns the upserted server with its revision populated.
UpsertProxyServer(ctx context.Context, server types.Server) (types.Server, error)
UpsertHostUserInteractionTime(ctx context.Context, name string, loginTime time.Time) error
GetHostUserInteractionTime(ctx context.Context, name string) (time.Time, error)
UpdateNode(ctx context.Context, server types.Server) (types.Server, error)
+6 -4
View File
@@ -155,7 +155,8 @@ func TestProxyWatcher(t *testing.T) {
require.NoError(t, w.WaitInitialization())
// Add a proxy server.
proxy := newProxyServer(t, "proxy1", "127.0.0.1:2023")
require.NoError(t, presence.UpsertProxy(ctx, proxy))
_, err = presence.UpsertProxyServer(ctx, proxy)
require.NoError(t, err)
// The first event is always the current list of proxies.
select {
@@ -170,7 +171,8 @@ func TestProxyWatcher(t *testing.T) {
// Add a second proxy.
proxy2 := newProxyServer(t, "proxy2", "127.0.0.1:2023")
require.NoError(t, presence.UpsertProxy(ctx, proxy2))
_, err = presence.UpsertProxyServer(ctx, proxy2)
require.NoError(t, err)
// Watcher should detect the proxy list change.
select {
@@ -183,7 +185,7 @@ func TestProxyWatcher(t *testing.T) {
}
// Delete the first proxy.
require.NoError(t, presence.DeleteProxy(ctx, proxy.GetName()))
require.NoError(t, presence.DeleteProxyServer(ctx, proxy.GetName()))
// Watcher should detect the proxy list change.
select {
@@ -197,7 +199,7 @@ func TestProxyWatcher(t *testing.T) {
}
// Delete the second proxy.
require.NoError(t, presence.DeleteProxy(ctx, proxy2.GetName()))
require.NoError(t, presence.DeleteProxyServer(ctx, proxy2.GetName()))
// Watcher should detect the proxy list change.
select {
+3 -2
View File
@@ -121,7 +121,7 @@ func TestWatcher(t *testing.T) {
// Create a single Proxy with a PublicAddr to exercise that
// apps without a PublicAddr automatically get one specified
// by the watcher.
require.NoError(t, s.authServer.AuthServer.UpsertProxy(t.Context(), &types.ServerV2{
_, err = s.authServer.AuthServer.UpsertProxyServer(t.Context(), &types.ServerV2{
Kind: types.KindProxy,
Version: types.V2,
Metadata: types.Metadata{
@@ -130,7 +130,8 @@ func TestWatcher(t *testing.T) {
Spec: types.ServerSpecV2{
PublicAddrs: []string{"test.example.com"},
},
}))
})
require.NoError(t, err)
// Only app0 should be registered initially.
select {
+3 -3
View File
@@ -835,7 +835,7 @@ func TestDiscoveryServer(t *testing.T) {
t.Cleanup(func() { require.NoError(t, testAuthServer.Close()) })
if tc.requiresProxy {
err = testAuthServer.AuthServer.UpsertProxy(ctx, &types.ServerV2{
_, err = testAuthServer.AuthServer.UpsertProxyServer(ctx, &types.ServerV2{
Kind: types.KindProxy,
Metadata: types.Metadata{
Name: "proxy",
@@ -2838,7 +2838,7 @@ func TestDiscoveryDatabase(t *testing.T) {
PublicAddrs: []string{"teleport.example.com"},
})
require.NoError(t, err)
err = tlsServer.Auth().UpsertProxy(ctx, proxy)
_, err = tlsServer.Auth().UpsertProxyServer(ctx, proxy)
require.NoError(t, err)
_, err = tlsServer.Auth().CreateIntegration(ctx, awsOIDCIntegration)
@@ -3562,7 +3562,7 @@ func TestAzureVMDiscovery(t *testing.T) {
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, testAuthServer.Close()) })
err = testAuthServer.AuthServer.UpsertProxy(t.Context(), &types.ServerV2{
_, err = testAuthServer.AuthServer.UpsertProxyServer(t.Context(), &types.ServerV2{
Kind: types.KindProxy,
Metadata: types.Metadata{
Name: "proxy",
@@ -174,7 +174,7 @@ func TestDiscoveryKubeIntegrationEKS(t *testing.T) {
})
require.NoError(t, err)
err = testAuthServer.AuthServer.UpsertProxy(t.Context(), proxy)
_, err = testAuthServer.AuthServer.UpsertProxyServer(t.Context(), proxy)
require.NoError(t, err)
testAuthServer.AuthServer.IntegrationsTokenGenerator = &mockIntegrationsTokenGenerator{
+1 -1
View File
@@ -411,7 +411,7 @@ func (h *Heartbeat) announce() (doneSomething bool, _ error) {
if !ok {
return false, trace.BadParameter("expected services.Server, got %#v", h.current)
}
err := h.Announcer.UpsertProxy(h.cancelCtx, proxy)
err := h.Announcer.UpsertProxyServerWithoutReturn(h.cancelCtx, proxy)
if err != nil {
// try next announce using keep alive period,
// that happens more frequently
+1 -1
View File
@@ -376,7 +376,7 @@ func (f *fakeAnnouncer) UpsertNode(ctx context.Context, s types.Server) (*types.
return &types.KeepAlive{}, nil
}
func (f *fakeAnnouncer) UpsertProxy(ctx context.Context, s types.Server) error {
func (f *fakeAnnouncer) UpsertProxyServerWithoutReturn(ctx context.Context, s types.Server) error {
f.upsertCalls[HeartbeatModeProxy]++
return f.err
}
+1 -1
View File
@@ -1379,7 +1379,7 @@ func TestUnifiedResourcesGet_AppComponentFeatures(t *testing.T) {
{
for srv := range clientutils.Resources(ctx, env.server.Auth().ListProxyServers) {
srv.SetComponentFeatures(componentfeatures.New(feature1))
err := env.server.Auth().UpsertProxy(ctx, srv)
_, err := env.server.Auth().UpsertProxyServer(ctx, srv)
require.NoError(t, err)
}
}
+2 -2
View File
@@ -100,7 +100,7 @@ func BenchmarkGetClusterDetails(b *testing.B) {
}
// insertServers inserts a collection of servers into a backend.
func insertServers(ctx context.Context, b *testing.B, svc services.Presence, kind string, count int) {
func insertServers(ctx context.Context, b *testing.B, svc services.PresenceInternal, kind string, count int) {
const labelCount = 10
labels := make(map[string]string, labelCount)
for i := range labelCount {
@@ -127,7 +127,7 @@ func insertServers(ctx context.Context, b *testing.B, svc services.Presence, kin
case types.KindNode:
_, err = svc.UpsertNode(ctx, server)
case types.KindProxy:
err = svc.UpsertProxy(ctx, server)
_, err = svc.UpsertProxyServer(ctx, server)
case types.KindAuthServer:
err = svc.UpsertAuthServer(ctx, server)
default:
+1 -1
View File
@@ -74,7 +74,7 @@ func getProxy(ctx context.Context, client *authclient.Client, ref services.Ref,
}
func deleteProxy(ctx context.Context, client *authclient.Client, ref services.Ref) error {
if err := client.DeleteProxy(ctx, ref.Name); err != nil {
if err := client.DeleteProxyServer(ctx, ref.Name); err != nil {
return trace.Wrap(err)
}
fmt.Printf("Proxy %q has been deleted\n", ref.Name)