mirror of
https://github.com/ccfos/nightingale.git
synced 2026-03-02 22:19:10 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02474818c0 | ||
|
|
f942772d2b | ||
|
|
fbc0c22d7a | ||
|
|
abd452a6df | ||
|
|
47f05627d9 | ||
|
|
edd8e2a3db | ||
|
|
c4ca2920ef | ||
|
|
afc8d7d21c | ||
|
|
c0e13e2870 | ||
|
|
4f186a71ba | ||
|
|
104c275f2d | ||
|
|
2ba7a970e8 |
@@ -211,8 +211,8 @@ func (rt *Router) Config(r *gin.Engine) {
|
||||
pages.GET("/datasource/brief", rt.auth(), rt.user(), rt.datasourceBriefs)
|
||||
pages.POST("/datasource/query", rt.auth(), rt.user(), rt.datasourceQuery)
|
||||
|
||||
pages.POST("/ds-query", rt.auth(), rt.QueryData)
|
||||
pages.POST("/logs-query", rt.auth(), rt.QueryLogV2)
|
||||
pages.POST("/ds-query", rt.auth(), rt.user(), rt.QueryData)
|
||||
pages.POST("/logs-query", rt.auth(), rt.user(), rt.QueryLogV2)
|
||||
|
||||
pages.POST("/tdengine-databases", rt.auth(), rt.tdengineDatabases)
|
||||
pages.POST("/tdengine-tables", rt.auth(), rt.tdengineTables)
|
||||
|
||||
@@ -293,11 +293,15 @@ func DatasourceCheck(c *gin.Context, ds models.Datasource) error {
|
||||
}
|
||||
}
|
||||
|
||||
// 使用 TLS 配置(支持 mTLS)
|
||||
tlsConfig, err := ds.HTTPJson.TLS.TLSConfig()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create TLS config: %v", err)
|
||||
}
|
||||
|
||||
client := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: ds.HTTPJson.TLS.SkipTlsVerify,
|
||||
},
|
||||
TLSClientConfig: tlsConfig,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -169,8 +168,15 @@ func (rt *Router) dsProxy(c *gin.Context) {
|
||||
|
||||
transport, has := transportGet(dsId, ds.UpdatedAt)
|
||||
if !has {
|
||||
// 使用 TLS 配置(支持 mTLS)
|
||||
tlsConfig, err := ds.HTTPJson.TLS.TLSConfig()
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, "failed to create TLS config: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: ds.HTTPJson.TLS.SkipTlsVerify},
|
||||
TLSClientConfig: tlsConfig,
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: time.Duration(ds.HTTPJson.DialTimeout) * time.Millisecond,
|
||||
|
||||
@@ -12,7 +12,9 @@ import (
|
||||
"github.com/toolkits/pkg/logger"
|
||||
)
|
||||
|
||||
func CheckDsPerm(c *gin.Context, dsId int64, cate string, q interface{}) bool {
|
||||
type CheckDsPermFunc func(c *gin.Context, dsId int64, cate string, q interface{}) bool
|
||||
|
||||
var CheckDsPerm CheckDsPermFunc = func(c *gin.Context, dsId int64, cate string, q interface{}) bool {
|
||||
// todo: 后续需要根据 cate 判断是否需要权限
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -87,8 +87,8 @@ services:
|
||||
- mysql
|
||||
- redis
|
||||
- victoriametrics
|
||||
command: >
|
||||
sh -c "/app/n9e"
|
||||
command:
|
||||
- /app/n9e
|
||||
|
||||
categraf:
|
||||
image: "flashcatcloud/categraf:latest"
|
||||
|
||||
@@ -59,8 +59,8 @@ services:
|
||||
- mysql
|
||||
- redis
|
||||
- prometheus
|
||||
command: >
|
||||
sh -c "/app/n9e"
|
||||
command:
|
||||
- /app/n9e
|
||||
|
||||
categraf:
|
||||
image: "flashcatcloud/categraf:latest"
|
||||
|
||||
@@ -58,8 +58,8 @@ services:
|
||||
- mysql
|
||||
- redis
|
||||
- prometheus
|
||||
command: >
|
||||
sh -c "/app/n9e"
|
||||
command:
|
||||
- /app/n9e
|
||||
|
||||
categraf:
|
||||
image: "flashcatcloud/categraf:latest"
|
||||
|
||||
@@ -74,8 +74,8 @@ services:
|
||||
- postgres:postgres
|
||||
- redis:redis
|
||||
- victoriametrics:victoriametrics
|
||||
command: >
|
||||
sh -c "/app/n9e"
|
||||
command:
|
||||
- /app/n9e
|
||||
|
||||
categraf:
|
||||
image: "flashcatcloud/categraf:latest"
|
||||
|
||||
@@ -804,6 +804,9 @@ CREATE TABLE builtin_metrics (
|
||||
lang varchar(191) NOT NULL DEFAULT '',
|
||||
note varchar(4096) NOT NULL,
|
||||
expression varchar(4096) NOT NULL,
|
||||
expression_type varchar(32) NOT NULL DEFAULT 'promql',
|
||||
metric_type varchar(191) NOT NULL DEFAULT '',
|
||||
extra_fields text,
|
||||
created_at bigint NOT NULL DEFAULT 0,
|
||||
created_by varchar(191) NOT NULL DEFAULT '',
|
||||
updated_at bigint NOT NULL DEFAULT 0,
|
||||
@@ -826,6 +829,9 @@ COMMENT ON COLUMN builtin_metrics.unit IS 'unit of metric';
|
||||
COMMENT ON COLUMN builtin_metrics.lang IS 'language of metric';
|
||||
COMMENT ON COLUMN builtin_metrics.note IS 'description of metric in Chinese';
|
||||
COMMENT ON COLUMN builtin_metrics.expression IS 'expression of metric';
|
||||
COMMENT ON COLUMN builtin_metrics.expression_type IS 'expression type: metric_name or promql';
|
||||
COMMENT ON COLUMN builtin_metrics.metric_type IS 'metric type like counter/gauge';
|
||||
COMMENT ON COLUMN builtin_metrics.extra_fields IS 'custom extra fields';
|
||||
COMMENT ON COLUMN builtin_metrics.created_at IS 'create time';
|
||||
COMMENT ON COLUMN builtin_metrics.created_by IS 'creator';
|
||||
COMMENT ON COLUMN builtin_metrics.updated_at IS 'update time';
|
||||
|
||||
@@ -719,6 +719,9 @@ CREATE TABLE `builtin_metrics` (
|
||||
`lang` varchar(191) NOT NULL DEFAULT 'zh' COMMENT '''language''',
|
||||
`note` varchar(4096) NOT NULL COMMENT '''description of metric''',
|
||||
`expression` varchar(4096) NOT NULL COMMENT '''expression of metric''',
|
||||
`expression_type` varchar(32) NOT NULL DEFAULT 'promql' COMMENT '''expression type: metric_name or promql''',
|
||||
`metric_type` varchar(191) NOT NULL DEFAULT '' COMMENT '''metric type like counter/gauge''',
|
||||
`extra_fields` text COMMENT '''custom extra fields''',
|
||||
`created_at` bigint NOT NULL DEFAULT 0 COMMENT '''create time''',
|
||||
`created_by` varchar(191) NOT NULL DEFAULT '' COMMENT '''creator''',
|
||||
`updated_at` bigint NOT NULL DEFAULT 0 COMMENT '''update time''',
|
||||
|
||||
@@ -292,4 +292,9 @@ ALTER TABLE `alert_rule` ADD COLUMN `pipeline_configs` text COMMENT 'pipeline co
|
||||
|
||||
/* v8.4.2 2025-11-13 */
|
||||
ALTER TABLE `board` ADD COLUMN `note` varchar(1024) not null default '' comment 'note';
|
||||
ALTER TABLE `builtin_payloads` ADD COLUMN `note` varchar(1024) not null default '' comment 'note of payload';
|
||||
ALTER TABLE `builtin_payloads` ADD COLUMN `note` varchar(1024) not null default '' comment 'note of payload';
|
||||
|
||||
/* v8.5.0 builtin_metrics new fields */
|
||||
ALTER TABLE `builtin_metrics` ADD COLUMN `expression_type` varchar(32) NOT NULL DEFAULT 'promql' COMMENT 'expression type: metric_name or promql';
|
||||
ALTER TABLE `builtin_metrics` ADD COLUMN `metric_type` varchar(191) NOT NULL DEFAULT '' COMMENT 'metric type like counter/gauge';
|
||||
ALTER TABLE `builtin_metrics` ADD COLUMN `extra_fields` text COMMENT 'custom extra fields';
|
||||
@@ -651,6 +651,9 @@ CREATE TABLE `builtin_metrics` (
|
||||
`lang` varchar(191) NOT NULL DEFAULT '',
|
||||
`note` varchar(4096) NOT NULL,
|
||||
`expression` varchar(4096) NOT NULL,
|
||||
`expression_type` varchar(32) NOT NULL DEFAULT 'promql',
|
||||
`metric_type` varchar(191) NOT NULL DEFAULT '',
|
||||
`extra_fields` text,
|
||||
`created_at` bigint NOT NULL DEFAULT 0,
|
||||
`created_by` varchar(191) NOT NULL DEFAULT '',
|
||||
`updated_at` bigint NOT NULL DEFAULT 0,
|
||||
|
||||
@@ -57,3 +57,29 @@ func (cs *Cache) Get(cate string, dsId int64) (datasource.Datasource, bool) {
|
||||
|
||||
return cs.datas[cate][dsId], true
|
||||
}
|
||||
|
||||
func (cs *Cache) Delete(cate string, dsId int64) {
|
||||
cs.mutex.Lock()
|
||||
defer cs.mutex.Unlock()
|
||||
if _, found := cs.datas[cate]; !found {
|
||||
return
|
||||
}
|
||||
delete(cs.datas[cate], dsId)
|
||||
|
||||
logger.Debugf("delete plugin:%s %d from cache", cate, dsId)
|
||||
}
|
||||
|
||||
// GetAllIds 返回缓存中所有数据源的 ID,按类型分组
|
||||
func (cs *Cache) GetAllIds() map[string][]int64 {
|
||||
cs.mutex.RLock()
|
||||
defer cs.mutex.RUnlock()
|
||||
result := make(map[string][]int64)
|
||||
for cate, dsMap := range cs.datas {
|
||||
ids := make([]int64, 0, len(dsMap))
|
||||
for dsId := range dsMap {
|
||||
ids = append(ids, dsId)
|
||||
}
|
||||
result[cate] = ids
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -173,7 +173,10 @@ func esN9eToDatasourceInfo(ds *datasource.DatasourceInfo, item models.Datasource
|
||||
}
|
||||
|
||||
func PutDatasources(items []datasource.DatasourceInfo) {
|
||||
// 记录当前有效的数据源 ID,按类型分组
|
||||
validIds := make(map[string]map[int64]struct{})
|
||||
ids := make([]int64, 0)
|
||||
|
||||
for _, item := range items {
|
||||
if item.Type == "prometheus" {
|
||||
continue
|
||||
@@ -202,6 +205,12 @@ func PutDatasources(items []datasource.DatasourceInfo) {
|
||||
}
|
||||
ids = append(ids, item.Id)
|
||||
|
||||
// 记录有效的数据源 ID
|
||||
if _, ok := validIds[typ]; !ok {
|
||||
validIds[typ] = make(map[int64]struct{})
|
||||
}
|
||||
validIds[typ][item.Id] = struct{}{}
|
||||
|
||||
// 异步初始化 client 不然数据源同步的会很慢
|
||||
go func() {
|
||||
defer func() {
|
||||
@@ -213,5 +222,19 @@ func PutDatasources(items []datasource.DatasourceInfo) {
|
||||
}()
|
||||
}
|
||||
|
||||
// 删除 items 中不存在但 DsCache 中存在的数据源
|
||||
cachedIds := DsCache.GetAllIds()
|
||||
for cate, dsIds := range cachedIds {
|
||||
for _, dsId := range dsIds {
|
||||
if _, ok := validIds[cate]; !ok {
|
||||
// 该类型在 items 中完全不存在,删除缓存中的所有该类型数据源
|
||||
DsCache.Delete(cate, dsId)
|
||||
} else if _, ok := validIds[cate][dsId]; !ok {
|
||||
// 该数据源 ID 在 items 中不存在,删除
|
||||
DsCache.Delete(cate, dsId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.Debugf("get plugin by type success Ids:%v", ids)
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ type Doris struct {
|
||||
FeAddr string `json:"doris.fe_addr" mapstructure:"doris.fe_addr"` // fe http endpoint
|
||||
User string `json:"doris.user" mapstructure:"doris.user"` //
|
||||
Password string `json:"doris.password" mapstructure:"doris.password"` //
|
||||
Timeout int `json:"doris.timeout" mapstructure:"doris.timeout"`
|
||||
Timeout int `json:"doris.timeout" mapstructure:"doris.timeout"` // ms
|
||||
MaxIdleConns int `json:"doris.max_idle_conns" mapstructure:"doris.max_idle_conns"`
|
||||
MaxOpenConns int `json:"doris.max_open_conns" mapstructure:"doris.max_open_conns"`
|
||||
ConnMaxLifetime int `json:"doris.conn_max_lifetime" mapstructure:"doris.conn_max_lifetime"`
|
||||
@@ -71,7 +71,7 @@ func (d *Doris) NewConn(ctx context.Context, database string) (*sql.DB, error) {
|
||||
|
||||
// Set default values similar to postgres implementation
|
||||
if d.Timeout == 0 {
|
||||
d.Timeout = 60
|
||||
d.Timeout = 60000
|
||||
}
|
||||
if d.MaxIdleConns == 0 {
|
||||
d.MaxIdleConns = 10
|
||||
@@ -127,7 +127,7 @@ func (d *Doris) createTimeoutContext(ctx context.Context) (context.Context, cont
|
||||
if timeout == 0 {
|
||||
timeout = 60
|
||||
}
|
||||
return context.WithTimeout(ctx, time.Duration(timeout)*time.Second)
|
||||
return context.WithTimeout(ctx, time.Duration(timeout)*time.Millisecond)
|
||||
}
|
||||
|
||||
// ShowDatabases lists all databases in Doris
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
@@ -12,20 +13,23 @@ import (
|
||||
|
||||
// BuiltinMetric represents a metric along with its metadata.
|
||||
type BuiltinMetric struct {
|
||||
ID int64 `json:"id" gorm:"primaryKey;type:bigint;autoIncrement;comment:'unique identifier'"`
|
||||
UUID int64 `json:"uuid" gorm:"type:bigint;not null;default:0;comment:'uuid'"`
|
||||
Collector string `json:"collector" gorm:"type:varchar(191);not null;index:idx_collector,sort:asc;comment:'type of collector'"`
|
||||
Typ string `json:"typ" gorm:"type:varchar(191);not null;index:idx_typ,sort:asc;comment:'type of metric'"`
|
||||
Name string `json:"name" gorm:"type:varchar(191);not null;index:idx_builtinmetric_name,sort:asc;comment:'name of metric'"`
|
||||
Unit string `json:"unit" gorm:"type:varchar(191);not null;comment:'unit of metric'"`
|
||||
Note string `json:"note" gorm:"type:varchar(4096);not null;comment:'description of metric'"`
|
||||
Lang string `json:"lang" gorm:"type:varchar(191);not null;default:'zh';index:idx_lang,sort:asc;comment:'language'"`
|
||||
Translation []Translation `json:"translation" gorm:"type:text;serializer:json;comment:'translation of metric'"`
|
||||
Expression string `json:"expression" gorm:"type:varchar(4096);not null;comment:'expression of metric'"`
|
||||
CreatedAt int64 `json:"created_at" gorm:"type:bigint;not null;default:0;comment:'create time'"`
|
||||
CreatedBy string `json:"created_by" gorm:"type:varchar(191);not null;default:'';comment:'creator'"`
|
||||
UpdatedAt int64 `json:"updated_at" gorm:"type:bigint;not null;default:0;comment:'update time'"`
|
||||
UpdatedBy string `json:"updated_by" gorm:"type:varchar(191);not null;default:'';comment:'updater'"`
|
||||
ID int64 `json:"id" gorm:"primaryKey;type:bigint;autoIncrement;comment:'unique identifier'"`
|
||||
UUID int64 `json:"uuid" gorm:"type:bigint;not null;default:0;comment:'uuid'"`
|
||||
Collector string `json:"collector" gorm:"type:varchar(191);not null;index:idx_collector,sort:asc;comment:'type of collector'"`
|
||||
Typ string `json:"typ" gorm:"type:varchar(191);not null;index:idx_typ,sort:asc;comment:'type of metric'"`
|
||||
Name string `json:"name" gorm:"type:varchar(191);not null;index:idx_builtinmetric_name,sort:asc;comment:'name of metric'"`
|
||||
Unit string `json:"unit" gorm:"type:varchar(191);not null;comment:'unit of metric'"`
|
||||
Note string `json:"note" gorm:"type:varchar(4096);not null;comment:'description of metric'"`
|
||||
Lang string `json:"lang" gorm:"type:varchar(191);not null;default:'zh';index:idx_lang,sort:asc;comment:'language'"`
|
||||
Translation []Translation `json:"translation" gorm:"type:text;serializer:json;comment:'translation of metric'"`
|
||||
Expression string `json:"expression" gorm:"type:varchar(4096);not null;comment:'expression of metric'"`
|
||||
ExpressionType string `json:"expression_type" gorm:"type:varchar(32);not null;default:'promql';comment:'expression type: metric_name or promql'"`
|
||||
MetricType string `json:"metric_type" gorm:"type:varchar(191);not null;default:'';comment:'metric type like counter/gauge'"`
|
||||
ExtraFields json.RawMessage `json:"extra_fields" gorm:"type:text;serializer:json;comment:'custom extra fields'"`
|
||||
CreatedAt int64 `json:"created_at" gorm:"type:bigint;not null;default:0;comment:'create time'"`
|
||||
CreatedBy string `json:"created_by" gorm:"type:varchar(191);not null;default:'';comment:'creator'"`
|
||||
UpdatedAt int64 `json:"updated_at" gorm:"type:bigint;not null;default:0;comment:'update time'"`
|
||||
UpdatedBy string `json:"updated_by" gorm:"type:varchar(191);not null;default:'';comment:'updater'"`
|
||||
}
|
||||
|
||||
type Translation struct {
|
||||
|
||||
@@ -29,6 +29,27 @@ func (bp *BuiltinPayload) TableName() string {
|
||||
return "builtin_payloads"
|
||||
}
|
||||
|
||||
type PostgresBuiltinPayload struct {
|
||||
ID int64 `json:"id" gorm:"primaryKey;type:bigint;autoIncrement;comment:'unique identifier'"`
|
||||
Type string `json:"type" gorm:"type:varchar(191);not null;index:idx_type,sort:asc;comment:'type of payload'"`
|
||||
Component string `json:"component" gorm:"type:varchar(191);not null;index:idx_component,sort:asc;comment:'component of payload'"`
|
||||
ComponentID uint64 `json:"component_id" gorm:"type:bigint;index:idx_component,sort:asc;comment:'component_id of payload'"`
|
||||
Cate string `json:"cate" gorm:"type:varchar(191);not null;comment:'category of payload'"`
|
||||
Name string `json:"name" gorm:"type:varchar(191);not null;index:idx_buildinpayload_name,sort:asc;comment:'name of payload'"`
|
||||
Tags string `json:"tags" gorm:"type:varchar(191);not null;default:'';comment:'tags of payload'"`
|
||||
Content string `json:"content" gorm:"type:text;not null;comment:'content of payload'"`
|
||||
UUID int64 `json:"uuid" gorm:"type:bigint;not null;index:idx_uuid;comment:'uuid of payload'"`
|
||||
Note string `json:"note" gorm:"type:varchar(1024);not null;default:'';comment:'note of payload'"`
|
||||
CreatedAt int64 `json:"created_at" gorm:"type:bigint;not null;default:0;comment:'create time'"`
|
||||
CreatedBy string `json:"created_by" gorm:"type:varchar(191);not null;default:'';comment:'creator'"`
|
||||
UpdatedAt int64 `json:"updated_at" gorm:"type:bigint;not null;default:0;comment:'update time'"`
|
||||
UpdatedBy string `json:"updated_by" gorm:"type:varchar(191);not null;default:'';comment:'updater'"`
|
||||
}
|
||||
|
||||
func (bp *PostgresBuiltinPayload) TableName() string {
|
||||
return "builtin_payloads"
|
||||
}
|
||||
|
||||
func (bp *BuiltinPayload) Verify() error {
|
||||
bp.Type = strings.TrimSpace(bp.Type)
|
||||
if bp.Type == "" {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -144,6 +147,72 @@ func (h HTTP) ParseUrl() (target *url.URL, err error) {
|
||||
|
||||
type TLS struct {
|
||||
SkipTlsVerify bool `json:"skip_tls_verify"`
|
||||
// mTLS 配置
|
||||
CACert string `json:"ca_cert"` // CA 证书内容 (PEM 格式)
|
||||
ClientCert string `json:"client_cert"` // 客户端证书内容 (PEM 格式)
|
||||
ClientKey string `json:"client_key"` // 客户端密钥内容 (PEM 格式)
|
||||
ClientKeyPassword string `json:"client_key_password"` // 密钥密码(可选)
|
||||
ServerName string `json:"server_name"` // TLS ServerName(可选,用于证书验证)
|
||||
MinVersion string `json:"min_version"` // TLS 最小版本 (1.0, 1.1, 1.2, 1.3)
|
||||
MaxVersion string `json:"max_version"` // TLS 最大版本
|
||||
}
|
||||
|
||||
// TLSConfig 从证书内容创建 tls.Config
|
||||
// 证书内容为 PEM 格式字符串
|
||||
func (t *TLS) TLSConfig() (*tls.Config, error) {
|
||||
tlsConfig := &tls.Config{
|
||||
InsecureSkipVerify: t.SkipTlsVerify,
|
||||
}
|
||||
|
||||
// 设置 ServerName
|
||||
if t.ServerName != "" {
|
||||
tlsConfig.ServerName = t.ServerName
|
||||
}
|
||||
|
||||
// 设置 TLS 版本
|
||||
if t.MinVersion != "" {
|
||||
if v, ok := tlsVersionMap[t.MinVersion]; ok {
|
||||
tlsConfig.MinVersion = v
|
||||
}
|
||||
}
|
||||
if t.MaxVersion != "" {
|
||||
if v, ok := tlsVersionMap[t.MaxVersion]; ok {
|
||||
tlsConfig.MaxVersion = v
|
||||
}
|
||||
}
|
||||
|
||||
// 如果配置了客户端证书,则加载 mTLS 配置
|
||||
clientCert := strings.TrimSpace(t.ClientCert)
|
||||
clientKey := strings.TrimSpace(t.ClientKey)
|
||||
caCert := strings.TrimSpace(t.CACert)
|
||||
|
||||
if clientCert != "" && clientKey != "" {
|
||||
// 加载客户端证书和密钥
|
||||
cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load client certificate: %w", err)
|
||||
}
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
|
||||
// 加载 CA 证书
|
||||
if caCert != "" {
|
||||
caCertPool := x509.NewCertPool()
|
||||
if !caCertPool.AppendCertsFromPEM([]byte(caCert)) {
|
||||
return nil, fmt.Errorf("failed to parse CA certificate")
|
||||
}
|
||||
tlsConfig.RootCAs = caCertPool
|
||||
}
|
||||
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
// tlsVersionMap TLS 版本映射
|
||||
var tlsVersionMap = map[string]uint16{
|
||||
"1.0": tls.VersionTLS10,
|
||||
"1.1": tls.VersionTLS11,
|
||||
"1.2": tls.VersionTLS12,
|
||||
"1.3": tls.VersionTLS13,
|
||||
}
|
||||
|
||||
func (ds *Datasource) TableName() string {
|
||||
|
||||
@@ -99,7 +99,11 @@ func MigrateTables(db *gorm.DB) error {
|
||||
}()
|
||||
|
||||
if !db.Migrator().HasTable(&models.BuiltinPayload{}) {
|
||||
dts = append(dts, &models.BuiltinPayload{})
|
||||
if isPostgres(db) {
|
||||
dts = append(dts, &models.PostgresBuiltinPayload{})
|
||||
} else {
|
||||
dts = append(dts, &models.BuiltinPayload{})
|
||||
}
|
||||
} else {
|
||||
dts = append(dts, &BuiltinPayloads{})
|
||||
}
|
||||
|
||||
@@ -1494,10 +1494,6 @@ func sqliteDataBaseInit(db *gorm.DB) error {
|
||||
{RoleName: "Standard", Operation: "/alert-rules-built-in"},
|
||||
{RoleName: "Standard", Operation: "/dashboards-built-in"},
|
||||
{RoleName: "Standard", Operation: "/trace/dependencies"},
|
||||
{RoleName: "Admin", Operation: "/help/source"},
|
||||
{RoleName: "Admin", Operation: "/help/sso"},
|
||||
{RoleName: "Admin", Operation: "/help/notification-tpls"},
|
||||
{RoleName: "Admin", Operation: "/help/notification-settings"},
|
||||
{RoleName: "Standard", Operation: "/users"},
|
||||
{RoleName: "Standard", Operation: "/user-groups"},
|
||||
{RoleName: "Standard", Operation: "/user-groups/add"},
|
||||
@@ -1690,10 +1686,6 @@ func mysqlDataBaseInit(db *gorm.DB) error {
|
||||
{RoleName: "Standard", Operation: "/alert-rules-built-in"},
|
||||
{RoleName: "Standard", Operation: "/dashboards-built-in"},
|
||||
{RoleName: "Standard", Operation: "/trace/dependencies"},
|
||||
{RoleName: "Admin", Operation: "/help/source"},
|
||||
{RoleName: "Admin", Operation: "/help/sso"},
|
||||
{RoleName: "Admin", Operation: "/help/notification-tpls"},
|
||||
{RoleName: "Admin", Operation: "/help/notification-settings"},
|
||||
{RoleName: "Standard", Operation: "/users"},
|
||||
{RoleName: "Standard", Operation: "/user-groups"},
|
||||
{RoleName: "Standard", Operation: "/user-groups/add"},
|
||||
@@ -1886,10 +1878,6 @@ func postgresDataBaseInit(db *gorm.DB) error {
|
||||
{RoleName: "Standard", Operation: "/alert-rules-built-in"},
|
||||
{RoleName: "Standard", Operation: "/dashboards-built-in"},
|
||||
{RoleName: "Standard", Operation: "/trace/dependencies"},
|
||||
{RoleName: "Admin", Operation: "/help/source"},
|
||||
{RoleName: "Admin", Operation: "/help/sso"},
|
||||
{RoleName: "Admin", Operation: "/help/notification-tpls"},
|
||||
{RoleName: "Admin", Operation: "/help/notification-settings"},
|
||||
{RoleName: "Standard", Operation: "/users"},
|
||||
{RoleName: "Standard", Operation: "/user-groups"},
|
||||
{RoleName: "Standard", Operation: "/user-groups/add"},
|
||||
|
||||
@@ -3,7 +3,7 @@ package prom
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/ccfos/nightingale/v6/pkg/tlsx"
|
||||
"github.com/ccfos/nightingale/v6/models"
|
||||
)
|
||||
|
||||
type PromOption struct {
|
||||
@@ -20,7 +20,8 @@ type PromOption struct {
|
||||
|
||||
Headers []string
|
||||
|
||||
tlsx.ClientConfig
|
||||
// TLS 配置(支持 mTLS)
|
||||
TLS models.TLS
|
||||
}
|
||||
|
||||
func (po *PromOption) Equal(target PromOption) bool {
|
||||
@@ -52,10 +53,6 @@ func (po *PromOption) Equal(target PromOption) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if po.InsecureSkipVerify != target.InsecureSkipVerify {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(po.Headers) != len(target.Headers) {
|
||||
return false
|
||||
}
|
||||
@@ -66,6 +63,29 @@ func (po *PromOption) Equal(target PromOption) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// 比较 TLS 配置
|
||||
if po.TLS.SkipTlsVerify != target.TLS.SkipTlsVerify {
|
||||
return false
|
||||
}
|
||||
if po.TLS.CACert != target.TLS.CACert {
|
||||
return false
|
||||
}
|
||||
if po.TLS.ClientCert != target.TLS.ClientCert {
|
||||
return false
|
||||
}
|
||||
if po.TLS.ClientKey != target.TLS.ClientKey {
|
||||
return false
|
||||
}
|
||||
if po.TLS.ServerName != target.TLS.ServerName {
|
||||
return false
|
||||
}
|
||||
if po.TLS.MinVersion != target.TLS.MinVersion {
|
||||
return false
|
||||
}
|
||||
if po.TLS.MaxVersion != target.TLS.MaxVersion {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -101,11 +101,7 @@ func (pc *PromClientMap) loadFromDatabase() {
|
||||
DialTimeout: ds.HTTPJson.DialTimeout,
|
||||
MaxIdleConnsPerHost: ds.HTTPJson.MaxIdleConnsPerHost,
|
||||
Headers: header,
|
||||
}
|
||||
|
||||
if strings.HasPrefix(ds.HTTPJson.Url, "https") {
|
||||
po.UseTLS = true
|
||||
po.InsecureSkipVerify = ds.HTTPJson.TLS.SkipTlsVerify
|
||||
TLS: ds.HTTPJson.TLS,
|
||||
}
|
||||
|
||||
if internalAddr != "" && !pc.ctx.IsCenter {
|
||||
@@ -149,7 +145,10 @@ func (pc *PromClientMap) loadFromDatabase() {
|
||||
}
|
||||
|
||||
func (pc *PromClientMap) newReaderClientFromPromOption(po PromOption) (api.Client, error) {
|
||||
tlsConfig, _ := po.TLSConfig()
|
||||
tlsConfig, err := po.TLS.TLSConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create TLS config: %v", err)
|
||||
}
|
||||
|
||||
return api.NewClient(api.Config{
|
||||
Address: po.Url,
|
||||
@@ -166,7 +165,10 @@ func (pc *PromClientMap) newReaderClientFromPromOption(po PromOption) (api.Clien
|
||||
}
|
||||
|
||||
func (pc *PromClientMap) newWriterClientFromPromOption(po PromOption) (api.Client, error) {
|
||||
tlsConfig, _ := po.TLSConfig()
|
||||
tlsConfig, err := po.TLS.TLSConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create TLS config: %v", err)
|
||||
}
|
||||
|
||||
return api.NewClient(api.Config{
|
||||
Address: po.WriteAddr,
|
||||
|
||||
Reference in New Issue
Block a user