Netpulse_SasS/gen/go/netpulse/v1/telemetry.pb.go
byrsapty ddaae60fa0 Етап 8: реєстрація зонда одноразовим запрошенням
Найбільше вузьке місце до запуску: агент заводився INSERT-ом у базу, а
токен вписувався в командний рядок руками. Поставити зонд у клієнта було
неможливо.

core.agent_enrollments тримає sha256 одноразового токена; сам токен
повертається рівно один раз. Видача під FOR UPDATE в одній транзакції:
два агенти з однієї скопійованої команди інакше створили б два зонди з
одного запрошення. Відповідь на «немає», «згоріло» і «використано»
однакова — розрізняти їх означає підказувати тому, хто підбирає токени.

Токен зонда їде окремим полем agent_token, а не в certificate:
сертифікат відповідає на інше питання й живе за іншим циклом.

Агент зберігає посвідчення в /etc/netpulse/agent.json з правами 0600,
через тимчасовий файл і перейменування — обрив живлення посеред запису
інакше лишив би половину токена.

Знайдено живим прогоном: реєстрація не проходила автентифікацію, бо
інтерсептор стоїть на всьому сервері, а не на окремому сервісі — мій же
коментар стверджував протилежне. І запуск із самим посвідченням падав:
validate() вимагав -agent-id, не знаючи про файл.

Сторінка зондів: команда встановлення з токеном, відкликання
запрошень, керування модулями й лімітами, видалення.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 00:50:57 +03:00

