Implement semantic search API for unified resources (#31881)

* Implement semantic search API for unified resources

* use require.eventually to complete test faster

* reset mod and sum

* Update lib/auth/assist/assistv1/test/service_test.go

Co-authored-by: Jakub Nyckowski <jakub.nyckowski@goteleport.com>

* use correct proto numbering

* reset e

* make grpc

---------

Co-authored-by: Jakub Nyckowski <jakub.nyckowski@goteleport.com>
This commit is contained in:
Joel
2023-10-02 19:57:54 +00:00
committed by GitHub
co-authored by Jakub Nyckowski
parent ba907374b5
commit fb77d4ff23
10 changed files with 758 additions and 279 deletions
+265 -95
View File
@@ -21,6 +21,7 @@
package assist
import (
proto "github.com/gravitational/teleport/api/client/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
emptypb "google.golang.org/protobuf/types/known/emptypb"
@@ -958,6 +959,122 @@ func (x *GetAssistantEmbeddingsResponse) GetEmbeddings() []*EmbeddedDocument {
return nil
}
// SearchUnifiedResourcesRequest is a request to search for one or more resource kinds using similiarity search.
type SearchUnifiedResourcesRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// query is the query used for similarity search.
Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"`
// limit is the number of embeddings to return (also known as k).
Limit int32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"`
// kinds is the kind of embeddings to return (ex, node). Returns all supported kinds if empty.
Kinds []string `protobuf:"bytes,3,rep,name=kinds,proto3" json:"kinds,omitempty"`
}
func (x *SearchUnifiedResourcesRequest) Reset() {
*x = SearchUnifiedResourcesRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_teleport_assist_v1_assist_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SearchUnifiedResourcesRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SearchUnifiedResourcesRequest) ProtoMessage() {}
func (x *SearchUnifiedResourcesRequest) ProtoReflect() protoreflect.Message {
mi := &file_teleport_assist_v1_assist_proto_msgTypes[16]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SearchUnifiedResourcesRequest.ProtoReflect.Descriptor instead.
func (*SearchUnifiedResourcesRequest) Descriptor() ([]byte, []int) {
return file_teleport_assist_v1_assist_proto_rawDescGZIP(), []int{16}
}
func (x *SearchUnifiedResourcesRequest) GetQuery() string {
if x != nil {
return x.Query
}
return ""
}
func (x *SearchUnifiedResourcesRequest) GetLimit() int32 {
if x != nil {
return x.Limit
}
return 0
}
func (x *SearchUnifiedResourcesRequest) GetKinds() []string {
if x != nil {
return x.Kinds
}
return nil
}
// SearchUnifiedResourcesResponse is a response from the assistant service with a similarity-ordered list of resources.
type SearchUnifiedResourcesResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// resources is the list of resources.
Resources []*proto.PaginatedResource `protobuf:"bytes,1,rep,name=resources,proto3" json:"resources,omitempty"`
}
func (x *SearchUnifiedResourcesResponse) Reset() {
*x = SearchUnifiedResourcesResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_teleport_assist_v1_assist_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SearchUnifiedResourcesResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SearchUnifiedResourcesResponse) ProtoMessage() {}
func (x *SearchUnifiedResourcesResponse) ProtoReflect() protoreflect.Message {
mi := &file_teleport_assist_v1_assist_proto_msgTypes[17]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SearchUnifiedResourcesResponse.ProtoReflect.Descriptor instead.
func (*SearchUnifiedResourcesResponse) Descriptor() ([]byte, []int) {
return file_teleport_assist_v1_assist_proto_rawDescGZIP(), []int{17}
}
func (x *SearchUnifiedResourcesResponse) GetResources() []*proto.PaginatedResource {
if x != nil {
return x.Resources
}
return nil
}
var File_teleport_assist_v1_assist_proto protoreflect.FileDescriptor
var file_teleport_assist_v1_assist_proto_rawDesc = []byte{
@@ -968,6 +1085,9 @@ var file_teleport_assist_v1_assist_proto_rawDesc = []byte{
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x65,
0x67, 0x61, 0x63, 0x79, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0x62, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74,
0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69,
@@ -1070,75 +1190,95 @@ var file_teleport_assist_v1_assist_proto_rawDesc = []byte{
0x24, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73,
0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x44, 0x6f, 0x63,
0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67,
0x73, 0x32, 0xdd, 0x06, 0x0a, 0x0d, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73,
0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x12, 0x36, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61,
0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41,
0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x74, 0x65,
0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74,
0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69,
0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x12, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73,
0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73,
0x73, 0x22, 0x61, 0x0a, 0x1d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x6e, 0x69, 0x66, 0x69,
0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69,
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x14,
0x0a, 0x05, 0x6b, 0x69, 0x6e, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6b,
0x69, 0x6e, 0x64, 0x73, 0x22, 0x58, 0x0a, 0x1e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x6e,
0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x32, 0xde,
0x07, 0x0a, 0x0d, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x12, 0x8e, 0x01, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73,
0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70,
0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72,
0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x6d, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61,
0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36,
0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74,
0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74,
0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x79,
0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72,
0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41,
0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f,
0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x12, 0x36, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69,
0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69,
0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70,
0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e,
0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x88, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61,
0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12,
0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73,
0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e,
0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74,
0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x73,
0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x1b,
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43,
0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x2e, 0x74, 0x65,
0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31,
0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74,
0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x79, 0x0a, 0x14, 0x47,
0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61,
0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69,
0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e,
0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73,
0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x16, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61,
0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41,
0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x75,
0x0a, 0x1f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e,
0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66,
0x6f, 0x12, 0x3a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73,
0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73,
0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x6a, 0x0a, 0x0f, 0x49, 0x73, 0x41, 0x73, 0x73, 0x69, 0x73,
0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70,
0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73,
0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e,
0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x41, 0x73, 0x73, 0x69,
0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x32, 0x99, 0x01, 0x0a, 0x16, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x6d, 0x62, 0x65,
0x64, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7f, 0x0a, 0x16,
0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x45, 0x6d, 0x62, 0x65,
0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72,
0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41,
0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e,
0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65,
0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47,
0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x45, 0x6d, 0x62, 0x65, 0x64,
0x64, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x45, 0x5a,
0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76,
0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f,
0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x73,
0x73, 0x69, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69,
0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69,
0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x75, 0x0a, 0x1f, 0x55,
0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f,
0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3a,
0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74,
0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74,
0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49,
0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
0x74, 0x79, 0x12, 0x6a, 0x0a, 0x0f, 0x49, 0x73, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x6e,
0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74,
0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x41, 0x73, 0x73,
0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73,
0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f,
0x0a, 0x16, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70,
0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65,
0x61, 0x72, 0x63, 0x68, 0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x74, 0x65,
0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31,
0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32,
0x99, 0x01, 0x0a, 0x16, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64,
0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7f, 0x0a, 0x16, 0x47, 0x65,
0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64,
0x69, 0x6e, 0x67, 0x73, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e,
0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73,
0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f,
0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69,
0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x45, 0x5a, 0x43, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74,
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67,
0x6f, 0x2f, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x73, 0x73, 0x69,
0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1153,7 +1293,7 @@ func file_teleport_assist_v1_assist_proto_rawDescGZIP() []byte {
return file_teleport_assist_v1_assist_proto_rawDescData
}
var file_teleport_assist_v1_assist_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
var file_teleport_assist_v1_assist_proto_msgTypes = make([]protoimpl.MessageInfo, 18)
var file_teleport_assist_v1_assist_proto_goTypes = []interface{}{
(*GetAssistantMessagesRequest)(nil), // 0: teleport.assist.v1.GetAssistantMessagesRequest
(*AssistantMessage)(nil), // 1: teleport.assist.v1.AssistantMessage
@@ -1171,38 +1311,44 @@ var file_teleport_assist_v1_assist_proto_goTypes = []interface{}{
(*GetAssistantEmbeddingsRequest)(nil), // 13: teleport.assist.v1.GetAssistantEmbeddingsRequest
(*EmbeddedDocument)(nil), // 14: teleport.assist.v1.EmbeddedDocument
(*GetAssistantEmbeddingsResponse)(nil), // 15: teleport.assist.v1.GetAssistantEmbeddingsResponse
(*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp
(*emptypb.Empty)(nil), // 17: google.protobuf.Empty
(*SearchUnifiedResourcesRequest)(nil), // 16: teleport.assist.v1.SearchUnifiedResourcesRequest
(*SearchUnifiedResourcesResponse)(nil), // 17: teleport.assist.v1.SearchUnifiedResourcesResponse
(*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp
(*proto.PaginatedResource)(nil), // 19: proto.PaginatedResource
(*emptypb.Empty)(nil), // 20: google.protobuf.Empty
}
var file_teleport_assist_v1_assist_proto_depIdxs = []int32{
16, // 0: teleport.assist.v1.AssistantMessage.created_time:type_name -> google.protobuf.Timestamp
18, // 0: teleport.assist.v1.AssistantMessage.created_time:type_name -> google.protobuf.Timestamp
1, // 1: teleport.assist.v1.CreateAssistantMessageRequest.message:type_name -> teleport.assist.v1.AssistantMessage
1, // 2: teleport.assist.v1.GetAssistantMessagesResponse.messages:type_name -> teleport.assist.v1.AssistantMessage
16, // 3: teleport.assist.v1.ConversationInfo.created_time:type_name -> google.protobuf.Timestamp
18, // 3: teleport.assist.v1.ConversationInfo.created_time:type_name -> google.protobuf.Timestamp
5, // 4: teleport.assist.v1.GetAssistantConversationsResponse.conversations:type_name -> teleport.assist.v1.ConversationInfo
16, // 5: teleport.assist.v1.CreateAssistantConversationRequest.created_time:type_name -> google.protobuf.Timestamp
18, // 5: teleport.assist.v1.CreateAssistantConversationRequest.created_time:type_name -> google.protobuf.Timestamp
14, // 6: teleport.assist.v1.GetAssistantEmbeddingsResponse.embeddings:type_name -> teleport.assist.v1.EmbeddedDocument
7, // 7: teleport.assist.v1.AssistService.CreateAssistantConversation:input_type -> teleport.assist.v1.CreateAssistantConversationRequest
4, // 8: teleport.assist.v1.AssistService.GetAssistantConversations:input_type -> teleport.assist.v1.GetAssistantConversationsRequest
12, // 9: teleport.assist.v1.AssistService.DeleteAssistantConversation:input_type -> teleport.assist.v1.DeleteAssistantConversationRequest
0, // 10: teleport.assist.v1.AssistService.GetAssistantMessages:input_type -> teleport.assist.v1.GetAssistantMessagesRequest
2, // 11: teleport.assist.v1.AssistService.CreateAssistantMessage:input_type -> teleport.assist.v1.CreateAssistantMessageRequest
9, // 12: teleport.assist.v1.AssistService.UpdateAssistantConversationInfo:input_type -> teleport.assist.v1.UpdateAssistantConversationInfoRequest
10, // 13: teleport.assist.v1.AssistService.IsAssistEnabled:input_type -> teleport.assist.v1.IsAssistEnabledRequest
13, // 14: teleport.assist.v1.AssistEmbeddingService.GetAssistantEmbeddings:input_type -> teleport.assist.v1.GetAssistantEmbeddingsRequest
8, // 15: teleport.assist.v1.AssistService.CreateAssistantConversation:output_type -> teleport.assist.v1.CreateAssistantConversationResponse
6, // 16: teleport.assist.v1.AssistService.GetAssistantConversations:output_type -> teleport.assist.v1.GetAssistantConversationsResponse
17, // 17: teleport.assist.v1.AssistService.DeleteAssistantConversation:output_type -> google.protobuf.Empty
3, // 18: teleport.assist.v1.AssistService.GetAssistantMessages:output_type -> teleport.assist.v1.GetAssistantMessagesResponse
17, // 19: teleport.assist.v1.AssistService.CreateAssistantMessage:output_type -> google.protobuf.Empty
17, // 20: teleport.assist.v1.AssistService.UpdateAssistantConversationInfo:output_type -> google.protobuf.Empty
11, // 21: teleport.assist.v1.AssistService.IsAssistEnabled:output_type -> teleport.assist.v1.IsAssistEnabledResponse
15, // 22: teleport.assist.v1.AssistEmbeddingService.GetAssistantEmbeddings:output_type -> teleport.assist.v1.GetAssistantEmbeddingsResponse
15, // [15:23] is the sub-list for method output_type
7, // [7:15] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
19, // 7: teleport.assist.v1.SearchUnifiedResourcesResponse.resources:type_name -> proto.PaginatedResource
7, // 8: teleport.assist.v1.AssistService.CreateAssistantConversation:input_type -> teleport.assist.v1.CreateAssistantConversationRequest
4, // 9: teleport.assist.v1.AssistService.GetAssistantConversations:input_type -> teleport.assist.v1.GetAssistantConversationsRequest
12, // 10: teleport.assist.v1.AssistService.DeleteAssistantConversation:input_type -> teleport.assist.v1.DeleteAssistantConversationRequest
0, // 11: teleport.assist.v1.AssistService.GetAssistantMessages:input_type -> teleport.assist.v1.GetAssistantMessagesRequest
2, // 12: teleport.assist.v1.AssistService.CreateAssistantMessage:input_type -> teleport.assist.v1.CreateAssistantMessageRequest
9, // 13: teleport.assist.v1.AssistService.UpdateAssistantConversationInfo:input_type -> teleport.assist.v1.UpdateAssistantConversationInfoRequest
10, // 14: teleport.assist.v1.AssistService.IsAssistEnabled:input_type -> teleport.assist.v1.IsAssistEnabledRequest
16, // 15: teleport.assist.v1.AssistService.SearchUnifiedResources:input_type -> teleport.assist.v1.SearchUnifiedResourcesRequest
13, // 16: teleport.assist.v1.AssistEmbeddingService.GetAssistantEmbeddings:input_type -> teleport.assist.v1.GetAssistantEmbeddingsRequest
8, // 17: teleport.assist.v1.AssistService.CreateAssistantConversation:output_type -> teleport.assist.v1.CreateAssistantConversationResponse
6, // 18: teleport.assist.v1.AssistService.GetAssistantConversations:output_type -> teleport.assist.v1.GetAssistantConversationsResponse
20, // 19: teleport.assist.v1.AssistService.DeleteAssistantConversation:output_type -> google.protobuf.Empty
3, // 20: teleport.assist.v1.AssistService.GetAssistantMessages:output_type -> teleport.assist.v1.GetAssistantMessagesResponse
20, // 21: teleport.assist.v1.AssistService.CreateAssistantMessage:output_type -> google.protobuf.Empty
20, // 22: teleport.assist.v1.AssistService.UpdateAssistantConversationInfo:output_type -> google.protobuf.Empty
11, // 23: teleport.assist.v1.AssistService.IsAssistEnabled:output_type -> teleport.assist.v1.IsAssistEnabledResponse
17, // 24: teleport.assist.v1.AssistService.SearchUnifiedResources:output_type -> teleport.assist.v1.SearchUnifiedResourcesResponse
15, // 25: teleport.assist.v1.AssistEmbeddingService.GetAssistantEmbeddings:output_type -> teleport.assist.v1.GetAssistantEmbeddingsResponse
17, // [17:26] is the sub-list for method output_type
8, // [8:17] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
}
func init() { file_teleport_assist_v1_assist_proto_init() }
@@ -1403,6 +1549,30 @@ func file_teleport_assist_v1_assist_proto_init() {
return nil
}
}
file_teleport_assist_v1_assist_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SearchUnifiedResourcesRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_teleport_assist_v1_assist_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SearchUnifiedResourcesResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -1410,7 +1580,7 @@ func file_teleport_assist_v1_assist_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_teleport_assist_v1_assist_proto_rawDesc,
NumEnums: 0,
NumMessages: 16,
NumMessages: 18,
NumExtensions: 0,
NumServices: 2,
},
@@ -41,6 +41,7 @@ const (
AssistService_CreateAssistantMessage_FullMethodName = "/teleport.assist.v1.AssistService/CreateAssistantMessage"
AssistService_UpdateAssistantConversationInfo_FullMethodName = "/teleport.assist.v1.AssistService/UpdateAssistantConversationInfo"
AssistService_IsAssistEnabled_FullMethodName = "/teleport.assist.v1.AssistService/IsAssistEnabled"
AssistService_SearchUnifiedResources_FullMethodName = "/teleport.assist.v1.AssistService/SearchUnifiedResources"
)
// AssistServiceClient is the client API for AssistService service.
@@ -61,6 +62,8 @@ type AssistServiceClient interface {
UpdateAssistantConversationInfo(ctx context.Context, in *UpdateAssistantConversationInfoRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// IsAssistEnabled returns true if the assist is enabled or not on the auth level.
IsAssistEnabled(ctx context.Context, in *IsAssistEnabledRequest, opts ...grpc.CallOption) (*IsAssistEnabledResponse, error)
// SearchUnifiedResources returns a similarity-ordered list of resources from the unified resource cache.
SearchUnifiedResources(ctx context.Context, in *SearchUnifiedResourcesRequest, opts ...grpc.CallOption) (*SearchUnifiedResourcesResponse, error)
}
type assistServiceClient struct {
@@ -134,6 +137,15 @@ func (c *assistServiceClient) IsAssistEnabled(ctx context.Context, in *IsAssistE
return out, nil
}
func (c *assistServiceClient) SearchUnifiedResources(ctx context.Context, in *SearchUnifiedResourcesRequest, opts ...grpc.CallOption) (*SearchUnifiedResourcesResponse, error) {
out := new(SearchUnifiedResourcesResponse)
err := c.cc.Invoke(ctx, AssistService_SearchUnifiedResources_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// AssistServiceServer is the server API for AssistService service.
// All implementations must embed UnimplementedAssistServiceServer
// for forward compatibility
@@ -152,6 +164,8 @@ type AssistServiceServer interface {
UpdateAssistantConversationInfo(context.Context, *UpdateAssistantConversationInfoRequest) (*emptypb.Empty, error)
// IsAssistEnabled returns true if the assist is enabled or not on the auth level.
IsAssistEnabled(context.Context, *IsAssistEnabledRequest) (*IsAssistEnabledResponse, error)
// SearchUnifiedResources returns a similarity-ordered list of resources from the unified resource cache.
SearchUnifiedResources(context.Context, *SearchUnifiedResourcesRequest) (*SearchUnifiedResourcesResponse, error)
mustEmbedUnimplementedAssistServiceServer()
}
@@ -180,6 +194,9 @@ func (UnimplementedAssistServiceServer) UpdateAssistantConversationInfo(context.
func (UnimplementedAssistServiceServer) IsAssistEnabled(context.Context, *IsAssistEnabledRequest) (*IsAssistEnabledResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsAssistEnabled not implemented")
}
func (UnimplementedAssistServiceServer) SearchUnifiedResources(context.Context, *SearchUnifiedResourcesRequest) (*SearchUnifiedResourcesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SearchUnifiedResources not implemented")
}
func (UnimplementedAssistServiceServer) mustEmbedUnimplementedAssistServiceServer() {}
// UnsafeAssistServiceServer may be embedded to opt out of forward compatibility for this service.
@@ -319,6 +336,24 @@ func _AssistService_IsAssistEnabled_Handler(srv interface{}, ctx context.Context
return interceptor(ctx, in, info, handler)
}
func _AssistService_SearchUnifiedResources_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SearchUnifiedResourcesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AssistServiceServer).SearchUnifiedResources(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AssistService_SearchUnifiedResources_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AssistServiceServer).SearchUnifiedResources(ctx, req.(*SearchUnifiedResourcesRequest))
}
return interceptor(ctx, in, info, handler)
}
// AssistService_ServiceDesc is the grpc.ServiceDesc for AssistService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -354,6 +389,10 @@ var AssistService_ServiceDesc = grpc.ServiceDesc{
MethodName: "IsAssistEnabled",
Handler: _AssistService_IsAssistEnabled_Handler,
},
{
MethodName: "SearchUnifiedResources",
Handler: _AssistService_SearchUnifiedResources_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "teleport/assist/v1/assist.proto",
+20
View File
@@ -18,6 +18,7 @@ package teleport.assist.v1;
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
import "teleport/legacy/client/proto/authservice.proto";
option go_package = "github.com/gravitational/teleport/api/gen/proto/go/assist/v1;assist";
@@ -150,6 +151,22 @@ message GetAssistantEmbeddingsResponse {
repeated EmbeddedDocument embeddings = 1;
}
// SearchUnifiedResourcesRequest is a request to search for one or more resource kinds using similiarity search.
message SearchUnifiedResourcesRequest {
// query is the query used for similarity search.
string query = 1;
// limit is the number of embeddings to return (also known as k).
int32 limit = 2;
// kinds is the kind of embeddings to return (ex, node). Returns all supported kinds if empty.
repeated string kinds = 3;
}
// SearchUnifiedResourcesResponse is a response from the assistant service with a similarity-ordered list of resources.
message SearchUnifiedResourcesResponse {
// resources is the list of resources.
repeated proto.PaginatedResource resources = 1;
}
// AssistService is a service that provides an ability to communicate with the Teleport Assist.
service AssistService {
// CreateNewConversation creates a new conversation and returns the UUID of it.
@@ -172,6 +189,9 @@ service AssistService {
// IsAssistEnabled returns true if the assist is enabled or not on the auth level.
rpc IsAssistEnabled(IsAssistEnabledRequest) returns (IsAssistEnabledResponse);
// SearchUnifiedResources returns a similarity-ordered list of resources from the unified resource cache.
rpc SearchUnifiedResources(SearchUnifiedResourcesRequest) returns (SearchUnifiedResourcesResponse);
}
// AssistEmbeddingService is a service that provides an ability to communicate with the Assist Embedding service.
+29 -51
View File
@@ -41,53 +41,6 @@ import (
"github.com/gravitational/teleport/lib/utils"
)
// MockEmbedder returns embeddings based on the sha256 hash function. Those
// embeddings have no semantic meaning but ensure different embedded content
// provides different embeddings.
type MockEmbedder struct {
timesCalled map[string]int
}
func (m *MockEmbedder) ComputeEmbeddings(_ context.Context, input []string) ([]embedding.Vector64, error) {
result := make([]embedding.Vector64, len(input))
for i, text := range input {
name := strings.Split(text, "\n")[0]
m.timesCalled[name]++
hash := sha256.Sum256([]byte(text))
vector := make(embedding.Vector64, len(hash))
for j, x := range hash {
vector[j] = 1 / float64(int(x)+1)
}
result[i] = vector
}
return result, nil
}
type mockResourceGetter struct {
services.Presence
services.AccessLists
}
func (m *mockResourceGetter) GetDatabaseServers(_ context.Context, _ string, _ ...services.MarshalOption) ([]types.DatabaseServer, error) {
return nil, nil
}
func (m *mockResourceGetter) GetKubernetesServers(_ context.Context) ([]types.KubeServer, error) {
return nil, nil
}
func (m *mockResourceGetter) GetApplicationServers(_ context.Context, _ string) ([]types.AppServer, error) {
return nil, nil
}
func (m *mockResourceGetter) GetWindowsDesktops(_ context.Context, _ types.WindowsDesktopFilter) ([]types.WindowsDesktop, error) {
return nil, nil
}
func (m *mockResourceGetter) ListSAMLIdPServiceProviders(_ context.Context, _ int, _ string) ([]types.SAMLIdPServiceProvider, string, error) {
return nil, "", nil
}
func TestNodeEmbeddingGeneration(t *testing.T) {
t.Parallel()
@@ -104,8 +57,8 @@ func TestNodeEmbeddingGeneration(t *testing.T) {
})
require.NoError(t, err)
embedder := MockEmbedder{
timesCalled: make(map[string]int),
embedder := ai.MockEmbedder{
TimesCalled: make(map[string]int),
}
events := local.NewEventsService(bk)
accessLists, err := local.NewAccessListService(bk, clock)
@@ -163,7 +116,7 @@ func TestNodeEmbeddingGeneration(t *testing.T) {
nodesAcquired,
embeddings.GetAllEmbeddings(ctx))
for k, v := range embedder.timesCalled {
for k, v := range embedder.TimesCalled {
require.Equal(t, 1, v, "expected %v to be computed once, was %d", k, v)
}
@@ -184,7 +137,7 @@ func TestNodeEmbeddingGeneration(t *testing.T) {
return len(items) == numInitialNodes+1
}, 7*time.Second, 200*time.Millisecond)
for k, v := range embedder.timesCalled {
for k, v := range embedder.TimesCalled {
expected := 1
if strings.Contains(k, "node1") {
expected = 2
@@ -331,3 +284,28 @@ func Test_batchReducer_Add(t *testing.T) {
})
}
}
type mockResourceGetter struct {
services.Presence
services.AccessLists
}
func (m *mockResourceGetter) GetDatabaseServers(_ context.Context, _ string, _ ...services.MarshalOption) ([]types.DatabaseServer, error) {
return nil, nil
}
func (m *mockResourceGetter) GetKubernetesServers(_ context.Context) ([]types.KubeServer, error) {
return nil, nil
}
func (m *mockResourceGetter) GetApplicationServers(_ context.Context, _ string) ([]types.AppServer, error) {
return nil, nil
}
func (m *mockResourceGetter) GetWindowsDesktops(_ context.Context, _ types.WindowsDesktopFilter) ([]types.WindowsDesktop, error) {
return nil, nil
}
func (m *mockResourceGetter) ListSAMLIdPServiceProviders(_ context.Context, _ int, _ string) ([]types.SAMLIdPServiceProvider, string, error) {
return nil, "", nil
}
+52
View File
@@ -0,0 +1,52 @@
/*
* Copyright 2023 Gravitational, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ai
import (
"context"
"crypto/sha256"
"strings"
"sync"
"github.com/gravitational/teleport/lib/ai/embedding"
)
// MockEmbedder returns embeddings based on the sha256 hash function. Those
// embeddings have no semantic meaning but ensure different embedded content
// provides different embeddings.
type MockEmbedder struct {
mu sync.Mutex
TimesCalled map[string]int
}
func (m *MockEmbedder) ComputeEmbeddings(_ context.Context, input []string) ([]embedding.Vector64, error) {
m.mu.Lock()
defer m.mu.Unlock()
result := make([]embedding.Vector64, len(input))
for i, text := range input {
name := strings.Split(text, "\n")[0]
m.TimesCalled[name]++
hash := sha256.Sum256([]byte(text))
vector := make(embedding.Vector64, len(hash))
for j, x := range hash {
vector[j] = 1 / float64(int(x)+1)
}
result[i] = vector
}
return result, nil
}
+100 -8
View File
@@ -23,6 +23,7 @@ import (
"github.com/gravitational/trace"
"github.com/sirupsen/logrus"
"golang.org/x/exp/slices"
"google.golang.org/protobuf/types/known/emptypb"
"github.com/gravitational/teleport/api/defaults"
@@ -34,6 +35,12 @@ import (
"github.com/gravitational/teleport/lib/services"
)
const (
// maxSearchLimit is the maximum number of search results to return.
// We have a hard cap due the simplistic design of our retriever which has quadratic complexity.
maxSearchLimit = 100
)
// ServiceConfig holds configuration options for
// the assist gRPC service.
type ServiceConfig struct {
@@ -250,9 +257,37 @@ func (a *Service) GetAssistantEmbeddings(ctx context.Context, msg *assist.GetAss
// Use default values for the id and content, as we only care about the embeddings.
queryEmbeddings := embeddinglib.NewEmbedding(msg.Kind, "", embeddings[0], [32]byte{})
accessChecker := accessCheckerForKind(ctx, a, authCtx, msg.Kind)
accessChecker := makeAccessChecker(ctx, a, authCtx, msg.Kind)
documents := a.embeddings.GetRelevant(queryEmbeddings, int(msg.Limit), accessChecker)
return assembleEmbeddingResponseForKind(ctx, a, msg.Kind, documents)
return assembleEmbeddingResponse(ctx, a, documents)
}
// SearchUnifiedResources returns a similarity-ordered list of resources from the unified resource cache
func (a *Service) SearchUnifiedResources(ctx context.Context, msg *assist.SearchUnifiedResourcesRequest) (*assist.SearchUnifiedResourcesResponse, error) {
if a.embedder == nil {
return nil, trace.BadParameter("assist is not configured in auth server")
}
// Call the openAI API to get the embeddings for the query.
embeddings, err := a.embedder.ComputeEmbeddings(ctx, []string{msg.Query})
if err != nil {
return nil, trace.Wrap(err)
}
if len(embeddings) == 0 {
return nil, trace.NotFound("OpenAI embeddings returned no results")
}
authCtx, err := a.authorizer.Authorize(ctx)
if err != nil {
return nil, authz.ConvertAuthorizerError(ctx, a.log, err)
}
// Use default values for the id and content, as we only care about the embeddings.
queryEmbeddings := embeddinglib.NewEmbedding("", "", embeddings[0], [32]byte{})
limit := max(msg.Limit, maxSearchLimit)
accessChecker := makeAccessChecker(ctx, a, authCtx, msg.Kinds...)
documents := a.embeddings.GetRelevant(queryEmbeddings, int(limit), accessChecker)
return assembleSearchResponse(ctx, a, documents)
}
// userHasAccess returns true if the user should have access to the resource.
@@ -260,13 +295,68 @@ func userHasAccess(authCtx *authz.Context, req interface{ GetUsername() string }
return !authz.IsCurrentUser(*authCtx, req.GetUsername()) && !authz.HasBuiltinRole(*authCtx, string(types.RoleAdmin))
}
func assembleEmbeddingResponseForKind(ctx context.Context, a *Service, kind string, documents []*ai.Document) (*assist.GetAssistantEmbeddingsResponse, error) {
func assembleSearchResponse(ctx context.Context, a *Service, documents []*ai.Document) (*assist.SearchUnifiedResourcesResponse, error) {
resources := make([]types.ResourceWithLabels, 0, len(documents))
for _, doc := range documents {
var resource types.ResourceWithLabels
var err error
switch doc.EmbeddedKind {
case types.KindNode:
resource, err = a.resourceGetter.GetNode(ctx, defaults.Namespace, doc.GetEmbeddedID())
case types.KindKubernetesCluster:
resource, err = a.resourceGetter.GetKubernetesCluster(ctx, doc.GetEmbeddedID())
case types.KindApp:
resource, err = a.resourceGetter.GetApp(ctx, doc.GetEmbeddedID())
case types.KindDatabase:
resource, err = a.resourceGetter.GetDatabase(ctx, doc.GetEmbeddedID())
case types.KindWindowsDesktop:
desktops, err := a.resourceGetter.GetWindowsDesktops(ctx, types.WindowsDesktopFilter{
Name: doc.GetEmbeddedID(),
})
if err != nil {
return nil, trace.Wrap(err)
}
for _, d := range desktops {
if d.GetName() == doc.GetEmbeddedID() {
resource = d
break
}
}
if resource == nil {
return nil, trace.NotFound("windows desktop %q not found", doc.GetEmbeddedID())
}
default:
return nil, trace.BadParameter("resource kind %v is not supported", doc.EmbeddedKind)
}
if err != nil {
return nil, trace.Wrap(err)
}
resources = append(resources, resource)
}
paginated, err := services.MakePaginatedResources(types.KindUnifiedResource, resources)
if err != nil {
return nil, trace.Wrap(err)
}
return &assist.SearchUnifiedResourcesResponse{
Resources: paginated,
}, nil
}
func assembleEmbeddingResponse(ctx context.Context, a *Service, documents []*ai.Document) (*assist.GetAssistantEmbeddingsResponse, error) {
protoDocs := make([]*assist.EmbeddedDocument, 0, len(documents))
for _, doc := range documents {
var content []byte
switch kind {
switch doc.EmbeddedKind {
case types.KindNode:
node, err := a.resourceGetter.GetNode(ctx, defaults.Namespace, doc.GetEmbeddedID())
if err != nil {
@@ -345,23 +435,22 @@ func assembleEmbeddingResponseForKind(ctx context.Context, a *Service, kind stri
}, nil
}
func accessCheckerForKind(ctx context.Context, a *Service, authCtx *authz.Context, kind string) func(id string, embedding *embeddinglib.Embedding) bool {
func makeAccessChecker(ctx context.Context, a *Service, authCtx *authz.Context, kinds ...string) func(id string, embedding *embeddinglib.Embedding) bool {
return func(id string, embedding *embeddinglib.Embedding) bool {
if embedding.EmbeddedKind != kind {
if !slices.Contains(kinds, embedding.EmbeddedKind) && len(kinds) > 0 {
return false
}
var resource services.AccessCheckable
var err error
switch kind {
switch embedding.EmbeddedKind {
case types.KindNode:
resource, err = a.resourceGetter.GetNode(ctx, defaults.Namespace, embedding.GetEmbeddedID())
if err != nil {
a.log.Tracef("failed to get node %q: %v", embedding.GetName(), err)
return false
}
case types.KindKubernetesCluster:
resource, err = a.resourceGetter.GetKubernetesCluster(ctx, embedding.GetEmbeddedID())
if err != nil {
@@ -400,6 +489,9 @@ func accessCheckerForKind(ctx context.Context, a *Service, authCtx *authz.Contex
a.log.Tracef("failed to find windows desktop %q: %v", embedding.GetName(), err)
return false
}
default:
a.log.Tracef("resource kind %v is not supported", embedding.EmbeddedKind)
return false
}
return authCtx.Checker.CheckAccess(resource, services.AccessState{MFAVerified: true}) == nil
+137 -10
View File
@@ -19,18 +19,25 @@ package assistv1_test
import (
"context"
"testing"
"time"
"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/gravitational/teleport"
assistpb "github.com/gravitational/teleport/api/gen/proto/go/assist/v1"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/utils/retryutils"
"github.com/gravitational/teleport/lib/ai"
"github.com/gravitational/teleport/lib/assist"
"github.com/gravitational/teleport/lib/auth/assist/assistv1"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/backend/memory"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/services/local"
"github.com/gravitational/teleport/lib/tlsca"
@@ -268,6 +275,42 @@ func TestService_InsertAssistantMessage(t *testing.T) {
}
}
func TestService_SearchUnifiedResources(t *testing.T) {
t.Parallel()
tests := []struct {
username string
req *assistpb.SearchUnifiedResourcesRequest
returnedLen int
}{
{
username: defaultUser,
req: &assistpb.SearchUnifiedResourcesRequest{
Kinds: []string{types.KindNode},
},
returnedLen: 2,
},
{
username: noAccessUser,
req: &assistpb.SearchUnifiedResourcesRequest{
Kinds: []string{types.KindNode},
},
returnedLen: 0,
},
}
for _, tt := range tests {
t.Run(tt.username, func(t *testing.T) {
ctxs, svc := initSvc(t)
require.Eventually(t, func() bool {
resp, err := svc.SearchUnifiedResources(ctxs[tt.username], tt.req)
require.NoError(t, err)
return tt.returnedLen == len(resp.GetResources())
}, 5*time.Second, 100*time.Millisecond)
})
}
}
func initSvc(t *testing.T) (map[string]context.Context, *assistv1.Service) {
ctx := context.Background()
backend, err := memory.New(memory.Config{})
@@ -278,6 +321,7 @@ func initSvc(t *testing.T) (map[string]context.Context, *assistv1.Service) {
trustSvc := local.NewCAService(backend)
roleSvc := local.NewAccessService(backend)
userSvc := local.NewIdentityService(backend)
presenceSvc := local.NewPresenceService(backend)
require.NoError(t, clusterConfigSvc.SetAuthPreference(ctx, types.DefaultAuthPreference()))
require.NoError(t, clusterConfigSvc.SetClusterAuditConfig(ctx, types.DefaultClusterAuditConfig()))
@@ -289,13 +333,27 @@ func initSvc(t *testing.T) (map[string]context.Context, *assistv1.Service) {
services.Trust
services.RoleGetter
services.UserGetter
services.Presence
}{
ClusterConfiguration: clusterConfigSvc,
Trust: trustSvc,
RoleGetter: roleSvc,
UserGetter: userSvc,
Presence: presenceSvc,
}
n1, err := types.NewServer("node-1", types.KindNode, types.ServerSpecV2{})
require.NoError(t, err)
n2, err := types.NewServer("node-2", types.KindNode, types.ServerSpecV2{})
require.NoError(t, err)
_, err = presenceSvc.UpsertNode(ctx, n1)
require.NoError(t, err)
_, err = presenceSvc.UpsertNode(ctx, n2)
require.NoError(t, err)
accesslistSvc, err := local.NewAccessListService(backend, clockwork.NewFakeClock())
require.NoError(t, err)
accessService := local.NewAccessService(backend)
eventService := local.NewEventsService(backend)
lockWatcher, err := services.NewLockWatcher(ctx, services.LockWatcherConfig{
@@ -318,11 +376,17 @@ func initSvc(t *testing.T) (map[string]context.Context, *assistv1.Service) {
role, err := types.NewRole("allow-rules", types.RoleSpecV6{
Allow: types.RoleConditions{
Namespaces: []string{},
NodeLabels: types.Labels{types.Wildcard: []string{types.Wildcard}},
Rules: []types.Rule{
{
Resources: []string{types.KindAssistant},
Verbs: []string{types.VerbList, types.VerbRead, types.VerbUpdate, types.VerbCreate, types.VerbDelete},
},
{
Resources: []string{types.KindNode},
Verbs: []string{types.VerbList, types.VerbRead},
},
},
},
})
@@ -358,36 +422,99 @@ func initSvc(t *testing.T) (map[string]context.Context, *assistv1.Service) {
ctxs[user.GetName()] = ctx
}
embedder := ai.MockEmbedder{
TimesCalled: make(map[string]int),
}
embeddings := &ai.SimpleRetriever{}
embeddingSrv := local.NewEmbeddingsService(backend)
svc, err := assistv1.NewService(&assistv1.ServiceConfig{
Backend: local.NewAssistService(backend),
Authorizer: authorizer,
Embeddings: &ai.SimpleRetriever{},
ResourceGetter: &resourceGetterFake{},
Backend: local.NewAssistService(backend),
Authorizer: authorizer,
Embeddings: embeddings,
ResourceGetter: &resourceGetterAllImpl{
PresenceService: presenceSvc,
AccessLists: accesslistSvc,
},
Embedder: &embedder,
})
require.NoError(t, err)
unifiedResourcesCache, err := services.NewUnifiedResourceCache(ctx, services.UnifiedResourceCacheConfig{
ResourceWatcherConfig: services.ResourceWatcherConfig{
QueueSize: defaults.UnifiedResourcesQueueSize,
Component: teleport.ComponentUnifiedResource,
Client: eventService,
MaxStaleness: time.Second,
},
ResourceGetter: &resourceGetterAllImpl{
PresenceService: presenceSvc,
AccessLists: accesslistSvc,
},
})
require.NoError(t, err)
log.Debugf("Starting embedding watcher")
embeddingProcessor := ai.NewEmbeddingProcessor(&ai.EmbeddingProcessorConfig{
AIClient: &embedder,
EmbeddingsRetriever: embeddings,
EmbeddingSrv: embeddingSrv,
NodeSrv: unifiedResourcesCache,
Jitter: retryutils.NewFullJitter(),
Log: log.NewEntry(log.StandardLogger()),
})
log.Debugf("Starting embedding processor")
embeddingProcessorCtx, embeddingProcessorCancel := context.WithCancel(context.Background())
go embeddingProcessor.Run(embeddingProcessorCtx, time.Millisecond*100, time.Millisecond*100)
t.Cleanup(embeddingProcessorCancel)
return ctxs, svc
}
type resourceGetterFake struct {
type resourceGetterAllImpl struct {
*local.PresenceService
services.AccessLists
}
func (g *resourceGetterFake) GetNode(ctx context.Context, namespace, name string) (types.Server, error) {
func (g *resourceGetterAllImpl) GetKubernetesCluster(ctx context.Context, name string) (types.KubeCluster, error) {
kubeServers, err := g.PresenceService.GetKubernetesServers(ctx)
if err != nil {
return nil, err
}
for _, kubeServer := range kubeServers {
if kubeServer.GetName() == name {
return kubeServer.GetCluster(), nil
}
}
return nil, trace.NotFound("cluster not found")
}
func (g *resourceGetterAllImpl) GetApp(ctx context.Context, name string) (types.Application, error) {
return nil, nil
}
func (g *resourceGetterFake) GetKubernetesCluster(ctx context.Context, name string) (types.KubeCluster, error) {
func (g *resourceGetterAllImpl) GetDatabase(ctx context.Context, name string) (types.Database, error) {
return nil, nil
}
func (g *resourceGetterFake) GetApp(ctx context.Context, name string) (types.Application, error) {
func (g *resourceGetterAllImpl) GetWindowsDesktops(ctx context.Context, _ types.WindowsDesktopFilter) ([]types.WindowsDesktop, error) {
return nil, nil
}
func (g *resourceGetterFake) GetDatabase(ctx context.Context, name string) (types.Database, error) {
func (m *resourceGetterAllImpl) GetDatabaseServers(_ context.Context, _ string, _ ...services.MarshalOption) ([]types.DatabaseServer, error) {
return nil, nil
}
func (g *resourceGetterFake) GetWindowsDesktops(ctx context.Context, _ types.WindowsDesktopFilter) ([]types.WindowsDesktop, error) {
func (m *resourceGetterAllImpl) GetKubernetesServers(_ context.Context) ([]types.KubeServer, error) {
return nil, nil
}
func (m *resourceGetterAllImpl) GetApplicationServers(_ context.Context, _ string) ([]types.AppServer, error) {
return nil, nil
}
func (m *resourceGetterAllImpl) ListSAMLIdPServiceProviders(_ context.Context, _ int, _ string) ([]types.SAMLIdPServiceProvider, string, error) {
return nil, "", nil
}
+1 -106
View File
@@ -1501,111 +1501,6 @@ func (a *ServerWithRoles) GetNode(ctx context.Context, namespace, name string) (
return node, nil
}
func (s *ServerWithRoles) MakePaginatedResources(requestType string, resources []types.ResourceWithLabels) ([]*proto.PaginatedResource, error) {
paginatedResources := make([]*proto.PaginatedResource, 0, len(resources))
for _, resource := range resources {
var protoResource *proto.PaginatedResource
resourceKind := requestType
if requestType == types.KindUnifiedResource {
resourceKind = resource.GetKind()
}
switch resourceKind {
case types.KindDatabaseServer:
database, ok := resource.(*types.DatabaseServerV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_DatabaseServer{DatabaseServer: database}}
case types.KindDatabaseService:
databaseService, ok := resource.(*types.DatabaseServiceV1)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_DatabaseService{DatabaseService: databaseService}}
case types.KindAppServer:
app, ok := resource.(*types.AppServerV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_AppServer{AppServer: app}}
case types.KindNode:
srv, ok := resource.(*types.ServerV2)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_Node{Node: srv}}
case types.KindKubeServer:
srv, ok := resource.(*types.KubernetesServerV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_KubernetesServer{KubernetesServer: srv}}
case types.KindWindowsDesktop:
desktop, ok := resource.(*types.WindowsDesktopV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_WindowsDesktop{WindowsDesktop: desktop}}
case types.KindWindowsDesktopService:
desktopService, ok := resource.(*types.WindowsDesktopServiceV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_WindowsDesktopService{WindowsDesktopService: desktopService}}
case types.KindKubernetesCluster:
cluster, ok := resource.(*types.KubernetesClusterV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_KubeCluster{KubeCluster: cluster}}
case types.KindUserGroup:
userGroup, ok := resource.(*types.UserGroupV1)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_UserGroup{UserGroup: userGroup}}
case types.KindSAMLIdPServiceProvider, types.KindAppOrSAMLIdPServiceProvider:
switch appOrSP := resource.(type) {
case *types.AppServerV3:
protoResource = &proto.PaginatedResource{
Resource: &proto.PaginatedResource_AppServerOrSAMLIdPServiceProvider{
AppServerOrSAMLIdPServiceProvider: &types.AppServerOrSAMLIdPServiceProviderV1{
Resource: &types.AppServerOrSAMLIdPServiceProviderV1_AppServer{
AppServer: appOrSP,
},
},
}}
case *types.SAMLIdPServiceProviderV1:
protoResource = &proto.PaginatedResource{
Resource: &proto.PaginatedResource_AppServerOrSAMLIdPServiceProvider{
AppServerOrSAMLIdPServiceProvider: &types.AppServerOrSAMLIdPServiceProviderV1{
Resource: &types.AppServerOrSAMLIdPServiceProviderV1_SAMLIdPServiceProvider{
SAMLIdPServiceProvider: appOrSP,
},
},
}}
default:
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
default:
return nil, trace.NotImplemented("resource type %s doesn't support pagination", resource.GetKind())
}
paginatedResources = append(paginatedResources, protoResource)
}
return paginatedResources, nil
}
// ListUnifiedResources returns a paginated list of unified resources filtered by user access.
func (a *ServerWithRoles) ListUnifiedResources(ctx context.Context, req *proto.ListUnifiedResourcesRequest) (*proto.ListUnifiedResourcesResponse, error) {
// Fetch full list of resources in the backend.
@@ -1726,7 +1621,7 @@ func (a *ServerWithRoles) ListUnifiedResources(ctx context.Context, req *proto.L
return nil, trace.Wrap(err)
}
paginatedResources, err := a.MakePaginatedResources(types.KindUnifiedResource, resp.Resources)
paginatedResources, err := services.MakePaginatedResources(types.KindUnifiedResource, resp.Resources)
if err != nil {
return nil, trace.Wrap(err, "making paginated unified resources")
}
+1 -1
View File
@@ -4404,7 +4404,7 @@ func (g *GRPCServer) ListResources(ctx context.Context, req *authpb.ListResource
return nil, trace.Wrap(err)
}
paginatedResources, err := auth.MakePaginatedResources(req.ResourceType, resp.Resources)
paginatedResources, err := services.MakePaginatedResources(req.ResourceType, resp.Resources)
if err != nil {
return nil, trace.Wrap(err, "making paginated resources")
}
+114 -8
View File
@@ -26,6 +26,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/client/proto"
apidefaults "github.com/gravitational/teleport/api/defaults"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/accesslist"
@@ -33,6 +34,9 @@ import (
"github.com/gravitational/teleport/lib/utils"
)
// UnifiedResourceKinds is a list of all kinds that are stored in the unified resource cache.
var UnifiedResourceKinds []string = []string{types.KindNode, types.KindKubeServer, types.KindDatabaseServer, types.KindAppServer, types.KindSAMLIdPServiceProvider, types.KindWindowsDesktop, types.KindAccessList}
// UnifiedResourceCacheConfig is used to configure a UnifiedResourceCache
type UnifiedResourceCacheConfig struct {
// BTreeDegree is a degree of B-Tree, 2 for example, will create a
@@ -485,15 +489,12 @@ func (c *UnifiedResourceCache) processEventAndUpdateCurrent(ctx context.Context,
// resourceKinds returns a list of resources to be watched.
func (c *UnifiedResourceCache) resourceKinds() []types.WatchKind {
return []types.WatchKind{
{Kind: types.KindNode},
{Kind: types.KindDatabaseServer},
{Kind: types.KindAppServer},
{Kind: types.KindSAMLIdPServiceProvider},
{Kind: types.KindWindowsDesktop},
{Kind: types.KindKubeServer},
{Kind: types.KindAccessList},
watchKinds := make([]types.WatchKind, 0, len(UnifiedResourceKinds))
for _, kind := range UnifiedResourceKinds {
watchKinds = append(watchKinds, types.WatchKind{Kind: kind})
}
return watchKinds
}
func (c *UnifiedResourceCache) defineCollectorAsInitialized() {
@@ -543,3 +544,108 @@ type item struct {
const (
prefix = "unified_resource"
)
// MakePaginatedResources converts a list of resources into a list of paginated proto representations.
func MakePaginatedResources(requestType string, resources []types.ResourceWithLabels) ([]*proto.PaginatedResource, error) {
paginatedResources := make([]*proto.PaginatedResource, 0, len(resources))
for _, resource := range resources {
var protoResource *proto.PaginatedResource
resourceKind := requestType
if requestType == types.KindUnifiedResource {
resourceKind = resource.GetKind()
}
switch resourceKind {
case types.KindDatabaseServer:
database, ok := resource.(*types.DatabaseServerV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_DatabaseServer{DatabaseServer: database}}
case types.KindDatabaseService:
databaseService, ok := resource.(*types.DatabaseServiceV1)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_DatabaseService{DatabaseService: databaseService}}
case types.KindAppServer:
app, ok := resource.(*types.AppServerV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_AppServer{AppServer: app}}
case types.KindNode:
srv, ok := resource.(*types.ServerV2)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_Node{Node: srv}}
case types.KindKubeServer:
srv, ok := resource.(*types.KubernetesServerV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_KubernetesServer{KubernetesServer: srv}}
case types.KindWindowsDesktop:
desktop, ok := resource.(*types.WindowsDesktopV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_WindowsDesktop{WindowsDesktop: desktop}}
case types.KindWindowsDesktopService:
desktopService, ok := resource.(*types.WindowsDesktopServiceV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_WindowsDesktopService{WindowsDesktopService: desktopService}}
case types.KindKubernetesCluster:
cluster, ok := resource.(*types.KubernetesClusterV3)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_KubeCluster{KubeCluster: cluster}}
case types.KindUserGroup:
userGroup, ok := resource.(*types.UserGroupV1)
if !ok {
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
protoResource = &proto.PaginatedResource{Resource: &proto.PaginatedResource_UserGroup{UserGroup: userGroup}}
case types.KindSAMLIdPServiceProvider, types.KindAppOrSAMLIdPServiceProvider:
switch appOrSP := resource.(type) {
case *types.AppServerV3:
protoResource = &proto.PaginatedResource{
Resource: &proto.PaginatedResource_AppServerOrSAMLIdPServiceProvider{
AppServerOrSAMLIdPServiceProvider: &types.AppServerOrSAMLIdPServiceProviderV1{
Resource: &types.AppServerOrSAMLIdPServiceProviderV1_AppServer{
AppServer: appOrSP,
},
},
}}
case *types.SAMLIdPServiceProviderV1:
protoResource = &proto.PaginatedResource{
Resource: &proto.PaginatedResource_AppServerOrSAMLIdPServiceProvider{
AppServerOrSAMLIdPServiceProvider: &types.AppServerOrSAMLIdPServiceProviderV1{
Resource: &types.AppServerOrSAMLIdPServiceProviderV1_SAMLIdPServiceProvider{
SAMLIdPServiceProvider: appOrSP,
},
},
}}
default:
return nil, trace.BadParameter("%s has invalid type %T", resourceKind, resource)
}
default:
return nil, trace.NotImplemented("resource type %s doesn't support pagination", resource.GetKind())
}
paginatedResources = append(paginatedResources, protoResource)
}
return paginatedResources, nil
}