diff --git a/buf-ts.gen.yaml b/buf-ts.gen.yaml index 23ced1d4ae1c6..f39f79dead31b 100644 --- a/buf-ts.gen.yaml +++ b/buf-ts.gen.yaml @@ -11,6 +11,7 @@ inputs: - api/proto/teleport/userpreferences/ - proto/prehog/ - proto/teleport/lib/teleterm/ + - proto/teleport/lib/vnet/diag/ plugins: - local: diff --git a/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service.pb.go b/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service.pb.go index 5809ba759eece..46c391222a581 100644 --- a/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service.pb.go +++ b/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service.pb.go @@ -23,6 +23,7 @@ package vnetv1 import ( + v1 "github.com/gravitational/teleport/gen/proto/go/teleport/lib/vnet/diag/v1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -455,6 +456,8 @@ type RunDiagnosticsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + Report *v1.Report `protobuf:"bytes,1,opt,name=report,proto3" json:"report,omitempty"` } func (x *RunDiagnosticsResponse) Reset() { @@ -487,6 +490,13 @@ func (*RunDiagnosticsResponse) Descriptor() ([]byte, []int) { return file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_rawDescGZIP(), []int{9} } +func (x *RunDiagnosticsResponse) GetReport() *v1.Report { + if x != nil { + return x.Report + } + return nil +} + var File_teleport_lib_teleterm_vnet_v1_vnet_service_proto protoreflect.FileDescriptor var file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_rawDesc = []byte{ @@ -495,89 +505,95 @@ var file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_rawDesc = []byte{ 0x76, 0x6e, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x22, 0x0e, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x0e, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x4e, 0x53, 0x5a, 0x6f, 0x6e, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x33, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, - 0x44, 0x4e, 0x53, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6e, 0x73, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x08, 0x64, 0x6e, 0x73, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x22, 0x20, 0x0a, - 0x1e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x74, - 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0x6e, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, - 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, - 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x74, 0x65, - 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, - 0x17, 0x0a, 0x15, 0x52, 0x75, 0x6e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x75, 0x6e, 0x44, - 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2a, 0x8b, 0x02, 0x0a, 0x14, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, - 0x64, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x26, 0x0a, 0x22, 0x42, - 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x29, 0x0a, 0x25, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, - 0x44, 0x5f, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, - 0x54, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x22, - 0x0a, 0x1e, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x49, 0x54, 0x45, - 0x4d, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, - 0x10, 0x02, 0x12, 0x2c, 0x0a, 0x28, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, - 0x5f, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x51, - 0x55, 0x49, 0x52, 0x45, 0x53, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x10, 0x03, - 0x12, 0x24, 0x0a, 0x20, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x49, - 0x54, 0x45, 0x4d, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, - 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x04, 0x12, 0x28, 0x0a, 0x24, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, - 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, - 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x05, - 0x32, 0xe5, 0x04, 0x0a, 0x0b, 0x56, 0x6e, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x62, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, - 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, - 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x2a, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, - 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x31, 0x1a, 0x24, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, + 0x76, 0x6e, 0x65, 0x74, 0x2f, 0x64, 0x69, 0x61, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, 0x61, + 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x0e, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0e, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x44, + 0x4e, 0x53, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x33, + 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x4e, 0x53, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6e, 0x73, 0x5f, 0x7a, 0x6f, + 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x64, 0x6e, 0x73, 0x5a, 0x6f, + 0x6e, 0x65, 0x73, 0x22, 0x20, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6e, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, - 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x4e, 0x53, - 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x12, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, - 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x4e, 0x53, 0x5a, 0x6f, 0x6e, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x75, 0x6e, 0x44, 0x69, 0x61, 0x67, + 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x53, + 0x0a, 0x16, 0x52, 0x75, 0x6e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x64, 0x69, 0x61, + 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x06, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2a, 0x8b, 0x02, 0x0a, 0x14, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x26, 0x0a, 0x22, + 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x49, 0x54, 0x45, 0x4d, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x29, 0x0a, 0x25, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, + 0x4e, 0x44, 0x5f, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, + 0x4f, 0x54, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, + 0x22, 0x0a, 0x1e, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x49, 0x54, + 0x45, 0x4d, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, + 0x44, 0x10, 0x02, 0x12, 0x2c, 0x0a, 0x28, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, + 0x44, 0x5f, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, + 0x51, 0x55, 0x49, 0x52, 0x45, 0x53, 0x5f, 0x41, 0x50, 0x50, 0x52, 0x4f, 0x56, 0x41, 0x4c, 0x10, + 0x03, 0x12, 0x24, 0x0a, 0x20, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, + 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, + 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x04, 0x12, 0x28, 0x0a, 0x24, 0x42, 0x41, 0x43, 0x4b, 0x47, + 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x49, 0x54, 0x45, 0x4d, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, + 0x05, 0x32, 0xe5, 0x04, 0x0a, 0x0b, 0x56, 0x6e, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x62, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2b, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, + 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x2a, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, + 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, - 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x4e, - 0x53, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x98, - 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, - 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3d, 0x2e, 0x74, 0x65, 0x6c, + 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x4e, + 0x53, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x12, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, + 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x4e, 0x53, 0x5a, 0x6f, + 0x6e, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, + 0x4e, 0x53, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x98, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3d, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, - 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, - 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x0e, 0x52, 0x75, 0x6e, - 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x34, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x44, - 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x55, 0x5a, 0x53, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, - 0x2f, 0x76, 0x6e, 0x65, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x6e, 0x65, 0x74, 0x76, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x0e, 0x52, 0x75, + 0x6e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x34, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, + 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, + 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x55, 0x5a, 0x53, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, + 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, + 0x6d, 0x2f, 0x76, 0x6e, 0x65, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x6e, 0x65, 0x74, 0x76, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -606,24 +622,26 @@ var file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_goTypes = []any{ (*GetBackgroundItemStatusResponse)(nil), // 8: teleport.lib.teleterm.vnet.v1.GetBackgroundItemStatusResponse (*RunDiagnosticsRequest)(nil), // 9: teleport.lib.teleterm.vnet.v1.RunDiagnosticsRequest (*RunDiagnosticsResponse)(nil), // 10: teleport.lib.teleterm.vnet.v1.RunDiagnosticsResponse + (*v1.Report)(nil), // 11: teleport.lib.vnet.diag.v1.Report } var file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_depIdxs = []int32{ 0, // 0: teleport.lib.teleterm.vnet.v1.GetBackgroundItemStatusResponse.status:type_name -> teleport.lib.teleterm.vnet.v1.BackgroundItemStatus - 1, // 1: teleport.lib.teleterm.vnet.v1.VnetService.Start:input_type -> teleport.lib.teleterm.vnet.v1.StartRequest - 3, // 2: teleport.lib.teleterm.vnet.v1.VnetService.Stop:input_type -> teleport.lib.teleterm.vnet.v1.StopRequest - 5, // 3: teleport.lib.teleterm.vnet.v1.VnetService.ListDNSZones:input_type -> teleport.lib.teleterm.vnet.v1.ListDNSZonesRequest - 7, // 4: teleport.lib.teleterm.vnet.v1.VnetService.GetBackgroundItemStatus:input_type -> teleport.lib.teleterm.vnet.v1.GetBackgroundItemStatusRequest - 9, // 5: teleport.lib.teleterm.vnet.v1.VnetService.RunDiagnostics:input_type -> teleport.lib.teleterm.vnet.v1.RunDiagnosticsRequest - 2, // 6: teleport.lib.teleterm.vnet.v1.VnetService.Start:output_type -> teleport.lib.teleterm.vnet.v1.StartResponse - 4, // 7: teleport.lib.teleterm.vnet.v1.VnetService.Stop:output_type -> teleport.lib.teleterm.vnet.v1.StopResponse - 6, // 8: teleport.lib.teleterm.vnet.v1.VnetService.ListDNSZones:output_type -> teleport.lib.teleterm.vnet.v1.ListDNSZonesResponse - 8, // 9: teleport.lib.teleterm.vnet.v1.VnetService.GetBackgroundItemStatus:output_type -> teleport.lib.teleterm.vnet.v1.GetBackgroundItemStatusResponse - 10, // 10: teleport.lib.teleterm.vnet.v1.VnetService.RunDiagnostics:output_type -> teleport.lib.teleterm.vnet.v1.RunDiagnosticsResponse - 6, // [6:11] is the sub-list for method output_type - 1, // [1:6] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 11, // 1: teleport.lib.teleterm.vnet.v1.RunDiagnosticsResponse.report:type_name -> teleport.lib.vnet.diag.v1.Report + 1, // 2: teleport.lib.teleterm.vnet.v1.VnetService.Start:input_type -> teleport.lib.teleterm.vnet.v1.StartRequest + 3, // 3: teleport.lib.teleterm.vnet.v1.VnetService.Stop:input_type -> teleport.lib.teleterm.vnet.v1.StopRequest + 5, // 4: teleport.lib.teleterm.vnet.v1.VnetService.ListDNSZones:input_type -> teleport.lib.teleterm.vnet.v1.ListDNSZonesRequest + 7, // 5: teleport.lib.teleterm.vnet.v1.VnetService.GetBackgroundItemStatus:input_type -> teleport.lib.teleterm.vnet.v1.GetBackgroundItemStatusRequest + 9, // 6: teleport.lib.teleterm.vnet.v1.VnetService.RunDiagnostics:input_type -> teleport.lib.teleterm.vnet.v1.RunDiagnosticsRequest + 2, // 7: teleport.lib.teleterm.vnet.v1.VnetService.Start:output_type -> teleport.lib.teleterm.vnet.v1.StartResponse + 4, // 8: teleport.lib.teleterm.vnet.v1.VnetService.Stop:output_type -> teleport.lib.teleterm.vnet.v1.StopResponse + 6, // 9: teleport.lib.teleterm.vnet.v1.VnetService.ListDNSZones:output_type -> teleport.lib.teleterm.vnet.v1.ListDNSZonesResponse + 8, // 10: teleport.lib.teleterm.vnet.v1.VnetService.GetBackgroundItemStatus:output_type -> teleport.lib.teleterm.vnet.v1.GetBackgroundItemStatusResponse + 10, // 11: teleport.lib.teleterm.vnet.v1.VnetService.RunDiagnostics:output_type -> teleport.lib.teleterm.vnet.v1.RunDiagnosticsResponse + 7, // [7:12] is the sub-list for method output_type + 2, // [2:7] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_init() } diff --git a/gen/proto/go/teleport/lib/vnet/diag/v1/diag.pb.go b/gen/proto/go/teleport/lib/vnet/diag/v1/diag.pb.go new file mode 100644 index 0000000000000..270f8c6b6fa7f --- /dev/null +++ b/gen/proto/go/teleport/lib/vnet/diag/v1/diag.pb.go @@ -0,0 +1,976 @@ +// Teleport +// Copyright (C) 2025 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 . + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: teleport/lib/vnet/diag/v1/diag.proto + +package diagv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// CheckAttemptStatus describes whether CheckAttempt finished successfully. This is different from +// CheckReportStatus, which describes whether a successful attempt at running a check has found any +// issues. See the comment for CheckAttempt for an example. +type CheckAttemptStatus int32 + +const ( + CheckAttemptStatus_CHECK_ATTEMPT_STATUS_UNSPECIFIED CheckAttemptStatus = 0 + // CHECK_ATTEMPT_STATUS_OK indicates that the check ran successfully. + CheckAttemptStatus_CHECK_ATTEMPT_STATUS_OK CheckAttemptStatus = 1 + // CHECK_ATTEMPT_STATUS_ERROR indicates that the check failed to run. + CheckAttemptStatus_CHECK_ATTEMPT_STATUS_ERROR CheckAttemptStatus = 2 +) + +// Enum value maps for CheckAttemptStatus. +var ( + CheckAttemptStatus_name = map[int32]string{ + 0: "CHECK_ATTEMPT_STATUS_UNSPECIFIED", + 1: "CHECK_ATTEMPT_STATUS_OK", + 2: "CHECK_ATTEMPT_STATUS_ERROR", + } + CheckAttemptStatus_value = map[string]int32{ + "CHECK_ATTEMPT_STATUS_UNSPECIFIED": 0, + "CHECK_ATTEMPT_STATUS_OK": 1, + "CHECK_ATTEMPT_STATUS_ERROR": 2, + } +) + +func (x CheckAttemptStatus) Enum() *CheckAttemptStatus { + p := new(CheckAttemptStatus) + *p = x + return p +} + +func (x CheckAttemptStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CheckAttemptStatus) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_lib_vnet_diag_v1_diag_proto_enumTypes[0].Descriptor() +} + +func (CheckAttemptStatus) Type() protoreflect.EnumType { + return &file_teleport_lib_vnet_diag_v1_diag_proto_enumTypes[0] +} + +func (x CheckAttemptStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CheckAttemptStatus.Descriptor instead. +func (CheckAttemptStatus) EnumDescriptor() ([]byte, []int) { + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP(), []int{0} +} + +// CheckReportStatus describes the outcome of a successful attempt at running a check. +type CheckReportStatus int32 + +const ( + CheckReportStatus_CHECK_REPORT_STATUS_UNSPECIFIED CheckReportStatus = 0 + // CHECK_REPORT_STATUS_OK indicates that the check has not found any issues. + CheckReportStatus_CHECK_REPORT_STATUS_OK CheckReportStatus = 1 + // CHECK_REPORT_STATUS_ISSUES_FOUND indicates that the check has found at least one issue. + CheckReportStatus_CHECK_REPORT_STATUS_ISSUES_FOUND CheckReportStatus = 2 +) + +// Enum value maps for CheckReportStatus. +var ( + CheckReportStatus_name = map[int32]string{ + 0: "CHECK_REPORT_STATUS_UNSPECIFIED", + 1: "CHECK_REPORT_STATUS_OK", + 2: "CHECK_REPORT_STATUS_ISSUES_FOUND", + } + CheckReportStatus_value = map[string]int32{ + "CHECK_REPORT_STATUS_UNSPECIFIED": 0, + "CHECK_REPORT_STATUS_OK": 1, + "CHECK_REPORT_STATUS_ISSUES_FOUND": 2, + } +) + +func (x CheckReportStatus) Enum() *CheckReportStatus { + p := new(CheckReportStatus) + *p = x + return p +} + +func (x CheckReportStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CheckReportStatus) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_lib_vnet_diag_v1_diag_proto_enumTypes[1].Descriptor() +} + +func (CheckReportStatus) Type() protoreflect.EnumType { + return &file_teleport_lib_vnet_diag_v1_diag_proto_enumTypes[1] +} + +func (x CheckReportStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CheckReportStatus.Descriptor instead. +func (CheckReportStatus) EnumDescriptor() ([]byte, []int) { + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP(), []int{1} +} + +// CommandAttemptStatus describes the status of CommandAttempt. +type CommandAttemptStatus int32 + +const ( + CommandAttemptStatus_COMMAND_ATTEMPT_STATUS_UNSPECIFIED CommandAttemptStatus = 0 + CommandAttemptStatus_COMMAND_ATTEMPT_STATUS_OK CommandAttemptStatus = 1 + CommandAttemptStatus_COMMAND_ATTEMPT_STATUS_ERROR CommandAttemptStatus = 2 +) + +// Enum value maps for CommandAttemptStatus. +var ( + CommandAttemptStatus_name = map[int32]string{ + 0: "COMMAND_ATTEMPT_STATUS_UNSPECIFIED", + 1: "COMMAND_ATTEMPT_STATUS_OK", + 2: "COMMAND_ATTEMPT_STATUS_ERROR", + } + CommandAttemptStatus_value = map[string]int32{ + "COMMAND_ATTEMPT_STATUS_UNSPECIFIED": 0, + "COMMAND_ATTEMPT_STATUS_OK": 1, + "COMMAND_ATTEMPT_STATUS_ERROR": 2, + } +) + +func (x CommandAttemptStatus) Enum() *CommandAttemptStatus { + p := new(CommandAttemptStatus) + *p = x + return p +} + +func (x CommandAttemptStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CommandAttemptStatus) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_lib_vnet_diag_v1_diag_proto_enumTypes[2].Descriptor() +} + +func (CommandAttemptStatus) Type() protoreflect.EnumType { + return &file_teleport_lib_vnet_diag_v1_diag_proto_enumTypes[2] +} + +func (x CommandAttemptStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CommandAttemptStatus.Descriptor instead. +func (CommandAttemptStatus) EnumDescriptor() ([]byte, []int) { + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP(), []int{2} +} + +// Report represents the attempts at running individual checks. It also includes general information +// about the network stack managed by VNet. It assumes that each individual check as well as getting +// info about the network stack can fail. +type Report struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // created_at is the UTC timestamp at which the report was generated. + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + NetworkStackAttempt *NetworkStackAttempt `protobuf:"bytes,2,opt,name=network_stack_attempt,json=networkStackAttempt,proto3" json:"network_stack_attempt,omitempty"` + Checks []*CheckAttempt `protobuf:"bytes,3,rep,name=checks,proto3" json:"checks,omitempty"` +} + +func (x *Report) Reset() { + *x = Report{} + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Report) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Report) ProtoMessage() {} + +func (x *Report) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Report.ProtoReflect.Descriptor instead. +func (*Report) Descriptor() ([]byte, []int) { + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP(), []int{0} +} + +func (x *Report) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Report) GetNetworkStackAttempt() *NetworkStackAttempt { + if x != nil { + return x.NetworkStackAttempt + } + return nil +} + +func (x *Report) GetChecks() []*CheckAttempt { + if x != nil { + return x.Checks + } + return nil +} + +// NetworkStackAttempt represents the attempt at getting information about the network stack managed +// by VNet. +type NetworkStackAttempt struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status CheckAttemptStatus `protobuf:"varint,1,opt,name=status,proto3,enum=teleport.lib.vnet.diag.v1.CheckAttemptStatus" json:"status,omitempty"` + // error is present if status is CHECK_ATTEMPT_STATUS_ERROR. + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + NetworkStack *NetworkStack `protobuf:"bytes,3,opt,name=network_stack,json=networkStack,proto3" json:"network_stack,omitempty"` +} + +func (x *NetworkStackAttempt) Reset() { + *x = NetworkStackAttempt{} + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetworkStackAttempt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetworkStackAttempt) ProtoMessage() {} + +func (x *NetworkStackAttempt) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetworkStackAttempt.ProtoReflect.Descriptor instead. +func (*NetworkStackAttempt) Descriptor() ([]byte, []int) { + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP(), []int{1} +} + +func (x *NetworkStackAttempt) GetStatus() CheckAttemptStatus { + if x != nil { + return x.Status + } + return CheckAttemptStatus_CHECK_ATTEMPT_STATUS_UNSPECIFIED +} + +func (x *NetworkStackAttempt) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *NetworkStackAttempt) GetNetworkStack() *NetworkStack { + if x != nil { + return x.NetworkStack + } + return nil +} + +// NetworkStack describes the network stack managed by VNet. +type NetworkStack struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // interface_name is the name of the interface set up and used by VNet. + InterfaceName string `protobuf:"bytes,1,opt,name=interface_name,json=interfaceName,proto3" json:"interface_name,omitempty"` + // ipv4_cidr_ranges are all the possible ranges under which VNet is going to assign IPv4 addresses + // for apps. The first IP of the first range is used for the TUN device. + // Each root cluster can specify its own CIDR range to be used for apps within that profile. + Ipv4CidrRanges []string `protobuf:"bytes,2,rep,name=ipv4_cidr_ranges,json=ipv4CidrRanges,proto3" json:"ipv4_cidr_ranges,omitempty"` + // ipv6_prefix is the IPv6 prefix under which VNet creates IPv6 addresses for apps and its DNS + // server. + Ipv6Prefix string `protobuf:"bytes,3,opt,name=ipv6_prefix,json=ipv6Prefix,proto3" json:"ipv6_prefix,omitempty"` + // dns_zones lists domains for which DNS queries are supposed to be captured by VNet. + DnsZones []string `protobuf:"bytes,4,rep,name=dns_zones,json=dnsZones,proto3" json:"dns_zones,omitempty"` +} + +func (x *NetworkStack) Reset() { + *x = NetworkStack{} + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NetworkStack) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetworkStack) ProtoMessage() {} + +func (x *NetworkStack) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetworkStack.ProtoReflect.Descriptor instead. +func (*NetworkStack) Descriptor() ([]byte, []int) { + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP(), []int{2} +} + +func (x *NetworkStack) GetInterfaceName() string { + if x != nil { + return x.InterfaceName + } + return "" +} + +func (x *NetworkStack) GetIpv4CidrRanges() []string { + if x != nil { + return x.Ipv4CidrRanges + } + return nil +} + +func (x *NetworkStack) GetIpv6Prefix() string { + if x != nil { + return x.Ipv6Prefix + } + return "" +} + +func (x *NetworkStack) GetDnsZones() []string { + if x != nil { + return x.DnsZones + } + return nil +} + +// CheckAttempt describes the attempt at running a particular diagnostic check. If it succeeds +// (status is CHECK_ATTEMPT_STATUS_OK), check_report can be inspected to see if the check has found +// any issues. +// +// For example, a check that inspects network routes can succeed (CHECK_ATTEMPT_STATUS_OK) and it +// might or might not find conflicting routes (CHECK_REPORT_STATUS_ISSUES_FOUND or +// CHECK_REPORT_STATUS_OK). But it can also fail to run (CHECK_ATTEMPT_STATUS_ERROR) because the +// syscall to list routes has failed. +type CheckAttempt struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // status represents the status of an attempt at running a particular diagnostic check. This is + // not the same as the status of CheckReport. + Status CheckAttemptStatus `protobuf:"varint,1,opt,name=status,proto3,enum=teleport.lib.vnet.diag.v1.CheckAttemptStatus" json:"status,omitempty"` + // error is present if the check failed to run (status is CHECK_ATTEMPT_STATUS_ERROR). + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + // check_report is the output of a particular check. + // + // If check failed to run (status is CHECK_ATTEMPT_STATUS_ERROR), the report oneof in check_report + // is set to a specific member while the member itself is empty. This means that a particular + // CheckAttempt can be distinguished from other attempts describing other checks even if the check + // failed to run. + CheckReport *CheckReport `protobuf:"bytes,3,opt,name=check_report,json=checkReport,proto3" json:"check_report,omitempty"` + // commands are the outputs from additional diagnostic commands executed by the diagnostic + // check. They are meant to help inspect the general state of the OS related to the given check. + // Unless a callsite specifically requests commands to be skipped, commands are present even if + // status is CHECK_ATTEMPT_STATUS_ERROR, as they are useful even if the check failed. + Commands []*CommandAttempt `protobuf:"bytes,4,rep,name=commands,proto3" json:"commands,omitempty"` +} + +func (x *CheckAttempt) Reset() { + *x = CheckAttempt{} + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CheckAttempt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CheckAttempt) ProtoMessage() {} + +func (x *CheckAttempt) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CheckAttempt.ProtoReflect.Descriptor instead. +func (*CheckAttempt) Descriptor() ([]byte, []int) { + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP(), []int{3} +} + +func (x *CheckAttempt) GetStatus() CheckAttemptStatus { + if x != nil { + return x.Status + } + return CheckAttemptStatus_CHECK_ATTEMPT_STATUS_UNSPECIFIED +} + +func (x *CheckAttempt) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *CheckAttempt) GetCheckReport() *CheckReport { + if x != nil { + return x.CheckReport + } + return nil +} + +func (x *CheckAttempt) GetCommands() []*CommandAttempt { + if x != nil { + return x.Commands + } + return nil +} + +// CheckReport is the output of a successful attempt at running a particular check. +type CheckReport struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // status indicates if the check has found any issues. This is so that a callsite operating on + // a CheckReport can understand the outcome of the check without having to understand the + // semantics of the output included under report. + Status CheckReportStatus `protobuf:"varint,1,opt,name=status,proto3,enum=teleport.lib.vnet.diag.v1.CheckReportStatus" json:"status,omitempty"` + // Types that are assignable to Report: + // + // *CheckReport_RouteConflictReport + Report isCheckReport_Report `protobuf_oneof:"report"` +} + +func (x *CheckReport) Reset() { + *x = CheckReport{} + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CheckReport) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CheckReport) ProtoMessage() {} + +func (x *CheckReport) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CheckReport.ProtoReflect.Descriptor instead. +func (*CheckReport) Descriptor() ([]byte, []int) { + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP(), []int{4} +} + +func (x *CheckReport) GetStatus() CheckReportStatus { + if x != nil { + return x.Status + } + return CheckReportStatus_CHECK_REPORT_STATUS_UNSPECIFIED +} + +func (m *CheckReport) GetReport() isCheckReport_Report { + if m != nil { + return m.Report + } + return nil +} + +func (x *CheckReport) GetRouteConflictReport() *RouteConflictReport { + if x, ok := x.GetReport().(*CheckReport_RouteConflictReport); ok { + return x.RouteConflictReport + } + return nil +} + +type isCheckReport_Report interface { + isCheckReport_Report() +} + +type CheckReport_RouteConflictReport struct { + // route_conflict reports whether there are routes that might conflict with routes set up by + // VNet. + RouteConflictReport *RouteConflictReport `protobuf:"bytes,2,opt,name=route_conflict_report,json=routeConflictReport,proto3,oneof"` +} + +func (*CheckReport_RouteConflictReport) isCheckReport_Report() {} + +// CommandAttempt describes the attempt at running a particular command associated with a diagnostic +// check. +type CommandAttempt struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status CommandAttemptStatus `protobuf:"varint,1,opt,name=status,proto3,enum=teleport.lib.vnet.diag.v1.CommandAttemptStatus" json:"status,omitempty"` + // error is present if status is COMMAND_ATTEMPT_STATUS_ERROR. + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + // command shows which command was executed along with its arguments, e.g., "netstat -rn -f inet". + Command string `protobuf:"bytes,3,opt,name=command,proto3" json:"command,omitempty"` + // output is stdout from the command if status is COMMAND_ATTEMPT_STATUS_OK. + Output string `protobuf:"bytes,4,opt,name=output,proto3" json:"output,omitempty"` +} + +func (x *CommandAttempt) Reset() { + *x = CommandAttempt{} + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CommandAttempt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommandAttempt) ProtoMessage() {} + +func (x *CommandAttempt) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CommandAttempt.ProtoReflect.Descriptor instead. +func (*CommandAttempt) Descriptor() ([]byte, []int) { + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP(), []int{5} +} + +func (x *CommandAttempt) GetStatus() CommandAttemptStatus { + if x != nil { + return x.Status + } + return CommandAttemptStatus_COMMAND_ATTEMPT_STATUS_UNSPECIFIED +} + +func (x *CommandAttempt) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *CommandAttempt) GetCommand() string { + if x != nil { + return x.Command + } + return "" +} + +func (x *CommandAttempt) GetOutput() string { + if x != nil { + return x.Output + } + return "" +} + +// RouteConflictReport describes conflicting routes found by RouteConflictDiag. +type RouteConflictReport struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RouteConflicts []*RouteConflict `protobuf:"bytes,1,rep,name=route_conflicts,json=routeConflicts,proto3" json:"route_conflicts,omitempty"` +} + +func (x *RouteConflictReport) Reset() { + *x = RouteConflictReport{} + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RouteConflictReport) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RouteConflictReport) ProtoMessage() {} + +func (x *RouteConflictReport) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RouteConflictReport.ProtoReflect.Descriptor instead. +func (*RouteConflictReport) Descriptor() ([]byte, []int) { + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP(), []int{6} +} + +func (x *RouteConflictReport) GetRouteConflicts() []*RouteConflict { + if x != nil { + return x.RouteConflicts + } + return nil +} + +// RouteConflict describes a conflict between a route set up by a 3rd-party app where the +// destination overlaps with a destination in a route set up by VNet. +type RouteConflict struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // dest is the destination of the conflicting route. + Dest string `protobuf:"bytes,1,opt,name=dest,proto3" json:"dest,omitempty"` + // vnet_dest is the destination of a VNet route that Dest overlaps with. + VnetDest string `protobuf:"bytes,2,opt,name=vnet_dest,json=vnetDest,proto3" json:"vnet_dest,omitempty"` + // interface_name is the name of the interface the route uses, e.g. "utun4". + InterfaceName string `protobuf:"bytes,3,opt,name=interface_name,json=interfaceName,proto3" json:"interface_name,omitempty"` + // interface_app may contain the name of the application responsible for setting up the interface. + // At the moment, the only source of this information is NetworkExtension description included in + // the output of `ifconfig -v `. Not all VPN applications use this framework, so + // it's likely to be empty. + InterfaceApp string `protobuf:"bytes,4,opt,name=interface_app,json=interfaceApp,proto3" json:"interface_app,omitempty"` +} + +func (x *RouteConflict) Reset() { + *x = RouteConflict{} + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RouteConflict) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RouteConflict) ProtoMessage() {} + +func (x *RouteConflict) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RouteConflict.ProtoReflect.Descriptor instead. +func (*RouteConflict) Descriptor() ([]byte, []int) { + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP(), []int{7} +} + +func (x *RouteConflict) GetDest() string { + if x != nil { + return x.Dest + } + return "" +} + +func (x *RouteConflict) GetVnetDest() string { + if x != nil { + return x.VnetDest + } + return "" +} + +func (x *RouteConflict) GetInterfaceName() string { + if x != nil { + return x.InterfaceName + } + return "" +} + +func (x *RouteConflict) GetInterfaceApp() string { + if x != nil { + return x.InterfaceApp + } + return "" +} + +var File_teleport_lib_vnet_diag_v1_diag_proto protoreflect.FileDescriptor + +var file_teleport_lib_vnet_diag_v1_diag_proto_rawDesc = []byte{ + 0x0a, 0x24, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x76, + 0x6e, 0x65, 0x74, 0x2f, 0x64, 0x69, 0x61, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, 0x61, 0x67, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x64, 0x69, 0x61, 0x67, 0x2e, 0x76, + 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0xe8, 0x01, 0x0a, 0x06, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x39, 0x0a, + 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x62, 0x0a, 0x15, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x64, 0x69, 0x61, 0x67, + 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x52, 0x13, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x53, 0x74, 0x61, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x12, 0x3f, 0x0a, 0x06, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x76, 0x6e, 0x65, 0x74, + 0x2e, 0x64, 0x69, 0x61, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x74, + 0x74, 0x65, 0x6d, 0x70, 0x74, 0x52, 0x06, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x22, 0xc0, 0x01, + 0x0a, 0x13, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x41, 0x74, + 0x74, 0x65, 0x6d, 0x70, 0x74, 0x12, 0x45, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x64, 0x69, 0x61, 0x67, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x12, 0x4c, 0x0a, 0x0d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x64, 0x69, + 0x61, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x74, 0x61, + 0x63, 0x6b, 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x22, 0x9d, 0x01, 0x0a, 0x0c, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x74, 0x61, 0x63, + 0x6b, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x69, 0x70, 0x76, 0x34, + 0x5f, 0x63, 0x69, 0x64, 0x72, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0e, 0x69, 0x70, 0x76, 0x34, 0x43, 0x69, 0x64, 0x72, 0x52, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, + 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x70, 0x76, 0x36, 0x50, 0x72, 0x65, + 0x66, 0x69, 0x78, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6e, 0x73, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x64, 0x6e, 0x73, 0x5a, 0x6f, 0x6e, 0x65, 0x73, + 0x22, 0xfd, 0x01, 0x0a, 0x0c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, + 0x74, 0x12, 0x45, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, + 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x64, 0x69, 0x61, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x49, + 0x0a, 0x0c, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x6c, 0x69, 0x62, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x64, 0x69, 0x61, 0x67, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0b, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, + 0x64, 0x69, 0x61, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, + 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, + 0x22, 0xc3, 0x01, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x12, 0x44, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, + 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x64, 0x69, 0x61, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x64, 0x0a, 0x15, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, + 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x64, 0x69, 0x61, 0x67, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x13, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x08, 0x0a, 0x06, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x12, 0x47, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x64, 0x69, + 0x61, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x74, 0x74, + 0x65, 0x6d, 0x70, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x68, 0x0a, 0x13, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x12, 0x51, 0x0a, 0x0f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, + 0x69, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x64, + 0x69, 0x61, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x6c, 0x69, 0x63, 0x74, 0x52, 0x0e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x6c, + 0x69, 0x63, 0x74, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x6e, + 0x65, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x76, + 0x6e, 0x65, 0x74, 0x44, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, + 0x0a, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, + 0x41, 0x70, 0x70, 0x2a, 0x77, 0x0a, 0x12, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x74, 0x74, 0x65, + 0x6d, 0x70, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x0a, 0x20, 0x43, 0x48, 0x45, + 0x43, 0x4b, 0x5f, 0x41, 0x54, 0x54, 0x45, 0x4d, 0x50, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x1b, 0x0a, 0x17, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x41, 0x54, 0x54, 0x45, 0x4d, 0x50, 0x54, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, + 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x41, 0x54, 0x54, 0x45, 0x4d, 0x50, 0x54, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x2a, 0x7a, 0x0a, 0x11, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x52, 0x45, 0x50, 0x4f, 0x52, + 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, + 0x52, 0x45, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x4b, + 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x52, 0x45, 0x50, 0x4f, + 0x52, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x53, + 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x2a, 0x7f, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x26, 0x0a, 0x22, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x41, 0x54, 0x54, 0x45, + 0x4d, 0x50, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x4d, 0x4d, + 0x41, 0x4e, 0x44, 0x5f, 0x41, 0x54, 0x54, 0x45, 0x4d, 0x50, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4d, 0x4d, 0x41, + 0x4e, 0x44, 0x5f, 0x41, 0x54, 0x54, 0x45, 0x4d, 0x50, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x42, 0x51, 0x5a, 0x4f, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, + 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x76, 0x6e, 0x65, 0x74, 0x2f, 0x64, 0x69, + 0x61, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x69, 0x61, 0x67, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_lib_vnet_diag_v1_diag_proto_rawDescOnce sync.Once + file_teleport_lib_vnet_diag_v1_diag_proto_rawDescData = file_teleport_lib_vnet_diag_v1_diag_proto_rawDesc +) + +func file_teleport_lib_vnet_diag_v1_diag_proto_rawDescGZIP() []byte { + file_teleport_lib_vnet_diag_v1_diag_proto_rawDescOnce.Do(func() { + file_teleport_lib_vnet_diag_v1_diag_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_lib_vnet_diag_v1_diag_proto_rawDescData) + }) + return file_teleport_lib_vnet_diag_v1_diag_proto_rawDescData +} + +var file_teleport_lib_vnet_diag_v1_diag_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_teleport_lib_vnet_diag_v1_diag_proto_goTypes = []any{ + (CheckAttemptStatus)(0), // 0: teleport.lib.vnet.diag.v1.CheckAttemptStatus + (CheckReportStatus)(0), // 1: teleport.lib.vnet.diag.v1.CheckReportStatus + (CommandAttemptStatus)(0), // 2: teleport.lib.vnet.diag.v1.CommandAttemptStatus + (*Report)(nil), // 3: teleport.lib.vnet.diag.v1.Report + (*NetworkStackAttempt)(nil), // 4: teleport.lib.vnet.diag.v1.NetworkStackAttempt + (*NetworkStack)(nil), // 5: teleport.lib.vnet.diag.v1.NetworkStack + (*CheckAttempt)(nil), // 6: teleport.lib.vnet.diag.v1.CheckAttempt + (*CheckReport)(nil), // 7: teleport.lib.vnet.diag.v1.CheckReport + (*CommandAttempt)(nil), // 8: teleport.lib.vnet.diag.v1.CommandAttempt + (*RouteConflictReport)(nil), // 9: teleport.lib.vnet.diag.v1.RouteConflictReport + (*RouteConflict)(nil), // 10: teleport.lib.vnet.diag.v1.RouteConflict + (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp +} +var file_teleport_lib_vnet_diag_v1_diag_proto_depIdxs = []int32{ + 11, // 0: teleport.lib.vnet.diag.v1.Report.created_at:type_name -> google.protobuf.Timestamp + 4, // 1: teleport.lib.vnet.diag.v1.Report.network_stack_attempt:type_name -> teleport.lib.vnet.diag.v1.NetworkStackAttempt + 6, // 2: teleport.lib.vnet.diag.v1.Report.checks:type_name -> teleport.lib.vnet.diag.v1.CheckAttempt + 0, // 3: teleport.lib.vnet.diag.v1.NetworkStackAttempt.status:type_name -> teleport.lib.vnet.diag.v1.CheckAttemptStatus + 5, // 4: teleport.lib.vnet.diag.v1.NetworkStackAttempt.network_stack:type_name -> teleport.lib.vnet.diag.v1.NetworkStack + 0, // 5: teleport.lib.vnet.diag.v1.CheckAttempt.status:type_name -> teleport.lib.vnet.diag.v1.CheckAttemptStatus + 7, // 6: teleport.lib.vnet.diag.v1.CheckAttempt.check_report:type_name -> teleport.lib.vnet.diag.v1.CheckReport + 8, // 7: teleport.lib.vnet.diag.v1.CheckAttempt.commands:type_name -> teleport.lib.vnet.diag.v1.CommandAttempt + 1, // 8: teleport.lib.vnet.diag.v1.CheckReport.status:type_name -> teleport.lib.vnet.diag.v1.CheckReportStatus + 9, // 9: teleport.lib.vnet.diag.v1.CheckReport.route_conflict_report:type_name -> teleport.lib.vnet.diag.v1.RouteConflictReport + 2, // 10: teleport.lib.vnet.diag.v1.CommandAttempt.status:type_name -> teleport.lib.vnet.diag.v1.CommandAttemptStatus + 10, // 11: teleport.lib.vnet.diag.v1.RouteConflictReport.route_conflicts:type_name -> teleport.lib.vnet.diag.v1.RouteConflict + 12, // [12:12] is the sub-list for method output_type + 12, // [12:12] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name +} + +func init() { file_teleport_lib_vnet_diag_v1_diag_proto_init() } +func file_teleport_lib_vnet_diag_v1_diag_proto_init() { + if File_teleport_lib_vnet_diag_v1_diag_proto != nil { + return + } + file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes[4].OneofWrappers = []any{ + (*CheckReport_RouteConflictReport)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_lib_vnet_diag_v1_diag_proto_rawDesc, + NumEnums: 3, + NumMessages: 8, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_lib_vnet_diag_v1_diag_proto_goTypes, + DependencyIndexes: file_teleport_lib_vnet_diag_v1_diag_proto_depIdxs, + EnumInfos: file_teleport_lib_vnet_diag_v1_diag_proto_enumTypes, + MessageInfos: file_teleport_lib_vnet_diag_v1_diag_proto_msgTypes, + }.Build() + File_teleport_lib_vnet_diag_v1_diag_proto = out.File + file_teleport_lib_vnet_diag_v1_diag_proto_rawDesc = nil + file_teleport_lib_vnet_diag_v1_diag_proto_goTypes = nil + file_teleport_lib_vnet_diag_v1_diag_proto_depIdxs = nil +} diff --git a/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.ts b/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.ts index af92039c34a14..08f7483ad36b1 100644 --- a/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.ts +++ b/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.ts @@ -30,6 +30,7 @@ import type { IBinaryReader } from "@protobuf-ts/runtime"; import type { PartialMessage } from "@protobuf-ts/runtime"; import { reflectionMergePartial } from "@protobuf-ts/runtime"; import { MessageType } from "@protobuf-ts/runtime"; +import { Report } from "../../../vnet/diag/v1/diag_pb"; /** * Request for Start. * @@ -109,6 +110,10 @@ export interface RunDiagnosticsRequest { * @generated from protobuf message teleport.lib.teleterm.vnet.v1.RunDiagnosticsResponse */ export interface RunDiagnosticsResponse { + /** + * @generated from protobuf field: teleport.lib.vnet.diag.v1.Report report = 1; + */ + report?: Report; } /** * BackgroundItemStatus maps to SMAppServiceStatus of the Service Management framework in macOS. @@ -417,7 +422,9 @@ export const RunDiagnosticsRequest = new RunDiagnosticsRequest$Type(); // @generated message type with reflection information, may provide speed optimized methods class RunDiagnosticsResponse$Type extends MessageType { constructor() { - super("teleport.lib.teleterm.vnet.v1.RunDiagnosticsResponse", []); + super("teleport.lib.teleterm.vnet.v1.RunDiagnosticsResponse", [ + { no: 1, name: "report", kind: "message", T: () => Report } + ]); } create(value?: PartialMessage): RunDiagnosticsResponse { const message = globalThis.Object.create((this.messagePrototype!)); @@ -426,9 +433,28 @@ class RunDiagnosticsResponse$Type extends MessageType { return message; } internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: RunDiagnosticsResponse): RunDiagnosticsResponse { - return target ?? this.create(); + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* teleport.lib.vnet.diag.v1.Report report */ 1: + message.report = Report.internalBinaryRead(reader, reader.uint32(), options, message.report); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; } internalBinaryWrite(message: RunDiagnosticsResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* teleport.lib.vnet.diag.v1.Report report = 1; */ + if (message.report) + Report.internalBinaryWrite(message.report, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); diff --git a/gen/proto/ts/teleport/lib/vnet/diag/v1/diag_pb.ts b/gen/proto/ts/teleport/lib/vnet/diag/v1/diag_pb.ts new file mode 100644 index 0000000000000..dd193b224d559 --- /dev/null +++ b/gen/proto/ts/teleport/lib/vnet/diag/v1/diag_pb.ts @@ -0,0 +1,843 @@ +/* eslint-disable */ +// @generated by protobuf-ts 2.9.3 with parameter eslint_disable,add_pb_suffix,server_grpc1,ts_nocheck +// @generated from protobuf file "teleport/lib/vnet/diag/v1/diag.proto" (package "teleport.lib.vnet.diag.v1", syntax proto3) +// tslint:disable +// @ts-nocheck +// +// Teleport +// Copyright (C) 2025 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 type { BinaryWriteOptions } from "@protobuf-ts/runtime"; +import type { IBinaryWriter } from "@protobuf-ts/runtime"; +import { WireType } from "@protobuf-ts/runtime"; +import type { BinaryReadOptions } from "@protobuf-ts/runtime"; +import type { IBinaryReader } from "@protobuf-ts/runtime"; +import { UnknownFieldHandler } from "@protobuf-ts/runtime"; +import type { PartialMessage } from "@protobuf-ts/runtime"; +import { reflectionMergePartial } from "@protobuf-ts/runtime"; +import { MessageType } from "@protobuf-ts/runtime"; +import { Timestamp } from "../../../../../google/protobuf/timestamp_pb"; +/** + * Report represents the attempts at running individual checks. It also includes general information + * about the network stack managed by VNet. It assumes that each individual check as well as getting + * info about the network stack can fail. + * + * @generated from protobuf message teleport.lib.vnet.diag.v1.Report + */ +export interface Report { + /** + * created_at is the UTC timestamp at which the report was generated. + * + * @generated from protobuf field: google.protobuf.Timestamp created_at = 1; + */ + createdAt?: Timestamp; + /** + * @generated from protobuf field: teleport.lib.vnet.diag.v1.NetworkStackAttempt network_stack_attempt = 2; + */ + networkStackAttempt?: NetworkStackAttempt; + /** + * @generated from protobuf field: repeated teleport.lib.vnet.diag.v1.CheckAttempt checks = 3; + */ + checks: CheckAttempt[]; +} +/** + * NetworkStackAttempt represents the attempt at getting information about the network stack managed + * by VNet. + * + * @generated from protobuf message teleport.lib.vnet.diag.v1.NetworkStackAttempt + */ +export interface NetworkStackAttempt { + /** + * @generated from protobuf field: teleport.lib.vnet.diag.v1.CheckAttemptStatus status = 1; + */ + status: CheckAttemptStatus; + /** + * error is present if status is CHECK_ATTEMPT_STATUS_ERROR. + * + * @generated from protobuf field: string error = 2; + */ + error: string; + /** + * @generated from protobuf field: teleport.lib.vnet.diag.v1.NetworkStack network_stack = 3; + */ + networkStack?: NetworkStack; +} +/** + * NetworkStack describes the network stack managed by VNet. + * + * @generated from protobuf message teleport.lib.vnet.diag.v1.NetworkStack + */ +export interface NetworkStack { + /** + * interface_name is the name of the interface set up and used by VNet. + * + * @generated from protobuf field: string interface_name = 1; + */ + interfaceName: string; + /** + * ipv4_cidr_ranges are all the possible ranges under which VNet is going to assign IPv4 addresses + * for apps. The first IP of the first range is used for the TUN device. + * Each root cluster can specify its own CIDR range to be used for apps within that profile. + * + * @generated from protobuf field: repeated string ipv4_cidr_ranges = 2; + */ + ipv4CidrRanges: string[]; + /** + * ipv6_prefix is the IPv6 prefix under which VNet creates IPv6 addresses for apps and its DNS + * server. + * + * @generated from protobuf field: string ipv6_prefix = 3; + */ + ipv6Prefix: string; + /** + * dns_zones lists domains for which DNS queries are supposed to be captured by VNet. + * + * @generated from protobuf field: repeated string dns_zones = 4; + */ + dnsZones: string[]; +} +/** + * CheckAttempt describes the attempt at running a particular diagnostic check. If it succeeds + * (status is CHECK_ATTEMPT_STATUS_OK), check_report can be inspected to see if the check has found + * any issues. + * + * For example, a check that inspects network routes can succeed (CHECK_ATTEMPT_STATUS_OK) and it + * might or might not find conflicting routes (CHECK_REPORT_STATUS_ISSUES_FOUND or + * CHECK_REPORT_STATUS_OK). But it can also fail to run (CHECK_ATTEMPT_STATUS_ERROR) because the + * syscall to list routes has failed. + * + * @generated from protobuf message teleport.lib.vnet.diag.v1.CheckAttempt + */ +export interface CheckAttempt { + /** + * status represents the status of an attempt at running a particular diagnostic check. This is + * not the same as the status of CheckReport. + * + * + * @generated from protobuf field: teleport.lib.vnet.diag.v1.CheckAttemptStatus status = 1; + */ + status: CheckAttemptStatus; + /** + * error is present if the check failed to run (status is CHECK_ATTEMPT_STATUS_ERROR). + * + * @generated from protobuf field: string error = 2; + */ + error: string; + /** + * check_report is the output of a particular check. + * + * If check failed to run (status is CHECK_ATTEMPT_STATUS_ERROR), the report oneof in check_report + * is set to a specific member while the member itself is empty. This means that a particular + * CheckAttempt can be distinguished from other attempts describing other checks even if the check + * failed to run. + * + * @generated from protobuf field: teleport.lib.vnet.diag.v1.CheckReport check_report = 3; + */ + checkReport?: CheckReport; + /** + * commands are the outputs from additional diagnostic commands executed by the diagnostic + * check. They are meant to help inspect the general state of the OS related to the given check. + * Unless a callsite specifically requests commands to be skipped, commands are present even if + * status is CHECK_ATTEMPT_STATUS_ERROR, as they are useful even if the check failed. + * + * @generated from protobuf field: repeated teleport.lib.vnet.diag.v1.CommandAttempt commands = 4; + */ + commands: CommandAttempt[]; +} +/** + * CheckReport is the output of a successful attempt at running a particular check. + * + * @generated from protobuf message teleport.lib.vnet.diag.v1.CheckReport + */ +export interface CheckReport { + /** + * status indicates if the check has found any issues. This is so that a callsite operating on + * a CheckReport can understand the outcome of the check without having to understand the + * semantics of the output included under report. + * + * @generated from protobuf field: teleport.lib.vnet.diag.v1.CheckReportStatus status = 1; + */ + status: CheckReportStatus; + /** + * @generated from protobuf oneof: report + */ + report: { + oneofKind: "routeConflictReport"; + /** + * route_conflict reports whether there are routes that might conflict with routes set up by + * VNet. + * + * @generated from protobuf field: teleport.lib.vnet.diag.v1.RouteConflictReport route_conflict_report = 2; + */ + routeConflictReport: RouteConflictReport; + } | { + oneofKind: undefined; + }; +} +/** + * CommandAttempt describes the attempt at running a particular command associated with a diagnostic + * check. + * + * @generated from protobuf message teleport.lib.vnet.diag.v1.CommandAttempt + */ +export interface CommandAttempt { + /** + * @generated from protobuf field: teleport.lib.vnet.diag.v1.CommandAttemptStatus status = 1; + */ + status: CommandAttemptStatus; + /** + * error is present if status is COMMAND_ATTEMPT_STATUS_ERROR. + * + * @generated from protobuf field: string error = 2; + */ + error: string; + /** + * command shows which command was executed along with its arguments, e.g., "netstat -rn -f inet". + * + * @generated from protobuf field: string command = 3; + */ + command: string; + /** + * output is stdout from the command if status is COMMAND_ATTEMPT_STATUS_OK. + * + * @generated from protobuf field: string output = 4; + */ + output: string; +} +/** + * RouteConflictReport describes conflicting routes found by RouteConflictDiag. + * + * @generated from protobuf message teleport.lib.vnet.diag.v1.RouteConflictReport + */ +export interface RouteConflictReport { + /** + * @generated from protobuf field: repeated teleport.lib.vnet.diag.v1.RouteConflict route_conflicts = 1; + */ + routeConflicts: RouteConflict[]; +} +/** + * RouteConflict describes a conflict between a route set up by a 3rd-party app where the + * destination overlaps with a destination in a route set up by VNet. + * + * @generated from protobuf message teleport.lib.vnet.diag.v1.RouteConflict + */ +export interface RouteConflict { + /** + * dest is the destination of the conflicting route. + * + * @generated from protobuf field: string dest = 1; + */ + dest: string; + /** + * vnet_dest is the destination of a VNet route that Dest overlaps with. + * + * @generated from protobuf field: string vnet_dest = 2; + */ + vnetDest: string; + /** + * interface_name is the name of the interface the route uses, e.g. "utun4". + * + * @generated from protobuf field: string interface_name = 3; + */ + interfaceName: string; + /** + * interface_app may contain the name of the application responsible for setting up the interface. + * At the moment, the only source of this information is NetworkExtension description included in + * the output of `ifconfig -v `. Not all VPN applications use this framework, so + * it's likely to be empty. + * + * @generated from protobuf field: string interface_app = 4; + */ + interfaceApp: string; +} +/** + * CheckAttemptStatus describes whether CheckAttempt finished successfully. This is different from + * CheckReportStatus, which describes whether a successful attempt at running a check has found any + * issues. See the comment for CheckAttempt for an example. + * + * @generated from protobuf enum teleport.lib.vnet.diag.v1.CheckAttemptStatus + */ +export enum CheckAttemptStatus { + /** + * @generated from protobuf enum value: CHECK_ATTEMPT_STATUS_UNSPECIFIED = 0; + */ + UNSPECIFIED = 0, + /** + * CHECK_ATTEMPT_STATUS_OK indicates that the check ran successfully. + * + * @generated from protobuf enum value: CHECK_ATTEMPT_STATUS_OK = 1; + */ + OK = 1, + /** + * CHECK_ATTEMPT_STATUS_ERROR indicates that the check failed to run. + * + * @generated from protobuf enum value: CHECK_ATTEMPT_STATUS_ERROR = 2; + */ + ERROR = 2 +} +/** + * CheckReportStatus describes the outcome of a successful attempt at running a check. + * + * @generated from protobuf enum teleport.lib.vnet.diag.v1.CheckReportStatus + */ +export enum CheckReportStatus { + /** + * @generated from protobuf enum value: CHECK_REPORT_STATUS_UNSPECIFIED = 0; + */ + UNSPECIFIED = 0, + /** + * CHECK_REPORT_STATUS_OK indicates that the check has not found any issues. + * + * @generated from protobuf enum value: CHECK_REPORT_STATUS_OK = 1; + */ + OK = 1, + /** + * CHECK_REPORT_STATUS_ISSUES_FOUND indicates that the check has found at least one issue. + * + * @generated from protobuf enum value: CHECK_REPORT_STATUS_ISSUES_FOUND = 2; + */ + ISSUES_FOUND = 2 +} +/** + * CommandAttemptStatus describes the status of CommandAttempt. + * + * @generated from protobuf enum teleport.lib.vnet.diag.v1.CommandAttemptStatus + */ +export enum CommandAttemptStatus { + /** + * @generated from protobuf enum value: COMMAND_ATTEMPT_STATUS_UNSPECIFIED = 0; + */ + UNSPECIFIED = 0, + /** + * @generated from protobuf enum value: COMMAND_ATTEMPT_STATUS_OK = 1; + */ + OK = 1, + /** + * @generated from protobuf enum value: COMMAND_ATTEMPT_STATUS_ERROR = 2; + */ + ERROR = 2 +} +// @generated message type with reflection information, may provide speed optimized methods +class Report$Type extends MessageType { + constructor() { + super("teleport.lib.vnet.diag.v1.Report", [ + { no: 1, name: "created_at", kind: "message", T: () => Timestamp }, + { no: 2, name: "network_stack_attempt", kind: "message", T: () => NetworkStackAttempt }, + { no: 3, name: "checks", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => CheckAttempt } + ]); + } + create(value?: PartialMessage): Report { + const message = globalThis.Object.create((this.messagePrototype!)); + message.checks = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: Report): Report { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* google.protobuf.Timestamp created_at */ 1: + message.createdAt = Timestamp.internalBinaryRead(reader, reader.uint32(), options, message.createdAt); + break; + case /* teleport.lib.vnet.diag.v1.NetworkStackAttempt network_stack_attempt */ 2: + message.networkStackAttempt = NetworkStackAttempt.internalBinaryRead(reader, reader.uint32(), options, message.networkStackAttempt); + break; + case /* repeated teleport.lib.vnet.diag.v1.CheckAttempt checks */ 3: + message.checks.push(CheckAttempt.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: Report, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* google.protobuf.Timestamp created_at = 1; */ + if (message.createdAt) + Timestamp.internalBinaryWrite(message.createdAt, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + /* teleport.lib.vnet.diag.v1.NetworkStackAttempt network_stack_attempt = 2; */ + if (message.networkStackAttempt) + NetworkStackAttempt.internalBinaryWrite(message.networkStackAttempt, writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + /* repeated teleport.lib.vnet.diag.v1.CheckAttempt checks = 3; */ + for (let i = 0; i < message.checks.length; i++) + CheckAttempt.internalBinaryWrite(message.checks[i], writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.vnet.diag.v1.Report + */ +export const Report = new Report$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class NetworkStackAttempt$Type extends MessageType { + constructor() { + super("teleport.lib.vnet.diag.v1.NetworkStackAttempt", [ + { no: 1, name: "status", kind: "enum", T: () => ["teleport.lib.vnet.diag.v1.CheckAttemptStatus", CheckAttemptStatus, "CHECK_ATTEMPT_STATUS_"] }, + { no: 2, name: "error", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "network_stack", kind: "message", T: () => NetworkStack } + ]); + } + create(value?: PartialMessage): NetworkStackAttempt { + const message = globalThis.Object.create((this.messagePrototype!)); + message.status = 0; + message.error = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: NetworkStackAttempt): NetworkStackAttempt { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* teleport.lib.vnet.diag.v1.CheckAttemptStatus status */ 1: + message.status = reader.int32(); + break; + case /* string error */ 2: + message.error = reader.string(); + break; + case /* teleport.lib.vnet.diag.v1.NetworkStack network_stack */ 3: + message.networkStack = NetworkStack.internalBinaryRead(reader, reader.uint32(), options, message.networkStack); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: NetworkStackAttempt, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* teleport.lib.vnet.diag.v1.CheckAttemptStatus status = 1; */ + if (message.status !== 0) + writer.tag(1, WireType.Varint).int32(message.status); + /* string error = 2; */ + if (message.error !== "") + writer.tag(2, WireType.LengthDelimited).string(message.error); + /* teleport.lib.vnet.diag.v1.NetworkStack network_stack = 3; */ + if (message.networkStack) + NetworkStack.internalBinaryWrite(message.networkStack, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.vnet.diag.v1.NetworkStackAttempt + */ +export const NetworkStackAttempt = new NetworkStackAttempt$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class NetworkStack$Type extends MessageType { + constructor() { + super("teleport.lib.vnet.diag.v1.NetworkStack", [ + { no: 1, name: "interface_name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "ipv4_cidr_ranges", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "ipv6_prefix", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "dns_zones", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): NetworkStack { + const message = globalThis.Object.create((this.messagePrototype!)); + message.interfaceName = ""; + message.ipv4CidrRanges = []; + message.ipv6Prefix = ""; + message.dnsZones = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: NetworkStack): NetworkStack { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string interface_name */ 1: + message.interfaceName = reader.string(); + break; + case /* repeated string ipv4_cidr_ranges */ 2: + message.ipv4CidrRanges.push(reader.string()); + break; + case /* string ipv6_prefix */ 3: + message.ipv6Prefix = reader.string(); + break; + case /* repeated string dns_zones */ 4: + message.dnsZones.push(reader.string()); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: NetworkStack, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string interface_name = 1; */ + if (message.interfaceName !== "") + writer.tag(1, WireType.LengthDelimited).string(message.interfaceName); + /* repeated string ipv4_cidr_ranges = 2; */ + for (let i = 0; i < message.ipv4CidrRanges.length; i++) + writer.tag(2, WireType.LengthDelimited).string(message.ipv4CidrRanges[i]); + /* string ipv6_prefix = 3; */ + if (message.ipv6Prefix !== "") + writer.tag(3, WireType.LengthDelimited).string(message.ipv6Prefix); + /* repeated string dns_zones = 4; */ + for (let i = 0; i < message.dnsZones.length; i++) + writer.tag(4, WireType.LengthDelimited).string(message.dnsZones[i]); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.vnet.diag.v1.NetworkStack + */ +export const NetworkStack = new NetworkStack$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class CheckAttempt$Type extends MessageType { + constructor() { + super("teleport.lib.vnet.diag.v1.CheckAttempt", [ + { no: 1, name: "status", kind: "enum", T: () => ["teleport.lib.vnet.diag.v1.CheckAttemptStatus", CheckAttemptStatus, "CHECK_ATTEMPT_STATUS_"] }, + { no: 2, name: "error", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "check_report", kind: "message", T: () => CheckReport }, + { no: 4, name: "commands", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => CommandAttempt } + ]); + } + create(value?: PartialMessage): CheckAttempt { + const message = globalThis.Object.create((this.messagePrototype!)); + message.status = 0; + message.error = ""; + message.commands = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: CheckAttempt): CheckAttempt { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* teleport.lib.vnet.diag.v1.CheckAttemptStatus status */ 1: + message.status = reader.int32(); + break; + case /* string error */ 2: + message.error = reader.string(); + break; + case /* teleport.lib.vnet.diag.v1.CheckReport check_report */ 3: + message.checkReport = CheckReport.internalBinaryRead(reader, reader.uint32(), options, message.checkReport); + break; + case /* repeated teleport.lib.vnet.diag.v1.CommandAttempt commands */ 4: + message.commands.push(CommandAttempt.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: CheckAttempt, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* teleport.lib.vnet.diag.v1.CheckAttemptStatus status = 1; */ + if (message.status !== 0) + writer.tag(1, WireType.Varint).int32(message.status); + /* string error = 2; */ + if (message.error !== "") + writer.tag(2, WireType.LengthDelimited).string(message.error); + /* teleport.lib.vnet.diag.v1.CheckReport check_report = 3; */ + if (message.checkReport) + CheckReport.internalBinaryWrite(message.checkReport, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + /* repeated teleport.lib.vnet.diag.v1.CommandAttempt commands = 4; */ + for (let i = 0; i < message.commands.length; i++) + CommandAttempt.internalBinaryWrite(message.commands[i], writer.tag(4, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.vnet.diag.v1.CheckAttempt + */ +export const CheckAttempt = new CheckAttempt$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class CheckReport$Type extends MessageType { + constructor() { + super("teleport.lib.vnet.diag.v1.CheckReport", [ + { no: 1, name: "status", kind: "enum", T: () => ["teleport.lib.vnet.diag.v1.CheckReportStatus", CheckReportStatus, "CHECK_REPORT_STATUS_"] }, + { no: 2, name: "route_conflict_report", kind: "message", oneof: "report", T: () => RouteConflictReport } + ]); + } + create(value?: PartialMessage): CheckReport { + const message = globalThis.Object.create((this.messagePrototype!)); + message.status = 0; + message.report = { oneofKind: undefined }; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: CheckReport): CheckReport { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* teleport.lib.vnet.diag.v1.CheckReportStatus status */ 1: + message.status = reader.int32(); + break; + case /* teleport.lib.vnet.diag.v1.RouteConflictReport route_conflict_report */ 2: + message.report = { + oneofKind: "routeConflictReport", + routeConflictReport: RouteConflictReport.internalBinaryRead(reader, reader.uint32(), options, (message.report as any).routeConflictReport) + }; + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: CheckReport, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* teleport.lib.vnet.diag.v1.CheckReportStatus status = 1; */ + if (message.status !== 0) + writer.tag(1, WireType.Varint).int32(message.status); + /* teleport.lib.vnet.diag.v1.RouteConflictReport route_conflict_report = 2; */ + if (message.report.oneofKind === "routeConflictReport") + RouteConflictReport.internalBinaryWrite(message.report.routeConflictReport, writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.vnet.diag.v1.CheckReport + */ +export const CheckReport = new CheckReport$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class CommandAttempt$Type extends MessageType { + constructor() { + super("teleport.lib.vnet.diag.v1.CommandAttempt", [ + { no: 1, name: "status", kind: "enum", T: () => ["teleport.lib.vnet.diag.v1.CommandAttemptStatus", CommandAttemptStatus, "COMMAND_ATTEMPT_STATUS_"] }, + { no: 2, name: "error", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "command", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "output", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): CommandAttempt { + const message = globalThis.Object.create((this.messagePrototype!)); + message.status = 0; + message.error = ""; + message.command = ""; + message.output = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: CommandAttempt): CommandAttempt { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* teleport.lib.vnet.diag.v1.CommandAttemptStatus status */ 1: + message.status = reader.int32(); + break; + case /* string error */ 2: + message.error = reader.string(); + break; + case /* string command */ 3: + message.command = reader.string(); + break; + case /* string output */ 4: + message.output = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: CommandAttempt, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* teleport.lib.vnet.diag.v1.CommandAttemptStatus status = 1; */ + if (message.status !== 0) + writer.tag(1, WireType.Varint).int32(message.status); + /* string error = 2; */ + if (message.error !== "") + writer.tag(2, WireType.LengthDelimited).string(message.error); + /* string command = 3; */ + if (message.command !== "") + writer.tag(3, WireType.LengthDelimited).string(message.command); + /* string output = 4; */ + if (message.output !== "") + writer.tag(4, WireType.LengthDelimited).string(message.output); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.vnet.diag.v1.CommandAttempt + */ +export const CommandAttempt = new CommandAttempt$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class RouteConflictReport$Type extends MessageType { + constructor() { + super("teleport.lib.vnet.diag.v1.RouteConflictReport", [ + { no: 1, name: "route_conflicts", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => RouteConflict } + ]); + } + create(value?: PartialMessage): RouteConflictReport { + const message = globalThis.Object.create((this.messagePrototype!)); + message.routeConflicts = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: RouteConflictReport): RouteConflictReport { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* repeated teleport.lib.vnet.diag.v1.RouteConflict route_conflicts */ 1: + message.routeConflicts.push(RouteConflict.internalBinaryRead(reader, reader.uint32(), options)); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: RouteConflictReport, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* repeated teleport.lib.vnet.diag.v1.RouteConflict route_conflicts = 1; */ + for (let i = 0; i < message.routeConflicts.length; i++) + RouteConflict.internalBinaryWrite(message.routeConflicts[i], writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.vnet.diag.v1.RouteConflictReport + */ +export const RouteConflictReport = new RouteConflictReport$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class RouteConflict$Type extends MessageType { + constructor() { + super("teleport.lib.vnet.diag.v1.RouteConflict", [ + { no: 1, name: "dest", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "vnet_dest", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "interface_name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "interface_app", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): RouteConflict { + const message = globalThis.Object.create((this.messagePrototype!)); + message.dest = ""; + message.vnetDest = ""; + message.interfaceName = ""; + message.interfaceApp = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: RouteConflict): RouteConflict { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string dest */ 1: + message.dest = reader.string(); + break; + case /* string vnet_dest */ 2: + message.vnetDest = reader.string(); + break; + case /* string interface_name */ 3: + message.interfaceName = reader.string(); + break; + case /* string interface_app */ 4: + message.interfaceApp = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: RouteConflict, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string dest = 1; */ + if (message.dest !== "") + writer.tag(1, WireType.LengthDelimited).string(message.dest); + /* string vnet_dest = 2; */ + if (message.vnetDest !== "") + writer.tag(2, WireType.LengthDelimited).string(message.vnetDest); + /* string interface_name = 3; */ + if (message.interfaceName !== "") + writer.tag(3, WireType.LengthDelimited).string(message.interfaceName); + /* string interface_app = 4; */ + if (message.interfaceApp !== "") + writer.tag(4, WireType.LengthDelimited).string(message.interfaceApp); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.vnet.diag.v1.RouteConflict + */ +export const RouteConflict = new RouteConflict$Type(); diff --git a/lib/teleterm/vnet/service.go b/lib/teleterm/vnet/service.go index e3a6b320182a0..73796b17a8556 100644 --- a/lib/teleterm/vnet/service.go +++ b/lib/teleterm/vnet/service.go @@ -239,8 +239,14 @@ func (s *Service) ListDNSZones(ctx context.Context, req *api.ListDNSZonesRequest return nil, trace.Wrap(err) } - dnsZones := []string{} + dnsZones, _ := s.listDNSZonesAndCIDRRanges(ctx, profileNames) + return &api.ListDNSZonesResponse{ + DnsZones: dnsZones, + }, nil +} + +func (s *Service) listDNSZonesAndCIDRRanges(ctx context.Context, profileNames []string) (dnsZones []string, cidrRanges []string) { for _, profileName := range profileNames { rootClusterURI := uri.NewClusterURI(profileName) cLog := log.With("cluster", rootClusterURI) @@ -257,6 +263,7 @@ func (s *Service) ListDNSZones(ctx context.Context, req *api.ListDNSZonesRequest } dnsZones = append(dnsZones, clusterConfig.DNSZones...) + cidrRanges = append(cidrRanges, clusterConfig.IPv4CIDRRange) leafClusters, err := s.cfg.DaemonService.ListLeafClusters(ctx, rootClusterURI.String()) if err != nil { @@ -279,14 +286,14 @@ func (s *Service) ListDNSZones(ctx context.Context, req *api.ListDNSZonesRequest } dnsZones = append(dnsZones, clusterConfig.DNSZones...) + cidrRanges = append(cidrRanges, clusterConfig.IPv4CIDRRange) } } dnsZones = utils.Deduplicate(dnsZones) + cidrRanges = utils.Deduplicate(cidrRanges) - return &api.ListDNSZonesResponse{ - DnsZones: dnsZones, - }, nil + return dnsZones, cidrRanges } func (s *Service) stopLocked() error { diff --git a/lib/teleterm/vnet/service_darwin.go b/lib/teleterm/vnet/service_darwin.go index 2b039687664a1..7944bb9fefa13 100644 --- a/lib/teleterm/vnet/service_darwin.go +++ b/lib/teleterm/vnet/service_darwin.go @@ -22,6 +22,7 @@ import ( "github.com/gravitational/trace" api "github.com/gravitational/teleport/gen/proto/go/teleport/lib/teleterm/vnet/v1" + diagv1 "github.com/gravitational/teleport/gen/proto/go/teleport/lib/vnet/diag/v1" "github.com/gravitational/teleport/lib/vnet/diag" ) @@ -39,7 +40,20 @@ func (s *Service) RunDiagnostics(ctx context.Context, req *api.RunDiagnosticsReq return nil, trace.BadParameter("no interface name, this is a bug") } - conflictingRoutesDiag, err := diag.NewRouteConflictDiag(&diag.RouteConflictConfig{ + if s.networkStackInfo.IPv6Prefix == "" { + return nil, trace.BadParameter("no IPv6 prefix, this is a bug") + } + + nsa := &diagv1.NetworkStackAttempt{} + if ns, err := s.getNetworkStack(ctx); err != nil { + nsa.Status = diagv1.CheckAttemptStatus_CHECK_ATTEMPT_STATUS_ERROR + nsa.Error = err.Error() + } else { + nsa.Status = diagv1.CheckAttemptStatus_CHECK_ATTEMPT_STATUS_OK + nsa.NetworkStack = ns + } + + routeConflictDiag, err := diag.NewRouteConflictDiag(&diag.RouteConflictConfig{ VnetIfaceName: s.networkStackInfo.IfaceName, Routing: &diag.DarwinRouting{}, Interfaces: &diag.NetInterfaces{}, @@ -47,14 +61,33 @@ func (s *Service) RunDiagnostics(ctx context.Context, req *api.RunDiagnosticsReq if err != nil { return nil, trace.Wrap(err) } - crs, err := conflictingRoutesDiag.Run(ctx) + + report, err := diag.GenerateReport(ctx, diag.ReportPrerequisites{ + Clock: s.cfg.Clock, + NetworkStackAttempt: nsa, + DiagChecks: []diag.DiagCheck{routeConflictDiag}, + }) if err != nil { return nil, trace.Wrap(err) } - for _, cr := range crs { - log.InfoContext(ctx, "Found conflicting route", "route", cr) + return &api.RunDiagnosticsResponse{ + Report: report, + }, nil +} + +func (s *Service) getNetworkStack(ctx context.Context) (*diagv1.NetworkStack, error) { + profileNames, err := s.cfg.DaemonService.ListProfileNames() + if err != nil { + return nil, trace.Wrap(err) } - return &api.RunDiagnosticsResponse{}, nil + dnsZones, cidrRanges := s.listDNSZonesAndCIDRRanges(ctx, profileNames) + + return &diagv1.NetworkStack{ + InterfaceName: s.networkStackInfo.IfaceName, + Ipv6Prefix: s.networkStackInfo.IPv6Prefix, + Ipv4CidrRanges: cidrRanges, + DnsZones: dnsZones, + }, nil } diff --git a/lib/vnet/diag/diag.go b/lib/vnet/diag/diag.go new file mode 100644 index 0000000000000..3fea45a771f52 --- /dev/null +++ b/lib/vnet/diag/diag.go @@ -0,0 +1,159 @@ +// Teleport +// Copyright (C) 2025 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 diag + +import ( + "context" + "errors" + "fmt" + "os/exec" + "strings" + "unicode/utf8" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/gravitational/teleport" + diagv1 "github.com/gravitational/teleport/gen/proto/go/teleport/lib/vnet/diag/v1" + logutils "github.com/gravitational/teleport/lib/utils/log" +) + +var log = logutils.NewPackageLogger(teleport.ComponentKey, teleport.Component("vnet", "diag")) + +// Diagnostician runs individual diag checks along with their accompanying commands and produces a +// report. +type Diagnostician struct{} + +// DiagCheck is an individual diag check run by [GenerateReport]. +type DiagCheck interface { + // Run performs the check. + Run(context.Context) (*diagv1.CheckReport, error) + // Commands returns commands accompanying the check which are supposed to help inspect the state of + // the OS relevant to the given check even if the check itself fails. + Commands(context.Context) []*exec.Cmd + // EmptyCheckReport returns an empty version of [diagv1.CheckReport] belonging to this DiagCheck. + // If Run fails, it's used to set the correct kind of [diagv1.CheckReport] on [diagv1.CheckAttempt]. + EmptyCheckReport() *diagv1.CheckReport +} + +// ReportPrerequisites are items needed by [GenerateReport]. +type ReportPrerequisites struct { + Clock clockwork.Clock + NetworkStackAttempt *diagv1.NetworkStackAttempt + DiagChecks []DiagCheck + // SkipCommands controls whether the report returned from [GenerateReport] is going to include + // extra commands accompanying each diagnostic check. Useful in contexts where there's no place to + // display output of those commands. + SkipCommands bool +} + +func (rp *ReportPrerequisites) check() error { + if rp.Clock == nil { + return trace.BadParameter("missing clock") + } + + if rp.NetworkStackAttempt == nil { + return trace.BadParameter("missing network stack attempt") + } + + if len(rp.DiagChecks) == 0 { + return trace.BadParameter("no diag checks provided") + } + + return nil +} + +// GenerateReport generates a report using the output of the checks provided through [rp]. +func GenerateReport(ctx context.Context, rp ReportPrerequisites) (*diagv1.Report, error) { + if err := rp.check(); err != nil { + return nil, trace.Wrap(err) + } + + report := &diagv1.Report{} + report.CreatedAt = timestamppb.New(rp.Clock.Now().UTC()) + report.NetworkStackAttempt = rp.NetworkStackAttempt + + for _, diagCheck := range rp.DiagChecks { + checkAttempt := runCheck(ctx, diagCheck, rp.SkipCommands) + + report.Checks = append(report.Checks, checkAttempt) + } + + return report, nil +} + +func runCheck(ctx context.Context, diagCheck DiagCheck, skipCommands bool) *diagv1.CheckAttempt { + attempt := &diagv1.CheckAttempt{} + + report, err := diagCheck.Run(ctx) + if err != nil { + attempt.Status = diagv1.CheckAttemptStatus_CHECK_ATTEMPT_STATUS_ERROR + attempt.Error = err.Error() + // In case of an error, CheckReport needs to be set to an empty value. Otherwise it'd be + // impossible to identify the type of a failed check. + attempt.CheckReport = diagCheck.EmptyCheckReport() + } else { + attempt.Status = diagv1.CheckAttemptStatus_CHECK_ATTEMPT_STATUS_OK + attempt.CheckReport = report + } + + if !skipCommands { + for _, cmd := range diagCheck.Commands(ctx) { + attempt.Commands = append(attempt.Commands, runCommand(cmd)) + } + } + + return attempt +} + +func runCommand(cmd *exec.Cmd) *diagv1.CommandAttempt { + command := strings.Join(cmd.Args, " ") + + output, err := cmd.Output() + if err != nil { + var exitError *exec.ExitError + errMessage := err.Error() + if errors.As(err, &exitError) { + stderr := string(exitError.Stderr) + if stderr != "" && utf8.Valid(exitError.Stderr) { + errMessage = fmt.Sprintf("%s\n%s", errMessage, stderr) + } + } + + return &diagv1.CommandAttempt{ + Status: diagv1.CommandAttemptStatus_COMMAND_ATTEMPT_STATUS_ERROR, + Error: errMessage, + Command: command, + } + } + + // A protobuf string must contain valid UTF-8 or 7-bit ASCII text . + if !utf8.Valid(output) { + return &diagv1.CommandAttempt{ + Status: diagv1.CommandAttemptStatus_COMMAND_ATTEMPT_STATUS_ERROR, + Error: "command output contains text that is not UTF-8 encoded", + Command: command, + } + } + + return &diagv1.CommandAttempt{ + Status: diagv1.CommandAttemptStatus_COMMAND_ATTEMPT_STATUS_OK, + Command: command, + Output: string(output), + } +} diff --git a/lib/vnet/diag/diag_test.go b/lib/vnet/diag/diag_test.go new file mode 100644 index 0000000000000..aca92b53905af --- /dev/null +++ b/lib/vnet/diag/diag_test.go @@ -0,0 +1,93 @@ +// Teleport +// Copyright (C) 2025 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 diag + +import ( + "context" + "os/exec" + "testing" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/require" + + diagv1 "github.com/gravitational/teleport/gen/proto/go/teleport/lib/vnet/diag/v1" +) + +func TestGenerateReport_FailedCheck(t *testing.T) { + diagCheck := &FakeDiagCheck{shouldFail: true} + + report, err := GenerateReport(context.Background(), ReportPrerequisites{ + Clock: clockwork.NewFakeClock(), + NetworkStackAttempt: &diagv1.NetworkStackAttempt{}, + DiagChecks: []DiagCheck{diagCheck}, + }) + + require.NoError(t, err) + require.Len(t, report.Checks, 1) + checkAttempt := report.Checks[0] + require.Equal(t, diagv1.CheckAttemptStatus_CHECK_ATTEMPT_STATUS_ERROR, checkAttempt.Status) + + // Verify that commands are still included even if the check itself failed. + require.Len(t, checkAttempt.Commands, 1) + // Verify that CheckReport is not empty, as otherwise it'd be impossible to tell the kind of the + // check that failed. + require.NotNil(t, checkAttempt.CheckReport) +} + +func TestGenerateReport_SkipCommands(t *testing.T) { + diagCheck := &FakeDiagCheck{} + + report, err := GenerateReport(context.Background(), ReportPrerequisites{ + Clock: clockwork.NewFakeClock(), + NetworkStackAttempt: &diagv1.NetworkStackAttempt{}, + DiagChecks: []DiagCheck{diagCheck}, + SkipCommands: true, + }) + + require.NoError(t, err) + require.Len(t, report.Checks, 1) + checkAttempt := report.Checks[0] + require.Equal(t, diagv1.CheckAttemptStatus_CHECK_ATTEMPT_STATUS_OK, checkAttempt.Status) + require.Empty(t, checkAttempt.Commands) +} + +type FakeDiagCheck struct { + shouldFail bool +} + +func (f *FakeDiagCheck) Run(ctx context.Context) (*diagv1.CheckReport, error) { + if f.shouldFail { + return nil, trace.Errorf("something went wrong") + } + + return &diagv1.CheckReport{ + Report: &diagv1.CheckReport_RouteConflictReport{ + RouteConflictReport: &diagv1.RouteConflictReport{ + RouteConflicts: []*diagv1.RouteConflict{}, + }, + }, + }, nil +} + +func (f *FakeDiagCheck) Commands(ctx context.Context) []*exec.Cmd { + return []*exec.Cmd{exec.CommandContext(ctx, "echo", "foo")} +} + +func (f *FakeDiagCheck) EmptyCheckReport() *diagv1.CheckReport { + return &diagv1.CheckReport{} +} diff --git a/lib/vnet/diag/routeconflict.go b/lib/vnet/diag/routeconflict.go index 777781f48d7ae..9cd0871959e3e 100644 --- a/lib/vnet/diag/routeconflict.go +++ b/lib/vnet/diag/routeconflict.go @@ -23,17 +23,15 @@ import ( "errors" "net" "net/netip" + "os/exec" "regexp" "strings" "github.com/gravitational/trace" - "github.com/gravitational/teleport" - logutils "github.com/gravitational/teleport/lib/utils/log" + diagv1 "github.com/gravitational/teleport/gen/proto/go/teleport/lib/vnet/diag/v1" ) -var log = logutils.NewPackageLogger(teleport.ComponentKey, teleport.Component("vnet", "diag")) - // RouteConflictConfig includes everything that [RouteConflictDiag] needs to run. type RouteConflictConfig struct { // VnetIfaceName is the name of the network interface set up by VNet. [RouteConflictDiag] needs it @@ -104,10 +102,10 @@ func NewRouteConflictDiag(cfg *RouteConflictConfig) (*RouteConflictDiag, error) // // If a 3rd-party route conflicts with more than one VNet route, Run returns a single RouteConflict // for that 3rd-party route describing the conflict with the first conflicting VNet route. -func (c *RouteConflictDiag) Run(ctx context.Context) ([]RouteConflict, error) { +func (c *RouteConflictDiag) Run(ctx context.Context) (*diagv1.CheckReport, error) { retries := 0 for { - crs, err := c.run(ctx) + rcs, err := c.run(ctx) if err != nil { // UnstableIfaceError usually means that an interface was removed between fetching route // messages and getting the details of the interface. In this case, the routes for that @@ -119,11 +117,30 @@ func (c *RouteConflictDiag) Run(ctx context.Context) ([]RouteConflict, error) { } return nil, trace.Wrap(err) } - return crs, nil + + status := diagv1.CheckReportStatus_CHECK_REPORT_STATUS_OK + if len(rcs) > 0 { + status = diagv1.CheckReportStatus_CHECK_REPORT_STATUS_ISSUES_FOUND + } + + return &diagv1.CheckReport{ + Status: status, + Report: &diagv1.CheckReport_RouteConflictReport{ + RouteConflictReport: &diagv1.RouteConflictReport{ + RouteConflicts: rcs, + }, + }, + }, nil + } +} + +func (c *RouteConflictDiag) EmptyCheckReport() *diagv1.CheckReport { + return &diagv1.CheckReport{ + Report: &diagv1.CheckReport_RouteConflictReport{}, } } -func (c *RouteConflictDiag) run(ctx context.Context) ([]RouteConflict, error) { +func (c *RouteConflictDiag) run(ctx context.Context) ([]*diagv1.RouteConflict, error) { // Unlike in other interactions with Interfaces, it doesn't make sense to re-fetch the routes, // hence why NewUnstableIfaceError is not used. If this call gives an error, then VnetIfaceName is // likely wrong. @@ -144,7 +161,7 @@ func (c *RouteConflictDiag) run(ctx context.Context) ([]RouteConflict, error) { } } - var crs []RouteConflict + var rcs []*diagv1.RouteConflict for _, rd := range rds { if rd.IfaceIndex() == vnetIface.Index { continue @@ -170,33 +187,22 @@ func (c *RouteConflictDiag) run(ctx context.Context) ([]RouteConflict, error) { return nil, trace.Wrap(err) } - crs = append(crs, RouteConflict{ - Dest: rd, - VnetDest: vnetDest, - IfaceName: iface.Name, - IfaceApp: ifaceNetworkExtDesc, + rcs = append(rcs, &diagv1.RouteConflict{ + Dest: rd.String(), + VnetDest: vnetDest.String(), + InterfaceName: iface.Name, + InterfaceApp: ifaceNetworkExtDesc, }) break } } - return crs, nil + return rcs, nil } -// RouteConflict describes a conflict between a route set up by a 3rd-party app where the -// destination overlaps with a destination in a route set up by VNet. -type RouteConflict struct { - // Dest is the destination of the conflicting route. - Dest RouteDest - // VnetDest is the destination of a VNet route that Dest overlaps with. - VnetDest RouteDest - // IfaceName is the name of the interface the route uses, e.g. "utun4". - IfaceName string - // IfaceApp may contain the name of the application responsible for setting up the interface. - // At the moment, the only source of this information is NetworkExtension description included in - // the output of `ifconfig -v `. Not all VPN applications use this framework, so - // it's likely to be empty. - IfaceApp string +// Commands returns the accompanying command showing the state of routes in the system. +func (c *RouteConflictDiag) Commands(ctx context.Context) []*exec.Cmd { + return c.commands(ctx) } // RouteDest allows singular treatment of route destinations, no matter if they have a netmask or not. diff --git a/lib/vnet/diag/routeconflict_darwin.go b/lib/vnet/diag/routeconflict_darwin.go index 29d1c5e05e7e7..ae533ff1744ba 100644 --- a/lib/vnet/diag/routeconflict_darwin.go +++ b/lib/vnet/diag/routeconflict_darwin.go @@ -125,3 +125,9 @@ func (n *NetInterfaces) interfaceApp(ctx context.Context, ifaceName string) (str return extractNetworkExtDescFromIfconfigOutput(stdout), nil } + +func (c *RouteConflictDiag) commands(ctx context.Context) []*exec.Cmd { + return []*exec.Cmd{ + exec.CommandContext(ctx, "netstat", "-rn", "-f", "inet"), + } +} diff --git a/lib/vnet/diag/routeconflict_other.go b/lib/vnet/diag/routeconflict_other.go index c83813a2f61be..16572f7c4fcd0 100644 --- a/lib/vnet/diag/routeconflict_other.go +++ b/lib/vnet/diag/routeconflict_other.go @@ -21,6 +21,7 @@ package diag import ( "context" + "os/exec" "github.com/gravitational/trace" ) @@ -28,3 +29,7 @@ import ( func (n *NetInterfaces) interfaceApp(ctx context.Context, ifaceName string) (string, error) { return "", trace.NotImplemented("InterfaceApp is not implemented") } + +func (c *RouteConflictDiag) commands(ctx context.Context) []*exec.Cmd { + return nil +} diff --git a/lib/vnet/diag/routeconflict_test.go b/lib/vnet/diag/routeconflict_test.go index 40da4fef28e21..4ac73b5e4d200 100644 --- a/lib/vnet/diag/routeconflict_test.go +++ b/lib/vnet/diag/routeconflict_test.go @@ -24,6 +24,8 @@ import ( "github.com/gravitational/trace" "github.com/stretchr/testify/require" + + diagv1 "github.com/gravitational/teleport/gen/proto/go/teleport/lib/vnet/diag/v1" ) const vnetIface = "utun4" @@ -32,18 +34,18 @@ const vnetIfaceIndex = 1 const quuxIfaceIndex = 2 func TestRouteConflictDiag(t *testing.T) { - singleRouteConflict := func(t *testing.T, dests []RouteDest, crs []RouteConflict) { - require.Len(t, crs, 1) - cr := crs[0] - require.Equal(t, dests[0], cr.Dest) - require.Equal(t, dests[1], cr.VnetDest) - require.Equal(t, quuxIface, cr.IfaceName) - require.Equal(t, "foobar", cr.IfaceApp) + singleRouteConflict := func(t *testing.T, dests []RouteDest, rcs []*diagv1.RouteConflict) { + require.Len(t, rcs, 1) + rc := rcs[0] + require.Equal(t, dests[0].String(), rc.Dest) + require.Equal(t, dests[1].String(), rc.VnetDest) + require.Equal(t, quuxIface, rc.InterfaceName) + require.Equal(t, "foobar", rc.InterfaceApp) } tests := map[string]struct { dests []RouteDest - checkResult func(t *testing.T, dests []RouteDest, crs []RouteConflict) + checkResult func(t *testing.T, dests []RouteDest, rcs []*diagv1.RouteConflict) }{ "single IP vs VNet single IP": { dests: []RouteDest{ @@ -87,20 +89,20 @@ func TestRouteConflictDiag(t *testing.T) { &RouteDestPrefix{ifaceIndex: quuxIfaceIndex, Prefix: netip.MustParsePrefix("1.2.3.0/24")}, &RouteDestPrefix{ifaceIndex: vnetIfaceIndex, Prefix: netip.MustParsePrefix("0.0.0.0/1")}, }, - checkResult: func(t *testing.T, dests []RouteDest, crs []RouteConflict) { - require.Len(t, crs, 2) - - cr1 := crs[0] - require.Equal(t, "1.2.3.4", cr1.Dest.String()) - require.Equal(t, "0.0.0.0/1", cr1.VnetDest.String()) - require.Equal(t, quuxIface, cr1.IfaceName) - require.Equal(t, "foobar", cr1.IfaceApp) - - cr2 := crs[1] - require.Equal(t, "1.2.3.0/24", cr2.Dest.String()) - require.Equal(t, "0.0.0.0/1", cr2.VnetDest.String()) - require.Equal(t, quuxIface, cr2.IfaceName) - require.Equal(t, "foobar", cr2.IfaceApp) + checkResult: func(t *testing.T, dests []RouteDest, rcs []*diagv1.RouteConflict) { + require.Len(t, rcs, 2) + + rc1 := rcs[0] + require.Equal(t, "1.2.3.4", rc1.Dest) + require.Equal(t, "0.0.0.0/1", rc1.VnetDest) + require.Equal(t, quuxIface, rc1.InterfaceName) + require.Equal(t, "foobar", rc1.InterfaceApp) + + rc2 := rcs[1] + require.Equal(t, "1.2.3.0/24", rc2.Dest) + require.Equal(t, "0.0.0.0/1", rc2.VnetDest) + require.Equal(t, quuxIface, rc2.InterfaceName) + require.Equal(t, "foobar", rc2.InterfaceApp) }, }, "default dests are ignored": { @@ -110,8 +112,8 @@ func TestRouteConflictDiag(t *testing.T) { &RouteDestPrefix{ifaceIndex: vnetIfaceIndex, Prefix: netip.MustParsePrefix("0.0.0.0/1")}, &RouteDestPrefix{ifaceIndex: vnetIfaceIndex, Prefix: netip.MustParsePrefix("128.0.0.0/1")}, }, - checkResult: func(t *testing.T, dests []RouteDest, crs []RouteConflict) { - require.Empty(t, crs) + checkResult: func(t *testing.T, dests []RouteDest, rcs []*diagv1.RouteConflict) { + require.Empty(t, rcs) }, }, } @@ -126,14 +128,15 @@ func TestRouteConflictDiag(t *testing.T) { } routing := &FakeRouting{dests: test.dests} - conflictingRoutesDiag, err := NewRouteConflictDiag(&RouteConflictConfig{ + routeConflictDiag, err := NewRouteConflictDiag(&RouteConflictConfig{ VnetIfaceName: vnetIface, Interfaces: interfaces, Routing: routing, }) require.NoError(t, err) - crs, err := conflictingRoutesDiag.Run(context.Background()) + report, err := routeConflictDiag.Run(context.Background()) require.NoError(t, err) + rcs := report.GetRouteConflictReport().RouteConflicts - test.checkResult(t, test.dests, crs) + test.checkResult(t, test.dests, rcs) }) } } @@ -150,11 +153,11 @@ func TestRouteConflictDiag_RetriesOnUnstableIfaceError(t *testing.T) { &RouteDestIP{ifaceIndex: vnetIfaceIndex, Addr: netip.AddrFrom4([4]byte{1, 2, 3, 4})}, }} - conflictingRoutesDiag, err := NewRouteConflictDiag(&RouteConflictConfig{ + routeConflictDiag, err := NewRouteConflictDiag(&RouteConflictConfig{ VnetIfaceName: vnetIface, Interfaces: interfaces, Routing: routing, }) require.NoError(t, err) - _, err = conflictingRoutesDiag.Run(context.Background()) + _, err = routeConflictDiag.Run(context.Background()) require.NoError(t, err) require.Equal(t, 2, routing.getRouteDestinationsCallCount, "Unexpected number of calls to Routing.GetRouteDestinations") @@ -172,11 +175,11 @@ func TestRouteConflictDiag_RetriesUpToThreeTimes(t *testing.T) { &RouteDestIP{ifaceIndex: vnetIfaceIndex, Addr: netip.AddrFrom4([4]byte{1, 2, 3, 4})}, }} - conflictingRoutesDiag, err := NewRouteConflictDiag(&RouteConflictConfig{ + routeConflictDiag, err := NewRouteConflictDiag(&RouteConflictConfig{ VnetIfaceName: vnetIface, Interfaces: interfaces, Routing: routing, }) require.NoError(t, err) - _, err = conflictingRoutesDiag.Run(context.Background()) + _, err = routeConflictDiag.Run(context.Background()) require.ErrorContains(t, err, "whoops something went wrong") require.Equal(t, 3, routing.getRouteDestinationsCallCount, "Unexpected number of calls to Routing.GetRouteDestinations") diff --git a/lib/vnet/network_stack.go b/lib/vnet/network_stack.go index 0a9091a8d514b..7ad1b2b159333 100644 --- a/lib/vnet/network_stack.go +++ b/lib/vnet/network_stack.go @@ -724,4 +724,6 @@ func protocolVersion(b byte) (tcpip.NetworkProtocolNumber, bool) { type NetworkStackInfo struct { // IfaceName is the name of the interface used by VNet. IfaceName string + // IPv6Prefix is the IPv6 prefix under which VNet assigns addresses for apps and the DNS nameserver. + IPv6Prefix string } diff --git a/lib/vnet/user_process_darwin.go b/lib/vnet/user_process_darwin.go index 80c61ef9f0f4b..d1a55fc99fdde 100644 --- a/lib/vnet/user_process_darwin.go +++ b/lib/vnet/user_process_darwin.go @@ -130,7 +130,8 @@ func runPlatformUserProcess(ctx context.Context, cfg *UserProcessConfig) (pm *Pr }) nsi = NetworkStackInfo{ - IfaceName: tunDeviceName, + IfaceName: tunDeviceName, + IPv6Prefix: ipv6Prefix.String(), } return pm, nsi, nil diff --git a/proto/teleport/lib/teleterm/vnet/v1/vnet_service.proto b/proto/teleport/lib/teleterm/vnet/v1/vnet_service.proto index dfd1365dbeb07..05acea0a5c6ca 100644 --- a/proto/teleport/lib/teleterm/vnet/v1/vnet_service.proto +++ b/proto/teleport/lib/teleterm/vnet/v1/vnet_service.proto @@ -18,6 +18,8 @@ syntax = "proto3"; package teleport.lib.teleterm.vnet.v1; +import "teleport/lib/vnet/diag/v1/diag.proto"; + option go_package = "github.com/gravitational/teleport/gen/proto/go/teleport/lib/teleterm/vnet/v1;vnetv1"; // VnetService provides methods to manage a VNet instance. @@ -94,4 +96,6 @@ enum BackgroundItemStatus { message RunDiagnosticsRequest {} // Response for RunDiagnostics. -message RunDiagnosticsResponse {} +message RunDiagnosticsResponse { + teleport.lib.vnet.diag.v1.Report report = 1; +} diff --git a/proto/teleport/lib/vnet/diag/v1/diag.proto b/proto/teleport/lib/vnet/diag/v1/diag.proto new file mode 100644 index 0000000000000..6d96cf1958a78 --- /dev/null +++ b/proto/teleport/lib/vnet/diag/v1/diag.proto @@ -0,0 +1,160 @@ +// Teleport +// Copyright (C) 2025 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 . + +syntax = "proto3"; + +package teleport.lib.vnet.diag.v1; + +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/gravitational/teleport/gen/proto/go/teleport/lib/vnet/diag/v1;diagv1"; + +// Report represents the attempts at running individual checks. It also includes general information +// about the network stack managed by VNet. It assumes that each individual check as well as getting +// info about the network stack can fail. +message Report { + // created_at is the UTC timestamp at which the report was generated. + google.protobuf.Timestamp created_at = 1; + NetworkStackAttempt network_stack_attempt = 2; + repeated CheckAttempt checks = 3; +} + +// NetworkStackAttempt represents the attempt at getting information about the network stack managed +// by VNet. +message NetworkStackAttempt { + CheckAttemptStatus status = 1; + // error is present if status is CHECK_ATTEMPT_STATUS_ERROR. + string error = 2; + NetworkStack network_stack = 3; +} + +// NetworkStack describes the network stack managed by VNet. +message NetworkStack { + // interface_name is the name of the interface set up and used by VNet. + string interface_name = 1; + // ipv4_cidr_ranges are all the possible ranges under which VNet is going to assign IPv4 addresses + // for apps. The first IP of the first range is used for the TUN device. + // Each root cluster can specify its own CIDR range to be used for apps within that profile. + repeated string ipv4_cidr_ranges = 2; + // ipv6_prefix is the IPv6 prefix under which VNet creates IPv6 addresses for apps and its DNS + // server. + string ipv6_prefix = 3; + // dns_zones lists domains for which DNS queries are supposed to be captured by VNet. + repeated string dns_zones = 4; +} + +// CheckAttempt describes the attempt at running a particular diagnostic check. If it succeeds +// (status is CHECK_ATTEMPT_STATUS_OK), check_report can be inspected to see if the check has found +// any issues. +// +// For example, a check that inspects network routes can succeed (CHECK_ATTEMPT_STATUS_OK) and it +// might or might not find conflicting routes (CHECK_REPORT_STATUS_ISSUES_FOUND or +// CHECK_REPORT_STATUS_OK). But it can also fail to run (CHECK_ATTEMPT_STATUS_ERROR) because the +// syscall to list routes has failed. +message CheckAttempt { + // status represents the status of an attempt at running a particular diagnostic check. This is + // not the same as the status of CheckReport. + // + CheckAttemptStatus status = 1; + // error is present if the check failed to run (status is CHECK_ATTEMPT_STATUS_ERROR). + string error = 2; + // check_report is the output of a particular check. + // + // If check failed to run (status is CHECK_ATTEMPT_STATUS_ERROR), the report oneof in check_report + // is set to a specific member while the member itself is empty. This means that a particular + // CheckAttempt can be distinguished from other attempts describing other checks even if the check + // failed to run. + CheckReport check_report = 3; + // commands are the outputs from additional diagnostic commands executed by the diagnostic + // check. They are meant to help inspect the general state of the OS related to the given check. + // Unless a callsite specifically requests commands to be skipped, commands are present even if + // status is CHECK_ATTEMPT_STATUS_ERROR, as they are useful even if the check failed. + repeated CommandAttempt commands = 4; +} + +// CheckAttemptStatus describes whether CheckAttempt finished successfully. This is different from +// CheckReportStatus, which describes whether a successful attempt at running a check has found any +// issues. See the comment for CheckAttempt for an example. +enum CheckAttemptStatus { + CHECK_ATTEMPT_STATUS_UNSPECIFIED = 0; + // CHECK_ATTEMPT_STATUS_OK indicates that the check ran successfully. + CHECK_ATTEMPT_STATUS_OK = 1; + // CHECK_ATTEMPT_STATUS_ERROR indicates that the check failed to run. + CHECK_ATTEMPT_STATUS_ERROR = 2; +} + +// CheckReport is the output of a successful attempt at running a particular check. +message CheckReport { + // status indicates if the check has found any issues. This is so that a callsite operating on + // a CheckReport can understand the outcome of the check without having to understand the + // semantics of the output included under report. + CheckReportStatus status = 1; + + oneof report { + // route_conflict reports whether there are routes that might conflict with routes set up by + // VNet. + RouteConflictReport route_conflict_report = 2; + } +} + +// CheckReportStatus describes the outcome of a successful attempt at running a check. +enum CheckReportStatus { + CHECK_REPORT_STATUS_UNSPECIFIED = 0; + // CHECK_REPORT_STATUS_OK indicates that the check has not found any issues. + CHECK_REPORT_STATUS_OK = 1; + // CHECK_REPORT_STATUS_ISSUES_FOUND indicates that the check has found at least one issue. + CHECK_REPORT_STATUS_ISSUES_FOUND = 2; +} + +// CommandAttempt describes the attempt at running a particular command associated with a diagnostic +// check. +message CommandAttempt { + CommandAttemptStatus status = 1; + // error is present if status is COMMAND_ATTEMPT_STATUS_ERROR. + string error = 2; + // command shows which command was executed along with its arguments, e.g., "netstat -rn -f inet". + string command = 3; + // output is stdout from the command if status is COMMAND_ATTEMPT_STATUS_OK. + string output = 4; +} + +// CommandAttemptStatus describes the status of CommandAttempt. +enum CommandAttemptStatus { + COMMAND_ATTEMPT_STATUS_UNSPECIFIED = 0; + COMMAND_ATTEMPT_STATUS_OK = 1; + COMMAND_ATTEMPT_STATUS_ERROR = 2; +} + +// RouteConflictReport describes conflicting routes found by RouteConflictDiag. +message RouteConflictReport { + repeated RouteConflict route_conflicts = 1; +} + +// RouteConflict describes a conflict between a route set up by a 3rd-party app where the +// destination overlaps with a destination in a route set up by VNet. +message RouteConflict { + // dest is the destination of the conflicting route. + string dest = 1; + // vnet_dest is the destination of a VNet route that Dest overlaps with. + string vnet_dest = 2; + // interface_name is the name of the interface the route uses, e.g. "utun4". + string interface_name = 3; + // interface_app may contain the name of the application responsible for setting up the interface. + // At the moment, the only source of this information is NetworkExtension description included in + // the output of `ifconfig -v `. Not all VPN applications use this framework, so + // it's likely to be empty. + string interface_app = 4; +} diff --git a/tool/tsh/common/vnet_darwin.go b/tool/tsh/common/vnet_darwin.go index 0744c30d9a216..3ca4ef9f15be2 100644 --- a/tool/tsh/common/vnet_darwin.go +++ b/tool/tsh/common/vnet_darwin.go @@ -92,7 +92,7 @@ func newPlatformVnetServiceCommand(app *kingpin.Application) vnetCommandNotSuppo func runVnetDiagnostics(ctx context.Context, nsi vnet.NetworkStackInfo) error { fmt.Println("Running diagnostics.") - conflictingRoutesDiag, err := diag.NewRouteConflictDiag(&diag.RouteConflictConfig{ + routeConflictDiag, err := diag.NewRouteConflictDiag(&diag.RouteConflictConfig{ VnetIfaceName: nsi.IfaceName, Routing: &diag.DarwinRouting{}, Interfaces: &diag.NetInterfaces{}, @@ -100,13 +100,13 @@ func runVnetDiagnostics(ctx context.Context, nsi vnet.NetworkStackInfo) error { if err != nil { return trace.Wrap(err) } - crs, err := conflictingRoutesDiag.Run(ctx) + rcs, err := routeConflictDiag.Run(ctx) if err != nil { return trace.Wrap(err) } - for _, cr := range crs { - fmt.Printf("Found a conflicting route: %+v\n", cr) + for _, rc := range rcs.GetRouteConflictReport().RouteConflicts { + fmt.Printf("Found a conflicting route: %+v\n", rc) } return nil