1110 lines
37 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// =====================================================================
// NetPulse :: telemetry.proto
// Гарячий шлях: метрики від агента до сервера.
//
// Три типи навантаження, свідомо різні:
// 1. IcmpResult → ts.icmp_samples (широка таблиця, колір вузла)
// 2. InterfaceCounters → ts.if_counters (широка таблиця, анімація лінії)
// 3. MetricSample → ts.series/samples (узагальнена, будь-який плагін)
//
// Перші два денормалізовані, бо їх читає мапа на кожному тику WebSocket.
// Третій — розширюваний без зміни контракту: плагін реєструє свій
// metric_key і працює.
// =====================================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.12
// protoc (unknown)
// source: netpulse/v1/telemetry.proto
package netpulsev1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
durationpb "google.golang.org/protobuf/types/known/durationpb"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
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)
)
type SeriesDescriptor struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Локальний номер у межах сесії. Нумерація з 1; 0 — недійсний.
SeriesRef uint32 `protobuf:"varint,1,opt,name=series_ref,json=seriesRef,proto3" json:"series_ref,omitempty"`
DeviceId string `protobuf:"bytes,2,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
// Заповнюється для метрик рівня інтерфейсу.
InterfaceId string `protobuf:"bytes,3,opt,name=interface_id,json=interfaceId,proto3" json:"interface_id,omitempty"`
// Плагін-джерело: snmp, modbus, http...
PluginKey string `protobuf:"bytes,4,opt,name=plugin_key,json=pluginKey,proto3" json:"plugin_key,omitempty"`
// cpu.util, mem.used, ups.battery.pct, sensor.temp
MetricKey string `protobuf:"bytes,5,opt,name=metric_key,json=metricKey,proto3" json:"metric_key,omitempty"`
// pct, bps, C, V, ms
Unit string `protobuf:"bytes,6,opt,name=unit,proto3" json:"unit,omitempty"`
// Додаткові виміри: {"core":"0","phase":"L1"}
Labels map[string]string `protobuf:"bytes,7,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SeriesDescriptor) Reset() {
*x = SeriesDescriptor{}
mi := &file_netpulse_v1_telemetry_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SeriesDescriptor) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SeriesDescriptor) ProtoMessage() {}
func (x *SeriesDescriptor) ProtoReflect() protoreflect.Message {
mi := &file_netpulse_v1_telemetry_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 SeriesDescriptor.ProtoReflect.Descriptor instead.
func (*SeriesDescriptor) Descriptor() ([]byte, []int) {
return file_netpulse_v1_telemetry_proto_rawDescGZIP(), []int{0}
}
func (x *SeriesDescriptor) GetSeriesRef() uint32 {
if x != nil {
return x.SeriesRef
}
return 0
}
func (x *SeriesDescriptor) GetDeviceId() string {
if x != nil {
return x.DeviceId
}
return ""
}
func (x *SeriesDescriptor) GetInterfaceId() string {
if x != nil {
return x.InterfaceId
}
return ""
}
func (x *SeriesDescriptor) GetPluginKey() string {
if x != nil {
return x.PluginKey
}
return ""
}
func (x *SeriesDescriptor) GetMetricKey() string {
if x != nil {
return x.MetricKey
}
return ""
}
func (x *SeriesDescriptor) GetUnit() string {
if x != nil {
return x.Unit
}
return ""
}
func (x *SeriesDescriptor) GetLabels() map[string]string {
if x != nil {
return x.Labels
}
return nil
}
// Один вимір узагальненої метрики.
type MetricSample struct {
state protoimpl.MessageState `protogen:"open.v1"`
SeriesRef uint32 `protobuf:"varint,1,opt,name=series_ref,json=seriesRef,proto3" json:"series_ref,omitempty"`
Ts *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=ts,proto3" json:"ts,omitempty"`
Value float64 `protobuf:"fixed64,3,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *MetricSample) Reset() {
*x = MetricSample{}
mi := &file_netpulse_v1_telemetry_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *MetricSample) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MetricSample) ProtoMessage() {}
func (x *MetricSample) ProtoReflect() protoreflect.Message {
mi := &file_netpulse_v1_telemetry_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 MetricSample.ProtoReflect.Descriptor instead.
func (*MetricSample) Descriptor() ([]byte, []int) {
return file_netpulse_v1_telemetry_proto_rawDescGZIP(), []int{1}
}
func (x *MetricSample) GetSeriesRef() uint32 {
if x != nil {
return x.SeriesRef
}
return 0
}
func (x *MetricSample) GetTs() *timestamppb.Timestamp {
if x != nil {
return x.Ts
}
return nil
}
func (x *MetricSample) GetValue() float64 {
if x != nil {
return x.Value
}
return 0
}
type IcmpResult struct {
state protoimpl.MessageState `protogen:"open.v1"`
DeviceId string `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
CheckId string `protobuf:"bytes,2,opt,name=check_id,json=checkId,proto3" json:"check_id,omitempty"`
Ts *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=ts,proto3" json:"ts,omitempty"`
RttAvgMs float32 `protobuf:"fixed32,4,opt,name=rtt_avg_ms,json=rttAvgMs,proto3" json:"rtt_avg_ms,omitempty"`
RttMinMs float32 `protobuf:"fixed32,5,opt,name=rtt_min_ms,json=rttMinMs,proto3" json:"rtt_min_ms,omitempty"`
RttMaxMs float32 `protobuf:"fixed32,6,opt,name=rtt_max_ms,json=rttMaxMs,proto3" json:"rtt_max_ms,omitempty"`
JitterMs float32 `protobuf:"fixed32,7,opt,name=jitter_ms,json=jitterMs,proto3" json:"jitter_ms,omitempty"`
LossPct float32 `protobuf:"fixed32,8,opt,name=loss_pct,json=lossPct,proto3" json:"loss_pct,omitempty"`
PacketsSent uint32 `protobuf:"varint,9,opt,name=packets_sent,json=packetsSent,proto3" json:"packets_sent,omitempty"`
PacketsRecv uint32 `protobuf:"varint,10,opt,name=packets_recv,json=packetsRecv,proto3" json:"packets_recv,omitempty"`
Reachable bool `protobuf:"varint,11,opt,name=reachable,proto3" json:"reachable,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *IcmpResult) Reset() {
*x = IcmpResult{}
mi := &file_netpulse_v1_telemetry_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *IcmpResult) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*IcmpResult) ProtoMessage() {}
func (x *IcmpResult) ProtoReflect() protoreflect.Message {
mi := &file_netpulse_v1_telemetry_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 IcmpResult.ProtoReflect.Descriptor instead.
func (*IcmpResult) Descriptor() ([]byte, []int) {
return file_netpulse_v1_telemetry_proto_rawDescGZIP(), []int{2}
}
func (x *IcmpResult) GetDeviceId() string {
if x != nil {
return x.DeviceId
}
return ""
}
func (x *IcmpResult) GetCheckId() string {
if x != nil {
return x.CheckId
}
return ""
}
func (x *IcmpResult) GetTs() *timestamppb.Timestamp {
if x != nil {
return x.Ts
}
return nil
}
func (x *IcmpResult) GetRttAvgMs() float32 {
if x != nil {
return x.RttAvgMs
}
return 0
}
func (x *IcmpResult) GetRttMinMs() float32 {
if x != nil {
return x.RttMinMs
}
return 0
}
func (x *IcmpResult) GetRttMaxMs() float32 {
if x != nil {
return x.RttMaxMs
}
return 0
}
func (x *IcmpResult) GetJitterMs() float32 {
if x != nil {
return x.JitterMs
}
return 0
}
func (x *IcmpResult) GetLossPct() float32 {
if x != nil {
return x.LossPct
}
return 0
}
func (x *IcmpResult) GetPacketsSent() uint32 {
if x != nil {
return x.PacketsSent
}
return 0
}
func (x *IcmpResult) GetPacketsRecv() uint32 {
if x != nil {
return x.PacketsRecv
}
return 0
}
func (x *IcmpResult) GetReachable() bool {
if x != nil {
return x.Reachable
}
return false
}
type InterfaceCounters struct {
state protoimpl.MessageState `protogen:"open.v1"`
DeviceId string `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
InterfaceId string `protobuf:"bytes,2,opt,name=interface_id,json=interfaceId,proto3" json:"interface_id,omitempty"`
Ts *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=ts,proto3" json:"ts,omitempty"`
InOctets uint64 `protobuf:"varint,4,opt,name=in_octets,json=inOctets,proto3" json:"in_octets,omitempty"`
OutOctets uint64 `protobuf:"varint,5,opt,name=out_octets,json=outOctets,proto3" json:"out_octets,omitempty"`
InUcastPkts uint64 `protobuf:"varint,6,opt,name=in_ucast_pkts,json=inUcastPkts,proto3" json:"in_ucast_pkts,omitempty"`
OutUcastPkts uint64 `protobuf:"varint,7,opt,name=out_ucast_pkts,json=outUcastPkts,proto3" json:"out_ucast_pkts,omitempty"`
InErrors uint64 `protobuf:"varint,8,opt,name=in_errors,json=inErrors,proto3" json:"in_errors,omitempty"`
OutErrors uint64 `protobuf:"varint,9,opt,name=out_errors,json=outErrors,proto3" json:"out_errors,omitempty"`
InDiscards uint64 `protobuf:"varint,10,opt,name=in_discards,json=inDiscards,proto3" json:"in_discards,omitempty"`
OutDiscards uint64 `protobuf:"varint,11,opt,name=out_discards,json=outDiscards,proto3" json:"out_discards,omitempty"`
// Похідні швидкості за фактичний інтервал між опитуваннями.
InBps float64 `protobuf:"fixed64,12,opt,name=in_bps,json=inBps,proto3" json:"in_bps,omitempty"`
OutBps float64 `protobuf:"fixed64,13,opt,name=out_bps,json=outBps,proto3" json:"out_bps,omitempty"`
InPps float64 `protobuf:"fixed64,14,opt,name=in_pps,json=inPps,proto3" json:"in_pps,omitempty"`
OutPps float64 `protobuf:"fixed64,15,opt,name=out_pps,json=outPps,proto3" json:"out_pps,omitempty"`
// % від номінальної швидкості порту — джерело анімації трафіку на мапі.
UtilInPct float32 `protobuf:"fixed32,16,opt,name=util_in_pct,json=utilInPct,proto3" json:"util_in_pct,omitempty"`
UtilOutPct float32 `protobuf:"fixed32,17,opt,name=util_out_pct,json=utilOutPct,proto3" json:"util_out_pct,omitempty"`
OperUp bool `protobuf:"varint,18,opt,name=oper_up,json=operUp,proto3" json:"oper_up,omitempty"`
AdminUp bool `protobuf:"varint,19,opt,name=admin_up,json=adminUp,proto3" json:"admin_up,omitempty"`
// Лічильник обнулився (reboot/wrap) — швидкості цього разу недійсні.
CounterReset bool `protobuf:"varint,20,opt,name=counter_reset,json=counterReset,proto3" json:"counter_reset,omitempty"`
// Фактичний інтервал, за який пораховані швидкості.
Interval *durationpb.Duration `protobuf:"bytes,21,opt,name=interval,proto3" json:"interval,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *InterfaceCounters) Reset() {
*x = InterfaceCounters{}
mi := &file_netpulse_v1_telemetry_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *InterfaceCounters) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*InterfaceCounters) ProtoMessage() {}
func (x *InterfaceCounters) ProtoReflect() protoreflect.Message {
mi := &file_netpulse_v1_telemetry_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 InterfaceCounters.ProtoReflect.Descriptor instead.
func (*InterfaceCounters) Descriptor() ([]byte, []int) {
return file_netpulse_v1_telemetry_proto_rawDescGZIP(), []int{3}
}
func (x *InterfaceCounters) GetDeviceId() string {
if x != nil {
return x.DeviceId
}
return ""
}
func (x *InterfaceCounters) GetInterfaceId() string {
if x != nil {
return x.InterfaceId
}
return ""
}
func (x *InterfaceCounters) GetTs() *timestamppb.Timestamp {
if x != nil {
return x.Ts
}
return nil
}
func (x *InterfaceCounters) GetInOctets() uint64 {
if x != nil {
return x.InOctets
}
return 0
}
func (x *InterfaceCounters) GetOutOctets() uint64 {
if x != nil {
return x.OutOctets
}
return 0
}
func (x *InterfaceCounters) GetInUcastPkts() uint64 {
if x != nil {
return x.InUcastPkts
}
return 0
}
func (x *InterfaceCounters) GetOutUcastPkts() uint64 {
if x != nil {
return x.OutUcastPkts
}
return 0
}
func (x *InterfaceCounters) GetInErrors() uint64 {
if x != nil {
return x.InErrors
}
return 0
}
func (x *InterfaceCounters) GetOutErrors() uint64 {
if x != nil {
return x.OutErrors
}
return 0
}
func (x *InterfaceCounters) GetInDiscards() uint64 {
if x != nil {
return x.InDiscards
}
return 0
}
func (x *InterfaceCounters) GetOutDiscards() uint64 {
if x != nil {
return x.OutDiscards
}
return 0
}
func (x *InterfaceCounters) GetInBps() float64 {
if x != nil {
return x.InBps
}
return 0
}
func (x *InterfaceCounters) GetOutBps() float64 {
if x != nil {
return x.OutBps
}
return 0
}
func (x *InterfaceCounters) GetInPps() float64 {
if x != nil {
return x.InPps
}
return 0
}
func (x *InterfaceCounters) GetOutPps() float64 {
if x != nil {
return x.OutPps
}
return 0
}
func (x *InterfaceCounters) GetUtilInPct() float32 {
if x != nil {
return x.UtilInPct
}
return 0
}
func (x *InterfaceCounters) GetUtilOutPct() float32 {
if x != nil {
return x.UtilOutPct
}
return 0
}
func (x *InterfaceCounters) GetOperUp() bool {
if x != nil {
return x.OperUp
}
return false
}
func (x *InterfaceCounters) GetAdminUp() bool {
if x != nil {
return x.AdminUp
}
return false
}
func (x *InterfaceCounters) GetCounterReset() bool {
if x != nil {
return x.CounterReset
}
return false
}
func (x *InterfaceCounters) GetInterval() *durationpb.Duration {
if x != nil {
return x.Interval
}
return nil
}
type StatusChange struct {
state protoimpl.MessageState `protogen:"open.v1"`
DeviceId string `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
Ts *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=ts,proto3" json:"ts,omitempty"`
Status Status `protobuf:"varint,3,opt,name=status,proto3,enum=netpulse.v1.Status" json:"status,omitempty"`
PreviousStatus Status `protobuf:"varint,4,opt,name=previous_status,json=previousStatus,proto3,enum=netpulse.v1.Status" json:"previous_status,omitempty"`
Reason string `protobuf:"bytes,5,opt,name=reason,proto3" json:"reason,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *StatusChange) Reset() {
*x = StatusChange{}
mi := &file_netpulse_v1_telemetry_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *StatusChange) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*StatusChange) ProtoMessage() {}
func (x *StatusChange) ProtoReflect() protoreflect.Message {
mi := &file_netpulse_v1_telemetry_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 StatusChange.ProtoReflect.Descriptor instead.
func (*StatusChange) Descriptor() ([]byte, []int) {
return file_netpulse_v1_telemetry_proto_rawDescGZIP(), []int{4}
}
func (x *StatusChange) GetDeviceId() string {
if x != nil {
return x.DeviceId
}
return ""
}
func (x *StatusChange) GetTs() *timestamppb.Timestamp {
if x != nil {
return x.Ts
}
return nil
}
func (x *StatusChange) GetStatus() Status {
if x != nil {
return x.Status
}
return Status_STATUS_UNSPECIFIED
}
func (x *StatusChange) GetPreviousStatus() Status {
if x != nil {
return x.PreviousStatus
}
return Status_STATUS_UNSPECIFIED
}
func (x *StatusChange) GetReason() string {
if x != nil {
return x.Reason
}
return ""
}
type CheckResult struct {
state protoimpl.MessageState `protogen:"open.v1"`
CheckId string `protobuf:"bytes,1,opt,name=check_id,json=checkId,proto3" json:"check_id,omitempty"`
DeviceId string `protobuf:"bytes,2,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
CheckType string `protobuf:"bytes,3,opt,name=check_type,json=checkType,proto3" json:"check_type,omitempty"` // icmp.ping, snmp.if, http.status
Ts *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=ts,proto3" json:"ts,omitempty"`
Duration *durationpb.Duration `protobuf:"bytes,5,opt,name=duration,proto3" json:"duration,omitempty"`
Success bool `protobuf:"varint,6,opt,name=success,proto3" json:"success,omitempty"`
Error *Error `protobuf:"bytes,7,opt,name=error,proto3" json:"error,omitempty"`
// Довільне корисне навантаження плагіна (JSON), яке не є метрикою:
// напр. http.status → {"status_code":200,"redirects":1}.
PayloadJson []byte `protobuf:"bytes,8,opt,name=payload_json,json=payloadJson,proto3" json:"payload_json,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CheckResult) Reset() {
*x = CheckResult{}
mi := &file_netpulse_v1_telemetry_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckResult) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckResult) ProtoMessage() {}
func (x *CheckResult) ProtoReflect() protoreflect.Message {
mi := &file_netpulse_v1_telemetry_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 CheckResult.ProtoReflect.Descriptor instead.
func (*CheckResult) Descriptor() ([]byte, []int) {
return file_netpulse_v1_telemetry_proto_rawDescGZIP(), []int{5}
}
func (x *CheckResult) GetCheckId() string {
if x != nil {
return x.CheckId
}
return ""
}
func (x *CheckResult) GetDeviceId() string {
if x != nil {
return x.DeviceId
}
return ""
}
func (x *CheckResult) GetCheckType() string {
if x != nil {
return x.CheckType
}
return ""
}
func (x *CheckResult) GetTs() *timestamppb.Timestamp {
if x != nil {
return x.Ts
}
return nil
}
func (x *CheckResult) GetDuration() *durationpb.Duration {
if x != nil {
return x.Duration
}
return nil
}
func (x *CheckResult) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
func (x *CheckResult) GetError() *Error {
if x != nil {
return x.Error
}
return nil
}
func (x *CheckResult) GetPayloadJson() []byte {
if x != nil {
return x.PayloadJson
}
return nil
}
type TelemetryBatch struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Монотонний номер батчу в межах сесії. Основа для ack і ретраїв.
BatchId uint64 `protobuf:"varint,1,opt,name=batch_id,json=batchId,proto3" json:"batch_id,omitempty"`
AgentId string `protobuf:"bytes,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`
// Час формування батчу на агенті (не час вимірів усередині).
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
// Нові серії, які вперше зустрічаються в цій сесії.
// Мають бути в тому ж батчі, що й перші семпли, які на них посилаються.
NewSeries []*SeriesDescriptor `protobuf:"bytes,4,rep,name=new_series,json=newSeries,proto3" json:"new_series,omitempty"`
Samples []*MetricSample `protobuf:"bytes,5,rep,name=samples,proto3" json:"samples,omitempty"`
Icmp []*IcmpResult `protobuf:"bytes,6,rep,name=icmp,proto3" json:"icmp,omitempty"`
Interfaces []*InterfaceCounters `protobuf:"bytes,7,rep,name=interfaces,proto3" json:"interfaces,omitempty"`
StatusChanges []*StatusChange `protobuf:"bytes,8,rep,name=status_changes,json=statusChanges,proto3" json:"status_changes,omitempty"`
CheckResults []*CheckResult `protobuf:"bytes,9,rep,name=check_results,json=checkResults,proto3" json:"check_results,omitempty"`
// Батч — повтор раніше не підтвердженого (після реконекту).
// Сервер робить upsert: PK (ts, device_id) робить це безпечним.
IsRetransmit bool `protobuf:"varint,10,opt,name=is_retransmit,json=isRetransmit,proto3" json:"is_retransmit,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *TelemetryBatch) Reset() {
*x = TelemetryBatch{}
mi := &file_netpulse_v1_telemetry_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *TelemetryBatch) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TelemetryBatch) ProtoMessage() {}
func (x *TelemetryBatch) ProtoReflect() protoreflect.Message {
mi := &file_netpulse_v1_telemetry_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 TelemetryBatch.ProtoReflect.Descriptor instead.
func (*TelemetryBatch) Descriptor() ([]byte, []int) {
return file_netpulse_v1_telemetry_proto_rawDescGZIP(), []int{6}
}
func (x *TelemetryBatch) GetBatchId() uint64 {
if x != nil {
return x.BatchId
}
return 0
}
func (x *TelemetryBatch) GetAgentId() string {
if x != nil {
return x.AgentId
}
return ""
}
func (x *TelemetryBatch) GetCreatedAt() *timestamppb.Timestamp {
if x != nil {
return x.CreatedAt
}
return nil
}
func (x *TelemetryBatch) GetNewSeries() []*SeriesDescriptor {
if x != nil {
return x.NewSeries
}
return nil
}
func (x *TelemetryBatch) GetSamples() []*MetricSample {
if x != nil {
return x.Samples
}
return nil
}
func (x *TelemetryBatch) GetIcmp() []*IcmpResult {
if x != nil {
return x.Icmp
}
return nil
}
func (x *TelemetryBatch) GetInterfaces() []*InterfaceCounters {
if x != nil {
return x.Interfaces
}
return nil
}
func (x *TelemetryBatch) GetStatusChanges() []*StatusChange {
if x != nil {
return x.StatusChanges
}
return nil
}
func (x *TelemetryBatch) GetCheckResults() []*CheckResult {
if x != nil {
return x.CheckResults
}
return nil
}
func (x *TelemetryBatch) GetIsRetransmit() bool {
if x != nil {
return x.IsRetransmit
}
return false
}
type TelemetryAck struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Усі батчі з номером <= цього прийняті й записані.
AckedThroughBatchId uint64 `protobuf:"varint,1,opt,name=acked_through_batch_id,json=ackedThroughBatchId,proto3" json:"acked_through_batch_id,omitempty"`
// Батчі, які треба переслати (напр. частковий збій запису).
NackBatchIds []uint64 `protobuf:"varint,2,rep,packed,name=nack_batch_ids,json=nackBatchIds,proto3" json:"nack_batch_ids,omitempty"`
// Скільки неacknowledged батчів агенту дозволено тримати в польоті.
MaxInFlight uint32 `protobuf:"varint,3,opt,name=max_in_flight,json=maxInFlight,proto3" json:"max_in_flight,omitempty"`
// Сервер під навантаженням: пригальмувати на цей час.
RetryAfter *durationpb.Duration `protobuf:"bytes,4,opt,name=retry_after,json=retryAfter,proto3" json:"retry_after,omitempty"`
// Сервер втратив мапу series_ref → id. Агент має обнулити локальну
// таблицю й перереєструвати всі серії наступним батчем.
ResetSeriesTable bool `protobuf:"varint,5,opt,name=reset_series_table,json=resetSeriesTable,proto3" json:"reset_series_table,omitempty"`
Error *Error `protobuf:"bytes,6,opt,name=error,proto3" json:"error,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *TelemetryAck) Reset() {
*x = TelemetryAck{}
mi := &file_netpulse_v1_telemetry_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *TelemetryAck) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TelemetryAck) ProtoMessage() {}
func (x *TelemetryAck) ProtoReflect() protoreflect.Message {
mi := &file_netpulse_v1_telemetry_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 TelemetryAck.ProtoReflect.Descriptor instead.
func (*TelemetryAck) Descriptor() ([]byte, []int) {
return file_netpulse_v1_telemetry_proto_rawDescGZIP(), []int{7}
}
func (x *TelemetryAck) GetAckedThroughBatchId() uint64 {
if x != nil {
return x.AckedThroughBatchId
}
return 0
}
func (x *TelemetryAck) GetNackBatchIds() []uint64 {
if x != nil {
return x.NackBatchIds
}
return nil
}
func (x *TelemetryAck) GetMaxInFlight() uint32 {
if x != nil {
return x.MaxInFlight
}
return 0
}
func (x *TelemetryAck) GetRetryAfter() *durationpb.Duration {
if x != nil {
return x.RetryAfter
}
return nil
}
func (x *TelemetryAck) GetResetSeriesTable() bool {
if x != nil {
return x.ResetSeriesTable
}
return false
}
func (x *TelemetryAck) GetError() *Error {
if x != nil {
return x.Error
}
return nil
}
var File_netpulse_v1_telemetry_proto protoreflect.FileDescriptor
const file_netpulse_v1_telemetry_proto_rawDesc = "" +
"\n" +
"\x1bnetpulse/v1/telemetry.proto\x12\vnetpulse.v1\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x18netpulse/v1/common.proto\"\xc1\x02\n" +
"\x10SeriesDescriptor\x12\x1d\n" +
"\n" +
"series_ref\x18\x01 \x01(\rR\tseriesRef\x12\x1b\n" +
"\tdevice_id\x18\x02 \x01(\tR\bdeviceId\x12!\n" +
"\finterface_id\x18\x03 \x01(\tR\vinterfaceId\x12\x1d\n" +
"\n" +
"plugin_key\x18\x04 \x01(\tR\tpluginKey\x12\x1d\n" +
"\n" +
"metric_key\x18\x05 \x01(\tR\tmetricKey\x12\x12\n" +
"\x04unit\x18\x06 \x01(\tR\x04unit\x12A\n" +
"\x06labels\x18\a \x03(\v2).netpulse.v1.SeriesDescriptor.LabelsEntryR\x06labels\x1a9\n" +
"\vLabelsEntry\x12\x10\n" +
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"o\n" +
"\fMetricSample\x12\x1d\n" +
"\n" +
"series_ref\x18\x01 \x01(\rR\tseriesRef\x12*\n" +
"\x02ts\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\x02ts\x12\x14\n" +
"\x05value\x18\x03 \x01(\x01R\x05value\"\xe6\x02\n" +
"\n" +
"IcmpResult\x12\x1b\n" +
"\tdevice_id\x18\x01 \x01(\tR\bdeviceId\x12\x19\n" +
"\bcheck_id\x18\x02 \x01(\tR\acheckId\x12*\n" +
"\x02ts\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\x02ts\x12\x1c\n" +
"\n" +
"rtt_avg_ms\x18\x04 \x01(\x02R\brttAvgMs\x12\x1c\n" +
"\n" +
"rtt_min_ms\x18\x05 \x01(\x02R\brttMinMs\x12\x1c\n" +
"\n" +
"rtt_max_ms\x18\x06 \x01(\x02R\brttMaxMs\x12\x1b\n" +
"\tjitter_ms\x18\a \x01(\x02R\bjitterMs\x12\x19\n" +
"\bloss_pct\x18\b \x01(\x02R\alossPct\x12!\n" +
"\fpackets_sent\x18\t \x01(\rR\vpacketsSent\x12!\n" +
"\fpackets_recv\x18\n" +
" \x01(\rR\vpacketsRecv\x12\x1c\n" +
"\treachable\x18\v \x01(\bR\treachable\"\xb7\x05\n" +
"\x11InterfaceCounters\x12\x1b\n" +
"\tdevice_id\x18\x01 \x01(\tR\bdeviceId\x12!\n" +
"\finterface_id\x18\x02 \x01(\tR\vinterfaceId\x12*\n" +
"\x02ts\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\x02ts\x12\x1b\n" +
"\tin_octets\x18\x04 \x01(\x04R\binOctets\x12\x1d\n" +
"\n" +
"out_octets\x18\x05 \x01(\x04R\toutOctets\x12\"\n" +
"\rin_ucast_pkts\x18\x06 \x01(\x04R\vinUcastPkts\x12$\n" +
"\x0eout_ucast_pkts\x18\a \x01(\x04R\foutUcastPkts\x12\x1b\n" +
"\tin_errors\x18\b \x01(\x04R\binErrors\x12\x1d\n" +
"\n" +
"out_errors\x18\t \x01(\x04R\toutErrors\x12\x1f\n" +
"\vin_discards\x18\n" +
" \x01(\x04R\n" +
"inDiscards\x12!\n" +
"\fout_discards\x18\v \x01(\x04R\voutDiscards\x12\x15\n" +
"\x06in_bps\x18\f \x01(\x01R\x05inBps\x12\x17\n" +
"\aout_bps\x18\r \x01(\x01R\x06outBps\x12\x15\n" +
"\x06in_pps\x18\x0e \x01(\x01R\x05inPps\x12\x17\n" +
"\aout_pps\x18\x0f \x01(\x01R\x06outPps\x12\x1e\n" +
"\vutil_in_pct\x18\x10 \x01(\x02R\tutilInPct\x12 \n" +
"\futil_out_pct\x18\x11 \x01(\x02R\n" +
"utilOutPct\x12\x17\n" +
"\aoper_up\x18\x12 \x01(\bR\x06operUp\x12\x19\n" +
"\badmin_up\x18\x13 \x01(\bR\aadminUp\x12#\n" +
"\rcounter_reset\x18\x14 \x01(\bR\fcounterReset\x125\n" +
"\binterval\x18\x15 \x01(\v2\x19.google.protobuf.DurationR\binterval\"\xda\x01\n" +
"\fStatusChange\x12\x1b\n" +
"\tdevice_id\x18\x01 \x01(\tR\bdeviceId\x12*\n" +
"\x02ts\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\x02ts\x12+\n" +
"\x06status\x18\x03 \x01(\x0e2\x13.netpulse.v1.StatusR\x06status\x12<\n" +
"\x0fprevious_status\x18\x04 \x01(\x0e2\x13.netpulse.v1.StatusR\x0epreviousStatus\x12\x16\n" +
"\x06reason\x18\x05 \x01(\tR\x06reason\"\xae\x02\n" +
"\vCheckResult\x12\x19\n" +
"\bcheck_id\x18\x01 \x01(\tR\acheckId\x12\x1b\n" +
"\tdevice_id\x18\x02 \x01(\tR\bdeviceId\x12\x1d\n" +
"\n" +
"check_type\x18\x03 \x01(\tR\tcheckType\x12*\n" +
"\x02ts\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\x02ts\x125\n" +
"\bduration\x18\x05 \x01(\v2\x19.google.protobuf.DurationR\bduration\x12\x18\n" +
"\asuccess\x18\x06 \x01(\bR\asuccess\x12(\n" +
"\x05error\x18\a \x01(\v2\x12.netpulse.v1.ErrorR\x05error\x12!\n" +
"\fpayload_json\x18\b \x01(\fR\vpayloadJson\"\x87\x04\n" +
"\x0eTelemetryBatch\x12\x19\n" +
"\bbatch_id\x18\x01 \x01(\x04R\abatchId\x12\x19\n" +
"\bagent_id\x18\x02 \x01(\tR\aagentId\x129\n" +
"\n" +
"created_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x12<\n" +
"\n" +
"new_series\x18\x04 \x03(\v2\x1d.netpulse.v1.SeriesDescriptorR\tnewSeries\x123\n" +
"\asamples\x18\x05 \x03(\v2\x19.netpulse.v1.MetricSampleR\asamples\x12+\n" +
"\x04icmp\x18\x06 \x03(\v2\x17.netpulse.v1.IcmpResultR\x04icmp\x12>\n" +
"\n" +
"interfaces\x18\a \x03(\v2\x1e.netpulse.v1.InterfaceCountersR\n" +
"interfaces\x12@\n" +
"\x0estatus_changes\x18\b \x03(\v2\x19.netpulse.v1.StatusChangeR\rstatusChanges\x12=\n" +
"\rcheck_results\x18\t \x03(\v2\x18.netpulse.v1.CheckResultR\fcheckResults\x12#\n" +
"\ris_retransmit\x18\n" +
" \x01(\bR\fisRetransmit\"\xa1\x02\n" +
"\fTelemetryAck\x123\n" +
"\x16acked_through_batch_id\x18\x01 \x01(\x04R\x13ackedThroughBatchId\x12$\n" +
"\x0enack_batch_ids\x18\x02 \x03(\x04R\fnackBatchIds\x12\"\n" +
"\rmax_in_flight\x18\x03 \x01(\rR\vmaxInFlight\x12:\n" +
"\vretry_after\x18\x04 \x01(\v2\x19.google.protobuf.DurationR\n" +
"retryAfter\x12,\n" +
"\x12reset_series_table\x18\x05 \x01(\bR\x10resetSeriesTable\x12(\n" +
"\x05error\x18\x06 \x01(\v2\x12.netpulse.v1.ErrorR\x05errorB\xaa\x01\n" +
"\x0fcom.netpulse.v1B\x0eTelemetryProtoP\x01Z:github.com/netpulse/netpulse/gen/go/netpulse/v1;netpulsev1\xa2\x02\x03NXX\xaa\x02\vNetpulse.V1\xca\x02\vNetpulse\\V1\xe2\x02\x17Netpulse\\V1\\GPBMetadata\xea\x02\fNetpulse::V1b\x06proto3"
var (
file_netpulse_v1_telemetry_proto_rawDescOnce sync.Once
file_netpulse_v1_telemetry_proto_rawDescData []byte
)
func file_netpulse_v1_telemetry_proto_rawDescGZIP() []byte {
file_netpulse_v1_telemetry_proto_rawDescOnce.Do(func() {
file_netpulse_v1_telemetry_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_netpulse_v1_telemetry_proto_rawDesc), len(file_netpulse_v1_telemetry_proto_rawDesc)))
})
return file_netpulse_v1_telemetry_proto_rawDescData
}
var file_netpulse_v1_telemetry_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_netpulse_v1_telemetry_proto_goTypes = []any{
(*SeriesDescriptor)(nil), // 0: netpulse.v1.SeriesDescriptor
(*MetricSample)(nil), // 1: netpulse.v1.MetricSample
(*IcmpResult)(nil), // 2: netpulse.v1.IcmpResult
(*InterfaceCounters)(nil), // 3: netpulse.v1.InterfaceCounters
(*StatusChange)(nil), // 4: netpulse.v1.StatusChange
(*CheckResult)(nil), // 5: netpulse.v1.CheckResult
(*TelemetryBatch)(nil), // 6: netpulse.v1.TelemetryBatch
(*TelemetryAck)(nil), // 7: netpulse.v1.TelemetryAck
nil, // 8: netpulse.v1.SeriesDescriptor.LabelsEntry
(*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp
(*durationpb.Duration)(nil), // 10: google.protobuf.Duration
(Status)(0), // 11: netpulse.v1.Status
(*Error)(nil), // 12: netpulse.v1.Error
}
var file_netpulse_v1_telemetry_proto_depIdxs = []int32{
8, // 0: netpulse.v1.SeriesDescriptor.labels:type_name -> netpulse.v1.SeriesDescriptor.LabelsEntry
9, // 1: netpulse.v1.MetricSample.ts:type_name -> google.protobuf.Timestamp
9, // 2: netpulse.v1.IcmpResult.ts:type_name -> google.protobuf.Timestamp
9, // 3: netpulse.v1.InterfaceCounters.ts:type_name -> google.protobuf.Timestamp
10, // 4: netpulse.v1.InterfaceCounters.interval:type_name -> google.protobuf.Duration
9, // 5: netpulse.v1.StatusChange.ts:type_name -> google.protobuf.Timestamp
11, // 6: netpulse.v1.StatusChange.status:type_name -> netpulse.v1.Status
11, // 7: netpulse.v1.StatusChange.previous_status:type_name -> netpulse.v1.Status
9, // 8: netpulse.v1.CheckResult.ts:type_name -> google.protobuf.Timestamp
10, // 9: netpulse.v1.CheckResult.duration:type_name -> google.protobuf.Duration
12, // 10: netpulse.v1.CheckResult.error:type_name -> netpulse.v1.Error
9, // 11: netpulse.v1.TelemetryBatch.created_at:type_name -> google.protobuf.Timestamp
0, // 12: netpulse.v1.TelemetryBatch.new_series:type_name -> netpulse.v1.SeriesDescriptor
1, // 13: netpulse.v1.TelemetryBatch.samples:type_name -> netpulse.v1.MetricSample
2, // 14: netpulse.v1.TelemetryBatch.icmp:type_name -> netpulse.v1.IcmpResult
3, // 15: netpulse.v1.TelemetryBatch.interfaces:type_name -> netpulse.v1.InterfaceCounters
4, // 16: netpulse.v1.TelemetryBatch.status_changes:type_name -> netpulse.v1.StatusChange
5, // 17: netpulse.v1.TelemetryBatch.check_results:type_name -> netpulse.v1.CheckResult
10, // 18: netpulse.v1.TelemetryAck.retry_after:type_name -> google.protobuf.Duration
12, // 19: netpulse.v1.TelemetryAck.error:type_name -> netpulse.v1.Error
20, // [20:20] is the sub-list for method output_type
20, // [20:20] is the sub-list for method input_type
20, // [20:20] is the sub-list for extension type_name
20, // [20:20] is the sub-list for extension extendee
0, // [0:20] is the sub-list for field type_name
}
func init() { file_netpulse_v1_telemetry_proto_init() }
func file_netpulse_v1_telemetry_proto_init() {
if File_netpulse_v1_telemetry_proto != nil {
return
}
file_netpulse_v1_common_proto_init()
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_netpulse_v1_telemetry_proto_rawDesc), len(file_netpulse_v1_telemetry_proto_rawDesc)),
NumEnums: 0,
NumMessages: 9,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_netpulse_v1_telemetry_proto_goTypes,
DependencyIndexes: file_netpulse_v1_telemetry_proto_depIdxs,
MessageInfos: file_netpulse_v1_telemetry_proto_msgTypes,
}.Build()
File_netpulse_v1_telemetry_proto = out.File
file_netpulse_v1_telemetry_proto_goTypes = nil
file_netpulse_v1_telemetry_proto_depIdxs = nil
}