mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-12 02:15:01 +00:00
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:
@@ -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 {}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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].
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
@@ -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]
|
||||
|
||||
Vendored
+9
-3
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user