diff --git a/api/gen/proto/go/teleport/integration/v1/awsoidc_service.pb.go b/api/gen/proto/go/teleport/integration/v1/awsoidc_service.pb.go index cec0138373c3c..8630cd64a4076 100644 --- a/api/gen/proto/go/teleport/integration/v1/awsoidc_service.pb.go +++ b/api/gen/proto/go/teleport/integration/v1/awsoidc_service.pb.go @@ -36,6 +36,8 @@ const ( ) // ListEICERequest is a request for a paginated list of AWS EC2 Instance Connect Endpoints. +// +// Deprecated: Marked as deprecated in teleport/integration/v1/awsoidc_service.proto. type ListEICERequest struct { state protoimpl.MessageState `protogen:"open.v1"` // Integration is the AWS OIDC Integration name. @@ -113,6 +115,8 @@ func (x *ListEICERequest) GetNextToken() string { } // EC2InstanceConnectEndpoint is a representation of a Amazon VPC EC2 Instance Connect Endpoint. +// +// Deprecated: Marked as deprecated in teleport/integration/v1/awsoidc_service.proto. type EC2InstanceConnectEndpoint struct { state protoimpl.MessageState `protogen:"open.v1"` // Name is the endpoint name. @@ -206,6 +210,8 @@ func (x *EC2InstanceConnectEndpoint) GetVpcId() string { } // ListEICEResponse contains a page of AWS EC2 Instance Connect Endpoints. +// +// Deprecated: Marked as deprecated in teleport/integration/v1/awsoidc_service.proto. type ListEICEResponse struct { state protoimpl.MessageState `protogen:"open.v1"` // EC2ICEs contains the page of EC2 Instance Connect Endpoints. @@ -271,6 +277,8 @@ func (x *ListEICEResponse) GetNextToken() string { } // CreateEICERequest contains the required fields to create an AWS EC2 Instance Connect Endpoint. +// +// Deprecated: Marked as deprecated in teleport/integration/v1/awsoidc_service.proto. type CreateEICERequest struct { state protoimpl.MessageState `protogen:"open.v1"` // Integration is the AWS OIDC Integration name. @@ -338,6 +346,8 @@ func (x *CreateEICERequest) GetEndpoints() []*EC2ICEndpoint { } // EC2ICEndpoint contains the information for a single Endpoint to be created. +// +// Deprecated: Marked as deprecated in teleport/integration/v1/awsoidc_service.proto. type EC2ICEndpoint struct { state protoimpl.MessageState `protogen:"open.v1"` // Name is the endpoint name. @@ -403,6 +413,8 @@ func (x *EC2ICEndpoint) GetSecurityGroupIds() []string { } // CreateEICEResponse is a request to create a VPC Endpoint of EC2 Instance Connect Endpoint type. +// +// Deprecated: Marked as deprecated in teleport/integration/v1/awsoidc_service.proto. type CreateEICEResponse struct { state protoimpl.MessageState `protogen:"open.v1"` // Name is the Endpoint ID. @@ -2257,6 +2269,8 @@ func (x *EnrollEKSClustersResponse) GetResults() []*EnrollEKSClusterResult { } // ListEC2Request is a request for a paginated list of AWS EC2 instances. +// +// Deprecated: Marked as deprecated in teleport/integration/v1/awsoidc_service.proto. type ListEC2Request struct { state protoimpl.MessageState `protogen:"open.v1"` // Integration is the AWS OIDC Integration name. @@ -2324,6 +2338,8 @@ func (x *ListEC2Request) GetNextToken() string { } // ListEC2Response contains a page of AWS EC2 instances represented as Nodes. +// +// Deprecated: Marked as deprecated in teleport/integration/v1/awsoidc_service.proto. type ListEC2Response struct { state protoimpl.MessageState `protogen:"open.v1"` // Servers contains the page of EC2. @@ -2748,7 +2764,7 @@ var file_teleport_integration_v1_awsoidc_service_proto_rawDesc = []byte{ 0x17, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x83, 0x01, 0x0a, 0x0f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x87, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x49, 0x43, 0x45, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, @@ -2757,466 +2773,469 @@ var file_teleport_integration_v1_awsoidc_service_proto_rawDesc = []byte{ 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x70, 0x63, 0x49, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x22, 0xc6, 0x01, 0x0a, 0x1a, 0x45, 0x43, 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, - 0x25, 0x0a, 0x0e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x6c, 0x69, 0x6e, - 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x76, 0x70, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x70, 0x63, 0x49, 0x64, 0x22, 0xa7, 0x01, 0x0a, 0x10, 0x4c, - 0x69, 0x73, 0x74, 0x45, 0x49, 0x43, 0x45, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4d, 0x0a, 0x07, 0x65, 0x63, 0x32, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x43, 0x32, 0x49, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x65, 0x63, 0x32, 0x69, 0x63, 0x65, 0x73, 0x12, 0x25, - 0x0a, 0x0e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, - 0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x93, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, - 0x49, 0x43, 0x45, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, - 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, - 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, - 0x31, 0x2e, 0x45, 0x43, 0x32, 0x49, 0x43, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, - 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x6e, 0x0a, 0x0d, 0x45, 0x43, + 0x6e, 0x3a, 0x02, 0x18, 0x01, 0x22, 0xca, 0x01, 0x0a, 0x1a, 0x45, 0x43, 0x32, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x23, + 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x61, 0x73, + 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x75, + 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, + 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x76, 0x70, 0x63, 0x5f, 0x69, + 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x70, 0x63, 0x49, 0x64, 0x3a, 0x02, + 0x18, 0x01, 0x22, 0xab, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x49, 0x43, 0x45, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x07, 0x65, 0x63, 0x32, 0x69, 0x63, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x45, 0x43, 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x65, + 0x63, 0x32, 0x69, 0x63, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1d, 0x0a, + 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x02, 0x18, 0x01, + 0x22, 0x97, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x49, 0x43, 0x45, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, + 0x12, 0x44, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x43, + 0x32, 0x49, 0x43, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x09, 0x65, 0x6e, 0x64, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x3a, 0x02, 0x18, 0x01, 0x22, 0x72, 0x0a, 0x0d, 0x45, 0x43, 0x32, 0x49, 0x43, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, - 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x22, 0x7d, 0x0a, 0x12, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x45, 0x49, 0x43, 0x45, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x53, 0x0a, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x43, 0x32, 0x49, 0x43, 0x45, - 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0xbb, 0x01, 0x0a, 0x14, 0x4c, 0x69, - 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, - 0x72, 0x64, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x72, 0x64, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x12, 0x15, 0x0a, 0x06, 0x76, 0x70, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x70, 0x63, 0x49, 0x64, 0x22, 0x67, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x44, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x2f, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, - 0x62, 0x61, 0x73, 0x65, 0x56, 0x33, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, - 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x22, 0x8b, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, - 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x76, 0x70, 0x63, 0x5f, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x70, 0x63, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x4d, - 0x0a, 0x15, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, - 0x75, 0x6c, 0x65, 0x43, 0x49, 0x44, 0x52, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x69, 0x64, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x57, 0x0a, - 0x18, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x75, - 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x44, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x80, 0x02, 0x0a, 0x11, 0x53, 0x65, 0x63, 0x75, 0x72, - 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x0b, - 0x69, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x69, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1b, 0x0a, - 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x08, 0x66, 0x72, 0x6f, 0x6d, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6f, - 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x74, 0x6f, 0x50, - 0x6f, 0x72, 0x74, 0x12, 0x44, 0x0a, 0x05, 0x63, 0x69, 0x64, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, - 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x43, 0x49, - 0x44, 0x52, 0x52, 0x05, 0x63, 0x69, 0x64, 0x72, 0x73, 0x12, 0x4e, 0x0a, 0x09, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x44, 0x52, - 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x22, 0xf9, 0x01, 0x0a, 0x0d, 0x53, 0x65, - 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x4f, 0x0a, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x72, 0x75, 0x6c, - 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0c, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x75, 0x6c, - 0x65, 0x73, 0x12, 0x51, 0x0a, 0x0e, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x72, - 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, - 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, - 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, - 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x84, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, - 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, + 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x3a, 0x02, 0x18, 0x01, 0x22, 0x81, + 0x01, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x49, 0x43, 0x45, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x53, 0x0a, 0x11, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x43, 0x32, 0x49, 0x43, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x10, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x3a, 0x02, + 0x18, 0x01, 0x22, 0xbb, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, - 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x76, 0x70, 0x63, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x70, 0x63, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x59, 0x0a, 0x06, 0x53, - 0x75, 0x62, 0x6e, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x76, 0x61, - 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, - 0x74, 0x79, 0x5a, 0x6f, 0x6e, 0x65, 0x22, 0x6f, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, - 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, - 0x07, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x52, - 0x07, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, - 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x6a, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x56, - 0x50, 0x43, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, - 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, - 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x22, 0x29, 0x0a, 0x03, 0x56, 0x50, 0x43, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x63, - 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x50, 0x43, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x76, 0x70, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x50, 0x43, 0x52, 0x04, - 0x76, 0x70, 0x63, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x22, 0xc0, 0x02, 0x0a, 0x1c, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x44, 0x61, - 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x64, 0x73, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x64, 0x73, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x07, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, + 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x76, 0x70, 0x63, + 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x70, 0x63, 0x49, 0x64, + 0x22, 0x67, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x64, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x56, 0x33, 0x52, + 0x09, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, + 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x8b, 0x01, 0x0a, 0x19, 0x4c, 0x69, + 0x73, 0x74, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, + 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, + 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x76, 0x70, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x70, 0x63, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, + 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x4d, 0x0a, 0x15, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x43, 0x49, 0x44, 0x52, + 0x12, 0x12, 0x0a, 0x04, 0x63, 0x69, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x63, 0x69, 0x64, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x57, 0x0a, 0x18, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, + 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x49, 0x44, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x20, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x80, 0x02, 0x0a, 0x11, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x70, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x70, + 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x66, 0x72, 0x6f, 0x6d, 0x50, + 0x6f, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6f, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x74, 0x6f, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x44, 0x0a, 0x05, + 0x63, 0x69, 0x64, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x43, 0x49, 0x44, 0x52, 0x52, 0x05, 0x63, 0x69, 0x64, + 0x72, 0x73, 0x12, 0x4e, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x75, 0x6c, + 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x44, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, + 0x64, 0x73, 0x22, 0xf9, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4f, 0x0a, 0x0d, 0x69, 0x6e, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, + 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0c, 0x69, + 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x51, 0x0a, 0x0e, 0x6f, + 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, + 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x0d, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x8c, + 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, + 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0e, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x1d, + 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x84, 0x01, + 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x22, - 0x0a, 0x0d, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x73, 0x6b, 0x52, 0x6f, 0x6c, 0x65, 0x41, - 0x72, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, - 0x1a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x17, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4a, 0x6f, 0x69, - 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x5a, 0x0a, 0x0b, 0x64, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x38, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xb6, 0x01, 0x0a, 0x1f, 0x44, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x12, 0x15, 0x0a, 0x06, 0x76, 0x70, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x70, 0x63, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x75, 0x62, - 0x6e, 0x65, 0x74, 0x49, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, - 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, - 0x74, 0x0a, 0x1d, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x72, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x72, - 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x73, - 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x13, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x55, 0x72, 0x6c, 0x22, 0x7e, 0x0a, 0x23, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, - 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, - 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, - 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xc2, 0x01, 0x0a, 0x17, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x73, - 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x55, 0x72, 0x6c, 0x12, 0x32, 0x0a, 0x15, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2b, 0x0a, - 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x22, 0xb5, 0x01, 0x0a, 0x24, 0x4c, - 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, - 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x1a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x5f, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x15, + 0x0a, 0x06, 0x76, 0x70, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x70, 0x63, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x59, 0x0a, 0x06, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x61, + 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5a, 0x6f, 0x6e, 0x65, 0x22, + 0x6f, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x18, 0x64, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x22, 0x83, 0x03, 0x0a, 0x14, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, - 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, - 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, - 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x27, - 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x75, 0x62, - 0x6e, 0x65, 0x74, 0x49, 0x64, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x72, - 0x6f, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, - 0x61, 0x73, 0x6b, 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x72, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x1a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x64, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x14, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0xbd, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x70, - 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x72, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x41, 0x72, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, - 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x41, 0x72, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x64, 0x65, 0x66, - 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x11, 0x74, 0x61, 0x73, 0x6b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x41, 0x72, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, - 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x73, 0x68, - 0x62, 0x6f, 0x61, 0x72, 0x64, 0x55, 0x72, 0x6c, 0x22, 0xfe, 0x02, 0x0a, 0x18, 0x45, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x22, 0x6a, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x50, 0x43, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, + 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x29, 0x0a, 0x03, + 0x56, 0x50, 0x43, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x63, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x56, + 0x50, 0x43, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x76, + 0x70, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x50, 0x43, 0x52, 0x04, 0x76, 0x70, 0x63, 0x73, 0x12, 0x1d, 0x0a, + 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xc0, 0x02, 0x0a, + 0x1c, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, + 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0d, 0x74, 0x61, 0x73, 0x6b, 0x5f, + 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x74, 0x61, 0x73, 0x6b, 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x72, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x1a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x64, 0x65, 0x70, 0x6c, + 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x5a, 0x0a, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, + 0xb6, 0x01, 0x0a, 0x1f, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x15, 0x0a, 0x06, 0x76, 0x70, 0x63, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x70, 0x63, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x73, 0x12, + 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, + 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x74, 0x0a, 0x1d, 0x44, 0x65, 0x70, 0x6c, + 0x6f, 0x79, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x72, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, + 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x55, 0x72, 0x6c, 0x22, 0x7e, + 0x0a, 0x23, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x44, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, - 0x2a, 0x0a, 0x11, 0x65, 0x6b, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x6b, 0x73, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x41, 0x70, 0x70, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x12, 0x23, 0x0a, - 0x0d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x65, 0x0a, 0x0c, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x78, 0x74, 0x72, - 0x61, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x65, 0x78, - 0x74, 0x72, 0x61, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x45, 0x78, 0x74, - 0x72, 0x61, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x98, 0x01, 0x0a, 0x16, 0x45, 0x6e, - 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x65, 0x6b, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x65, 0x6b, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, - 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, - 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x22, 0x66, 0x0a, 0x19, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x4b, - 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x49, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x69, 0x0a, 0x0e, - 0x4c, 0x69, 0x73, 0x74, 0x45, 0x43, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, - 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, - 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x5b, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x45, - 0x43, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x07, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x32, 0x52, 0x07, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x71, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x4b, 0x53, 0x43, + 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xc2, + 0x01, 0x0a, 0x17, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x32, + 0x0a, 0x15, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x55, + 0x72, 0x6c, 0x12, 0x32, 0x0a, 0x15, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x13, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x22, 0xb5, 0x01, 0x0a, 0x24, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, + 0x6f, 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x1a, + 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x18, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, + 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x83, 0x03, 0x0a, 0x14, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x27, + 0x0a, 0x0f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x73, 0x12, + 0x22, 0x0a, 0x0d, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x6e, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x73, 0x6b, 0x52, 0x6f, 0x6c, 0x65, + 0x41, 0x72, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, + 0x0a, 0x1a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6a, 0x6f, 0x69, + 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x17, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4a, 0x6f, + 0x69, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x22, 0xbd, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x63, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x72, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x72, 0x6e, 0x12, 0x2e, 0x0a, + 0x13, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x74, 0x61, 0x73, 0x6b, + 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x6e, 0x12, 0x32, 0x0a, + 0x15, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x55, 0x72, + 0x6c, 0x22, 0xfe, 0x02, 0x0a, 0x18, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, - 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xe2, 0x03, 0x0a, 0x0a, 0x45, 0x4b, 0x53, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, - 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, - 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x61, 0x72, 0x6e, 0x12, 0x47, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, - 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x54, 0x0a, - 0x0b, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x4b, 0x53, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x65, - 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6a, 0x6f, 0x69, 0x6e, 0x4c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x65, - 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x65, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, - 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, - 0x64, 0x65, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x6b, 0x73, 0x5f, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x6b, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, + 0x70, 0x70, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x70, 0x70, 0x44, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x65, 0x0a, 0x0c, 0x65, + 0x78, 0x74, 0x72, 0x61, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x42, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, + 0x6c, 0x6c, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x65, 0x78, 0x74, 0x72, 0x61, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x45, 0x78, 0x74, 0x72, 0x61, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0x98, 0x01, 0x0a, 0x16, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x4b, 0x53, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x28, 0x0a, + 0x10, 0x65, 0x6b, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6b, 0x73, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, + 0x0a, 0x0a, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x66, 0x0a, + 0x19, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x07, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x4b, 0x53, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x6d, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x43, 0x32, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, + 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, + 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x3a, 0x02, 0x18, 0x01, 0x22, 0x5f, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x43, 0x32, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x32, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x3a, 0x02, 0x18, 0x01, 0x22, 0x71, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x4b, 0x53, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, + 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xe2, 0x03, 0x0a, 0x0a, 0x45, 0x4b, 0x53, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, + 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, + 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x47, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x54, + 0x0a, 0x0b, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x4b, + 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6a, 0x6f, 0x69, 0x6e, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x34, 0x0a, 0x16, + 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x65, 0x6e, + 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x12, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x6f, 0x64, 0x65, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3d, + 0x0a, 0x0f, 0x4a, 0x6f, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3d, 0x0a, - 0x0f, 0x4a, 0x6f, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x79, 0x0a, 0x17, - 0x4c, 0x69, 0x73, 0x74, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x08, - 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, 0x74, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, - 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x4a, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, - 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f, 0x6c, 0x65, - 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x6f, 0x6c, 0x65, - 0x41, 0x72, 0x6e, 0x22, 0x58, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x61, 0x72, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x32, 0xce, 0x0b, - 0x0a, 0x0e, 0x41, 0x57, 0x53, 0x4f, 0x49, 0x44, 0x43, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x5f, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x49, 0x43, 0x45, 0x12, 0x28, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x49, 0x43, 0x45, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x49, 0x43, 0x45, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x65, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x49, 0x43, 0x45, 0x12, - 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x45, 0x49, 0x43, 0x45, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x49, 0x43, 0x45, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, - 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x32, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, - 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, - 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x5f, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x50, 0x43, 0x73, 0x12, 0x28, 0x2e, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x79, 0x0a, + 0x17, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x08, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, + 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, + 0x65, 0x78, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x4a, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, + 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f, 0x6c, + 0x65, 0x5f, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x6f, 0x6c, + 0x65, 0x41, 0x72, 0x6e, 0x22, 0x58, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x61, 0x72, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x32, 0xdd, + 0x0b, 0x0a, 0x0e, 0x41, 0x57, 0x53, 0x4f, 0x49, 0x44, 0x43, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x64, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x49, 0x43, 0x45, 0x12, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x50, 0x43, 0x73, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x49, 0x43, 0x45, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x50, 0x43, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x86, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x35, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, - 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x9b, 0x01, 0x0a, 0x1c, - 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, - 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, - 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x0d, 0x44, 0x65, 0x70, - 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2d, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x49, 0x43, 0x45, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x6a, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x45, 0x49, 0x43, 0x45, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x49, 0x43, 0x45, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x45, 0x49, 0x43, 0x45, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, + 0x88, 0x02, 0x01, 0x12, 0x6e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x11, 0x45, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x31, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x75, + 0x72, 0x69, 0x74, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x68, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, + 0x73, 0x12, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, - 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x07, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x43, 0x32, - 0x12, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, - 0x43, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, + 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x08, + 0x4c, 0x69, 0x73, 0x74, 0x56, 0x50, 0x43, 0x73, 0x12, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x50, 0x43, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x56, 0x50, 0x43, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x86, 0x01, + 0x0a, 0x15, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x44, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x9b, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x44, + 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x44, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x0d, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x11, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x4b, + 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x43, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x4b, 0x53, 0x43, 0x6c, + 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x4b, 0x53, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x61, 0x0a, 0x07, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x43, 0x32, 0x12, 0x27, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x43, 0x32, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x45, 0x43, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, + 0x88, 0x02, 0x01, 0x12, 0x74, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, diff --git a/api/gen/proto/go/teleport/integration/v1/awsoidc_service_grpc.pb.go b/api/gen/proto/go/teleport/integration/v1/awsoidc_service_grpc.pb.go index ad42b279f26f3..6e3313ceb331f 100644 --- a/api/gen/proto/go/teleport/integration/v1/awsoidc_service_grpc.pb.go +++ b/api/gen/proto/go/teleport/integration/v1/awsoidc_service_grpc.pb.go @@ -54,11 +54,13 @@ const ( // // AWSOIDCService provides access to AWS APIs using the AWS OIDC Integration. type AWSOIDCServiceClient interface { + // Deprecated: Do not use. // ListEICE returns a list of EC2 Instance Connect Endpoints. // An optional NextToken that can be used to fetch the next page. // It uses the following API: // https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstanceConnectEndpoints.html ListEICE(ctx context.Context, in *ListEICERequest, opts ...grpc.CallOption) (*ListEICEResponse, error) + // Deprecated: Do not use. // CreateEICE creates multiple EC2 Instance Connect Endpoint using the provided Subnets and Security Group IDs. // It uses the following API: // https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateInstanceConnectEndpoint.html @@ -88,6 +90,7 @@ type AWSOIDCServiceClient interface { DeployService(ctx context.Context, in *DeployServiceRequest, opts ...grpc.CallOption) (*DeployServiceResponse, error) // EnrollEKSClusters enrolls EKS clusters by installing kube agent Helm chart. EnrollEKSClusters(ctx context.Context, in *EnrollEKSClustersRequest, opts ...grpc.CallOption) (*EnrollEKSClustersResponse, error) + // Deprecated: Do not use. // ListEC2 lists the EC2 instances of the AWS account per region. // It uses the following API: // https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html @@ -112,6 +115,7 @@ func NewAWSOIDCServiceClient(cc grpc.ClientConnInterface) AWSOIDCServiceClient { return &aWSOIDCServiceClient{cc} } +// Deprecated: Do not use. func (c *aWSOIDCServiceClient) ListEICE(ctx context.Context, in *ListEICERequest, opts ...grpc.CallOption) (*ListEICEResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListEICEResponse) @@ -122,6 +126,7 @@ func (c *aWSOIDCServiceClient) ListEICE(ctx context.Context, in *ListEICERequest return out, nil } +// Deprecated: Do not use. func (c *aWSOIDCServiceClient) CreateEICE(ctx context.Context, in *CreateEICERequest, opts ...grpc.CallOption) (*CreateEICEResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(CreateEICEResponse) @@ -212,6 +217,7 @@ func (c *aWSOIDCServiceClient) EnrollEKSClusters(ctx context.Context, in *Enroll return out, nil } +// Deprecated: Do not use. func (c *aWSOIDCServiceClient) ListEC2(ctx context.Context, in *ListEC2Request, opts ...grpc.CallOption) (*ListEC2Response, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListEC2Response) @@ -248,11 +254,13 @@ func (c *aWSOIDCServiceClient) Ping(ctx context.Context, in *PingRequest, opts . // // AWSOIDCService provides access to AWS APIs using the AWS OIDC Integration. type AWSOIDCServiceServer interface { + // Deprecated: Do not use. // ListEICE returns a list of EC2 Instance Connect Endpoints. // An optional NextToken that can be used to fetch the next page. // It uses the following API: // https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstanceConnectEndpoints.html ListEICE(context.Context, *ListEICERequest) (*ListEICEResponse, error) + // Deprecated: Do not use. // CreateEICE creates multiple EC2 Instance Connect Endpoint using the provided Subnets and Security Group IDs. // It uses the following API: // https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateInstanceConnectEndpoint.html @@ -282,6 +290,7 @@ type AWSOIDCServiceServer interface { DeployService(context.Context, *DeployServiceRequest) (*DeployServiceResponse, error) // EnrollEKSClusters enrolls EKS clusters by installing kube agent Helm chart. EnrollEKSClusters(context.Context, *EnrollEKSClustersRequest) (*EnrollEKSClustersResponse, error) + // Deprecated: Do not use. // ListEC2 lists the EC2 instances of the AWS account per region. // It uses the following API: // https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html diff --git a/api/proto/teleport/integration/v1/awsoidc_service.proto b/api/proto/teleport/integration/v1/awsoidc_service.proto index fed5a7ffb63a8..28f81c87b5060 100644 --- a/api/proto/teleport/integration/v1/awsoidc_service.proto +++ b/api/proto/teleport/integration/v1/awsoidc_service.proto @@ -26,12 +26,18 @@ service AWSOIDCService { // An optional NextToken that can be used to fetch the next page. // It uses the following API: // https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstanceConnectEndpoints.html - rpc ListEICE(ListEICERequest) returns (ListEICEResponse); + rpc ListEICE(ListEICERequest) returns (ListEICEResponse) { + // TODO(marco): DELETE IN v19.0.0 + option deprecated = true; + } // CreateEICE creates multiple EC2 Instance Connect Endpoint using the provided Subnets and Security Group IDs. // It uses the following API: // https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateInstanceConnectEndpoint.html - rpc CreateEICE(CreateEICERequest) returns (CreateEICEResponse); + rpc CreateEICE(CreateEICERequest) returns (CreateEICEResponse) { + // TODO(marco): DELETE IN v19.0.0 + option deprecated = true; + } // ListDatabases calls the following AWS API: // https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_DescribeDBClusters.html @@ -69,7 +75,10 @@ service AWSOIDCService { // ListEC2 lists the EC2 instances of the AWS account per region. // It uses the following API: // https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html - rpc ListEC2(ListEC2Request) returns (ListEC2Response); + rpc ListEC2(ListEC2Request) returns (ListEC2Response) { + // TODO(marco): DELETE IN v19.0.0 + option deprecated = true; + } // ListEKSClusters retrieves a paginated list of EKS clusters in the specified AWS region for a specific account. // It uses the following APIs: @@ -86,6 +95,7 @@ service AWSOIDCService { // ListEICERequest is a request for a paginated list of AWS EC2 Instance Connect Endpoints. message ListEICERequest { + option deprecated = true; // Integration is the AWS OIDC Integration name. // Required. string integration = 1; @@ -102,6 +112,7 @@ message ListEICERequest { // EC2InstanceConnectEndpoint is a representation of a Amazon VPC EC2 Instance Connect Endpoint. message EC2InstanceConnectEndpoint { + option deprecated = true; // Name is the endpoint name. string name = 1; // State is the endpoint state. @@ -120,6 +131,7 @@ message EC2InstanceConnectEndpoint { // ListEICEResponse contains a page of AWS EC2 Instance Connect Endpoints. message ListEICEResponse { + option deprecated = true; // EC2ICEs contains the page of EC2 Instance Connect Endpoints. repeated EC2InstanceConnectEndpoint ec2ices = 1; // DashboardLink is the URL for AWS Web Console that lists all the Endpoints for the queries VPCs. @@ -131,6 +143,7 @@ message ListEICEResponse { // CreateEICERequest contains the required fields to create an AWS EC2 Instance Connect Endpoint. message CreateEICERequest { + option deprecated = true; // Integration is the AWS OIDC Integration name. // Required. string integration = 1; @@ -144,6 +157,7 @@ message CreateEICERequest { // EC2ICEndpoint contains the information for a single Endpoint to be created. message EC2ICEndpoint { + option deprecated = true; // Name is the endpoint name. string name = 1; // SubnetID is the Subnet where the Endpoint will be created. @@ -155,6 +169,7 @@ message EC2ICEndpoint { // CreateEICEResponse is a request to create a VPC Endpoint of EC2 Instance Connect Endpoint type. message CreateEICEResponse { + option deprecated = true; // Name is the Endpoint ID. string name = 1; // CreatedEndpoints contains the name of created endpoints and their Subnet. @@ -514,6 +529,7 @@ message EnrollEKSClustersResponse { // ListEC2Request is a request for a paginated list of AWS EC2 instances. message ListEC2Request { + option deprecated = true; // Integration is the AWS OIDC Integration name. // Required. string integration = 1; @@ -527,6 +543,7 @@ message ListEC2Request { // ListEC2Response contains a page of AWS EC2 instances represented as Nodes. message ListEC2Response { + option deprecated = true; // Servers contains the page of EC2. repeated types.ServerV2 servers = 1; // NextToken is used for pagination. diff --git a/lib/auth/integration/integrationv1/awsoidc.go b/lib/auth/integration/integrationv1/awsoidc.go index bcdff34276968..229b2a9e443ad 100644 --- a/lib/auth/integration/integrationv1/awsoidc.go +++ b/lib/auth/integration/integrationv1/awsoidc.go @@ -200,6 +200,8 @@ func (s *AWSOIDCService) awsClientReq(ctx context.Context, integrationName, regi } // ListEICE returns a paginated list of EC2 Instance Connect Endpoints. +// +// Deprecated: Marked as deprecated in teleport/integration/v1/awsoidc_service.proto. func (s *AWSOIDCService) ListEICE(ctx context.Context, req *integrationpb.ListEICERequest) (*integrationpb.ListEICEResponse, error) { authCtx, err := s.authorizer.Authorize(ctx) if err != nil { @@ -249,6 +251,8 @@ func (s *AWSOIDCService) ListEICE(ctx context.Context, req *integrationpb.ListEI } // CreateEICE creates multiple EC2 Instance Connect Endpoint using the provided Subnets and Security Group IDs. +// +// Deprecated: Marked as deprecated in teleport/integration/v1/awsoidc_service.proto. func (s *AWSOIDCService) CreateEICE(ctx context.Context, req *integrationpb.CreateEICERequest) (*integrationpb.CreateEICEResponse, error) { authCtx, err := s.authorizer.Authorize(ctx) if err != nil { @@ -661,6 +665,8 @@ func (s *AWSOIDCService) DeployService(ctx context.Context, req *integrationpb.D } // ListEC2 returns a paginated list of AWS EC2 instances. +// +// Deprecated: Marked as deprecated in teleport/integration/v1/awsoidc_service.proto. func (s *AWSOIDCService) ListEC2(ctx context.Context, req *integrationpb.ListEC2Request) (*integrationpb.ListEC2Response, error) { authCtx, err := s.authorizer.Authorize(ctx) if err != nil { diff --git a/lib/auth/integration/integrationv1/awsoidc_test.go b/lib/auth/integration/integrationv1/awsoidc_test.go index 6a2497229ab38..f5fff709faabb 100644 --- a/lib/auth/integration/integrationv1/awsoidc_test.go +++ b/lib/auth/integration/integrationv1/awsoidc_test.go @@ -240,18 +240,6 @@ func TestRBAC(t *testing.T) { userCtx := authorizerForDummyUser(t, ctx, role, localClient) for _, tt := range []endpointSubtest{ - { - name: "ListEICE", - fn: func() error { - _, err := awsoidService.ListEICE(userCtx, &integrationv1.ListEICERequest{ - Integration: integrationName, - Region: "my-region", - VpcIds: []string{"vpc-123"}, - NextToken: "", - }) - return err - }, - }, { name: "ListDatabases", fn: func() error { @@ -347,18 +335,6 @@ func TestRBAC(t *testing.T) { userCtx := authorizerForDummyUser(t, ctx, role, localClient) for _, tt := range []endpointSubtest{ - { - name: "ListEICE", - fn: func() error { - _, err := awsoidService.ListEICE(userCtx, &integrationv1.ListEICERequest{ - Integration: integrationName, - Region: "my-region", - VpcIds: []string{"vpc-123"}, - NextToken: "", - }) - return err - }, - }, { name: "ListDatabases", fn: func() error { diff --git a/lib/config/configuration.go b/lib/config/configuration.go index ee377cd41f8bb..fbe9a1d5ddf40 100644 --- a/lib/config/configuration.go +++ b/lib/config/configuration.go @@ -210,10 +210,6 @@ type CommandLineFlags struct { // `teleport integration configure deployservice-iam` command IntegrationConfDeployServiceIAMArguments IntegrationConfDeployServiceIAM - // IntegrationConfEICEIAMArguments contains the arguments of - // `teleport integration configure eice-iam` command - IntegrationConfEICEIAMArguments IntegrationConfEICEIAM - // IntegrationConfAWSAppAccessIAMArguments contains the arguments of // `teleport integration configure aws-app-access-iam` command IntegrationConfAWSAppAccessIAMArguments IntegrationConfAWSAppAccessIAM @@ -329,19 +325,6 @@ type IntegrationConfDeployServiceIAM struct { AutoConfirm bool } -// IntegrationConfEICEIAM contains the arguments of -// `teleport integration configure eice-iam` command -type IntegrationConfEICEIAM struct { - // Region is the AWS Region used to set up the client. - Region string - // Role is the AWS Role associated with the Integration - Role string - // AccountID is the AWS account ID. - AccountID string - // AutoConfirm skips user confirmation of the operation plan if true. - AutoConfirm bool -} - // IntegrationConfAWSAppAccessIAM contains the arguments of // `teleport integration configure aws-app-access-iam` command type IntegrationConfAWSAppAccessIAM struct { diff --git a/lib/integrations/awsoidc/eice_iam_config.go b/lib/integrations/awsoidc/eice_iam_config.go deleted file mode 100644 index 7026fa97fef5e..0000000000000 --- a/lib/integrations/awsoidc/eice_iam_config.go +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package awsoidc - -import ( - "context" - "io" - - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/service/iam" - "github.com/aws/aws-sdk-go-v2/service/sts" - "github.com/gravitational/trace" - - awslib "github.com/gravitational/teleport/lib/cloud/aws" - "github.com/gravitational/teleport/lib/cloud/provisioning" - "github.com/gravitational/teleport/lib/cloud/provisioning/awsactions" -) - -const ( - // defaultPolicyNameForEICE is the default name for the Inline Policy added to the IntegrationRole. - defaultPolicyNameForEICE = "EC2InstanceConnectEndpoint" -) - -// EICEIAMConfigureRequest is a request to configure the required Policies to use the EC2 Instance Connect Endpoint feature. -type EICEIAMConfigureRequest struct { - // Region is the AWS Region. - // Used to set up the AWS SDK Client. - Region string - - // IntegrationRole is the Integration's AWS Role used to set up Teleport as an OIDC IdP. - IntegrationRole string - - // IntegrationRoleEICEPolicy is the Policy Name that is created to allow access to call AWS APIs. - // Defaults to EC2InstanceConnectEndpoint - IntegrationRoleEICEPolicy string - - // AccountID is the AWS Account ID. - AccountID string - - // AutoConfirm skips user confirmation of the operation plan if true. - AutoConfirm bool - - // stdout is used to override stdout output in tests. - stdout io.Writer -} - -// CheckAndSetDefaults ensures the required fields are present. -func (r *EICEIAMConfigureRequest) CheckAndSetDefaults() error { - if r.Region == "" { - return trace.BadParameter("region is required") - } - - if r.IntegrationRole == "" { - return trace.BadParameter("integration role is required") - } - - if r.IntegrationRoleEICEPolicy == "" { - r.IntegrationRoleEICEPolicy = defaultPolicyNameForEICE - } - - return nil -} - -// EICEIAMConfigureClient describes the required methods to create the IAM Policies required for accessing EC2 instances usine EICE. -type EICEIAMConfigureClient interface { - CallerIdentityGetter - awsactions.RolePolicyPutter -} - -type defaultEICEIAMConfigureClient struct { - CallerIdentityGetter - *iam.Client -} - -// NewEICEIAMConfigureClient creates a new EICEIAMConfigureClient. -func NewEICEIAMConfigureClient(ctx context.Context, region string) (EICEIAMConfigureClient, error) { - if region == "" { - return nil, trace.BadParameter("region is required") - } - - cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region)) - if err != nil { - return nil, trace.Wrap(err) - } - - return &defaultEICEIAMConfigureClient{ - CallerIdentityGetter: sts.NewFromConfig(cfg), - Client: iam.NewFromConfig(cfg), - }, nil -} - -// ConfigureEICEIAM set ups the roles required for accessing an EC2 Instance using EICE. -// It creates an embedded policy with the following permissions: -// -// Action: List EC2 instances to add them as Teleport Nodes -// - ec2:DescribeInstances -// -// Action: List EC2 Instance Connect Endpoints so that knows if they must create one Endpoint. -// - ec2:DescribeInstanceConnectEndpoints -// -// Action: Select one or more SecurityGroups to apply to the EC2 Instance Connect Endpoints (the VPC's default SG is applied if no SG is provided). -// - ec2:DescribeSecurityGroups -// -// Action: Create EC2 Instance Connect Endpoint so the user can open a tunnel to the EC2 instance. -// More info: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/permissions-for-ec2-instance-connect-endpoint.html -// - ec2:CreateInstanceConnectEndpoint -// - ec2:CreateTags -// - ec2:CreateNetworkInterface -// - iam:CreateServiceLinkedRole -// -// Action: Send a temporary SSH Key to the target host. -// - ec2-instance-connect:SendSSHPublicKey -// -// Action: Open a Tunnel to the EC2 using the Endpoint -// - ec2-instance-connect:OpenTunnel -// -// The following actions must be allowed by the IAM Role assigned in the Client. -// - iam:PutRolePolicy -func ConfigureEICEIAM(ctx context.Context, clt EICEIAMConfigureClient, req EICEIAMConfigureRequest) error { - if err := req.CheckAndSetDefaults(); err != nil { - return trace.Wrap(err) - } - - if err := CheckAccountID(ctx, clt, req.AccountID); err != nil { - return trace.Wrap(err) - } - - policy := awslib.NewPolicyDocument( - awslib.StatementForEC2InstanceConnectEndpoint(), - ) - putRolePolicy, err := awsactions.PutRolePolicy(clt, req.IntegrationRoleEICEPolicy, req.IntegrationRole, policy) - if err != nil { - return trace.Wrap(err) - } - - return trace.Wrap(provisioning.Run(ctx, provisioning.OperationConfig{ - Name: "eice-iam", - Actions: []provisioning.Action{ - *putRolePolicy, - }, - AutoConfirm: req.AutoConfirm, - Output: req.stdout, - })) -} diff --git a/lib/integrations/awsoidc/eice_iam_config_test.go b/lib/integrations/awsoidc/eice_iam_config_test.go deleted file mode 100644 index db7bc840f7e5d..0000000000000 --- a/lib/integrations/awsoidc/eice_iam_config_test.go +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package awsoidc - -import ( - "bytes" - "context" - "fmt" - "slices" - "testing" - - "github.com/aws/aws-sdk-go-v2/service/iam" - iamtypes "github.com/aws/aws-sdk-go-v2/service/iam/types" - "github.com/stretchr/testify/require" - - "github.com/gravitational/teleport/lib/utils/testutils/golden" -) - -func TestEICEIAMConfigReqDefaults(t *testing.T) { - baseReq := func() EICEIAMConfigureRequest { - return EICEIAMConfigureRequest{ - Region: "us-east-1", - IntegrationRole: "integrationrole", - AccountID: "123456789012", - AutoConfirm: true, - } - } - - for _, tt := range []struct { - name string - req func() EICEIAMConfigureRequest - errCheck require.ErrorAssertionFunc - expected EICEIAMConfigureRequest - }{ - { - name: "set defaults", - req: baseReq, - errCheck: require.NoError, - expected: EICEIAMConfigureRequest{ - AccountID: "123456789012", - Region: "us-east-1", - IntegrationRole: "integrationrole", - IntegrationRoleEICEPolicy: "EC2InstanceConnectEndpoint", - AutoConfirm: true, - }, - }, - { - name: "missing region", - req: func() EICEIAMConfigureRequest { - req := baseReq() - req.Region = "" - return req - }, - errCheck: badParameterCheck, - }, - { - name: "missing integration role", - req: func() EICEIAMConfigureRequest { - req := baseReq() - req.IntegrationRole = "" - return req - }, - errCheck: badParameterCheck, - }, - { - name: "missing account id is ok", - req: func() EICEIAMConfigureRequest { - req := baseReq() - req.AccountID = "" - return req - }, - errCheck: require.NoError, - expected: EICEIAMConfigureRequest{ - Region: "us-east-1", - IntegrationRole: "integrationrole", - IntegrationRoleEICEPolicy: "EC2InstanceConnectEndpoint", - AutoConfirm: true, - }, - }, - } { - t.Run(tt.name, func(t *testing.T) { - req := tt.req() - err := req.CheckAndSetDefaults() - tt.errCheck(t, err) - if err != nil { - return - } - - require.Equal(t, tt.expected, req) - }) - } -} - -func TestEICEIAMConfig(t *testing.T) { - ctx := context.Background() - baseReq := func() EICEIAMConfigureRequest { - return EICEIAMConfigureRequest{ - Region: "us-east-1", - IntegrationRole: "integrationrole", - AccountID: "123456789012", - AutoConfirm: true, - } - } - - for _, tt := range []struct { - name string - mockAccountID string - mockExistingRoles []string - req func() EICEIAMConfigureRequest - errCheck require.ErrorAssertionFunc - }{ - { - name: "valid", - req: baseReq, - mockAccountID: "123456789012", - mockExistingRoles: []string{"integrationrole"}, - errCheck: require.NoError, - }, - { - name: "integration role does not exist", - mockAccountID: "123456789012", - mockExistingRoles: []string{}, - req: baseReq, - errCheck: notFoundCheck, - }, - { - name: "account does not match expected account", - req: baseReq, - mockAccountID: "222222222222", - mockExistingRoles: []string{"integrationrole"}, - errCheck: badParameterCheck, - }, - } { - t.Run(tt.name, func(t *testing.T) { - clt := mockEICEIAMConfigClient{ - CallerIdentityGetter: mockSTSClient{accountID: tt.mockAccountID}, - existingRoles: tt.mockExistingRoles, - } - - err := ConfigureEICEIAM(ctx, &clt, tt.req()) - tt.errCheck(t, err) - }) - } -} - -func TestEICEIAMConfigOutput(t *testing.T) { - ctx := context.Background() - var buf bytes.Buffer - req := EICEIAMConfigureRequest{ - Region: "us-east-1", - IntegrationRole: "integrationrole", - AccountID: "123456789012", - AutoConfirm: true, - stdout: &buf, - } - - clt := mockEICEIAMConfigClient{ - CallerIdentityGetter: mockSTSClient{accountID: req.AccountID}, - existingRoles: []string{req.IntegrationRole}, - } - - require.NoError(t, ConfigureEICEIAM(ctx, &clt, req)) - if golden.ShouldSet() { - golden.Set(t, buf.Bytes()) - } - require.Equal(t, string(golden.Get(t)), buf.String()) -} - -type mockEICEIAMConfigClient struct { - CallerIdentityGetter - existingRoles []string -} - -// PutRolePolicy creates or replaces a Policy by its name in a IAM Role. -func (m *mockEICEIAMConfigClient) PutRolePolicy(ctx context.Context, params *iam.PutRolePolicyInput, optFns ...func(*iam.Options)) (*iam.PutRolePolicyOutput, error) { - if !slices.Contains(m.existingRoles, *params.RoleName) { - noSuchEntityMessage := fmt.Sprintf("role %q does not exist.", *params.RoleName) - return nil, &iamtypes.NoSuchEntityException{ - Message: &noSuchEntityMessage, - } - } - return nil, nil -} diff --git a/lib/integrations/awsoidc/testdata/TestEICEIAMConfigOutput.golden b/lib/integrations/awsoidc/testdata/TestEICEIAMConfigOutput.golden deleted file mode 100644 index 318067357a97c..0000000000000 --- a/lib/integrations/awsoidc/testdata/TestEICEIAMConfigOutput.golden +++ /dev/null @@ -1,28 +0,0 @@ -"eice-iam" will perform the following action: - -Attach an inline IAM policy named "EC2InstanceConnectEndpoint" to IAM role "integrationrole". -PutRolePolicy: { - "PolicyDocument": { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "ec2:DescribeInstances", - "ec2:DescribeInstanceConnectEndpoints", - "ec2:DescribeSecurityGroups", - "ec2:CreateInstanceConnectEndpoint", - "ec2:CreateTags", - "ec2:CreateNetworkInterface", - "iam:CreateServiceLinkedRole", - "ec2-instance-connect:SendSSHPublicKey", - "ec2-instance-connect:OpenTunnel" - ], - "Resource": "*" - } - ] - }, - "PolicyName": "EC2InstanceConnectEndpoint", - "RoleName": "integrationrole" -} - diff --git a/lib/usagereporter/web/userevent.go b/lib/usagereporter/web/userevent.go index aab5706db84ca..5af970b7ce6b5 100644 --- a/lib/usagereporter/web/userevent.go +++ b/lib/usagereporter/web/userevent.go @@ -58,9 +58,6 @@ const ( uiDiscoverDesktopActiveDirectoryToolsInstallEvent = "tp.ui.discover.desktop.activeDirectory.tools.install" uiDiscoverDesktopActiveDirectoryConfigureEvent = "tp.ui.discover.desktop.activeDirectory.configure" uiDiscoverAutoDiscoveredResourcesEvent = "tp.ui.discover.autoDiscoveredResources" - uiDiscoverEC2InstanceSelectionEvent = "tp.ui.discover.selectedEC2Instance" - uiDiscoverDeployEICEEvent = "tp.ui.discover.deployEICE" - uiDiscoverCreateNodeEvent = "tp.ui.discover.createNode" uiDiscoverCreateAppServerEvent = "tp.ui.discover.createAppServer" uiDiscoverCreateDiscoveryConfigEvent = "tp.ui.discover.createDiscoveryConfig" uiDiscoverPrincipalsConfigureEvent = "tp.ui.discover.principals.configure" @@ -302,9 +299,6 @@ func ConvertUserEventRequestToUsageEvent(req CreateUserEventRequest) (*usageeven uiDiscoverAutoDiscoveredResourcesEvent, uiDiscoverPrincipalsConfigureEvent, uiDiscoverTestConnectionEvent, - uiDiscoverEC2InstanceSelectionEvent, - uiDiscoverDeployEICEEvent, - uiDiscoverCreateNodeEvent, uiDiscoverCreateAppServerEvent, uiDiscoverCreateDiscoveryConfigEvent, uiDiscoverCompletedEvent: diff --git a/lib/usagereporter/web/userevent_discover.go b/lib/usagereporter/web/userevent_discover.go index fb96620e26bb7..2a31bf7cdaf6f 100644 --- a/lib/usagereporter/web/userevent_discover.go +++ b/lib/usagereporter/web/userevent_discover.go @@ -219,33 +219,6 @@ func (d *DiscoverEventData) ToUsageEvent(eventName string) (*usageeventsv1.Usage }, }}, nil - case uiDiscoverEC2InstanceSelectionEvent: - return &usageeventsv1.UsageEventOneOf{Event: &usageeventsv1.UsageEventOneOf_UiDiscoverEc2InstanceSelection{ - UiDiscoverEc2InstanceSelection: &usageeventsv1.UIDiscoverEC2InstanceSelectionEvent{ - Metadata: metadata, - Resource: resource, - Status: status, - }, - }}, nil - - case uiDiscoverDeployEICEEvent: - return &usageeventsv1.UsageEventOneOf{Event: &usageeventsv1.UsageEventOneOf_UiDiscoverDeployEice{ - UiDiscoverDeployEice: &usageeventsv1.UIDiscoverDeployEICEEvent{ - Metadata: metadata, - Resource: resource, - Status: status, - }, - }}, nil - - case uiDiscoverCreateNodeEvent: - return &usageeventsv1.UsageEventOneOf{Event: &usageeventsv1.UsageEventOneOf_UiDiscoverCreateNode{ - UiDiscoverCreateNode: &usageeventsv1.UIDiscoverCreateNodeEvent{ - Metadata: metadata, - Resource: resource, - Status: status, - }, - }}, nil - case uiDiscoverCreateAppServerEvent: return &usageeventsv1.UsageEventOneOf{Event: &usageeventsv1.UsageEventOneOf_UiDiscoverCreateAppServerEvent{ UiDiscoverCreateAppServerEvent: &usageeventsv1.UIDiscoverCreateAppServerEvent{ diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index d28b29f109aa3..86b073588f27b 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -1022,20 +1022,16 @@ func (h *Handler) bindDefaultEndpoints() { h.POST("/webapi/sites/:site/integrations/aws-oidc/:name/deploydatabaseservices", h.WithClusterAuth(h.awsOIDCDeployDatabaseServices)) h.POST("/webapi/sites/:site/integrations/aws-oidc/:name/listdeployeddatabaseservices", h.WithClusterAuth(h.awsOIDCListDeployedDatabaseService)) h.GET("/webapi/scripts/integrations/configure/deployservice-iam.sh", h.WithLimiter(h.awsOIDCConfigureDeployServiceIAM)) - h.POST("/webapi/sites/:site/integrations/aws-oidc/:name/ec2", h.WithClusterAuth(h.awsOIDCListEC2)) h.POST("/webapi/sites/:site/integrations/aws-oidc/:name/eksclusters", h.WithClusterAuth(h.awsOIDCListEKSClusters)) // TODO(kimlisa): DELETE IN 19.0 - replaced by /v2/webapi/sites/:site/integrations/aws-oidc/:name/enrolleksclusters // MUST delete with related code found in web/packages/teleport/src/services/integrations/integrations.ts(enrollEksClusters) h.POST("/webapi/sites/:site/integrations/aws-oidc/:name/enrolleksclusters", h.WithClusterAuth(h.awsOIDCEnrollEKSClusters)) // v2 endpoint introduces "extraLabels" field. h.POST("/v2/webapi/sites/:site/integrations/aws-oidc/:name/enrolleksclusters", h.WithClusterAuth(h.awsOIDCEnrollEKSClusters)) - h.POST("/webapi/sites/:site/integrations/aws-oidc/:name/ec2ice", h.WithClusterAuth(h.awsOIDCListEC2ICE)) - h.POST("/webapi/sites/:site/integrations/aws-oidc/:name/deployec2ice", h.WithClusterAuth(h.awsOIDCDeployEC2ICE)) h.POST("/webapi/sites/:site/integrations/aws-oidc/:name/securitygroups", h.WithClusterAuth(h.awsOIDCListSecurityGroups)) h.POST("/webapi/sites/:site/integrations/aws-oidc/:name/databasevpcs", h.WithClusterAuth(h.awsOIDCListDatabaseVPCs)) h.POST("/webapi/sites/:site/integrations/aws-oidc/:name/subnets", h.WithClusterAuth(h.awsOIDCListSubnets)) h.POST("/webapi/sites/:site/integrations/aws-oidc/:name/requireddatabasesvpcs", h.WithClusterAuth(h.awsOIDCRequiredDatabasesVPCS)) - h.GET("/webapi/scripts/integrations/configure/eice-iam.sh", h.WithLimiter(h.awsOIDCConfigureEICEIAM)) h.GET("/webapi/scripts/integrations/configure/eks-iam.sh", h.WithLimiter(h.awsOIDCConfigureEKSIAM)) h.GET("/webapi/scripts/integrations/configure/access-graph-cloud-sync-iam.sh", h.WithLimiter(h.accessGraphCloudSyncOIDC)) h.GET("/webapi/scripts/integrations/configure/aws-app-access-iam.sh", h.WithLimiter(h.awsOIDCConfigureAWSAppAccessIAM)) diff --git a/lib/web/integrations_awsoidc.go b/lib/web/integrations_awsoidc.go index 028cd8635121d..27261a1fa6570 100644 --- a/lib/web/integrations_awsoidc.go +++ b/lib/web/integrations_awsoidc.go @@ -555,48 +555,6 @@ func (h *Handler) awsOIDCConfigureDeployServiceIAM(w http.ResponseWriter, r *htt return nil, trace.Wrap(err) } -// awsOIDCConfigureEICEIAM returns a script that configures the required IAM permissions to enable the usage of EC2 Instance Connect Endpoint -// to access EC2 instances. -func (h *Handler) awsOIDCConfigureEICEIAM(w http.ResponseWriter, r *http.Request, p httprouter.Params) (any, error) { - queryParams := r.URL.Query() - - awsRegion := queryParams.Get("awsRegion") - if err := aws.IsValidRegion(awsRegion); err != nil { - return nil, trace.BadParameter("invalid awsRegion") - } - - awsAccountID := queryParams.Get("awsAccountID") - if err := aws.IsValidAccountID(awsAccountID); err != nil { - return nil, trace.Wrap(err, "invalid awsAccountID") - } - - role := queryParams.Get("role") - if err := aws.IsValidIAMRoleName(role); err != nil { - return nil, trace.BadParameter("invalid role %q", role) - } - - // The script must execute the following command: - // teleport integration configure eice-iam - argsList := []string{ - "integration", "configure", "eice-iam", - fmt.Sprintf("--aws-region=%s", shsprintf.EscapeDefaultContext(awsRegion)), - fmt.Sprintf("--role=%s", shsprintf.EscapeDefaultContext(role)), - fmt.Sprintf("--aws-account-id=%s", shsprintf.EscapeDefaultContext(awsAccountID)), - } - script, err := oneoff.BuildScript(oneoff.OneOffScriptParams{ - TeleportArgs: strings.Join(argsList, " "), - SuccessMessage: "Success! You can now go back to the Teleport Web UI to complete the EC2 enrollment.", - }) - if err != nil { - return nil, trace.Wrap(err) - } - - httplib.SetScriptHeaders(w.Header()) - _, err = fmt.Fprint(w, script) - - return nil, trace.Wrap(err) -} - // awsOIDCConfigureAppAccessIAM returns a script that configures the required IAM permissions to enable App Access // using the AWS OIDC Credentials. // Only IAM Roles with `teleport.dev/integration: Allowed` Tag can be used. @@ -833,56 +791,6 @@ func (h *Handler) awsOIDCListEKSClusters(w http.ResponseWriter, r *http.Request, }, nil } -// awsOIDCListEC2 returns a list of EC2 Instances using the ListEC2 action of the AWS OIDC Integration. -func (h *Handler) awsOIDCListEC2(w http.ResponseWriter, r *http.Request, p httprouter.Params, sctx *SessionContext, site reversetunnelclient.RemoteSite) (any, error) { - ctx := r.Context() - - var req ui.AWSOIDCListEC2Request - if err := httplib.ReadJSON(r, &req); err != nil { - return nil, trace.Wrap(err) - } - - integrationName := p.ByName("name") - if integrationName == "" { - return nil, trace.BadParameter("an integration name is required") - } - - clt, err := sctx.GetUserClient(ctx, site) - if err != nil { - return nil, trace.Wrap(err) - } - - listResp, err := clt.IntegrationAWSOIDCClient().ListEC2(ctx, &integrationv1.ListEC2Request{ - Integration: integrationName, - Region: req.Region, - NextToken: req.NextToken, - }) - if err != nil { - return nil, trace.Wrap(err) - } - - accessChecker, err := sctx.GetUserAccessChecker() - if err != nil { - return nil, trace.Wrap(err) - } - - servers := make([]ui.Server, 0, len(listResp.Servers)) - for _, s := range listResp.Servers { - logins, err := accessChecker.GetAllowedLoginsForResource(s) - if err != nil { - return nil, trace.Wrap(err) - } - slices.Sort(logins) - - servers = append(servers, ui.MakeServer(h.auth.clusterName, s, logins, false /* requiresRequest */)) - } - - return ui.AWSOIDCListEC2Response{ - NextToken: listResp.NextToken, - Servers: servers, - }, nil -} - // awsOIDCListSecurityGroups returns a list of VPC Security Groups using the ListSecurityGroups action of the AWS OIDC Integration. func (h *Handler) awsOIDCListSecurityGroups(w http.ResponseWriter, r *http.Request, p httprouter.Params, sctx *SessionContext, site reversetunnelclient.RemoteSite) (any, error) { ctx := r.Context() @@ -1088,117 +996,6 @@ func awsOIDCRequiredVPCSHelper(ctx context.Context, clt client.GetResourcesClien }, nil } -// awsOIDCListEC2ICE returns a list of EC2 Instance Connect Endpoints using the ListEC2ICE action of the AWS OIDC Integration. -func (h *Handler) awsOIDCListEC2ICE(w http.ResponseWriter, r *http.Request, p httprouter.Params, sctx *SessionContext, site reversetunnelclient.RemoteSite) (any, error) { - ctx := r.Context() - - var req ui.AWSOIDCListEC2ICERequest - if err := httplib.ReadJSON(r, &req); err != nil { - return nil, trace.Wrap(err) - } - - integrationName := p.ByName("name") - if integrationName == "" { - return nil, trace.BadParameter("an integration name is required") - } - - clt, err := sctx.GetUserClient(ctx, site) - if err != nil { - return nil, trace.Wrap(err) - } - - vpcIds := req.VPCIDs - if len(vpcIds) == 0 { - vpcIds = []string{req.VPCID} - } - - resp, err := clt.IntegrationAWSOIDCClient().ListEICE(ctx, &integrationv1.ListEICERequest{ - Integration: integrationName, - Region: req.Region, - VpcIds: vpcIds, - NextToken: req.NextToken, - }) - if err != nil { - return nil, trace.Wrap(err) - } - - endpoints := make([]awsoidc.EC2InstanceConnectEndpoint, 0, len(resp.Ec2Ices)) - for _, e := range resp.Ec2Ices { - endpoints = append(endpoints, awsoidc.EC2InstanceConnectEndpoint{ - Name: e.Name, - State: e.State, - StateMessage: e.StateMessage, - DashboardLink: e.DashboardLink, - SubnetID: e.SubnetId, - VPCID: e.VpcId, - }) - } - - return ui.AWSOIDCListEC2ICEResponse{ - NextToken: resp.NextToken, - DashboardLink: resp.DashboardLink, - EC2ICEs: endpoints, - }, nil -} - -// awsOIDCDeployC2ICE creates an EC2 Instance Connect Endpoint. -func (h *Handler) awsOIDCDeployEC2ICE(w http.ResponseWriter, r *http.Request, p httprouter.Params, sctx *SessionContext, site reversetunnelclient.RemoteSite) (any, error) { - ctx := r.Context() - - var req ui.AWSOIDCDeployEC2ICERequest - if err := httplib.ReadJSON(r, &req); err != nil { - return nil, trace.Wrap(err) - } - - integrationName := p.ByName("name") - if integrationName == "" { - return nil, trace.BadParameter("an integration name is required") - } - - clt, err := sctx.GetUserClient(ctx, site) - if err != nil { - return nil, trace.Wrap(err) - } - - endpoints := make([]*integrationv1.EC2ICEndpoint, 0, len(req.Endpoints)) - for _, endpoint := range req.Endpoints { - endpoints = append(endpoints, &integrationv1.EC2ICEndpoint{ - SubnetId: endpoint.SubnetID, - SecurityGroupIds: endpoint.SecurityGroupIDs, - }) - } - - // Backwards compatible: get the endpoint from the deprecated fields. - if len(endpoints) == 0 { - endpoints = append(endpoints, &integrationv1.EC2ICEndpoint{ - SubnetId: req.SubnetID, - SecurityGroupIds: req.SecurityGroupIDs, - }) - } - - createResp, err := clt.IntegrationAWSOIDCClient().CreateEICE(ctx, &integrationv1.CreateEICERequest{ - Integration: integrationName, - Region: req.Region, - Endpoints: endpoints, - }) - if err != nil { - return nil, trace.Wrap(err) - } - - respEndpoints := make([]ui.AWSOIDCDeployEC2ICEResponseEndpoint, 0, len(createResp.CreatedEndpoints)) - for _, endpoint := range createResp.CreatedEndpoints { - respEndpoints = append(respEndpoints, ui.AWSOIDCDeployEC2ICEResponseEndpoint{ - Name: endpoint.Name, - SubnetID: endpoint.SubnetId, - }) - } - - return ui.AWSOIDCDeployEC2ICEResponse{ - Name: createResp.Name, - Endpoints: respEndpoints, - }, nil -} - // awsOIDCCreateAWSAppAccess creates an AppServer that uses an AWS OIDC Integration for proxying access. // v2 endpoint introduces "labels" field func (h *Handler) awsOIDCCreateAWSAppAccess(w http.ResponseWriter, r *http.Request, p httprouter.Params, sctx *SessionContext, site reversetunnelclient.RemoteSite) (any, error) { diff --git a/lib/web/integrations_awsoidc_test.go b/lib/web/integrations_awsoidc_test.go index 8bff3a13ab45f..60221151b0c66 100644 --- a/lib/web/integrations_awsoidc_test.go +++ b/lib/web/integrations_awsoidc_test.go @@ -179,110 +179,6 @@ func TestBuildDeployServiceConfigureIAMScript(t *testing.T) { } } -func TestBuildEICEConfigureIAMScript(t *testing.T) { - t.Parallel() - isBadParamErrFn := func(tt require.TestingT, err error, i ...any) { - require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err) - } - - ctx := context.Background() - env := newWebPack(t, 1) - - // Unauthenticated client for script downloading. - publicClt := env.proxies[0].newClient(t) - pathVars := []string{ - "webapi", - "scripts", - "integrations", - "configure", - "eice-iam.sh", - } - endpoint := publicClt.Endpoint(pathVars...) - - tests := []struct { - name string - reqRelativeURL string - reqQuery url.Values - errCheck require.ErrorAssertionFunc - expectedTeleportArgs string - }{ - { - name: "valid", - reqQuery: url.Values{ - "awsRegion": []string{"us-east-1"}, - "role": []string{"myRole"}, - "awsAccountID": []string{"123456789012"}, - }, - errCheck: require.NoError, - expectedTeleportArgs: "integration configure eice-iam " + - "--aws-region=us-east-1 " + - "--role=myRole " + - "--aws-account-id=123456789012", - }, - { - name: "valid with symbols in role", - reqQuery: url.Values{ - "awsRegion": []string{"us-east-1"}, - "role": []string{"Test+1=2,3.4@5-6_7"}, - "awsAccountID": []string{"123456789012"}, - }, - errCheck: require.NoError, - expectedTeleportArgs: "integration configure eice-iam " + - "--aws-region=us-east-1 " + - "--role=Test\\+1=2,3.4\\@5-6_7 " + - "--aws-account-id=123456789012", - }, - { - name: "missing aws-region", - reqQuery: url.Values{ - "role": []string{"myRole"}, - "awsAccountID": []string{"123456789012"}, - }, - errCheck: isBadParamErrFn, - }, - { - name: "missing account id", - reqQuery: url.Values{ - "awsRegion": []string{"us-east-1"}, - "role": []string{"myRole"}, - }, - errCheck: isBadParamErrFn, - }, - { - name: "missing role", - reqQuery: url.Values{ - "awsRegion": []string{"us-east-1"}, - "awsAccountID": []string{"123456789012"}, - }, - errCheck: isBadParamErrFn, - }, - { - name: "trying to inject escape sequence into query params", - reqQuery: url.Values{ - "awsRegion": []string{"'; rm -rf /tmp/dir; echo '"}, - "role": []string{"role"}, - "awsAccountID": []string{"123456789012"}, - }, - errCheck: isBadParamErrFn, - }, - } - - for _, tc := range tests { - tc := tc - t.Run(tc.name, func(t *testing.T) { - resp, err := publicClt.Get(ctx, endpoint, tc.reqQuery) - tc.errCheck(t, err) - if err != nil { - return - } - - require.Contains(t, string(resp.Bytes()), - fmt.Sprintf("teleportArgs='%s'\n", tc.expectedTeleportArgs), - ) - }) - } -} - func TestBuildEC2SSMIAMScript(t *testing.T) { t.Parallel() isBadParamErrFn := func(tt require.TestingT, err error, i ...any) { diff --git a/lib/web/ui/integration.go b/lib/web/ui/integration.go index ce8f527a8cbd5..b7b93470f67ae 100644 --- a/lib/web/ui/integration.go +++ b/lib/web/ui/integration.go @@ -439,25 +439,6 @@ type AWSOIDCListEKSClustersResponse struct { NextToken string `json:"nextToken,omitempty"` } -// AWSOIDCListEC2Request is a request to ListEC2s using the AWS OIDC Integration. -type AWSOIDCListEC2Request struct { - // Region is the AWS Region. - Region string `json:"region"` - // NextToken is the token to be used to fetch the next page. - // If empty, the first page is fetched. - NextToken string `json:"nextToken"` -} - -// AWSOIDCListEC2Response contains a list of Servers and a next token if more pages are available. -type AWSOIDCListEC2Response struct { - // Servers contains the page of Servers - Servers []Server `json:"servers"` - - // NextToken is used for pagination. - // If non-empty, it can be used to request the next page. - NextToken string `json:"nextToken,omitempty"` -} - // AWSOIDCListSecurityGroupsRequest is a request to ListSecurityGroups using the AWS OIDC Integration. type AWSOIDCListSecurityGroupsRequest struct { // Region is the AWS Region. @@ -549,78 +530,6 @@ type AWSOIDCRequiredVPCSResponse struct { VPCMapOfSubnets map[string][]string `json:"vpcMapOfSubnets"` } -// AWSOIDCListEC2ICERequest is a request to ListEC2ICEs using the AWS OIDC Integration. -type AWSOIDCListEC2ICERequest struct { - // Region is the AWS Region. - Region string `json:"region"` - // VPCID is the VPC to filter EC2 Instance Connect Endpoints. - // Deprecated: use VPCIDs instead. - VPCID string `json:"vpcId"` - // VPCIDs is a list of VPCs to filter EC2 Instance Connect Endpoints. - VPCIDs []string `json:"vpcIds"` - // NextToken is the token to be used to fetch the next page. - // If empty, the first page is fetched. - NextToken string `json:"nextToken"` -} - -// AWSOIDCListEC2ICEResponse contains a list of AWS Instance Connect Endpoints and a next token if more pages are available. -type AWSOIDCListEC2ICEResponse struct { - // EC2ICEs contains the page of Endpoints - EC2ICEs []awsoidc.EC2InstanceConnectEndpoint `json:"ec2Ices"` - - // DashboardLink is the URL for AWS Web Console that lists all the Endpoints for the queries VPCs. - DashboardLink string `json:"dashboardLink,omitempty"` - - // NextToken is used for pagination. - // If non-empty, it can be used to request the next page. - NextToken string `json:"nextToken,omitempty"` -} - -// AWSOIDCDeployEC2ICERequest is a request to create an AWS EC2 Instance Connect Endpoint. -type AWSOIDCDeployEC2ICERequest struct { - // Region is the AWS Region. - Region string `json:"region"` - // Endpoints is a list of endpoinst to create. - Endpoints []AWSOIDCDeployEC2ICERequestEndpoint `json:"endpoints"` - - // SubnetID is the subnet id for the EC2 Instance Connect Endpoint. - // Deprecated: use Endpoints instead. - SubnetID string `json:"subnetId"` - // SecurityGroupIDs is the list of SecurityGroups to apply to the Endpoint. - // If not specified, the Endpoint will receive the default SG for the Subnet's VPC. - // Deprecated: use Endpoints instead. - SecurityGroupIDs []string `json:"securityGroupIds"` -} - -// AWSOIDCDeployEC2ICERequestEndpoint is a single Endpoint that should be created. -type AWSOIDCDeployEC2ICERequestEndpoint struct { - // SubnetID is the subnet id for the EC2 Instance Connect Endpoint. - SubnetID string `json:"subnetId"` - // SecurityGroupIDs is the list of SecurityGroups to apply to the Endpoint. - // If not specified, the Endpoint will receive the default SG for the Subnet's VPC. - SecurityGroupIDs []string `json:"securityGroupIds"` -} - -// AWSOIDCDeployEC2ICEResponse is the response after creating an AWS EC2 Instance Connect Endpoint. -type AWSOIDCDeployEC2ICEResponse struct { - // Name is the name of the endpoint that was created. - // If multiple endpoints were created, this will contain all of them joined by a `,`. - // Eg, eice-1,eice-2 - // Deprecated: use Endpoints instead. - Name string `json:"name"` - - // Endpoints is a list of created endpoints - Endpoints []AWSOIDCDeployEC2ICEResponseEndpoint `json:"endpoints"` -} - -// AWSOIDCDeployEC2ICEResponseEndpoint describes a single endpoint that was created. -type AWSOIDCDeployEC2ICEResponseEndpoint struct { - // Name is the EC2 Instance Connect Endpoint name. - Name string `json:"name"` - // SubnetID is the subnet where this endpoint was created. - SubnetID string `json:"subnetId"` -} - // AWSOIDCPingResponse contains the result of the Ping request. // This response contains meta information about the current state of the Integration. type AWSOIDCPingResponse struct { diff --git a/tool/teleport/common/integration_configure.go b/tool/teleport/common/integration_configure.go index 26f8d93896853..514f61b2ab84b 100644 --- a/tool/teleport/common/integration_configure.go +++ b/tool/teleport/common/integration_configure.go @@ -64,24 +64,6 @@ func onIntegrationConfDeployService(ctx context.Context, params config.Integrati return trace.Wrap(awsoidc.ConfigureDeployServiceIAM(ctx, iamClient, confReq)) } -func onIntegrationConfEICEIAM(ctx context.Context, params config.IntegrationConfEICEIAM) error { - // Ensure we print output to the user. LogLevel at this point was set to Error. - utils.InitLogger(utils.LoggingForDaemon, slog.LevelInfo) - - clt, err := awsoidc.NewEICEIAMConfigureClient(ctx, params.Region) - if err != nil { - return trace.Wrap(err) - } - - confReq := awsoidc.EICEIAMConfigureRequest{ - Region: params.Region, - IntegrationRole: params.Role, - AccountID: params.AccountID, - AutoConfirm: params.AutoConfirm, - } - return trace.Wrap(awsoidc.ConfigureEICEIAM(ctx, clt, confReq)) -} - func onIntegrationConfEC2SSMIAM(ctx context.Context, params config.IntegrationConfEC2SSMIAM) error { // Ensure we print output to the user. LogLevel at this point was set to Error. utils.InitLogger(utils.LoggingForDaemon, slog.LevelInfo) diff --git a/tool/teleport/common/teleport.go b/tool/teleport/common/teleport.go index 02d45ed828632..6c5b673bf5147 100644 --- a/tool/teleport/common/teleport.go +++ b/tool/teleport/common/teleport.go @@ -479,12 +479,6 @@ func Run(options Options) (app *kingpin.Application, executedCommand string, con integrationConfDeployServiceCmd.Flag("aws-account-id", "The AWS account ID.").StringVar(&ccf.IntegrationConfDeployServiceIAMArguments.AccountID) integrationConfDeployServiceCmd.Flag("confirm", "Apply changes without confirmation prompt.").BoolVar(&ccf.IntegrationConfDeployServiceIAMArguments.AutoConfirm) - integrationConfEICECmd := integrationConfigureCmd.Command("eice-iam", "Adds required IAM permissions to connect to EC2 Instances using EC2 Instance Connect Endpoint.") - integrationConfEICECmd.Flag("aws-region", "AWS Region.").Required().StringVar(&ccf.IntegrationConfEICEIAMArguments.Region) - integrationConfEICECmd.Flag("role", "The AWS Role used by the AWS OIDC Integration.").Required().StringVar(&ccf.IntegrationConfEICEIAMArguments.Role) - integrationConfEICECmd.Flag("aws-account-id", "The AWS account ID.").StringVar(&ccf.IntegrationConfEICEIAMArguments.AccountID) - integrationConfEICECmd.Flag("confirm", "Apply changes without confirmation prompt.").BoolVar(&ccf.IntegrationConfEICEIAMArguments.AutoConfirm) - integrationConfEC2SSMCmd := integrationConfigureCmd.Command("ec2-ssm-iam", "Adds required IAM permissions and SSM Document to enable EC2 Auto Discover using SSM.") integrationConfEC2SSMCmd.Flag("role", "The AWS Role name used by the AWS OIDC Integration.").Required().StringVar(&ccf.IntegrationConfEC2SSMIAMArguments.RoleName) integrationConfEC2SSMCmd.Flag("aws-region", "AWS Region.").Required().StringVar(&ccf.IntegrationConfEC2SSMIAMArguments.Region) @@ -713,8 +707,6 @@ Examples: err = onJoinOpenSSH(ccf, conf) case integrationConfDeployServiceCmd.FullCommand(): err = onIntegrationConfDeployService(ctx, ccf.IntegrationConfDeployServiceIAMArguments) - case integrationConfEICECmd.FullCommand(): - err = onIntegrationConfEICEIAM(ctx, ccf.IntegrationConfEICEIAMArguments) case integrationConfEC2SSMCmd.FullCommand(): err = onIntegrationConfEC2SSMIAM(ctx, ccf.IntegrationConfEC2SSMIAMArguments) case integrationConfAWSAppAccessCmd.FullCommand(): diff --git a/web/packages/teleport/src/Discover/Server/CreateEc2Ice/CreateEc2Ice.story.tsx b/web/packages/teleport/src/Discover/Server/CreateEc2Ice/CreateEc2Ice.story.tsx deleted file mode 100644 index 185575a1fc8e1..0000000000000 --- a/web/packages/teleport/src/Discover/Server/CreateEc2Ice/CreateEc2Ice.story.tsx +++ /dev/null @@ -1,496 +0,0 @@ -/** - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import { delay, http, HttpResponse } from 'msw'; -import { MemoryRouter } from 'react-router'; - -import { Info } from 'design/Alert'; - -import { ContextProvider } from 'teleport'; -import cfg from 'teleport/config'; -import { - DiscoverContextState, - DiscoverProvider, -} from 'teleport/Discover/useDiscover'; -import { createTeleportContext } from 'teleport/mocks/contexts'; -import { - Ec2InstanceConnectEndpoint, - IntegrationKind, - IntegrationStatusCode, -} from 'teleport/services/integrations'; - -import { CreateEc2Ice } from './CreateEc2Ice'; - -export default { - title: 'Teleport/Discover/Server/EC2/CreateEICE', -}; - -const mockedCreatedEc2Ice: Ec2InstanceConnectEndpoint = { - name: 'test-eice', - state: 'create-complete', - stateMessage: '', - dashboardLink: 'goteleport.com', - subnetId: 'test-subnetid', - vpcId: 'test', -}; - -const deployEndpointSuccess = http.post( - cfg.getDeployEc2InstanceConnectEndpointUrl('test-oidc'), - () => HttpResponse.json({ name: 'test-eice' }) -); - -let tick = 0; -const ec2IceEndpointWithTick = http.post( - cfg.getListEc2InstanceConnectEndpointsUrl('test-oidc'), - () => { - if (tick == 1) { - tick = 0; // reset, the polling will be finished by this point. - return HttpResponse.json({ - ec2Ices: [mockedCreatedEc2Ice], - }); - } - tick += 1; - return HttpResponse.json({ - ec2Ices: [{ ...mockedCreatedEc2Ice, state: 'create-in-progress' }], - }); - } -); - -export const AutoDiscoverEnabled = () => ( - <> - - Devs: after clicking next, wait 10 seconds for in progress to change to - created - - - -); -AutoDiscoverEnabled.parameters = { - msw: { - handlers: [deployEndpointSuccess, ec2IceEndpointWithTick], - }, -}; - -export const ListSecurityGroupsLoading = () => ; - -ListSecurityGroupsLoading.parameters = { - msw: { - handlers: [ - http.post(cfg.getListSecurityGroupsUrl('test-oidc'), () => - delay('infinite') - ), - ], - }, -}; - -export const ListSecurityGroupsFail = () => ; - -ListSecurityGroupsFail.parameters = { - msw: { - handlers: [ - http.post(cfg.getListSecurityGroupsUrl('test-oidc'), () => - HttpResponse.json( - { - message: 'some error when trying to list security groups', - }, - { status: 403 } - ) - ), - ], - }, -}; - -export const DeployEiceFail = () => ( - <> - To trigger this Story's state, click on "Next." - - -); - -DeployEiceFail.parameters = { - msw: { - handlers: [ - http.post(cfg.getListSecurityGroupsUrl('test-oidc'), () => - HttpResponse.json({ securityGroups: securityGroupsResponse }) - ), - http.post(cfg.getDeployEc2InstanceConnectEndpointUrl('test-oidc'), () => - HttpResponse.json( - { - message: 'some error when trying to initiate the deployment', - }, - { status: 403 } - ) - ), - ], - }, -}; - -export const CreatingInProgress = () => ( - <> - To trigger this Story's state, click on "Next." - - -); - -CreatingInProgress.parameters = { - msw: { - handlers: [ - http.post(cfg.getListSecurityGroupsUrl('test-oidc'), () => - HttpResponse.json({ securityGroups: securityGroupsResponse }) - ), - http.post(cfg.getListEc2InstanceConnectEndpointsUrl('test-oidc'), () => - HttpResponse.json({ - ec2Ices: [ - { - name: 'test-eice', - state: 'create-in-progress', - stateMessage: '', - dashboardLink: 'goteleport.com', - subnetId: 'test-subnetid', - }, - ], - nextToken: '', - }) - ), - deployEndpointSuccess, - ], - }, -}; - -export const CreatingFailed = () => ( - <> - {' '} - - To trigger this Story's state, click on "Next" and wait 10 seconds. - - - -); - -CreatingFailed.parameters = { - msw: { - handlers: [ - http.post(cfg.getListSecurityGroupsUrl('test-oidc'), () => - HttpResponse.json({ securityGroups: securityGroupsResponse }) - ), - http.post(cfg.getListEc2InstanceConnectEndpointsUrl('test-oidc'), () => - HttpResponse.json({ - ec2Ices: [ - { - name: 'test-eice', - state: 'create-failed', - stateMessage: '', - dashboardLink: 'goteleport.com', - subnetId: 'test-subnetid', - }, - ], - nextToken: '', - }) - ), - deployEndpointSuccess, - ], - }, -}; - -export const CreatingComplete = () => ( - <> - - To trigger this Story's state, click on "Next" and wait 10 seconds. - - - -); - -CreatingComplete.parameters = { - msw: { - handlers: [ - http.post(cfg.getListSecurityGroupsUrl('test-oidc'), () => - HttpResponse.json({ securityGroups: securityGroupsResponse }) - ), - http.post(cfg.getDeployEc2InstanceConnectEndpointUrl('test-oidc'), () => - HttpResponse.json({ name: 'test-eice' }) - ), - http.post(cfg.getListEc2InstanceConnectEndpointsUrl('test-oidc'), () => - HttpResponse.json({ - ec2Ices: [ - { - name: 'test-eice', - state: 'create-complete', - stateMessage: '', - dashboardLink: 'goteleport.com', - subnetId: 'test-subnetid', - }, - ], - nextToken: '', - }) - ), - http.post(cfg.getClusterNodesUrlNoParams('localhost'), async () => { - await delay(2000); - return HttpResponse.json({ - id: 'ec2-instance-1', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-1', - labels: [{ name: 'instance', value: 'ec2-1' }], - addr: 'ec2.1.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - aws: { - accountId: 'test-account', - instanceId: 'instance-ec2-1', - region: 'us-east-1', - vpcId: 'test', - integration: 'test', - subnetId: 'test', - }, - }); - }), - ], - }, -}; - -const Component = ({ autoDiscover = false }: { autoDiscover?: boolean }) => { - const ctx = createTeleportContext(); - const discoverCtx: DiscoverContextState = { - agentMeta: { - awsRegion: 'us-east-1', - resourceName: 'node-name', - agentMatcherLabels: [], - node: { - kind: 'node', - subKind: 'openssh-ec2-ice', - id: 'test-node', - hostname: 'test-node-hostname', - clusterId: 'localhost', - labels: [], - addr: 'test', - tunnel: false, - sshLogins: [], - awsMetadata: { - accountId: 'test-account', - integration: 'test-oidc', - instanceId: 'i-test', - subnetId: 'test', - vpcId: 'test-vpc', - region: 'us-east-1', - }, - }, - awsIntegration: { - kind: IntegrationKind.AwsOidc, - name: 'test-oidc', - resourceType: 'integration', - spec: { - roleArn: 'arn-123', - issuerS3Bucket: '', - issuerS3Prefix: '', - }, - statusCode: IntegrationStatusCode.Running, - }, - autoDiscovery: autoDiscover - ? { - config: { name: '', discoveryGroup: '', aws: [] }, - requiredVpcsAndSubnets: { - 'vpc-1': ['subnet-1'], - 'vpc-2': ['subnet-2'], - }, - } - : undefined, - }, - updateAgentMeta: agentMeta => { - discoverCtx.agentMeta = agentMeta; - }, - currentStep: 0, - nextStep: () => null, - prevStep: () => null, - onSelectResource: () => null, - resourceSpec: {} as any, - exitFlow: () => null, - viewConfig: null, - indexedViews: [], - setResourceSpec: () => null, - emitErrorEvent: () => null, - emitEvent: () => null, - eventState: null, - }; - - cfg.proxyCluster = 'localhost'; - return ( - - - - - - - - ); -}; - -const securityGroupsResponse = [ - { - name: 'security-group-1', - id: 'sg-1', - description: 'this is security group 1', - inboundRules: [ - { - ipProtocol: 'tcp', - fromPort: '0', - toPort: '0', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '443', - toPort: '443', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '2000', - toPort: '5000', - cidrs: [ - { cidr: '192.168.1.0/24', description: 'Subnet Mask 255.255.255.0' }, - ], - }, - ], - outboundRules: [ - { - ipProtocol: 'tcp', - fromPort: '0', - toPort: '0', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '22', - toPort: '22', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '2000', - toPort: '5000', - cidrs: [ - { cidr: '10.0.0.0/16', description: 'Subnet Mask 255.255.0.0"' }, - ], - }, - ], - }, - { - name: 'security-group-2', - id: 'sg-2', - description: 'this is security group 2', - inboundRules: [ - { - ipProtocol: 'tcp', - fromPort: '0', - toPort: '0', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '443', - toPort: '443', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '2000', - toPort: '5000', - cidrs: [ - { cidr: '192.168.1.0/24', description: 'Subnet Mask 255.255.255.0' }, - ], - }, - ], - outboundRules: [ - { - ipProtocol: 'tcp', - fromPort: '0', - toPort: '0', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '22', - toPort: '22', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '2000', - toPort: '5000', - cidrs: [ - { cidr: '10.0.0.0/16', description: 'Subnet Mask 255.255.0.0"' }, - ], - }, - ], - }, - { - name: 'security-group-3', - id: 'sg-3', - description: 'this is security group 3', - inboundRules: [ - { - ipProtocol: 'tcp', - fromPort: '0', - toPort: '0', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '443', - toPort: '443', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '2000', - toPort: '5000', - cidrs: [ - { cidr: '192.168.1.0/24', description: 'Subnet Mask 255.255.255.0' }, - ], - }, - ], - outboundRules: [ - { - ipProtocol: 'tcp', - fromPort: '0', - toPort: '0', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '22', - toPort: '22', - cidrs: [{ cidr: '0.0.0.0/0', description: 'Everything' }], - }, - { - ipProtocol: 'tcp', - fromPort: '2000', - toPort: '5000', - cidrs: [ - { cidr: '10.0.0.0/16', description: 'Subnet Mask 255.255.0.0"' }, - ], - }, - ], - }, -]; diff --git a/web/packages/teleport/src/Discover/Server/CreateEc2Ice/CreateEc2Ice.tsx b/web/packages/teleport/src/Discover/Server/CreateEc2Ice/CreateEc2Ice.tsx deleted file mode 100644 index b3f23146fcb84..0000000000000 --- a/web/packages/teleport/src/Discover/Server/CreateEc2Ice/CreateEc2Ice.tsx +++ /dev/null @@ -1,320 +0,0 @@ -/** - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import React, { useEffect, useState } from 'react'; - -import { Box, Flex, H3, Indicator, Text } from 'design'; -import { Danger } from 'design/Alert'; -import Table from 'design/DataTable'; -import { FetchStatus } from 'design/DataTable/types'; -import { Warning } from 'design/Icon'; -import useAttempt, { Attempt } from 'shared/hooks/useAttemptNext'; -import { getErrMessage } from 'shared/utils/errorType'; - -import { - ActionButtons, - ButtonBlueText, - Header, - SecurityGroupPicker, -} from 'teleport/Discover/Shared'; -import { NodeMeta, useDiscover } from 'teleport/Discover/useDiscover'; -import { - AwsOidcDeployEc2InstanceConnectEndpointRequest, - integrationService, - SecurityGroup, -} from 'teleport/services/integrations'; -import { - DiscoverEvent, - DiscoverEventStatus, -} from 'teleport/services/userEvent'; - -import { CreateEc2IceDialog } from './CreateEc2IceDialog'; - -type TableData = { - items: SecurityGroup[]; - nextToken?: string; - fetchStatus: FetchStatus; -}; - -export function CreateEc2Ice() { - const [showCreatingDialog, setShowCreatingDialog] = useState(false); - const [selectedSecurityGroups, setSelectedSecurityGroups] = useState< - string[] - >([]); - const [tableData, setTableData] = useState({ - items: [], - nextToken: '', - fetchStatus: 'disabled', - }); - - const { - attempt: fetchSecurityGroupsAttempt, - setAttempt: setFetchSecurityGroupsAttempt, - } = useAttempt(''); - - const { attempt: deployEc2IceAttempt, setAttempt: setDeployEc2IceAttempt } = - useAttempt(''); - - const { emitErrorEvent, agentMeta, prevStep, nextStep, emitEvent } = - useDiscover(); - - const autoDiscoverEnabled = !!agentMeta.autoDiscovery; - - useEffect(() => { - // It has been decided for now that with auto discover, - // default security groups will be used (in the request - // this is depicted as an empty value) - if (!autoDiscoverEnabled) { - fetchSecurityGroups(); - } - }, []); - - function onSelectSecurityGroup( - sg: SecurityGroup, - e: React.ChangeEvent - ) { - if (e.target.checked) { - return setSelectedSecurityGroups([...selectedSecurityGroups, sg.id]); - } else { - setSelectedSecurityGroups( - selectedSecurityGroups.filter(id => id !== sg.id) - ); - } - } - - async function fetchSecurityGroups() { - const integration = agentMeta.awsIntegration; - - setFetchSecurityGroupsAttempt({ status: 'processing' }); - try { - const { securityGroups, nextToken } = - await integrationService.fetchSecurityGroups(integration.name, { - vpcId: (agentMeta as NodeMeta).node.awsMetadata.vpcId, - region: (agentMeta as NodeMeta).node.awsMetadata.region, - nextToken: tableData.nextToken, - }); - - setFetchSecurityGroupsAttempt({ status: 'success' }); - setTableData({ - nextToken: nextToken, - fetchStatus: nextToken ? '' : 'disabled', - items: [...tableData.items, ...securityGroups], - }); - } catch (err) { - const errMsg = getErrMessage(err); - setFetchSecurityGroupsAttempt({ status: 'failed', statusText: errMsg }); - emitErrorEvent(`fetch security groups error: ${errMsg}`); - } - } - - async function deployEc2InstanceConnectEndpoint() { - const integration = agentMeta.awsIntegration; - - let endpoints: AwsOidcDeployEc2InstanceConnectEndpointRequest[] = []; - if (autoDiscoverEnabled) { - endpoints = Object.values( - agentMeta.autoDiscovery.requiredVpcsAndSubnets - ).map(subnets => ({ - // Being in this step of the flow means - // the requiredVpcsAndSubnets will always - // be defined. - subnetId: subnets[0], - })); - } else { - endpoints = [ - { - subnetId: (agentMeta as NodeMeta).node.awsMetadata.subnetId, - ...(selectedSecurityGroups.length && { - securityGroupIds: selectedSecurityGroups, - }), - }, - ]; - } - - setDeployEc2IceAttempt({ status: 'processing' }); - setShowCreatingDialog(true); - try { - await integrationService.deployAwsEc2InstanceConnectEndpoints( - integration.name, - { - region: agentMeta.awsRegion, - endpoints, - } - ); - // Capture event for deploying EICE. - emitEvent( - { stepStatus: DiscoverEventStatus.Success }, - { - eventName: DiscoverEvent.EC2DeployEICE, - } - ); - setDeployEc2IceAttempt({ status: 'success' }); - } catch (err) { - const errMsg = getErrMessage(err); - setShowCreatingDialog(false); - setDeployEc2IceAttempt({ status: 'failed', statusText: errMsg }); - // Capture error event for failing to deploy EICE. - emitEvent( - { stepStatus: DiscoverEventStatus.Error, stepStatusError: errMsg }, - { - eventName: DiscoverEvent.EC2DeployEICE, - } - ); - } - } - - function handleOnProceed() { - deployEc2InstanceConnectEndpoint(); - } - - return ( - <> - -
- {autoDiscoverEnabled - ? 'Create EC2 Instance Connect Endpoints' - : 'Create an EC2 Instance Connect Endpoint'} -
- - {deployEc2IceAttempt.status === 'failed' && ( - {deployEc2IceAttempt.statusText} - )} - {autoDiscoverEnabled ? ( - - ) : ( - - )} - - handleOnProceed()} - disableProceed={deployEc2IceAttempt.status === 'processing'} - /> -
- {showCreatingDialog && ( - deployEc2InstanceConnectEndpoint()} - /> - )} - - ); -} - -function CreateEndpointsForAutoDiscover({ - requiredVpcIdsAndSubnets, -}: { - requiredVpcIdsAndSubnets: Record; -}) { - const items = Object.keys(requiredVpcIdsAndSubnets).map(key => ({ - vpcId: key, - subnetId: requiredVpcIdsAndSubnets[key][0], - })); - - return ( - - - EC2 Instance Connect Endpoints will be created for the following VPC - ID's: - - - - ); -} - -function SecurityGroups({ - fetchSecurityGroupsAttempt, - fetchSecurityGroups, - tableData, - onSelectSecurityGroup, - selectedSecurityGroups, -}: { - fetchSecurityGroupsAttempt: Attempt; - fetchSecurityGroups(): Promise; - tableData: TableData; - onSelectSecurityGroup( - sg: SecurityGroup, - e: React.ChangeEvent - ): void; - selectedSecurityGroups: string[]; -}) { - return ( - <> -

- Select AWS Security Groups to assign to the new EC2 Instance Connect - Endpoint: -

- - The security groups you pick should allow outbound connectivity for the - agent to be able to dial Teleport clusters. If you don't select any - security groups, the default one for the VPC will be used. - - {fetchSecurityGroupsAttempt.status === 'failed' && ( - <> - - - {fetchSecurityGroupsAttempt.statusText} - - - Retry - - - )} - {fetchSecurityGroupsAttempt.status === 'processing' && ( - - - - )} - {fetchSecurityGroupsAttempt.status === 'success' && ( - - fetchSecurityGroups()} - fetchStatus={tableData.fetchStatus} - onSelectSecurityGroup={onSelectSecurityGroup} - selectedSecurityGroups={selectedSecurityGroups} - /> - - )} - - ); -} diff --git a/web/packages/teleport/src/Discover/Server/CreateEc2Ice/CreateEc2IceDialog.tsx b/web/packages/teleport/src/Discover/Server/CreateEc2Ice/CreateEc2IceDialog.tsx deleted file mode 100644 index 5751259bc2c19..0000000000000 --- a/web/packages/teleport/src/Discover/Server/CreateEc2Ice/CreateEc2IceDialog.tsx +++ /dev/null @@ -1,378 +0,0 @@ -/** - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import { useEffect, useState } from 'react'; - -import { - AnimatedProgressBar, - Box, - ButtonPrimary, - Flex, - Link, - Mark, - Text, -} from 'design'; -import Dialog, { DialogContent } from 'design/DialogConfirmation'; -import * as Icons from 'design/Icon'; -import useAttempt, { Attempt } from 'shared/hooks/useAttemptNext'; -import { getErrMessage } from 'shared/utils/errorType'; - -import cfg from 'teleport/config'; -import { TextIcon } from 'teleport/Discover/Shared'; -import { usePoll } from 'teleport/Discover/Shared/usePoll'; -import { NodeMeta, useDiscover } from 'teleport/Discover/useDiscover'; -import { - Ec2InstanceConnectEndpoint, - integrationService, -} from 'teleport/services/integrations'; -import { - DiscoverEvent, - DiscoverEventStatus, -} from 'teleport/services/userEvent'; -import useTeleport from 'teleport/useTeleport'; - -export function CreateEc2IceDialog({ - nextStep, - retry, - existingEices = null, -}: { - nextStep: () => void; - retry?: () => void; - // Only supplied if there exists all the required ec2 - // instance connect endpoints, resulting in the user - // being able to skip the `eice deployment` step. - // Though the endpoints might all exist they may not all be - // in the `create-complete` state, which means polling - // for this endpoint is required until it becomes - // `create-complete`. - // If this field is NOT supplied, then new endpoints - // have been deployed which also needs to be polled - // until `create-complete`. - existingEices?: Ec2InstanceConnectEndpoint[]; -}) { - const { nodeService } = useTeleport(); - - // If the EICE already exists from the previous step and is - // create-complete, we don't need to do any polling for the EICE. - const [isPollingActive, setIsPollingActive] = useState(() => - existingEices - ? existingEices.some(e => e.state !== 'create-complete') - : true - ); - const [mainDashboardLink, setMainDashboardLink] = useState(''); - - const { emitErrorEvent, updateAgentMeta, agentMeta, emitEvent } = - useDiscover(); - const typedAgentMeta = agentMeta as NodeMeta; - const autoDiscoverEnabled = !!typedAgentMeta.autoDiscovery; - - const { attempt: fetchEc2IceAttempt, setAttempt: setFetchEc2IceAttempt } = - useAttempt(''); - const { attempt: createNodeAttempt, setAttempt: setCreateNodeAttempt } = - useAttempt(''); - - // When the EICE's state is 'create-complete', create the node. - useEffect(() => { - // Auto discovery will automatically create the discovered - // nodes in the backend. - if (autoDiscoverEnabled) return; - - if (typedAgentMeta.ec2Ices?.every(e => e.state === 'create-complete')) { - createNode(); - } - }, [typedAgentMeta.ec2Ices]); - - let ec2Ices = usePoll( - () => - fetchEc2InstanceConnectEndpoints().then(endpoints => { - if (endpoints?.every(e => e.state === 'create-complete')) { - setIsPollingActive(false); - updateAgentMeta({ - ...typedAgentMeta, - ec2Ices: endpoints, - }); - } - return endpoints; - }), - isPollingActive, - 10000 // poll every 10 seconds - ); - - // If the EICE already existed from the previous step and was create-complete, we set - // `ec2Ice` to it. - if (existingEices?.every(e => e.state === 'create-complete')) { - ec2Ices = existingEices; - } - - async function fetchEc2InstanceConnectEndpoints() { - let vpcIds: string[] = []; - if (autoDiscoverEnabled) { - const requiredVpcs = Object.keys( - typedAgentMeta.autoDiscovery.requiredVpcsAndSubnets - ); - const inprogressExistingEndpoints = - typedAgentMeta.ec2Ices - ?.filter(e => e.state === 'create-in-progress') - .map(e => e.vpcId) ?? []; - vpcIds = [...requiredVpcs, ...inprogressExistingEndpoints]; - } else { - vpcIds = [typedAgentMeta.node.awsMetadata.vpcId]; - } - - setFetchEc2IceAttempt({ status: 'processing' }); - try { - const resp = await integrationService.fetchAwsEc2InstanceConnectEndpoints( - typedAgentMeta.awsIntegration.name, - { - region: typedAgentMeta.awsRegion, - vpcIds, - } - ); - - setMainDashboardLink(resp.dashboardLink); - setFetchEc2IceAttempt({ status: 'success' }); - - const endpoints = resp.endpoints.filter( - e => - e.state === 'create-complete' || - e.state === 'create-in-progress' || - e.state === 'create-failed' - ); - - if (endpoints.length > 0) { - return endpoints; - } - } catch { - // eslint-disable-next-line no-empty - // Ignore any errors, as the poller will keep re-trying. - } - } - - async function createNode() { - setCreateNodeAttempt({ status: 'processing' }); - try { - const node = await nodeService.createNode(cfg.proxyCluster, { - hostname: typedAgentMeta.node.hostname, - addr: typedAgentMeta.node.addr, - labels: typedAgentMeta.node.labels, - aws: typedAgentMeta.node.awsMetadata, - name: typedAgentMeta.node.id, - subKind: 'openssh-ec2-ice', - }); - - updateAgentMeta({ - ...typedAgentMeta, - node, - resourceName: node.id, - }); - setCreateNodeAttempt({ status: 'success' }); - - // Capture event for creating the Node. - emitEvent( - { stepStatus: DiscoverEventStatus.Success }, - { - eventName: DiscoverEvent.CreateNode, - } - ); - } catch (err) { - const errMsg = getErrMessage(err); - setCreateNodeAttempt({ status: 'failed', statusText: errMsg }); - setIsPollingActive(false); - emitErrorEvent(`error creating teleport node: ${errMsg}`); - } - } - - const endpointsCreated = ec2Ices?.every(e => e.state === 'create-complete'); - - let content: JSX.Element; - if ( - fetchEc2IceAttempt.status === 'failed' || - createNodeAttempt.status === 'failed' - ) { - content = ( - <> - - {' '} - - - {fetchEc2IceAttempt.status === 'failed' - ? fetchEc2IceAttempt.statusText - : createNodeAttempt.statusText} - - - - {!!retry && ( - - Retry - - )} - - - ); - } else { - if (ec2Ices?.some(e => e.state === 'create-failed')) { - content = ( - <> - - - - - We couldn't create some EC2 Instance Connect Endpoints. -
- Please visit your{' '} - - dashboard{' '} - - to troubleshoot. -
- We'll keep looking for the endpoint until it becomes available. -
-
- - Next - - - ); - } else if (createNodeAttempt.status === 'success' && endpointsCreated) { - content = ( - <> - - - - The EC2 instance [{typedAgentMeta?.node.awsMetadata.instanceId}] has - been added to Teleport. - - nextStep()}> - Next - - - ); - } else if (autoDiscoverEnabled && endpointsCreated) { - content = ( - <> - - - - - All endpoints required are created. The discovery service can take - a few minutes to finish auto-enrolling resources found in region{' '} - {typedAgentMeta.awsRegion}. - - - nextStep()}> - Next - - - ); - } else { - content = ( - <> - - - - - This may take a few minutes.. - - {!endpointsCreated && mainDashboardLink && ( - - Meanwhile, visit your{' '} - - dashboard - {' '} - to view the status of{' '} - {autoDiscoverEnabled ? 'each endpoint' : 'this endpoint'} - - )} - - - Next - - - ); - } - } - - let title = 'Creating EC2 Instance Connect Endpoints'; - - if (!autoDiscoverEnabled && endpointsCreated) { - if (createNodeAttempt.status === 'success') { - title = 'Created Teleport Node'; - } else { - title = 'Creating Teleport Node'; - } - } - - return ( - - - - {title} - - {content} - - - ); -} - -export type CreateEc2IceDialogProps = { - ec2Ice: Ec2InstanceConnectEndpoint; - fetchEc2IceAttempt: Attempt; - createNodeAttempt: Attempt; - retry: () => void; - next: () => void; -}; - -function EndpointSuccessfullyDeployed({ - existingEices, -}: { - existingEices: Ec2InstanceConnectEndpoint[]; -}) { - // Don't show this message if the EICE had already been deployed before this step. - if (!existingEices?.every(e => e.state === 'create-complete')) { - return ( - - - The EC2 Instance Connect Endpoints are successfully deployed. - - ); - } -} diff --git a/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/Ec2InstanceList.tsx b/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/Ec2InstanceList.tsx deleted file mode 100644 index fa824991e2ac0..0000000000000 --- a/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/Ec2InstanceList.tsx +++ /dev/null @@ -1,154 +0,0 @@ -/** - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import { Text } from 'design'; -import Table from 'design/DataTable'; -import { FetchStatus } from 'design/DataTable/types'; -import { Attempt } from 'shared/hooks/useAttemptNext'; - -import { - DisableableCell as Cell, - labelMatcher, - Labels, - RadioCell, -} from 'teleport/Discover/Shared'; - -import { CheckedEc2Instance } from './EnrollEc2Instance'; - -type Props = { - attempt: Attempt; - items: CheckedEc2Instance[]; - fetchStatus: FetchStatus; - fetchNextPage(): void; - onSelectInstance(item: CheckedEc2Instance): void; - selectedInstance?: CheckedEc2Instance; - wantAutoDiscover: boolean; -}; - -export const Ec2InstanceList = ({ - attempt, - items = [], - fetchStatus = '', - fetchNextPage, - onSelectInstance, - selectedInstance, - wantAutoDiscover, -}: Props) => { - const hasError = attempt.status === 'failed'; - - return ( - <> - {!hasError && ( -
{ - const isChecked = - item.awsMetadata.instanceId === - selectedInstance?.awsMetadata.instanceId; - return ( - - item={item} - key={item.awsMetadata.instanceId} - isChecked={isChecked} - onChange={onSelectInstance} - value={item.awsMetadata.instanceId} - {...disabledStates( - item.ec2InstanceExists, - wantAutoDiscover - )} - /> - ); - }, - }, - { - altKey: 'name', - headerText: 'Name', - render: ({ labels, ec2InstanceExists }) => ( - - {labels.find(label => label.name === 'Name')?.value} - - ), - }, - { - key: 'hostname', - headerText: 'Hostname', - render: ({ hostname, ec2InstanceExists }) => ( - - {hostname} - - ), - }, - { - key: 'addr', - headerText: 'Address', - render: ({ addr, ec2InstanceExists }) => ( - - {addr} - - ), - }, - { - altKey: 'instanceId', - headerText: 'AWS Instance ID', - render: ({ awsMetadata, ec2InstanceExists }) => ( - - - {awsMetadata.instanceId} - - - ), - }, - { - key: 'labels', - headerText: 'Labels', - render: ({ labels, ec2InstanceExists }) => ( - - - - ), - }, - ]} - emptyText="No Results" - pagination={{ pageSize: 10 }} - customSearchMatchers={[labelMatcher]} - fetching={{ onFetchMore: fetchNextPage, fetchStatus }} - isSearchable - /> - )} - - ); -}; - -function disabledStates(ec2InstanceExists: boolean, wantAutoDiscover: boolean) { - const disabled = wantAutoDiscover || ec2InstanceExists; - - let disabledText = `This EC2 instance is already enrolled and is a part of this cluster`; - if (wantAutoDiscover) { - disabledText = 'All eligible EC2 instances will be enrolled automatically'; - } - - return { disabled, disabledText }; -} diff --git a/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/EnrollEc2Instance.story.tsx b/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/EnrollEc2Instance.story.tsx deleted file mode 100644 index 5ec6df825e5d7..0000000000000 --- a/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/EnrollEc2Instance.story.tsx +++ /dev/null @@ -1,417 +0,0 @@ -/** - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import { delay, http, HttpResponse } from 'msw'; -import { useEffect } from 'react'; -import { MemoryRouter } from 'react-router'; - -import { Info } from 'design/Alert'; - -import { ContextProvider } from 'teleport'; -import cfg from 'teleport/config'; -import { - DiscoverContextState, - DiscoverProvider, -} from 'teleport/Discover/useDiscover'; -import { createTeleportContext } from 'teleport/mocks/contexts'; -import { - Ec2InstanceConnectEndpoint, - IntegrationKind, - IntegrationStatusCode, -} from 'teleport/services/integrations'; - -import { EnrollEc2Instance } from './EnrollEc2Instance'; - -const defaultIsCloud = cfg.isCloud; -export default { - title: 'Teleport/Discover/Server/EC2/InstanceList', - decorators: [ - Story => { - useEffect(() => { - // Clean up - return () => { - cfg.isCloud = defaultIsCloud; - }; - }, []); - return ; - }, - ], -}; - -const baseHandlers = [ - http.post(cfg.getListEc2InstancesUrl('test-oidc'), () => - HttpResponse.json({ servers: ec2InstancesResponse }) - ), - http.get(cfg.getClusterNodesUrl('localhost'), () => - HttpResponse.json({ items: [ec2InstancesResponse[2]] }) - ), - http.post(cfg.api.discoveryConfigPath, () => HttpResponse.json({})), -]; - -let tick = 0; -const ec2IceEndpointWithTick = http.post( - cfg.getListEc2InstanceConnectEndpointsUrl('test-oidc'), - () => { - if (tick == 1) { - tick = 0; // reset, the polling will be finished by this point. - return HttpResponse.json({ - ec2Ices: [mockedCreatedEc2Ice], - }); - } - tick += 1; - return HttpResponse.json({ - ec2Ices: [{ ...mockedCreatedEc2Ice, state: 'create-in-progress' }], - }); - } -); - -const mockedCreatedEc2Ice: Ec2InstanceConnectEndpoint = { - name: 'test-eice', - state: 'create-complete', - stateMessage: '', - dashboardLink: 'goteleport.com', - subnetId: 'test-subnetid', - vpcId: 'test', -}; - -const mockedNode = { - id: '', - siteId: '', - subKind: 'teleport', - hostname: 'hostname', - addr: '', - tunnel: false, - tags: [], - sshLogins: [], - aws: {}, -}; - -export const SingleInstanceListCreated = () => ; -SingleInstanceListCreated.parameters = { - msw: { - handlers: [ - ...baseHandlers, - http.post(cfg.getListEc2InstanceConnectEndpointsUrl('test-oidc'), () => - HttpResponse.json({ - ec2Ices: [mockedCreatedEc2Ice], - }) - ), - http.post(cfg.api.nodesPathNoParams, () => HttpResponse.json(mockedNode)), - ], - }, -}; - -export const SingleInstanceListForCloudPending = () => { - cfg.isCloud = true; - return ( - <> - - Devs: Select region, after clicking next, wait 10 seconds for pending - state to go into created state - - - - ); -}; -SingleInstanceListForCloudPending.parameters = { - msw: { - handlers: [ - ...baseHandlers, - ec2IceEndpointWithTick, - http.post(cfg.api.nodesPathNoParams, () => HttpResponse.json(mockedNode)), - ], - }, -}; - -export const AutoDiscoverInstanceListForCloudCreated = () => { - cfg.isCloud = true; - return ; -}; -AutoDiscoverInstanceListForCloudCreated.parameters = { - msw: { - handlers: [ - ...baseHandlers, - http.post(cfg.getListEc2InstanceConnectEndpointsUrl('test-oidc'), () => - HttpResponse.json({ - ec2Ices: [mockedCreatedEc2Ice], - }) - ), - ], - }, -}; - -export const AutoDiscoverInstanceListForCloudPending = () => { - cfg.isCloud = true; - return ( - <> - - Devs: Select region, after clicking next, wait 10 seconds for pending - state to go into created state - - - - ); -}; -AutoDiscoverInstanceListForCloudPending.parameters = { - msw: { - handlers: [...baseHandlers, ec2IceEndpointWithTick], - }, -}; - -export const InstanceListLoading = () => ; -InstanceListLoading.parameters = { - msw: { - handlers: [ - http.post(cfg.getListEc2InstancesUrl('test-oidc'), () => - delay('infinite') - ), - ], - }, -}; - -export const WithAwsPermissionsError = () => ; - -WithAwsPermissionsError.parameters = { - msw: { - handlers: [ - http.post(cfg.api.ec2InstancesListPath, () => - HttpResponse.json( - { - message: 'StatusCode: 403, RequestID: operation error', - }, - { status: 403 } - ) - ), - ], - }, -}; - -export const WithOtherError = () => ; - -WithOtherError.parameters = { - msw: { - handlers: [ - http.post(cfg.getListEc2InstancesUrl('test-oidc'), () => - HttpResponse.json( - { - message: 'Some kind of error message', - }, - { status: 404 } - ) - ), - ], - }, -}; - -const Component = ({ - autoDiscover = false, - ec2Ices = [], -}: { - autoDiscover?: boolean; - ec2Ices?: Ec2InstanceConnectEndpoint[]; -}) => { - const ctx = createTeleportContext(); - const discoverCtx: DiscoverContextState = { - agentMeta: { - awsRegion: 'us-east-1', - resourceName: 'node-name', - agentMatcherLabels: [], - node: { - kind: 'node', - id: 'some-id', - clusterId: 'cluster-id', - hostname: 'some-hostname', - labels: [], - addr: '', - tunnel: false, - subKind: 'teleport', - sshLogins: [], - awsMetadata: { - accountId: 'aws-account-id', - instanceId: 'instance-id', - region: 'us-east-1', - vpcId: 'instance-vpc-id', - integration: 'integration-name', - subnetId: 'subnet-id', - }, - }, - ec2Ices: ec2Ices, - awsIntegration: { - kind: IntegrationKind.AwsOidc, - name: 'test-oidc', - resourceType: 'integration', - spec: { - roleArn: 'arn-123', - issuerS3Bucket: '', - issuerS3Prefix: '', - }, - statusCode: IntegrationStatusCode.Running, - }, - autoDiscovery: autoDiscover - ? { - config: { name: '', discoveryGroup: '', aws: [] }, - requiredVpcsAndSubnets: {}, - } - : undefined, - }, - currentStep: 0, - nextStep: () => null, - prevStep: () => null, - onSelectResource: () => null, - resourceSpec: {} as any, - exitFlow: () => null, - viewConfig: null, - indexedViews: [], - setResourceSpec: () => null, - updateAgentMeta: () => null, - emitErrorEvent: () => null, - emitEvent: () => null, - eventState: null, - }; - - cfg.proxyCluster = 'localhost'; - return ( - - - - - - - - ); -}; - -const ec2InstancesResponse = [ - { - id: 'ec2-instance-1', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-1', - tags: [ - { name: 'teleport.dev/instance-id', value: 'instance-ec2-1' }, - { name: 'Name', value: 'My EC2 Box 1' }, - ], - addr: 'ec2.1.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - aws: { - accountId: 'test-account', - instanceId: 'instance-ec2-1', - region: 'us-west-1', - vpcId: 'test', - integration: 'test', - subnetId: 'test', - }, - }, - { - id: 'ec2-instance-2', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-2', - tags: [ - { name: 'teleport.dev/instance-id', value: 'instance-ec2-2' }, - { name: 'Name', value: 'My EC2 Box 2' }, - ], - addr: 'ec2.2.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - aws: { - accountId: 'test-account', - instanceId: 'instance-ec2-2', - region: 'us-west-1', - vpcId: 'test', - integration: 'test', - subnetId: 'test', - }, - }, - { - id: 'ec2-instance-3', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-3', - tags: [ - { name: 'teleport.dev/instance-id', value: 'instance-ec2-3' }, - { name: 'Name', value: 'My EC2 Box 3' }, - ], - addr: 'ec2.3.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - aws: { - accountId: 'test-account', - instanceId: 'instance-ec2-3', - region: 'us-west-1', - vpcId: 'test', - integration: 'test', - subnetId: 'test', - }, - }, - { - id: 'ec2-instance-4', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-4', - tags: [ - { name: 'teleport.dev/instance-id', value: 'instance-ec2-4' }, - { name: 'Name', value: 'My EC2 Box 4' }, - ], - addr: 'ec2.4.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - aws: { - accountId: 'test-account', - instanceId: 'instance-ec2-4', - region: 'us-west-1', - vpcId: 'test', - integration: 'test', - subnetId: 'test', - }, - }, - { - id: 'ec2-instance-5', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-5', - tags: [ - { name: 'teleport.dev/instance-id', value: 'instance-ec2-5' }, - { name: 'Name', value: 'My EC2 Box 5' }, - ], - addr: 'ec2.5.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - aws: { - accountId: 'test-account', - instanceId: 'instance-ec2-5', - region: 'us-west-1', - vpcId: 'test', - integration: 'test', - subnetId: 'test', - }, - }, -]; diff --git a/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/EnrollEc2Instance.test.tsx b/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/EnrollEc2Instance.test.tsx deleted file mode 100644 index 0c9ab2a958cf3..0000000000000 --- a/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/EnrollEc2Instance.test.tsx +++ /dev/null @@ -1,726 +0,0 @@ -/** - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import { MemoryRouter } from 'react-router'; - -import { - act, - fireEvent, - render, - screen, - userEvent, -} from 'design/utils/testing'; - -import { ContextProvider } from 'teleport'; -import cfg from 'teleport/config'; -import { - DiscoverContextState, - DiscoverProvider, - NodeMeta, -} from 'teleport/Discover/useDiscover'; -import { FeaturesContextProvider } from 'teleport/FeaturesContext'; -import { createTeleportContext } from 'teleport/mocks/contexts'; -import * as discoveryApi from 'teleport/services/discovery/discovery'; -import { DEFAULT_DISCOVERY_GROUP_NON_CLOUD } from 'teleport/services/discovery/discovery'; -import { - Ec2InstanceConnectEndpoint, - IntegrationKind, - integrationService, - IntegrationStatusCode, -} from 'teleport/services/integrations'; -import { Node } from 'teleport/services/nodes'; -import { - DiscoverEvent, - DiscoverEventStatus, - userEventService, -} from 'teleport/services/userEvent'; -import TeleportContext from 'teleport/teleportContext'; - -import { EnrollEc2Instance } from './EnrollEc2Instance'; - -const defaultIsCloud = cfg.isCloud; - -describe('test EnrollEc2Instance.tsx', () => { - afterEach(() => { - cfg.isCloud = defaultIsCloud; - jest.restoreAllMocks(); - }); - - const selectedRegion = 'us-west-1'; - - async function selectARegion({ - waitForSelfHosted, - waitForTable, - }: { - waitForTable?: boolean; - waitForSelfHosted?: boolean; - }) { - const regionSelectorElement = screen.getByLabelText(/aws region/i); - fireEvent.focus(regionSelectorElement); - fireEvent.keyDown(regionSelectorElement, { key: 'ArrowDown', keyCode: 40 }); - fireEvent.click(screen.getByText(selectedRegion)); - - if (waitForTable) { - return await screen.findAllByText(/My EC2 Box 1/i); - } - - if (waitForSelfHosted) { - return await screen.findAllByText(/create a join token/i); - } - } - - test('a cloudshell script should be shown if there is an aws permissions error', async () => { - const { ctx, discoverCtx } = getMockedContexts(); - - jest - .spyOn(integrationService, 'fetchAwsEc2Instances') - .mockRejectedValue( - new Error('StatusCode: 403, RequestID: operation error') - ); - // Prevent noise in the test output caused by the error. - jest.spyOn(console, 'error').mockImplementation(); - - renderEc2Instances(ctx, discoverCtx); - await selectARegion({}); - - // Wait for results to be listed. - await screen.findAllByText( - /We were unable to list your EC2 instances. Run the command below/i - ); - - expect(integrationService.fetchAwsEc2Instances).toHaveBeenCalledTimes(1); - expect(ctx.nodeService.fetchNodes).not.toHaveBeenCalled(); - }); - - test('single instance, an instance that is already enrolled should be disabled', async () => { - const { ctx, discoverCtx } = getMockedContexts(); - - jest - .spyOn(integrationService, 'fetchAwsEc2Instances') - .mockResolvedValue({ instances: mockEc2Instances }); - - jest - .spyOn(ctx.nodeService, 'fetchNodes') - .mockResolvedValue({ agents: mockFetchedNodes }); - - renderEc2Instances(ctx, discoverCtx); - await selectARegion({ waitForTable: true }); - - expect(integrationService.fetchAwsEc2Instances).toHaveBeenCalledTimes(1); - expect(ctx.nodeService.fetchNodes).toHaveBeenCalledTimes(1); - - // Get the disabled table rows. - const disabledRowElements = screen - .getAllByTitle( - 'This EC2 instance is already enrolled and is a part of this cluster' - ) - // Only select the radio elements, this is to prevent duplicates since every - // column in the row will have the title we're querying for. - .filter(el => el.innerHTML.includes('type="radio"')) - // Get the row that the radio element is in. - .map(el => el.closest('tr')); - - // Expect the disabled row to be EC2 Box 2. - expect(disabledRowElements[0].innerHTML).toContain('My EC2 Box 2'); - // There should only be one disabled row. - expect(disabledRowElements).toHaveLength(1); - }); - - test('single instance, there should be no disabled rows if the fetchNodes response is empty', async () => { - const { ctx, discoverCtx } = getMockedContexts(); - - jest - .spyOn(integrationService, 'fetchAwsEc2Instances') - .mockResolvedValue({ instances: mockEc2Instances }); - - renderEc2Instances(ctx, discoverCtx); - await selectARegion({ waitForTable: true }); - - expect(integrationService.fetchAwsEc2Instances).toHaveBeenCalledTimes(1); - expect(ctx.nodeService.fetchNodes).toHaveBeenCalledTimes(1); - - // There should be no disabled rows. - expect( - screen.queryAllByTitle( - 'This EC2 instance is already enrolled and is a part of this cluster' - ) - ).toHaveLength(0); - }); - - test('self-hosted, auto discover toggling', async () => { - const { ctx, discoverCtx } = getMockedContexts(); - - jest - .spyOn(integrationService, 'fetchAwsEc2Instances') - .mockResolvedValue({ instances: mockEc2Instances }); - - renderEc2Instances(ctx, discoverCtx); - await selectARegion({ waitForTable: true }); - - // default toggler should not be checked. - expect(screen.getByTestId('toggle')).not.toBeChecked(); - expect(screen.getByText(/next/i, { selector: 'button' })).toBeDisabled(); - - // toggle on auto enroll, should render table. - await userEvent.click(screen.getByText(/auto-enroll all/i)); - expect(screen.getByTestId('toggle')).toBeChecked(); - expect(screen.getByText(/next/i, { selector: 'button' })).toBeEnabled(); - expect(screen.queryByText(/My EC2 Box 1/i)).not.toBeInTheDocument(); - expect(screen.getByText(/create a join token/i)).toBeInTheDocument(); - }); - - test('cloud, auto discover toggling', async () => { - cfg.isCloud = true; - - const { ctx, discoverCtx } = getMockedContexts(); - - jest - .spyOn(integrationService, 'fetchAwsEc2Instances') - .mockResolvedValue({ instances: mockEc2Instances }); - - renderEc2Instances(ctx, discoverCtx); - await selectARegion({ waitForTable: true }); - - // default toggler should be off. - expect(screen.getByTestId('toggle')).not.toBeChecked(); - - await userEvent.click(screen.getByText(/auto-enroll all/i)); - expect(screen.getByText(/next/i, { selector: 'button' })).toBeEnabled(); - expect(screen.queryByText(/create a join token/i)).not.toBeInTheDocument(); - }); - - test('self-hosted, auto discover without existing endpoints', async () => { - const { ctx, discoverCtx } = getMockedContexts(); - - jest - .spyOn(integrationService, 'fetchAwsEc2Instances') - .mockResolvedValue({ instances: mockEc2Instances }); - - jest - .spyOn(integrationService, 'fetchAwsEc2InstanceConnectEndpoints') - .mockResolvedValue({ endpoints: [], dashboardLink: '' }); - - const createDiscoveryConfig = jest - .spyOn(discoveryApi, 'createDiscoveryConfig') - .mockResolvedValue({ - name: 'discovery-cfg', - discoveryGroup: '', - aws: [], - }); - - renderEc2Instances(ctx, discoverCtx); - await selectARegion({ waitForTable: true }); - - // Toggle on. - await userEvent.click(screen.getByText(/auto-enroll all/i)); - - await userEvent.click(screen.getByText(/next/i, { selector: 'button' })); - expect(integrationService.fetchAwsEc2Instances).toHaveBeenCalledWith( - discoverCtx.agentMeta.awsIntegration.name, - { region: selectedRegion, nextToken: '' } - ); - expect(createDiscoveryConfig.mock.calls[0][1]['discoveryGroup']).toBe( - DEFAULT_DISCOVERY_GROUP_NON_CLOUD - ); - expect(discoverCtx.nextStep).toHaveBeenCalledTimes(1); - }); - - test('self-hosted, auto discover without all existing endpoints, creates node resource', async () => { - const { ctx, discoverCtx } = getMockedContexts(); - (discoverCtx.agentMeta as NodeMeta).ec2Ices = endpoints; - - jest - .spyOn(integrationService, 'fetchAwsEc2Instances') - .mockResolvedValue({ instances: mockEc2Instances }); - - jest - .spyOn(integrationService, 'fetchAwsEc2InstanceConnectEndpoints') - .mockResolvedValue({ endpoints, dashboardLink: '' }); - - jest.spyOn(discoveryApi, 'createDiscoveryConfig').mockResolvedValue({ - name: 'discovery-cfg', - discoveryGroup: '', - aws: [], - }); - - renderEc2Instances(ctx, discoverCtx); - await selectARegion({ waitForTable: true }); - - // Toggle on. - await userEvent.click(screen.getByText(/auto-enroll all/i)); - - await userEvent.click(screen.getByText(/next/i, { selector: 'button' })); - expect(integrationService.fetchAwsEc2Instances).toHaveBeenCalledTimes(1); - expect(discoveryApi.createDiscoveryConfig).toHaveBeenCalledTimes(1); - expect(discoverCtx.nextStep).not.toHaveBeenCalled(); - expect(discoverCtx.emitEvent).toHaveBeenCalledWith( - { stepStatus: DiscoverEventStatus.Skipped }, - { - eventName: DiscoverEvent.EC2DeployEICE, - } - ); - - await screen.findByText(/created teleport node/i); - expect(ctx.nodeService.createNode).toHaveBeenCalledTimes(1); - }); - - test('cloud, auto discover with all existing created endpoints and no auto discovery config', async () => { - cfg.isCloud = true; - - let { ctx, discoverCtx } = getMockedContexts(); - - jest - .spyOn(integrationService, 'fetchAwsEc2Instances') - .mockResolvedValue({ instances: mockEc2Instances }); - - jest - .spyOn(integrationService, 'fetchAwsEc2InstanceConnectEndpoints') - .mockResolvedValue({ - endpoints, - dashboardLink: '', - }); - - const createDiscoveryConfig = jest - .spyOn(discoveryApi, 'createDiscoveryConfig') - .mockResolvedValue({ - name: 'discovery-cfg', - discoveryGroup: '', - aws: [], - }); - - renderEc2Instances(ctx, discoverCtx); - await selectARegion({ waitForTable: true }); - - // Toggle on. - await userEvent.click(screen.getByText(/auto-enroll all/i)); - - await userEvent.click(screen.getByText(/next/i, { selector: 'button' })); - expect(integrationService.fetchAwsEc2Instances).toHaveBeenCalledWith( - discoverCtx.agentMeta.awsIntegration.name, - { region: selectedRegion, nextToken: '' } - ); - expect(createDiscoveryConfig.mock.calls[0][1]['discoveryGroup']).toBe( - discoveryApi.DISCOVERY_GROUP_CLOUD - ); - expect(discoverCtx.nextStep).not.toHaveBeenCalled(); - expect(discoverCtx.emitEvent).toHaveBeenCalledWith( - { stepStatus: DiscoverEventStatus.Skipped }, - { - eventName: DiscoverEvent.EC2DeployEICE, - } - ); - }); - - test('cloud, auto discover with all existing created endpoints, with already set discovery config', async () => { - cfg.isCloud = true; - - let { ctx, discoverCtx } = getMockedContexts(true /* withAutoDiscovery */); - - jest - .spyOn(integrationService, 'fetchAwsEc2Instances') - .mockResolvedValue({ instances: mockEc2Instances }); - - jest - .spyOn(integrationService, 'fetchAwsEc2InstanceConnectEndpoints') - .mockResolvedValue({ - endpoints: [ - { - name: 'endpoint-1', - state: 'create-complete', - dashboardLink: '', - subnetId: 'subnet-1', - vpcId: 'vpc-1', - }, - { - name: 'endpoint-2', - state: 'create-complete', - dashboardLink: '', - subnetId: 'subnet-2', - vpcId: 'vpc-2', - }, - { - name: 'endpoint-3', - state: 'create-complete', - dashboardLink: '', - subnetId: 'subnet-3', - vpcId: 'vpc-3', - }, - ], - dashboardLink: '', - }); - - jest.spyOn(discoveryApi, 'createDiscoveryConfig').mockResolvedValue({ - name: 'discovery-cfg', - discoveryGroup: '', - aws: [], - }); - - jest.spyOn(ctx.nodeService, 'createNode').mockResolvedValue({} as any); - - renderEc2Instances(ctx, discoverCtx); - await selectARegion({ waitForTable: true }); - - // Toggle on. - await userEvent.click(screen.getByText(/auto-enroll all/i)); - - await userEvent.click(screen.getByText(/next/i, { selector: 'button' })); - expect(integrationService.fetchAwsEc2Instances).toHaveBeenCalledWith( - discoverCtx.agentMeta.awsIntegration.name, - { region: selectedRegion, nextToken: '' } - ); - expect(discoveryApi.createDiscoveryConfig).not.toHaveBeenCalled(); - expect(discoverCtx.nextStep).not.toHaveBeenCalled(); - expect(ctx.nodeService.createNode).not.toHaveBeenCalled(); - - expect(discoverCtx.emitEvent).toHaveBeenCalledWith( - { stepStatus: DiscoverEventStatus.Skipped }, - { - eventName: DiscoverEvent.EC2DeployEICE, - } - ); - - await screen.findByText(/All endpoints required are created/i); - }); - - test('cloud, with partially created endpoints, with already set discovery config', async () => { - cfg.isCloud = true; - - const { ctx, discoverCtx } = getMockedContexts( - true /* withAutoDiscovery */ - ); - - jest - .spyOn(integrationService, 'fetchAwsEc2Instances') - .mockResolvedValue({ instances: mockEc2Instances }); - - const fetchEndpoints = jest - .spyOn(integrationService, 'fetchAwsEc2InstanceConnectEndpoints') - .mockResolvedValueOnce({ - endpoints: [ - { - name: 'endpoint-1', - state: 'create-complete', - dashboardLink: '', - subnetId: 'subnet-1', - vpcId: 'vpc-1', - }, - { - name: 'endpoint-2', - state: 'create-in-progress', // <-- should trigger polling - dashboardLink: '', - subnetId: 'subnet-2', - vpcId: 'vpc-2', - }, - { - name: 'endpoint-3', - state: 'create-complete', - dashboardLink: '', - subnetId: 'subnet-3', - vpcId: 'vpc-3', - }, - ], - dashboardLink: '', - }) - .mockResolvedValueOnce({ - endpoints: [ - { - name: 'endpoint-2', - state: 'create-complete', // <-- should stop polling - dashboardLink: '', - subnetId: 'subnet-2', - vpcId: 'vpc-2', - }, - ], - dashboardLink: '', - }); - jest.spyOn(discoveryApi, 'createDiscoveryConfig').mockResolvedValue({ - name: 'discovery-cfg', - discoveryGroup: '', - aws: [], - }); - jest.spyOn(ctx.nodeService, 'createNode').mockResolvedValue({} as any); - - renderEc2Instances(ctx, discoverCtx); - await selectARegion({ waitForTable: true }); - - await userEvent.click(screen.getByText(/auto-enroll all/i)); - expect(screen.getByTestId('toggle')).toBeChecked(); - - // Test it's polling. - jest.useFakeTimers(); - fireEvent.click(screen.getByText(/next/i, { selector: 'button' })); - await screen.findByText(/this may take a few minutes/i); - - expect(integrationService.fetchAwsEc2Instances).toHaveBeenCalledTimes(1); - expect(discoveryApi.createDiscoveryConfig).not.toHaveBeenCalled(); - expect(ctx.nodeService.createNode).not.toHaveBeenCalled(); - expect(discoverCtx.nextStep).not.toHaveBeenCalled(); - expect(discoverCtx.emitEvent).toHaveBeenCalledWith( - { stepStatus: DiscoverEventStatus.Skipped }, - { - eventName: DiscoverEvent.EC2DeployEICE, - } - ); - expect(fetchEndpoints).toHaveBeenCalledTimes(1); - fetchEndpoints.mockClear(); - - // advance timer to call the endpoint with completed state - await act(async () => jest.advanceTimersByTime(10000)); - await screen.findByText(/All endpoints required are created/i); - expect(fetchEndpoints).toHaveBeenCalledTimes(1); - - jest.useRealTimers(); - }); -}); - -function getMockedContexts(withAutoDiscovery = false) { - const ctx = createTeleportContext(); - const discoverCtx: DiscoverContextState = { - agentMeta: { - resourceName: 'node-name', - awsRegion: 'us-west-1', - agentMatcherLabels: [], - db: {} as any, - selectedAwsRdsDb: {} as any, - node: mockFetchedNodes[0], - awsIntegration: { - kind: IntegrationKind.AwsOidc, - name: 'test-oidc', - resourceType: 'integration', - spec: { - roleArn: 'arn:aws:iam::123456789012:role/test-role-arn', - issuerS3Bucket: '', - issuerS3Prefix: '', - }, - statusCode: IntegrationStatusCode.Running, - }, - autoDiscovery: withAutoDiscovery - ? { - config: { name: '', discoveryGroup: '', aws: [] }, - requiredVpcsAndSubnets: {}, - } - : undefined, - }, - currentStep: 0, - nextStep: jest.fn(), - prevStep: () => null, - onSelectResource: () => null, - resourceSpec: {} as any, - exitFlow: () => null, - viewConfig: null, - indexedViews: [], - setResourceSpec: () => null, - updateAgentMeta: () => null, - emitErrorEvent: () => null, - emitEvent: jest.fn(), - eventState: null, - }; - - jest.spyOn(ctx.nodeService, 'fetchNodes').mockResolvedValue({ agents: [] }); - jest - .spyOn(ctx.nodeService, 'createNode') - .mockResolvedValue(mockFetchedNodes[0]); - jest - .spyOn(userEventService, 'captureDiscoverEvent') - .mockResolvedValue(undefined as never); - - return { ctx, discoverCtx }; -} - -function renderEc2Instances( - ctx: TeleportContext, - discoverCtx: DiscoverContextState -) { - return render( - - - - - - - - - - ); -} - -const mockEc2Instances: Node[] = [ - { - id: 'ec2-instance-1', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-1', - labels: [ - { name: 'teleport.dev/instance-id', value: 'instance-ec2-1' }, - { name: 'Name', value: 'My EC2 Box 1' }, - ], - addr: 'ec2.1.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - awsMetadata: { - accountId: 'test-account', - instanceId: 'instance-ec2-1', - region: 'us-west-1', - vpcId: 'vpc-1', - integration: 'test', - subnetId: 'subnet-1', - }, - }, - { - id: 'ec2-instance-2', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-2', - labels: [ - { name: 'teleport.dev/instance-id', value: 'instance-ec2-2' }, - { name: 'Name', value: 'My EC2 Box 2' }, - ], - addr: 'ec2.2.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - awsMetadata: { - accountId: 'test-account', - instanceId: 'instance-ec2-2', - region: 'us-west-1', - vpcId: 'vpc-2', - integration: 'test', - subnetId: 'subnet-2', - }, - }, - { - id: 'ec2-instance-3', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-3', - labels: [ - { name: 'teleport.dev/instance-id', value: 'instance-ec2-3' }, - { name: 'Name', value: 'My EC2 Box 3' }, - ], - addr: 'ec2.3.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - awsMetadata: { - accountId: 'test-account', - instanceId: 'instance-ec2-3', - region: 'us-west-1', - vpcId: 'vpc-1', - integration: 'test', - subnetId: 'subnet-2', - }, - }, - { - id: 'ec2-instance-4', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-4', - labels: [ - { name: 'teleport.dev/instance-id', value: 'instance-ec2-4' }, - { name: 'Name', value: 'My EC2 Box 4' }, - ], - addr: 'ec2.4.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - awsMetadata: { - accountId: 'test-account', - instanceId: 'instance-ec2-4', - region: 'us-west-1', - vpcId: 'vpc-2', - integration: 'test', - subnetId: 'subnet-2', - }, - }, - { - id: 'ec2-instance-5', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-5', - labels: [ - { name: 'teleport.dev/instance-id', value: 'instance-ec2-5' }, - { name: 'Name', value: 'My EC2 Box 5' }, - ], - addr: 'ec2.5.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - awsMetadata: { - accountId: 'test-account', - instanceId: 'instance-ec2-5', - region: 'us-west-1', - vpcId: 'vpc-3', - integration: 'test', - subnetId: 'subnet-3', - }, - }, -]; - -const mockFetchedNodes: Node[] = [ - { - id: 'ec2-instance-2', - kind: 'node', - clusterId: 'cluster', - hostname: 'ec2-hostname-2', - labels: [ - { name: 'teleport.dev/instance-id', value: 'instance-ec2-2' }, - { name: 'Name', value: 'My EC2 Box 2' }, - ], - addr: 'ec2.2.com', - tunnel: false, - subKind: 'openssh-ec2-ice', - sshLogins: ['test'], - awsMetadata: { - instanceId: 'some-id', - accountId: '', - region: 'us-east-1', - vpcId: '', - integration: '', - subnetId: '', - }, - }, -]; - -const endpoints: Ec2InstanceConnectEndpoint[] = [ - { - name: 'endpoint-1', - state: 'create-complete', - dashboardLink: '', - subnetId: 'subnet-1', - vpcId: 'vpc-1', - }, - { - name: 'endpoint-2', - state: 'create-complete', - dashboardLink: '', - subnetId: 'subnet-2', - vpcId: 'vpc-2', - }, - { - name: 'endpoint-3', - state: 'create-complete', - dashboardLink: '', - subnetId: 'subnet-3', - vpcId: 'vpc-3', - }, -]; diff --git a/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/EnrollEc2Instance.tsx b/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/EnrollEc2Instance.tsx deleted file mode 100644 index e836c1e05d42c..0000000000000 --- a/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/EnrollEc2Instance.tsx +++ /dev/null @@ -1,565 +0,0 @@ -/** - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import { useState } from 'react'; -import { Link as InternalLink } from 'react-router-dom'; - -import { Box, Link as ExternalLink, Text, Toggle } from 'design'; -import { Danger } from 'design/Alert'; -import { OutlineInfo } from 'design/Alert/Alert'; -import { FetchStatus } from 'design/DataTable/types'; -import { IconTooltip } from 'design/Tooltip'; -import useAttempt from 'shared/hooks/useAttemptNext'; -import { getErrMessage } from 'shared/utils/errorType'; - -import cfg from 'teleport/config'; -import { ConfigureIamPerms } from 'teleport/Discover/Shared/Aws/ConfigureIamPerms'; -import { - getAttemptsOneOfErrorMsg, - isIamPermError, -} from 'teleport/Discover/Shared/Aws/error'; -import { AwsRegionSelector } from 'teleport/Discover/Shared/AwsRegionSelector'; -import { ConfigureDiscoveryServiceDirections } from 'teleport/Discover/Shared/ConfigureDiscoveryService'; -import { NodeMeta, useDiscover } from 'teleport/Discover/useDiscover'; -import { - createDiscoveryConfig, - DEFAULT_DISCOVERY_GROUP_NON_CLOUD, - DISCOVERY_GROUP_CLOUD, - DiscoveryConfig, -} from 'teleport/services/discovery'; -import { - Ec2InstanceConnectEndpoint, - integrationService, - Regions, -} from 'teleport/services/integrations'; -import { Node } from 'teleport/services/nodes'; -import { - DiscoverEvent, - DiscoverEventStatus, -} from 'teleport/services/userEvent'; -import useTeleport from 'teleport/useTeleport'; - -import { ActionButtons, Header } from '../../Shared'; -import { CreateEc2IceDialog } from '../CreateEc2Ice/CreateEc2IceDialog'; -import { Ec2InstanceList } from './Ec2InstanceList'; -import { NoEc2IceRequiredDialog } from './NoEc2IceRequiredDialog'; - -// CheckedEc2Instance is a type to describe that an EC2 instance -// has been checked to determine whether or not it is already enrolled in the cluster. -export type CheckedEc2Instance = Node & { - ec2InstanceExists?: boolean; -}; - -type TableData = { - items: CheckedEc2Instance[]; - fetchStatus: FetchStatus; - nextToken?: string; -}; - -const emptyTableData: TableData = { - items: [], - fetchStatus: 'disabled', - nextToken: '', -}; - -export function EnrollEc2Instance() { - const { agentMeta, emitErrorEvent, nextStep, updateAgentMeta, emitEvent } = - useDiscover(); - const { nodeService, storeUser } = useTeleport(); - - const [currRegion, setCurrRegion] = useState(); - const [foundAllRequiredEices, setFoundAllRequiredEices] = - useState(); - const [selectedInstance, setSelectedInstance] = - useState(); - - const [tableData, setTableData] = useState({ - items: [], - nextToken: '', - fetchStatus: 'disabled', - }); - - const [autoDiscoveryCfg, setAutoDiscoveryCfg] = useState(); - const [wantAutoDiscover, setWantAutoDiscover] = useState(false); - const [discoveryGroupName, setDiscoveryGroupName] = useState(() => - cfg.isCloud ? '' : DEFAULT_DISCOVERY_GROUP_NON_CLOUD - ); - - const { - attempt: fetchEc2InstancesAttempt, - setAttempt: setFetchEc2InstancesAttempt, - } = useAttempt(''); - - const { attempt: fetchEc2IceAttempt, setAttempt: setFetchEc2IceAttempt } = - useAttempt(''); - - function fetchEc2InstancesWithNewRegion(region: Regions) { - if (region) { - setCurrRegion(region); - fetchEc2Instances({ ...emptyTableData }, region); - } - } - - function fetchNextPage() { - fetchEc2Instances({ ...tableData }, currRegion); - } - - function refreshEc2Instances() { - setSelectedInstance(null); - setFetchEc2IceAttempt({ status: '' }); - // When refreshing, start the table back at page 1. - fetchEc2Instances({ ...tableData, items: [] }, currRegion); - } - - async function fetchEc2Instances(data: TableData, region: Regions) { - const integrationName = agentMeta.awsIntegration.name; - - setTableData({ ...data, fetchStatus: 'loading' }); - setFetchEc2InstancesAttempt({ status: 'processing' }); - - try { - let fetchedEc2Instances: Node[] = []; - let nextPage = ''; - // Requires list of all ec2 instances - // to formulate map of VPCs and its subnets. - do { - const { instances, nextToken } = - await integrationService.fetchAwsEc2Instances(integrationName, { - region: region, - nextToken: nextPage, - }); - - fetchedEc2Instances = [...fetchedEc2Instances, ...instances]; - nextPage = nextToken; - } while (nextPage); - // Abort if there were no EC2 instances for the selected region. - if (fetchedEc2Instances.length <= 0) { - setFetchEc2InstancesAttempt({ status: 'success' }); - setTableData({ ...data, fetchStatus: 'disabled' }); - return; - } - - // Check if fetched EC2 instances are already in the cluster - // so that they can be disabled in the table. - - // Builds the predicate string that will query for - // all the fetched EC2 instances by searching by the AWS instance ID label. - const instanceIdPredicateQueries: string[] = fetchedEc2Instances.map( - d => - `labels["teleport.dev/instance-id"] == "${d.awsMetadata.instanceId}"` - ); - const fullPredicateQuery = instanceIdPredicateQueries.join(' || '); - const { agents: fetchedNodes } = await nodeService.fetchNodes( - cfg.proxyCluster, - { - query: fullPredicateQuery, - limit: fetchedEc2Instances.length, - } - ); - - const ec2InstancesLookupByInstanceId: Record = {}; - fetchedNodes.forEach(d => { - // Extract the instanceId of the fetched node from its label. - const instanceId = d.labels.find( - label => label.name === 'teleport.dev/instance-id' - )?.value; - - ec2InstancesLookupByInstanceId[instanceId] = d; - }); - - // Check for already existing EC2 instances. - const checkedEc2Instances: CheckedEc2Instance[] = fetchedEc2Instances.map( - ec2 => { - const instance = - ec2InstancesLookupByInstanceId[ec2.awsMetadata.instanceId]; - if (instance) { - return { - ...ec2, - ec2InstanceExists: true, - }; - } - return ec2; - } - ); - - setFetchEc2InstancesAttempt({ status: 'success' }); - setTableData({ - ...data, - fetchStatus: 'disabled', - items: checkedEc2Instances, - }); - } catch (err) { - const errMsg = getErrMessage(err); - setTableData(data); - setFetchEc2InstancesAttempt({ status: 'failed', statusText: errMsg }); - emitErrorEvent(`ec2 instance fetch error: ${errMsg}`); - } - } - - /** - * @returns - * - undefined: if there was an error from request - * - array: list of ec2 instance connect endpoints or, - * empty list if no endpoints - */ - async function fetchEc2InstanceConnectEndpointsWithErrorHandling( - vpcIds: string[] - ) { - const integrationName = agentMeta.awsIntegration.name; - - try { - const { endpoints: fetchedEc2Ices } = - await integrationService.fetchAwsEc2InstanceConnectEndpoints( - integrationName, - { - region: currRegion, - vpcIds, - } - ); - return fetchedEc2Ices; - } catch (err) { - const errMsg = getErrMessage(err); - setFetchEc2IceAttempt({ status: 'failed', statusText: errMsg }); - emitErrorEvent(`ec2 instance connect endpoint fetch error: ${errMsg}`); - } - } - - function clear() { - setFetchEc2InstancesAttempt({ status: '' }); - setFetchEc2IceAttempt({ status: '' }); - setTableData(emptyTableData); - setSelectedInstance(null); - setAutoDiscoveryCfg(null); - setFoundAllRequiredEices(null); - } - - /** - * @returns - * - undefined: if there was an error from request or - * - object: the created discovery config object - */ - async function createAutoDiscoveryConfigWithErrorHandling() { - // We check the agentmeta because a user could've returned - // to this step from the deploy step (clicking "back" button) - const alreadyCreatedCfg = - agentMeta?.autoDiscovery && agentMeta.awsRegion === currRegion; - - if (!autoDiscoveryCfg && !alreadyCreatedCfg) { - try { - const discoveryConfig = await createDiscoveryConfig( - storeUser.getClusterId(), - { - name: crypto.randomUUID(), - discoveryGroup: cfg.isCloud - ? DISCOVERY_GROUP_CLOUD - : discoveryGroupName, - aws: [ - { - types: ['ec2'], - regions: [currRegion], - tags: { '*': ['*'] }, - integration: agentMeta.awsIntegration.name, - }, - ], - } - ); - return discoveryConfig; - } catch (err) { - const errMsg = getErrMessage(err); - setFetchEc2IceAttempt({ status: 'failed', statusText: errMsg }); - emitErrorEvent(`failed to create discovery config: ${errMsg}`); - } - } - - if (agentMeta.autoDiscovery) { - return agentMeta.autoDiscovery.config; - } - - return autoDiscoveryCfg; - } - - /** - * Note: takes about 1 minute to go from `create-in-progress` to `create-complete` - * `create-in-progress` can be polled until it reaches `create-complete` - */ - function getCompleteOrInProgressEndpoints( - endpoints: Ec2InstanceConnectEndpoint[] - ) { - return endpoints.filter( - e => e.state === 'create-complete' || e.state === 'create-in-progress' - ); - } - - async function enableAutoDiscovery() { - // Collect unique vpcIds and its subnet for instances. - const seenVpcIdAndSubnets: Record = {}; - tableData.items.forEach(i => { - const vpcId = i.awsMetadata.vpcId; - if (!seenVpcIdAndSubnets[vpcId]) { - // Instances can have the same vpcId and be assigned - // different subnetIds, but each subnet belongs to a - // single VPC, so it does not matter which subnet we - // assign to this vpc. - seenVpcIdAndSubnets[vpcId] = i.awsMetadata.subnetId; - } - }); - - // Check if an instance connect endpoint exist for the collected vpcs. - - // instancesVpcIds can be zero if if no ec2 instances are enrolled. - const instancesVpcIds = Object.keys(seenVpcIdAndSubnets); - const gotEc2Ices = - await fetchEc2InstanceConnectEndpointsWithErrorHandling(instancesVpcIds); - if (!gotEc2Ices) { - // errored - return; - } - - const listOfExistingEndpoints = - getCompleteOrInProgressEndpoints(gotEc2Ices); - - // Determine which instance vpc needs a ec2 instance connect endpoint. - const requiredVpcsAndSubnets: Record = {}; - if (instancesVpcIds.length != gotEc2Ices.length) { - instancesVpcIds.forEach(instanceVpcId => { - const found = gotEc2Ices.some( - endpoint => endpoint.vpcId == instanceVpcId - ); - if (!found) { - requiredVpcsAndSubnets[instanceVpcId] = [ - seenVpcIdAndSubnets[instanceVpcId], - ]; - } - }); - } - - const discoveryConfig = await createAutoDiscoveryConfigWithErrorHandling(); - if (!discoveryConfig) { - // errored - return; - } - setFetchEc2IceAttempt({ status: 'success' }); - setAutoDiscoveryCfg(discoveryConfig); - updateAgentMeta({ - ...(agentMeta as NodeMeta), - ec2Ices: listOfExistingEndpoints, - autoDiscovery: { - config: discoveryConfig, - requiredVpcsAndSubnets, - }, - awsRegion: currRegion, - }); - - // Check if creating endpoints is required. - - const allRequiredEndpointsExists = - listOfExistingEndpoints.length > 0 && - Object.keys(requiredVpcsAndSubnets).length === 0; - - if (allRequiredEndpointsExists || instancesVpcIds.length === 0) { - setFoundAllRequiredEices(listOfExistingEndpoints); - emitEvent( - { stepStatus: DiscoverEventStatus.Skipped }, - { - eventName: DiscoverEvent.EC2DeployEICE, - } - ); - } else { - nextStep(); - } - } - - async function handleOnProceed() { - setFetchEc2IceAttempt({ status: 'processing' }); - - if (wantAutoDiscover) { - enableAutoDiscovery(); - } else { - const ec2Ices = await fetchEc2InstanceConnectEndpointsWithErrorHandling([ - selectedInstance.awsMetadata.vpcId, - ]); - if (!ec2Ices) { - return; - } - setFetchEc2IceAttempt({ status: 'success' }); - - const existingEndpoint = getCompleteOrInProgressEndpoints(ec2Ices); - - // If we find existing EICE's that are either create-complete or create-in-progress, we skip the step where we create the EICE. - - // We first check for any EICE's that are create-complete, if we find one, the dialog will go straight to creating the node. - // If we don't find any, we check if there are any that are create-in-progress, if we find one, the dialog will wait until - // it's create-complete and then create the node. - if (existingEndpoint.length > 0) { - setFoundAllRequiredEices(existingEndpoint); - // Since the EICE had already been deployed before the flow, emit an event for EC2DeployEICE as `Skipped`. - emitEvent( - { stepStatus: DiscoverEventStatus.Skipped }, - { - eventName: DiscoverEvent.EC2DeployEICE, - } - ); - updateAgentMeta({ - ...(agentMeta as NodeMeta), - node: selectedInstance, - ec2Ices: existingEndpoint, - awsRegion: currRegion, - }); - // If we find neither, then we go to the next step to create the EICE. - } else { - updateAgentMeta({ - ...(agentMeta as NodeMeta), - node: selectedInstance, - awsRegion: currRegion, - }); - nextStep(); - } - } - } - - // (Temp) - // Self hosted auto enroll is different from cloud. - // For cloud, we already run the discovery service for customer. - // For on-prem, user has to run their own discovery service. - // We hide the table for on-prem if they are wanting auto discover - // because it takes up so much space to give them instructions. - // Future work will simply provide user a script so we can show the table then. - const showTable = cfg.isCloud || !wantAutoDiscover; - - const errorMsg = getAttemptsOneOfErrorMsg( - fetchEc2InstancesAttempt, - fetchEc2IceAttempt - ); - - const hasIamPermError = - isIamPermError(fetchEc2IceAttempt) || - isIamPermError(fetchEc2InstancesAttempt); - - const showContent = !hasIamPermError && currRegion; - const showAutoEnrollToggle = - !errorMsg && fetchEc2InstancesAttempt.status === 'success'; - - return ( - -
Enroll an EC2 instance
- - Select the AWS Region you would like to see EC2 instances for: - - - {!hasIamPermError && errorMsg && {errorMsg}} - {showContent && ( - <> - {showAutoEnrollToggle && ( - - setWantAutoDiscover(b => !b)} - disabled={tableData.items.length === 0} // necessary? - > - - Auto-enroll all EC2 instances for selected region - - - Auto-enroll will automatically identify all EC2 instances from - the selected region and register them as node resources in - your infrastructure. - - - {wantAutoDiscover && ( - - AWS enforces{' '} - - strict quotas - {' '} - on auto-enrolled EC2 instances, particularly for the maximum - number of allowed concurrent connections per EC2 Instance - Connect Endpoint. If these quotas restrict your needs, - consider following the{' '} - - Teleport service installation - {' '} - flow instead. - - )} - {!cfg.isCloud && wantAutoDiscover && ( - - )} - - )} - {showTable && ( - - )} - - )} - {foundAllRequiredEices?.length > 0 && ( - nextStep(2)} - existingEices={foundAllRequiredEices} - /> - )} - {foundAllRequiredEices?.length === 0 && ( - nextStep(2)} /> - )} - {hasIamPermError && ( - - - - )} - -
- ); -} diff --git a/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/NoEc2IceRequiredDialog.tsx b/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/NoEc2IceRequiredDialog.tsx deleted file mode 100644 index f1050435df708..0000000000000 --- a/web/packages/teleport/src/Discover/Server/EnrollEc2Instance/NoEc2IceRequiredDialog.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Teleport - * Copyright (C) 2024 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import { ButtonPrimary, Flex, Mark, Text } from 'design'; -import Dialog, { DialogContent } from 'design/DialogConfirmation'; -import * as Icons from 'design/Icon'; - -import { NodeMeta, useDiscover } from 'teleport/Discover/useDiscover'; - -export function NoEc2IceRequiredDialog({ nextStep }: { nextStep: () => void }) { - const { agentMeta } = useDiscover(); - const typedAgentMeta = agentMeta as NodeMeta; - - return ( - - - - - - The discovery service can take a few minutes to finish - auto-enrolling resources found in region{' '} - {typedAgentMeta.awsRegion}. - - - nextStep()}> - Next - - - - ); -} diff --git a/web/packages/teleport/src/Discover/Server/index.tsx b/web/packages/teleport/src/Discover/Server/index.tsx index 143344921839c..4f31ab999965d 100644 --- a/web/packages/teleport/src/Discover/Server/index.tsx +++ b/web/packages/teleport/src/Discover/Server/index.tsx @@ -31,9 +31,7 @@ import { import { ResourceSpec, ServerLocation } from '../SelectResource'; import { ConfigureDiscoveryService } from '../Shared/ConfigureDiscoveryService'; -import { CreateEc2Ice } from './CreateEc2Ice/CreateEc2Ice'; import { DiscoveryConfigSsm } from './DiscoveryConfigSsm/DiscoveryConfigSsm'; -import { EnrollEc2Instance } from './EnrollEc2Instance/EnrollEc2Instance'; import { ServerWrapper } from './ServerWrapper'; export const ServerResource: ResourceViewConfig = { @@ -57,29 +55,6 @@ export const ServerResource: ResourceViewConfig = { let configureResourceViews; const { nodeMeta } = resource; if ( - nodeMeta?.location === ServerLocation.Aws && - nodeMeta.discoveryConfigMethod === - DiscoverDiscoveryConfigMethod.AwsEc2Eice - ) { - configureResourceViews = [ - { - title: 'Connect AWS Account', - component: AwsAccount, - eventName: DiscoverEvent.IntegrationAWSOIDCConnectEvent, - }, - { - title: 'Enroll EC2 Instance', - component: EnrollEc2Instance, - eventName: DiscoverEvent.EC2InstanceSelection, - }, - { - title: 'Create EC2 Instance Connect Endpoint', - component: CreateEc2Ice, - eventName: DiscoverEvent.CreateNode, - manuallyEmitSuccessEvent: true, - }, - ]; - } else if ( nodeMeta?.location === ServerLocation.Aws && nodeMeta.discoveryConfigMethod === DiscoverDiscoveryConfigMethod.AwsEc2Ssm ) { diff --git a/web/packages/teleport/src/Discover/Shared/Aws/ConfigureIamPerms.tsx b/web/packages/teleport/src/Discover/Shared/Aws/ConfigureIamPerms.tsx index cb4670e649f05..99f0f851b001d 100644 --- a/web/packages/teleport/src/Discover/Shared/Aws/ConfigureIamPerms.tsx +++ b/web/packages/teleport/src/Discover/Shared/Aws/ConfigureIamPerms.tsx @@ -51,44 +51,7 @@ export function ConfigureIamPerms({ switch (kind) { case 'ec2': { - iamPolicyName = 'EC2InstanceConnectEndpoint'; - msg = 'We were unable to list your EC2 instances.'; - scriptUrl = cfg.getEc2InstanceConnectIAMConfigureScriptUrl({ - region, - iamRoleName, - accountID, - }); - - const json = `{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "ec2:DescribeInstances", - "ec2:DescribeInstanceConnectEndpoints", - "ec2:DescribeSecurityGroups", - "ec2:CreateInstanceConnectEndpoint", - "ec2:CreateTags", - "ec2:CreateNetworkInterface", - "iam:CreateServiceLinkedRole", - "ec2-instance-connect:SendSSHPublicKey", - "ec2-instance-connect:OpenTunnel" - ], - "Resource": "*" - } - ] -}`; - - editor = ( - - - - ); + // TODO(marco): should we remove `ec2` from the AwsResourceKind? break; } case 'eks': { diff --git a/web/packages/teleport/src/Discover/useDiscover.tsx b/web/packages/teleport/src/Discover/useDiscover.tsx index 2b353eb0d4f3d..11185ab4aaa2f 100644 --- a/web/packages/teleport/src/Discover/useDiscover.tsx +++ b/web/packages/teleport/src/Discover/useDiscover.tsx @@ -30,7 +30,6 @@ import type { Database } from 'teleport/services/databases'; import { DiscoveryConfig } from 'teleport/services/discovery'; import type { AwsRdsDatabase, - Ec2InstanceConnectEndpoint, Integration, Regions, } from 'teleport/services/integrations'; @@ -544,7 +543,6 @@ export type AutoDiscovery = { // that needs to be preserved throughout the flow. export type NodeMeta = BaseMeta & { node: Node; - ec2Ices?: Ec2InstanceConnectEndpoint[]; }; // DbMeta describes the fields for a db resource diff --git a/web/packages/teleport/src/config.ts b/web/packages/teleport/src/config.ts index af98acebdcde5..3078a118780ac 100644 --- a/web/packages/teleport/src/config.ts +++ b/web/packages/teleport/src/config.ts @@ -353,8 +353,6 @@ const cfg = { '/v1/webapi/scripts/integrations/configure/deployservice-iam.sh?integrationName=:integrationName&awsRegion=:region&role=:awsOidcRoleArn&taskRole=:taskRoleArn&awsAccountID=:accountID', awsConfigureIamScriptListDatabasesPath: '/v1/webapi/scripts/integrations/configure/listdatabases-iam.sh?awsRegion=:region&role=:iamRoleName&awsAccountID=:accountID', - awsConfigureIamScriptEc2InstanceConnectPath: - '/v1/webapi/scripts/integrations/configure/eice-iam.sh?awsRegion=:region&role=:iamRoleName&awsAccountID=:accountID', awsConfigureIamEksScriptPath: '/v1/webapi/scripts/integrations/configure/eks-iam.sh?awsRegion=:region&role=:iamRoleName&awsAccountID=:accountID', @@ -396,14 +394,6 @@ const cfg = { '/v2/webapi/sites/:clusterId/integrations/aws-oidc/:name/enrolleksclusters', }, - ec2InstancesListPath: - '/v1/webapi/sites/:clusterId/integrations/aws-oidc/:name/ec2', - ec2InstanceConnectEndpointsListPath: - '/v1/webapi/sites/:clusterId/integrations/aws-oidc/:name/ec2ice', - // Returns a script that configures the required IAM permissions to enable the usage of EC2 Instance Connect Endpoint to access EC2 instances. - ec2InstanceConnectDeployPath: - '/v1/webapi/sites/:clusterId/integrations/aws-oidc/:name/deployec2ice', - userGroupsListPath: '/v1/webapi/sites/:clusterId/user-groups?searchAsRoles=:searchAsRoles?&limit=:limit?&startKey=:startKey?&query=:query?&search=:search?&sort=:sort?', @@ -1156,33 +1146,6 @@ const cfg = { }); }, - getListEc2InstancesUrl(integrationName: string) { - const clusterId = cfg.proxyCluster; - - return generatePath(cfg.api.ec2InstancesListPath, { - clusterId, - name: integrationName, - }); - }, - - getListEc2InstanceConnectEndpointsUrl(integrationName: string) { - const clusterId = cfg.proxyCluster; - - return generatePath(cfg.api.ec2InstanceConnectEndpointsListPath, { - clusterId, - name: integrationName, - }); - }, - - getDeployEc2InstanceConnectEndpointUrl(integrationName: string) { - const clusterId = cfg.proxyCluster; - - return generatePath(cfg.api.ec2InstanceConnectDeployPath, { - clusterId, - name: integrationName, - }); - }, - getListSecurityGroupsUrl(integrationName: string) { const clusterId = cfg.proxyCluster; @@ -1199,17 +1162,6 @@ const cfg = { }); }, - getEc2InstanceConnectIAMConfigureScriptUrl( - params: UrlAwsConfigureIamScriptParams - ) { - return ( - cfg.baseUrl + - generatePath(cfg.api.awsConfigureIamScriptEc2InstanceConnectPath, { - ...params, - }) - ); - }, - getEksIamConfigureScriptUrl(params: UrlAwsConfigureIamScriptParams) { return ( cfg.baseUrl + diff --git a/web/packages/teleport/src/services/discovery/types.ts b/web/packages/teleport/src/services/discovery/types.ts index c30da28855aa9..2c37c33d025f2 100644 --- a/web/packages/teleport/src/services/discovery/types.ts +++ b/web/packages/teleport/src/services/discovery/types.ts @@ -33,7 +33,6 @@ type AwsMatcherTypes = 'rds' | 'eks' | 'ec2'; export enum InstallParamEnrollMode { Script = 1, - Eice = 2, } // AWSMatcher matches AWS EC2 instances, AWS EKS clusters and AWS Databases diff --git a/web/packages/teleport/src/services/integrations/integrations.ts b/web/packages/teleport/src/services/integrations/integrations.ts index baaa45c9d9b45..33da3cf2787e9 100644 --- a/web/packages/teleport/src/services/integrations/integrations.ts +++ b/web/packages/teleport/src/services/integrations/integrations.ts @@ -22,7 +22,6 @@ import api from 'teleport/services/api'; import { App } from '../apps'; import makeApp from '../apps/makeApps'; import auth, { MfaChallengeScope } from '../auth/auth'; -import makeNode from '../nodes/makeNode'; import { withUnsupportedLabelFeatureErrorConversion } from '../version/unsupported'; import { AwsDatabaseVpcsResponse, @@ -33,9 +32,6 @@ import { AwsOidcPingResponse, AwsRdsDatabase, CreateAwsAppAccessRequest, - DeployEc2InstanceConnectEndpointRequest, - DeployEc2InstanceConnectEndpointResponse, - Ec2InstanceConnectEndpoint, EnrollEksClustersRequest, EnrollEksClustersResponse, Integration, @@ -50,10 +46,6 @@ import { ListAwsSecurityGroupsResponse, ListAwsSubnetsRequest, ListAwsSubnetsResponse, - ListEc2InstanceConnectEndpointsRequest, - ListEc2InstanceConnectEndpointsResponse, - ListEc2InstancesRequest, - ListEc2InstancesResponse, ListEksClustersRequest, ListEksClustersResponse, RdsEngineIdentifier, @@ -380,52 +372,6 @@ export const integrationService = { }); }, - // Returns a list of EC2 Instances using the ListEC2ICE action of the AWS OIDC Integration. - fetchAwsEc2Instances( - integrationName, - req: ListEc2InstancesRequest - ): Promise { - return api - .post(cfg.getListEc2InstancesUrl(integrationName), req) - .then(json => { - const instances = json?.servers ?? []; - return { - instances: instances.map(makeNode), - nextToken: json?.nextToken, - }; - }); - }, - - // Returns a list of EC2 Instance Connect Endpoints using the ListEC2ICE action of the AWS OIDC Integration. - fetchAwsEc2InstanceConnectEndpoints( - integrationName, - req: ListEc2InstanceConnectEndpointsRequest - ): Promise { - return api - .post(cfg.getListEc2InstanceConnectEndpointsUrl(integrationName), req) - .then(json => { - const endpoints = json?.ec2Ices ?? []; - - return { - endpoints: endpoints.map(makeEc2InstanceConnectEndpoint), - nextToken: json?.nextToken, - dashboardLink: json?.dashboardLink, - }; - }); - }, - - // Deploys an EC2 Instance Connect Endpoint. - deployAwsEc2InstanceConnectEndpoints( - integrationName, - req: DeployEc2InstanceConnectEndpointRequest - ): Promise { - return api - .post(cfg.getDeployEc2InstanceConnectEndpointUrl(integrationName), req) - .then(resp => { - return resp ?? []; - }); - }, - // Returns a list of VPC Security Groups using the ListSecurityGroups action of the AWS OIDC Integration. fetchSecurityGroups( integrationName, @@ -516,20 +462,6 @@ export function makeAwsDatabase(json: any): AwsRdsDatabase { }; } -function makeEc2InstanceConnectEndpoint(json: any): Ec2InstanceConnectEndpoint { - json = json ?? {}; - const { name, state, stateMessage, dashboardLink, subnetId, vpcId } = json; - - return { - name, - state, - stateMessage, - dashboardLink, - subnetId, - vpcId, - }; -} - function makeSecurityGroup(json: any): SecurityGroup { json = json ?? {}; diff --git a/web/packages/teleport/src/services/integrations/types.ts b/web/packages/teleport/src/services/integrations/types.ts index 6fa11432c6af9..9e631c7caf506 100644 --- a/web/packages/teleport/src/services/integrations/types.ts +++ b/web/packages/teleport/src/services/integrations/types.ts @@ -19,7 +19,6 @@ import { Label } from 'teleport/types'; import { ResourceLabel } from '../agents'; -import { Node } from '../nodes'; /** * type Integration v. type Plugin: @@ -568,81 +567,6 @@ export type ListEksClustersResponse = { nextToken?: string; }; -export type ListEc2InstancesRequest = { - region: Regions; - nextToken?: string; -}; - -export type ListEc2InstancesResponse = { - // instances is the list of EC2 Instances. - instances: Node[]; - nextToken?: string; -}; - -export type ListEc2InstanceConnectEndpointsRequest = { - region: Regions; - // VPCIDs is a list of VPCs to filter EC2 Instance Connect Endpoints. - vpcIds: string[]; - nextToken?: string; -}; - -export type ListEc2InstanceConnectEndpointsResponse = { - // endpoints is the list of EC2 Instance Connect Endpoints. - endpoints: Ec2InstanceConnectEndpoint[]; - nextToken?: string; - // DashboardLink is the URL for AWS Web Console that - // lists all the Endpoints for the queries VPCs. - dashboardLink: string; -}; - -export type Ec2InstanceConnectEndpoint = { - name: string; - // state is the current state of the EC2 Instance Connect Endpoint. - state: Ec2InstanceConnectEndpointState; - // stateMessage is an optional message describing the state of the EICE, such as an error message. - stateMessage?: string; - // dashboardLink is a URL to AWS Console where the user can see the EC2 Instance Connect Endpoint. - dashboardLink: string; - // subnetID is the subnet used by the Endpoint. Please note that the Endpoint should be able to reach any subnet within the VPC. - subnetId: string; - // VPCID is the VPC ID where the Endpoint is created. - vpcId: string; -}; - -export type Ec2InstanceConnectEndpointState = - | 'create-in-progress' - | 'create-complete' - | 'create-failed' - | 'delete-in-progress' - | 'delete-complete' - | 'delete-failed'; - -export type AwsOidcDeployEc2InstanceConnectEndpointRequest = { - // SubnetID is the subnet id for the EC2 Instance Connect Endpoint. - subnetId: string; - // SecurityGroupIDs is the list of SecurityGroups to apply to the Endpoint. - // If not specified, the Endpoint will receive the default SG for the Subnet's VPC. - securityGroupIds?: string[]; -}; - -export type DeployEc2InstanceConnectEndpointRequest = { - region: Regions; - // Endpoints is a list of endpoinst to create. - endpoints: AwsOidcDeployEc2InstanceConnectEndpointRequest[]; -}; - -export type AwsEc2InstanceConnectEndpoint = { - // Name is the EC2 Instance Connect Endpoint name. - name: string; - // SubnetID is the subnet where this endpoint was created. - subnetId: string; -}; - -export type DeployEc2InstanceConnectEndpointResponse = { - // Endpoints is a list of created endpoints - endpoints: AwsEc2InstanceConnectEndpoint[]; -}; - export type Subnet = { /** * Subnet name. diff --git a/web/packages/teleport/src/services/userEvent/types.ts b/web/packages/teleport/src/services/userEvent/types.ts index 16e927986df65..09b0b5f7003f5 100644 --- a/web/packages/teleport/src/services/userEvent/types.ts +++ b/web/packages/teleport/src/services/userEvent/types.ts @@ -89,10 +89,7 @@ export enum DiscoverEvent { DatabaseRegister = 'tp.ui.discover.database.register', DatabaseConfigureMTLS = 'tp.ui.discover.database.configure.mtls', DatabaseConfigureIAMPolicy = 'tp.ui.discover.database.configure.iampolicy', - EC2InstanceSelection = 'tp.ui.discover.selectedEC2Instance', - EC2DeployEICE = 'tp.ui.discover.deployEICE', CreateApplicationServer = 'tp.ui.discover.createAppServer', - CreateNode = 'tp.ui.discover.createNode', CreateDiscoveryConfig = 'tp.ui.discover.createDiscoveryConfig', KubeEKSEnrollEvent = 'tp.ui.discover.kube.enroll.eks', PrincipalsConfigure = 'tp.ui.discover.principals.configure', @@ -241,7 +238,6 @@ export enum DiscoverServiceDeployType { export enum DiscoverDiscoveryConfigMethod { Unspecified = 'CONFIG_METHOD_UNSPECIFIED', AwsEc2Ssm = 'CONFIG_METHOD_AWS_EC2_SSM', - AwsEc2Eice = 'CONFIG_METHOD_AWS_EC2_EICE', AwsRdsEcs = 'CONFIG_METHOD_AWS_RDS_ECS', AwsEks = 'CONFIG_METHOD_AWS_EKS', }