整合 /srv/监控架构优化方案 核心代码: 后端模型(4个新文件): - monitor.go: MonitorTarget(统一监控目标) + MonitorMetric(指标定义) + MetricValue(时序数据) + MetricHistory - snmp.go: SNMPDevice + SNMPTemplate + OID模板管理 - site.go: SiteTask(拨测任务) + SiteResult(拨测结果) - alert_v2.go: 增强告警(多条件规则/模板/升级策略/静默) 后端 pkg(3个包): - pkg/prometheus/client.go (531行): PromQL查询/Range/Labels/Rules - pkg/zabbix/client.go: Zabbix API (Host/Item/Trigger/History) - pkg/snmp/collector.go (621行): gosnmp Walk/BulkWalk/自动发现 基础设施: - Dockerfile: Go 1.21→1.24 (gosnmp依赖) - Agent安装弹框: SSH一键安装Tab + server上下文 - 服务器列表操作栏: 安装按钮条件显示/隐藏 Handler层因类型不兼容暂时跳过,模型和客户端包已编译通过。
401 lines
19 KiB
Go
401 lines
19 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// ============================================
|
|
// AlertRuleV2 增强告警规则
|
|
// ============================================
|
|
|
|
// AlertRuleV2Status 告警规则状态
|
|
type AlertRuleV2Status string
|
|
|
|
const (
|
|
AlertRuleV2Enabled AlertRuleV2Status = "enabled" // 启用
|
|
AlertRuleV2Disabled AlertRuleV2Status = "disabled" // 禁用
|
|
)
|
|
|
|
// AlertSeverity 告警级别
|
|
type AlertSeverity string
|
|
|
|
const (
|
|
AlertSeverityCritical AlertSeverity = "critical" // 严重
|
|
AlertSeverityWarning AlertSeverity = "warning" // 警告
|
|
AlertSeverityNotice AlertSeverity = "notice" // 通知
|
|
AlertSeverityInfo AlertSeverity = "info" // 信息
|
|
)
|
|
|
|
// AggFunction 聚合函数
|
|
type AggFunction string
|
|
|
|
const (
|
|
AggFunctionAvg AggFunction = "avg" // 平均值
|
|
AggFunctionMin AggFunction = "min" // 最小值
|
|
AggFunctionMax AggFunction = "max" // 最大值
|
|
AggFunctionSum AggFunction = "sum" // 求和
|
|
AggFunctionCount AggFunction = "count" // 计数
|
|
AggFunctionLast AggFunction = "last" // 最新值
|
|
AggFunctionP95 AggFunction = "p95" // 95分位
|
|
AggFunctionP99 AggFunction = "p99" // 99分位
|
|
)
|
|
|
|
// Operator 比较运算符
|
|
type Operator string
|
|
|
|
const (
|
|
OperatorGT Operator = ">" // 大于
|
|
OperatorGTE Operator = ">=" // 大于等于
|
|
OperatorLT Operator = "<" // 小于
|
|
OperatorLTE Operator = "<=" // 小于等于
|
|
OperatorEQ Operator = "==" // 等于
|
|
OperatorNE Operator = "!=" // 不等于
|
|
)
|
|
|
|
// AlertRuleV2 增强告警规则表
|
|
// 支持多条件组合、聚合函数、静默期等高级特性
|
|
type AlertRuleV2 struct {
|
|
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
|
Name string `gorm:"type:varchar(128);not null;comment:规则名称" json:"name"`
|
|
Description string `gorm:"type:varchar(256);comment:规则描述" json:"description,omitempty"`
|
|
Severity AlertSeverity `gorm:"type:varchar(16);not null;comment:告警级别" json:"severity"`
|
|
Status AlertRuleV2Status `gorm:"type:varchar(16);default:'enabled';comment:规则状态" json:"status"`
|
|
// 关联目标
|
|
TargetType string `gorm:"type:varchar(32);comment:目标类型" json:"target_type,omitempty"`
|
|
TargetID uint `gorm:"index;comment:目标ID(0表示全部)" json:"target_id,omitempty"`
|
|
TargetTags string `gorm:"type:varchar(256);comment:目标标签筛选" json:"target_tags,omitempty"`
|
|
// 触发条件(JSON存储支持多条件)
|
|
Conditions string `gorm:"type:text;comment:触发条件JSON数组" json:"conditions,omitempty"`
|
|
// 聚合配置
|
|
AggWindow int `gorm:"default:300;comment:聚合窗口(秒)" json:"agg_window"`
|
|
AggFunction AggFunction `gorm:"type:varchar(16);default:'avg';comment:聚合函数" json:"agg_function"`
|
|
// 恢复配置
|
|
RecoverCount int `gorm:"default:1;comment:恢复次数(连续N次低于阈值触发恢复)" json:"recover_count"`
|
|
RecoverWindow int `gorm:"default:300;comment:恢复检查窗口(秒)" json:"recover_window"`
|
|
// 执行配置
|
|
Interval int `gorm:"default:60;comment:评估间隔(秒)" json:"interval"`
|
|
CheckTimes int `gorm:"default:1;comment:连续触发次数" json:"check_times"`
|
|
NotifyMode string `gorm:"type:varchar(16);default:'every';comment:通知模式: every/once/upgrade" json:"notify_mode"`
|
|
// 通知渠道
|
|
ChannelIDs string `gorm:"type:varchar(256);comment:通知渠道ID列表JSON" json:"channel_ids,omitempty"`
|
|
TemplateID uint `gorm:"comment:通知模板ID" json:"template_id,omitempty"`
|
|
// 升级策略
|
|
UpgradeID uint `gorm:"comment:升级策略ID" json:"upgrade_id,omitempty"`
|
|
// 静默策略
|
|
SilenceID uint `gorm:"comment:静默规则ID" json:"silence_id,omitempty"`
|
|
// 标签和注释
|
|
Labels string `gorm:"type:varchar(512);comment:标签JSON" json:"labels,omitempty"`
|
|
Annotations string `gorm:"type:text;comment:注释JSON(用于通知内容模板)" json:"annotations,omitempty"`
|
|
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
|
|
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
|
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
|
DeletedAt *time.Time `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
|
|
}
|
|
|
|
// TableName 指定表名
|
|
func (AlertRuleV2) TableName() string {
|
|
return "alert_rules_v2"
|
|
}
|
|
|
|
// AlertCondition 告警条件定义
|
|
type AlertCondition struct {
|
|
Metric string `json:"metric"` // 指标名称
|
|
Operator Operator `json:"operator"` // 比较运算符
|
|
Threshold float64 `json:"threshold"` // 阈值
|
|
Unit string `json:"unit"` // 单位
|
|
Index string `json:"index"` // 实例索引
|
|
LogicOp string `json:"logic_op"` // 逻辑关系: AND/OR
|
|
AggFunc AggFunction `json:"agg_func"` // 条件级聚合函数
|
|
Window int `json:"window"` // 条件级聚合窗口
|
|
}
|
|
|
|
// AlertConditionGroup 告警条件组
|
|
type AlertConditionGroup struct {
|
|
Conditions []AlertCondition `json:"conditions"` // 条件列表
|
|
LogicOp string `json:"logic_op"` // 组间逻辑: AND/OR
|
|
}
|
|
|
|
// RecoverConfig 告警恢复配置
|
|
type RecoverConfig struct {
|
|
Count int `json:"count"` // 连续恢复次数
|
|
Window int `json:"window"` // 恢复检查窗口(秒)
|
|
}
|
|
|
|
// NotifyMode 通知模式
|
|
type NotifyMode string
|
|
|
|
const (
|
|
NotifyModeEvery NotifyMode = "every" // 每次都通知
|
|
NotifyModeOnce NotifyMode = "once" // 仅通知一次
|
|
NotifyModeUpgrade NotifyMode = "upgrade" // 升级通知
|
|
)
|
|
|
|
// ============================================
|
|
// AlertNotifyTemplate 告警通知模板
|
|
// ============================================
|
|
|
|
// AlertNotifyTemplate 告警通知模板表
|
|
// 定义告警通知的内容模板,支持变量替换
|
|
type AlertNotifyTemplate struct {
|
|
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
|
Name string `gorm:"type:varchar(128);not null;comment:模板名称" json:"name"`
|
|
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
|
|
ChannelType string `gorm:"type:varchar(32);not null;comment:适用渠道类型: email/sms/webhook/dingtalk/wecom/feishu" json:"channel_type"`
|
|
// 模板内容
|
|
TitleTemplate string `gorm:"type:varchar(256);comment:标题模板" json:"title_template,omitempty"`
|
|
BodyTemplate string `gorm:"type:text;comment:正文模板" json:"body_template,omitempty"`
|
|
// 变量定义
|
|
Variables string `gorm:"type:text;comment:可用变量说明JSON" json:"variables,omitempty"`
|
|
// 恢复通知模板
|
|
RecoverTitleTemplate string `gorm:"type:varchar(256);comment:恢复标题模板" json:"recover_title_template,omitempty"`
|
|
RecoverBodyTemplate string `gorm:"type:text;comment:恢复正文模板" json:"recover_body_template,omitempty"`
|
|
IsDefault bool `gorm:"default:false;comment:是否默认模板" json:"is_default"`
|
|
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
|
|
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
|
|
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
|
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
|
DeletedAt *time.Time `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
|
|
}
|
|
|
|
// TableName 指定表名
|
|
func (AlertNotifyTemplate) TableName() string {
|
|
return "alert_notify_templates"
|
|
}
|
|
|
|
// TemplateVariable 模板变量定义
|
|
type TemplateVariable struct {
|
|
Name string `json:"name"` // 变量名
|
|
Description string `json:"description"` // 描述
|
|
Example string `json:"example"` // 示例
|
|
}
|
|
|
|
// DefaultTemplateVariables 默认模板变量
|
|
var DefaultTemplateVariables = []TemplateVariable{
|
|
{Name: "{{.RuleName}}", Description: "规则名称", Example: "CPU使用率告警"},
|
|
{Name: "{{.TargetName}}", Description: "目标名称", Example: "WebServer-01"},
|
|
{Name: "{{.TargetIP}}", Description: "目标IP", Example: "192.168.1.10"},
|
|
{Name: "{{.Severity}}", Description: "告警级别", Example: "critical"},
|
|
{Name: "{{.MetricName}}", Description: "指标名称", Example: "cpu_usage"},
|
|
{Name: "{{.Value}}", Description: "当前值", Example: "95.2"},
|
|
{Name: "{{.Threshold}}", Description: "阈值", Example: "90"},
|
|
{Name: "{{.Operator}}", Description: "运算符", Example: ">"},
|
|
{Name: "{{.Time}}", Description: "触发时间", Example: "2024-01-15 10:30:00"},
|
|
{Name: "{{.Duration}}", Description: "持续时间", Example: "5m"},
|
|
{Name: "{{.Description}}", Description: "规则描述", Example: "CPU使用率超过阈值"},
|
|
{Name: "{{.URL}}", Description: "详情链接", Example: "https://ezops.io/alerts/123"},
|
|
}
|
|
|
|
// ============================================
|
|
// AlertUpgrade 告警升级策略
|
|
// ============================================
|
|
|
|
// AlertUpgrade 告警升级策略表
|
|
// 定义告警在不同阶段的升级策略
|
|
type AlertUpgrade struct {
|
|
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
|
Name string `gorm:"type:varchar(128);not null;comment:策略名称" json:"name"`
|
|
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
|
|
// 升级规则(JSON存储支持多级升级)
|
|
Rules string `gorm:"type:text;comment:升级规则JSON数组" json:"rules,omitempty"`
|
|
// 执行配置
|
|
MaxLevel int `gorm:"default:3;comment:最大升级级别" json:"max_level"`
|
|
IsDefault bool `gorm:"default:false;comment:是否默认策略" json:"is_default"`
|
|
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
|
|
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
|
|
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
|
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
|
DeletedAt *time.Time `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
|
|
}
|
|
|
|
// TableName 指定表名
|
|
func (AlertUpgrade) TableName() string {
|
|
return "alert_upgrades"
|
|
}
|
|
|
|
// AlertUpgradeRule 告警升级规则
|
|
type AlertUpgradeRule struct {
|
|
Level int `json:"level"` // 升级级别
|
|
Duration int `json:"duration"` // 触发升级的持续时长(秒)
|
|
Severity string `json:"severity"` // 升级后的级别
|
|
ChannelIDs []string `json:"channel_ids"` // 升级后通知渠道
|
|
NotifyUsers []uint `json:"notify_users"` // 升级后通知用户
|
|
RepeatInterval int `json:"repeat_interval"` // 重复通知间隔(秒)
|
|
}
|
|
|
|
// AlertUpgradeRecord 告警升级记录
|
|
type AlertUpgradeRecord struct {
|
|
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
|
AlertID uint `gorm:"not null;index;comment:告警ID" json:"alert_id"`
|
|
RuleID uint `gorm:"not null;comment:规则ID" json:"rule_id"`
|
|
FromLevel int `gorm:"comment:原级别" json:"from_level"`
|
|
ToLevel int `gorm:"comment:升级后级别" json:"to_level"`
|
|
UpgradedAt time.Time `gorm:"not null;comment:升级时间" json:"upgraded_at"`
|
|
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
|
}
|
|
|
|
// TableName 指定表名
|
|
func (AlertUpgradeRecord) TableName() string {
|
|
return "alert_upgrade_records"
|
|
}
|
|
|
|
// ============================================
|
|
// AlertSilence 告警静默规则
|
|
// ============================================
|
|
|
|
// AlertSilenceType 静默类型
|
|
type AlertSilenceType string
|
|
|
|
const (
|
|
AlertSilenceOneTime AlertSilenceType = "onetime" // 一次性静默
|
|
AlertSilenceDaily AlertSilenceType = "daily" // 每日重复
|
|
AlertSilenceWeekly AlertSilenceType = "weekly" // 每周重复
|
|
)
|
|
|
|
// AlertSilence 告警静默规则表
|
|
// 定义告警静默策略,支持一次性、周期性静默
|
|
type AlertSilence struct {
|
|
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
|
Name string `gorm:"type:varchar(128);not null;comment:静默规则名称" json:"name"`
|
|
Description string `gorm:"type:varchar(256);comment:描述" json:"description,omitempty"`
|
|
// 匹配条件
|
|
RuleIDs string `gorm:"type:varchar(256);comment:匹配的告警规则ID列表JSON" json:"rule_ids,omitempty"`
|
|
TargetIDs string `gorm:"type:varchar(256);comment:匹配的目标ID列表JSON" json:"target_ids,omitempty"`
|
|
Matchers string `gorm:"type:text;comment:标签匹配条件JSON" json:"matchers,omitempty"`
|
|
// 时间配置
|
|
SilenceType AlertSilenceType `gorm:"type:varchar(16);default:'onetime';comment:静默类型" json:"silence_type"`
|
|
StartTime time.Time `gorm:"not null;comment:开始时间" json:"start_time"`
|
|
EndTime time.Time `gorm:"not null;comment:结束时间" json:"end_time"`
|
|
Timezone string `gorm:"type:varchar(32);default:'Asia/Shanghai';comment:时区" json:"timezone"`
|
|
// 周期性配置
|
|
Weekdays string `gorm:"type:varchar(64);comment:生效星期(0-6)JSON数组" json:"weekdays,omitempty"`
|
|
// 状态
|
|
Status int `gorm:"default:1;comment:状态: 1启用 0禁用" json:"status"`
|
|
CreatedBy uint `gorm:"index;comment:创建人ID" json:"created_by"`
|
|
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
|
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
|
DeletedAt *time.Time `gorm:"index;comment:删除时间" json:"deleted_at,omitempty"`
|
|
}
|
|
|
|
// TableName 指定表名
|
|
func (AlertSilence) TableName() string {
|
|
return "alert_silences"
|
|
}
|
|
|
|
// AlertSilenceMatcher 静默匹配条件
|
|
type AlertSilenceMatcher struct {
|
|
Name string `json:"name"` // 标签名
|
|
Value string `json:"value"` // 标签值
|
|
IsRegex bool `json:"is_regex"` // 是否正则匹配
|
|
}
|
|
|
|
// AlertSilenceCheckResult 静默检查结果
|
|
type AlertSilenceCheckResult struct {
|
|
IsSilenced bool `json:"is_silenced"`
|
|
SilenceID uint `json:"silence_id,omitempty"`
|
|
SilenceName string `json:"silence_name,omitempty"`
|
|
ExpiresAt *time.Time `json:"expires_at,omitempty"`
|
|
}
|
|
|
|
// ============================================
|
|
// AlertEventV2 增强告警事件
|
|
// ============================================
|
|
|
|
// AlertEventV2Status 告警事件状态
|
|
type AlertEventV2Status string
|
|
|
|
const (
|
|
AlertEventV2Firing AlertEventV2Status = "firing" // 触发中
|
|
AlertEventV2Resolved AlertEventV2Status = "resolved" // 已恢复
|
|
AlertEventV2Silenced AlertEventV2Status = "silenced" // 已静默
|
|
)
|
|
|
|
// AlertEventV2 增强告警事件表
|
|
// 记录告警触发和恢复的全过程
|
|
type AlertEventV2 struct {
|
|
ID uint `gorm:"primaryKey;autoIncrement;comment:主键ID" json:"id"`
|
|
RuleID uint `gorm:"not null;index:idx_rule_time;comment:规则ID" json:"rule_id"`
|
|
TargetID uint `gorm:"not null;index;comment:目标ID" json:"target_id"`
|
|
TargetName string `gorm:"type:varchar(128);comment:目标名称" json:"target_name,omitempty"`
|
|
TargetIP string `gorm:"type:varchar(64);comment:目标IP" json:"target_ip,omitempty"`
|
|
Severity AlertSeverity `gorm:"type:varchar(16);not null;index;comment:告警级别" json:"severity"`
|
|
Status AlertEventV2Status `gorm:"type:varchar(16);default:'firing';index;comment:事件状态" json:"status"`
|
|
Title string `gorm:"type:varchar(256);not null;comment:告警标题" json:"title"`
|
|
Message string `gorm:"type:text;comment:告警详情" json:"message,omitempty"`
|
|
// 触发值信息
|
|
MetricName string `gorm:"type:varchar(64);comment:指标名称" json:"metric_name,omitempty"`
|
|
Value float64 `gorm:"comment:触发值" json:"value,omitempty"`
|
|
Threshold float64 `gorm:"comment:阈值" json:"threshold,omitempty"`
|
|
Operator string `gorm:"type:varchar(8);comment:运算符" json:"operator,omitempty"`
|
|
Unit string `gorm:"type:varchar(32);comment:单位" json:"unit,omitempty"`
|
|
// 标签和注释
|
|
Labels string `gorm:"type:varchar(512);comment:标签JSON" json:"labels,omitempty"`
|
|
Annotations string `gorm:"type:text;comment:注释JSON" json:"annotations,omitempty"`
|
|
// 时间信息
|
|
StartedAt time.Time `gorm:"not null;index:idx_rule_time;comment:触发时间" json:"started_at"`
|
|
ResolvedAt *time.Time `gorm:"comment:恢复时间" json:"resolved_at,omitempty"`
|
|
Duration int `gorm:"comment:持续时间(秒)" json:"duration,omitempty"`
|
|
LastEvalAt time.Time `gorm:"comment:最后评估时间" json:"last_eval_at,omitempty"`
|
|
NotifyCount int `gorm:"default:0;comment:通知次数" json:"notify_count"`
|
|
LastNotifyAt *time.Time `gorm:"comment:最近通知时间" json:"last_notify_at,omitempty"`
|
|
UpgradeLevel int `gorm:"default:0;comment:当前升级级别" json:"upgrade_level"`
|
|
// 确认信息
|
|
Acknowledged bool `gorm:"default:false;comment:是否已确认" json:"acknowledged"`
|
|
AcknowledgedBy uint `gorm:"comment:确认人ID" json:"acknowledged_by,omitempty"`
|
|
AcknowledgedAt *time.Time `gorm:"comment:确认时间" json:"acknowledged_at,omitempty"`
|
|
AckComment string `gorm:"type:varchar(256);comment:确认备注" json:"ack_comment,omitempty"`
|
|
CreatedAt time.Time `gorm:"not null;comment:创建时间" json:"created_at"`
|
|
UpdatedAt time.Time `gorm:"not null;comment:更新时间" json:"updated_at"`
|
|
}
|
|
|
|
// TableName 指定表名
|
|
func (AlertEventV2) TableName() string {
|
|
return "alert_events_v2"
|
|
}
|
|
|
|
// AlertRuleV2CreateRequest 告警规则创建请求
|
|
type AlertRuleV2CreateRequest struct {
|
|
Name string `json:"name" binding:"required,max=128"`
|
|
Description string `json:"description"`
|
|
Severity AlertSeverity `json:"severity" binding:"required"`
|
|
TargetType string `json:"target_type"`
|
|
TargetID uint `json:"target_id"`
|
|
TargetTags string `json:"target_tags"`
|
|
Conditions []AlertCondition `json:"conditions" binding:"required,min=1"`
|
|
AggWindow int `json:"agg_window"`
|
|
AggFunction AggFunction `json:"agg_function"`
|
|
RecoverCount int `json:"recover_count"`
|
|
Interval int `json:"interval"`
|
|
CheckTimes int `json:"check_times"`
|
|
NotifyMode string `json:"notify_mode"`
|
|
ChannelIDs []string `json:"channel_ids"`
|
|
TemplateID uint `json:"template_id"`
|
|
UpgradeID uint `json:"upgrade_id"`
|
|
SilenceID uint `json:"silence_id"`
|
|
Labels map[string]string `json:"labels"`
|
|
Annotations map[string]string `json:"annotations"`
|
|
}
|
|
|
|
// AlertRuleV2UpdateRequest 告警规则更新请求
|
|
type AlertRuleV2UpdateRequest struct {
|
|
Name string `json:"name" binding:"max=128"`
|
|
Description string `json:"description"`
|
|
Severity AlertSeverity `json:"severity"`
|
|
Status AlertRuleV2Status `json:"status"`
|
|
TargetType string `json:"target_type"`
|
|
TargetID uint `json:"target_id"`
|
|
TargetTags string `json:"target_tags"`
|
|
Conditions []AlertCondition `json:"conditions"`
|
|
AggWindow int `json:"agg_window"`
|
|
AggFunction AggFunction `json:"agg_function"`
|
|
RecoverCount int `json:"recover_count"`
|
|
Interval int `json:"interval"`
|
|
CheckTimes int `json:"check_times"`
|
|
NotifyMode string `json:"notify_mode"`
|
|
ChannelIDs []string `json:"channel_ids"`
|
|
TemplateID uint `json:"template_id"`
|
|
UpgradeID uint `json:"upgrade_id"`
|
|
SilenceID uint `json:"silence_id"`
|
|
Labels map[string]string `json:"labels"`
|
|
Annotations map[string]string `json:"annotations"`
|
|
}
|