diff --git a/README.md b/README.md index af078eb..71c5de9 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,10 @@ Memcached |QCE/MEMCACHED|指标详情说明文档(待上线) Lighthouse |QCE/LIGHTHOUSE|[指标详情](https://cloud.tencent.com/document/product/248/60127) 分布式数据库 TDSQL MySQL 实例|QCE/TDMYSQL|[指标详情](https://cloud.tencent.com/document/product/248/54401) 弹性公网 IP|QCE/LB|[指标详情](https://cloud.tencent.com/document/product/248/45099) +TDMQ RocketMQ 版|QCE/TDMQ|[指标详情](https://cloud.tencent.com/document/product/248/51450#tdmq-rocketmq-.E7.89.88) +VPN 网关|QCE/VPNGW|[指标详情](https://cloud.tencent.com/document/product/248/45070) +VPN 通道|QCE/VPNX|[指标详情](https://cloud.tencent.com/document/product/248/45071) +CYNOSDB_MYSQL|QCE/CYNOSDB_MYSQL|[指标详情](https://cloud.tencent.com/document/product/248/45106) `后续会有更多的产品支持` diff --git a/configs/qcloud-cynosdbmysql-product.yml b/configs/qcloud-cynosdbmysql-product.yml new file mode 100644 index 0000000..a9a071d --- /dev/null +++ b/configs/qcloud-cynosdbmysql-product.yml @@ -0,0 +1,11 @@ +credential: + access_key: "access_key" + secret_key: "secret_key" + region: "region" + +rate_limit: 15 #云监控拉数据接口最大限制, 20/秒, 1200/分钟, https://cloud.tencent.com/document/product/248/31014 + +products: + - namespace: QCE/CYNOSDB_MYSQL #指标详情: https://cloud.tencent.com/document/product/248/45106 + all_metrics: true + all_instances: true diff --git a/configs/qcloud-tdmq-product.yml b/configs/qcloud-tdmq-product.yml new file mode 100644 index 0000000..835ddc2 --- /dev/null +++ b/configs/qcloud-tdmq-product.yml @@ -0,0 +1,12 @@ +credential: + access_key: "access_key" + secret_key: "secret_key" + region: "region" + +rate_limit: 15 #云监控拉数据接口最大限制, 20/秒, 1200/分钟, https://cloud.tencent.com/document/product/248/31014 + +products: + - namespace: QCE/TDMQ #指标详情: https://cloud.tencent.com/document/product/248/51450#tdmq-rocketmq-.E7.89.88 + all_metrics: true + all_instances: true + only_include_metrics: ["MsgAverageSize","MsgRateIn","MsgThroughputIn","InMessagesTotal","StorageSize","TenantInMessagesTotal","TenantMsgAverageSize","TenantRateIn","TenantRateOut","TenantStorageSize"] \ No newline at end of file diff --git a/configs/qcloud-vpngw-product.yml b/configs/qcloud-vpngw-product.yml new file mode 100644 index 0000000..0529a0e --- /dev/null +++ b/configs/qcloud-vpngw-product.yml @@ -0,0 +1,11 @@ +credential: + access_key: "access_key" + secret_key: "secret_key" + region: "region" + +rate_limit: 15 #云监控拉数据接口最大限制, 20/秒, 1200/分钟, https://cloud.tencent.com/document/product/248/31014 + +products: + - namespace: QCE/VPNGW #指标详情: https://cloud.tencent.com/document/product/248/45070 + all_metrics: true + all_instances: true diff --git a/configs/qcloud-vpnx-product.yml b/configs/qcloud-vpnx-product.yml new file mode 100644 index 0000000..9a9ba4c --- /dev/null +++ b/configs/qcloud-vpnx-product.yml @@ -0,0 +1,11 @@ +credential: + access_key: "access_key" + secret_key: "secret_key" + region: "region" + +rate_limit: 15 #云监控拉数据接口最大限制, 20/秒, 1200/分钟, https://cloud.tencent.com/document/product/248/31014 + +products: + - namespace: QCE/VPNX #指标详情: https://cloud.tencent.com/document/product/248/45071 + all_metrics: true + all_instances: true diff --git a/go.mod b/go.mod index 6288c6e..8b90e24 100644 --- a/go.mod +++ b/go.mod @@ -9,12 +9,13 @@ require ( github.com/prometheus/common v0.9.1 github.com/stretchr/testify v1.6.1 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs v1.0.334 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb v1.0.334 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb v1.0.413 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ckafka v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cmq v1.0.334 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.334 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.413 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.334 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.0.413 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dcdb v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/es v1.0.334 @@ -26,6 +27,8 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/postgres v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/redis v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sqlserver v1.0.334 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tdmq v1.0.413 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse v1.0.413 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.0.334 golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e gopkg.in/alecthomas/kingpin.v2 v2.2.6 diff --git a/go.sum b/go.sum index 2fb3e89..2b68361 100644 --- a/go.sum +++ b/go.sum @@ -79,10 +79,14 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tencentcloud/tencentcloud-sdk-go v1.0.413 h1:6mBQybv/rsrOCnzhifwJnSE7ki2EGfzRKb8+yPIijl8= +github.com/tencentcloud/tencentcloud-sdk-go v1.0.414 h1:1fAd3HgD+emgJBh0+q1SL04PfTZuy7iBfcY4Mvvkd1U= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs v1.0.334 h1:GijOjoDBcWXtra6hmzpj4IXOahWmsTE3bwpOcp5VBDw= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs v1.0.334/go.mod h1:PTp058qpOV//RukBVdYQT962rZg71lIt6eHLK1zdvEc= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb v1.0.334 h1:1NDpg/jeMASV09JFLMe7yU53QA9gY55H4X1j39JZ78w= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb v1.0.334/go.mod h1:BMLd7J4LnIxw3fSl9vo3UCudJbH1wZutP8Uo3sQGQTk= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb v1.0.413 h1:6cQPfHc3I1pKUj23csRd9P/xxUPcnGRLRK2e5NGqtzc= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb v1.0.413/go.mod h1:TEuicyMWitW1zPkLbknGYg+VBGNE5N7GckvCF+hurWo= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ckafka v1.0.334 h1:LOXFeP3NHL/0PFFXA2GhYH/i7rDbcBwhcJJvqRdFO/w= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ckafka v1.0.334/go.mod h1:toYhD7pJDpz6XY3cf/zhUXtKDRt1CbLkgmOidQ2j8kA= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.334 h1:NeYNgw78v+qhxWbROjHaazaeEWigt6xTvg7CUS1dt6g= @@ -91,8 +95,12 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cmq v1.0.334 h1:NlMAh8v github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cmq v1.0.334/go.mod h1:lMGRATy+K7bKhXtxNTqRbSmaCy48xSQXPJqc1tYV50k= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.334 h1:tNkXg+cTnESAX6EmQWfF05NsYfD7U8qKtk/3YbWOCKk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.334/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.413 h1:DvydszksqriOr0Zze9OREt8OrIrtMSFcVD8lz3xNAQA= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.413/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.334 h1:ulfSODMy8rpKa8MfnTIPbe5HyOArnlB4RJ1qmpj09to= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.334/go.mod h1:AqyM/ZZMD7q5mHBqNY9YImbSpEpoEe7E/vrTbUWX+po= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.0.413 h1:MomwSkFrSLB16s51Yu1h4JO+p3Pzc1yesIj+oNwAVM0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.0.413/go.mod h1:So5aRFItRXlmSqqrOEQnc8xLn5tuD0s3drXQpcuuFRA= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc v1.0.334 h1:inkOmQwxiqzUE+tXdxcyTOtLwgOqAOPlRVYdqnJXSa4= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc v1.0.334/go.mod h1:5WGSrlIZJOhwIqPjjafb6vzrPEZieSHPhPMjjGPXOSU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dcdb v1.0.334 h1:Xxe889sr1FVhUPPFdZC4Z5IyJObgnGh0ELe+MJH17Mo= @@ -115,6 +123,10 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/redis v1.0.334 h1:zOWzd github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/redis v1.0.334/go.mod h1:5bwboqeXqVnRvUlKn2G9Y9DbOnWMSVQ0zWhhPZKUVZE= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sqlserver v1.0.334 h1:d81zfsJrfjngBRTTNPFZQ2SZ9+/QtKwU14a1CBriNhU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sqlserver v1.0.334/go.mod h1:ySz4zbciCFruAviNMeBcu7wW2+BY9Maw8qGWawTywkM= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tdmq v1.0.413 h1:nNYCih7UReD8/l97egLhlVsC6r48MYYEvVgQfllqGwc= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tdmq v1.0.413/go.mod h1:rMQYgt5anP1/ME1c+0Apo1W9250pbEn5oQ+cNMAo1U0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse v1.0.413 h1:CniS5OHzPsajRc5cWqJ9X62QKm9mbdTv9yhp5qY7uSs= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse v1.0.413/go.mod h1:6ZY4UsmCp2fvcLsahzBtSeLOc0IXxCHrPDmccBaOpJs= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.0.334 h1:rcM2H2e8kqxv7pZcsBdaIMitNd65+3iTM8aK/q6LS7U= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.0.334/go.mod h1:SKgeSsIfPEM6BeoIFiGHsWG9UsEXzkK0SkWx51H/OS8= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/pkg/client/client.go b/pkg/client/client.go index 7ed7cf6..357f7d4 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -9,6 +9,7 @@ import ( "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + cynosdb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb/v20190107" dc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc/v20180410" dcdb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dcdb/v20180411" es "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/es/v20180416" @@ -20,6 +21,8 @@ import ( pg "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/postgres/v20170312" redis "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/redis/v20180412" sqlserver "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sqlserver/v20180328" + tdmq "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tdmq/v20200217" + tse "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse/v20201207" vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" "github.com/tencentyun/tencentcloud-exporter/pkg/config" @@ -31,7 +34,11 @@ func NewMonitorClient(conf *config.TencentConfig) (*monitor.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() - cpf.HttpProfile.Endpoint = "monitor.tencentcloudapi.com" + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "monitor.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "monitor.tencentcloudapi.com" + } return monitor.NewClient(credential, conf.Credential.Region, cpf) } @@ -41,7 +48,11 @@ func NewMongodbClient(conf *config.TencentConfig) (*mongodb.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() - cpf.HttpProfile.Endpoint = "mongodb.tencentcloudapi.com" + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "mongodb.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "mongodb.tencentcloudapi.com" + } return mongodb.NewClient(credential, conf.Credential.Region, cpf) } @@ -51,7 +62,11 @@ func NewCdbClient(conf *config.TencentConfig) (*cdb.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() - cpf.HttpProfile.Endpoint = "cdb.tencentcloudapi.com" + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "cdb.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "cdb.tencentcloudapi.com" + } return cdb.NewClient(credential, conf.Credential.Region, cpf) } @@ -61,7 +76,11 @@ func NewCvmClient(conf *config.TencentConfig) (*cvm.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() - cpf.HttpProfile.Endpoint = "cvm.tencentcloudapi.com" + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "cvm.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "cvm.tencentcloudapi.com" + } return cvm.NewClient(credential, conf.Credential.Region, cpf) } @@ -71,7 +90,11 @@ func NewRedisClient(conf *config.TencentConfig) (*redis.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() - cpf.HttpProfile.Endpoint = "redis.tencentcloudapi.com" + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "redis.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "redis.tencentcloudapi.com" + } return redis.NewClient(credential, conf.Credential.Region, cpf) } @@ -81,7 +104,11 @@ func NewDcClient(conf *config.TencentConfig) (*dc.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() - cpf.HttpProfile.Endpoint = "dc.tencentcloudapi.com" + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "dc.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "dc.tencentcloudapi.com" + } return dc.NewClient(credential, conf.Credential.Region, cpf) } @@ -91,7 +118,11 @@ func NewClbClient(conf *config.TencentConfig) (*clb.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() - cpf.HttpProfile.Endpoint = "clb.tencentcloudapi.com" + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "clb.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "clb.tencentcloudapi.com" + } return clb.NewClient(credential, conf.Credential.Region, cpf) } @@ -101,7 +132,11 @@ func NewVpvClient(conf *config.TencentConfig) (*vpc.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() - cpf.HttpProfile.Endpoint = "vpc.tencentcloudapi.com" + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "vpc.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "vpc.tencentcloudapi.com" + } return vpc.NewClient(credential, conf.Credential.Region, cpf) } @@ -111,7 +146,11 @@ func NewCbsClient(conf *config.TencentConfig) (*cbs.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() - cpf.HttpProfile.Endpoint = "cbs.tencentcloudapi.com" + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "cbs.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "cbs.tencentcloudapi.com" + } return cbs.NewClient(credential, conf.Credential.Region, cpf) } @@ -121,7 +160,11 @@ func NewSqlServerClient(conf *config.TencentConfig) (*sqlserver.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() - cpf.HttpProfile.Endpoint = "sqlserver.tencentcloudapi.com" + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "sqlserver.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "sqlserver.tencentcloudapi.com" + } return sqlserver.NewClient(credential, conf.Credential.Region, cpf) } @@ -131,6 +174,11 @@ func NewMariaDBClient(conf *config.TencentConfig) (*mariadb.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "mariadb.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "mariadb.tencentcloudapi.com" + } return mariadb.NewClient(credential, conf.Credential.Region, cpf) } @@ -140,6 +188,11 @@ func NewESClient(conf *config.TencentConfig) (*es.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "es.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "es.tencentcloudapi.com" + } return es.NewClient(credential, conf.Credential.Region, cpf) } @@ -149,6 +202,11 @@ func NewCMQClient(conf *config.TencentConfig) (*cmq.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "cmq.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "cmq.tencentcloudapi.com" + } return cmq.NewClient(credential, conf.Credential.Region, cpf) } @@ -158,6 +216,11 @@ func NewPGClient(conf *config.TencentConfig) (*pg.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "postgres.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "postgres.tencentcloudapi.com" + } return pg.NewClient(credential, conf.Credential.Region, cpf) } @@ -167,6 +230,11 @@ func NewMemcacheClient(conf *config.TencentConfig) (*memcached.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "memcached.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "memcached.tencentcloudapi.com" + } return memcached.NewClient(credential, conf.Credential.Region, cpf) } @@ -176,6 +244,11 @@ func NewLighthouseClient(conf *config.TencentConfig) (*lh.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "lighthouse.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "lighthouse.tencentcloudapi.com" + } return lh.NewClient(credential, conf.Credential.Region, cpf) } @@ -185,6 +258,11 @@ func NewKafkaClient(conf *config.TencentConfig) (*kafka.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "ckafka.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "ckafka.tencentcloudapi.com" + } return kafka.NewClient(credential, conf.Credential.Region, cpf) } @@ -194,5 +272,52 @@ func NewDCDBClient(conf *config.TencentConfig) (*dcdb.Client, error) { conf.Credential.SecretKey, ) cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "dcdb.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "dcdb.tencentcloudapi.com" + } return dcdb.NewClient(credential, conf.Credential.Region, cpf) } + +func NewTDMQClient(conf *config.TencentConfig) (*tdmq.Client, error) { + credential := common.NewCredential( + conf.Credential.AccessKey, + conf.Credential.SecretKey, + ) + cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "tdmq.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "tdmq.tencentcloudapi.com" + } + return tdmq.NewClient(credential, conf.Credential.Region, cpf) +} + +func NewTseClient(conf *config.TencentConfig) (*tse.Client, error) { + credential := common.NewCredential( + conf.Credential.AccessKey, + conf.Credential.SecretKey, + ) + cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "tse.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "tse.tencentcloudapi.com" + } + return tse.NewClient(credential, conf.Credential.Region, cpf) +} + +func NewCynosdbClient(conf *config.TencentConfig) (*cynosdb.Client, error) { + credential := common.NewCredential( + conf.Credential.AccessKey, + conf.Credential.SecretKey, + ) + cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "cynosdb.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "cynosdb.tencentcloudapi.com" + } + return cynosdb.NewClient(credential, conf.Credential.Region, cpf) +} diff --git a/pkg/collector/handler_cynosdb.go b/pkg/collector/handler_cynosdb.go new file mode 100644 index 0000000..29e7e6e --- /dev/null +++ b/pkg/collector/handler_cynosdb.go @@ -0,0 +1,192 @@ +package collector + +import ( + "fmt" + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/tencentyun/tencentcloud-exporter/pkg/instance" + "github.com/tencentyun/tencentcloud-exporter/pkg/metric" + "github.com/tencentyun/tencentcloud-exporter/pkg/util" +) + +const ( + CynosdbNamespace = "QCE/CYNOSDB_MYSQL" + CynosdbInstanceidKey = "InstanceId" +) + +func init() { + registerHandler(CynosdbNamespace, defaultHandlerEnabled, NewCynosdbHandler) +} + +type CynosdbHandler struct { + baseProductHandler +} + +func (h *CynosdbHandler) IsMetricMetaVaild(meta *metric.TcmMeta) bool { + return true +} + +func (h *CynosdbHandler) GetNamespace() string { + return CynosdbNamespace +} + +func (h *CynosdbHandler) IsMetricVaild(m *metric.TcmMetric) bool { + _, ok := excludeMetricName[m.Meta.MetricName] + if ok { + return false + } + p, err := m.Meta.GetPeriod(m.Conf.StatPeriodSeconds) + if err != nil { + return false + } + if p != m.Conf.StatPeriodSeconds { + return false + } + return true +} + +// func (h *CynosdbHandler) GetSeries(m *metric.TcmMetric) (slist []*metric.TcmSeries, err error) { +// if m.Conf.StatPeriodSeconds < 60 { +// m.Conf.StatPeriodSeconds = 60 +// } +// return h.baseProductHandler.GetSeries(m) +// } + +func (h *CynosdbHandler) GetSeries(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + if m.Conf.IsIncludeOnlyInstance() { + return h.GetSeriesByOnly(m) + } + + if m.Conf.IsIncludeAllInstance() { + return h.GetSeriesByAll(m) + } + + if m.Conf.IsCustomQueryDimensions() { + return h.GetSeriesByCustom(m) + } + + return nil, fmt.Errorf("must config all_instances or only_include_instances or custom_query_dimensions") +} + +func (h *CynosdbHandler) GetSeriesByOnly(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + for _, insId := range m.Conf.OnlyIncludeInstances { + ins, err := h.collector.InstanceRepo.Get(insId) + if err != nil { + level.Error(h.logger).Log("msg", "Instance not found", "id", insId) + continue + } + sl, err := h.getSeriesByMetricType(m, ins) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", ins.GetInstanceId()) + continue + } + slist = append(slist, sl...) + } + return slist, nil +} + +func (h *CynosdbHandler) GetSeriesByAll(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + insList, err := h.collector.InstanceRepo.ListByFilters(m.Conf.InstanceFilters) + if err != nil { + return nil, err + } + for _, ins := range insList { + if len(m.Conf.ExcludeInstances) != 0 && util.IsStrInList(m.Conf.ExcludeInstances, ins.GetInstanceId()) { + continue + } + sl, err := h.getSeriesByMetricType(m, ins) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", ins.GetInstanceId()) + continue + } + slist = append(slist, sl...) + } + return slist, nil +} + +func (h *CynosdbHandler) GetSeriesByCustom(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + for _, ql := range m.Conf.CustomQueryDimensions { + v, ok := ql[h.monitorQueryKey] + if !ok { + level.Error(h.logger).Log( + "msg", fmt.Sprintf("not found %s in queryDimensions", h.monitorQueryKey), + "ql", fmt.Sprintf("%v", ql)) + continue + } + ins, err := h.collector.InstanceRepo.Get(v) + if err != nil { + level.Error(h.logger).Log("msg", "Instance not found", "err", err, "id", v) + continue + } + + sl, err := h.getSeriesByMetricType(m, ins) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", ins.GetInstanceId()) + continue + } + slist = append(slist, sl...) + } + return slist, nil +} + +func (h *CynosdbHandler) getSeriesByMetricType(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var dimensions []string + for _, v := range m.Meta.SupportDimensions { + dimensions = append(dimensions, v) + } + if util.IsStrInList(dimensions, "ClusterId") { + return h.getClusterIdSeries(m, ins) + } else { + return h.getInstanceSeries(m, ins) + } +} +func (h *CynosdbHandler) getInstanceSeries(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var series []*metric.TcmSeries + + ql := map[string]string{ + h.monitorQueryKey: ins.GetMonitorQueryKey(), + } + s, err := metric.NewTcmSeries(m, ql, ins) + if err != nil { + return nil, err + } + series = append(series, s) + + return series, nil +} + +func (h *CynosdbHandler) getClusterIdSeries(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var series []*metric.TcmSeries + clusterId, err := ins.GetFieldValueByName("ClusterId") + if err != nil { + level.Error(h.logger).Log("msg", "ClusterId not found") + } + ql := map[string]string{ + h.monitorQueryKey: ins.GetMonitorQueryKey(), + "ClusterId": clusterId, + } + s, err := metric.NewTcmSeries(m, ql, ins) + if err != nil { + return nil, err + } + series = append(series, s) + return series, nil +} + +func NewCynosdbHandler(c *TcProductCollector, logger log.Logger) (handler ProductHandler, err error) { + handler = &CynosdbHandler{ + baseProductHandler{ + monitorQueryKey: CynosdbInstanceidKey, + collector: c, + logger: logger, + }, + } + return + +} diff --git a/pkg/collector/handler_nacos.go b/pkg/collector/handler_nacos.go new file mode 100644 index 0000000..9306730 --- /dev/null +++ b/pkg/collector/handler_nacos.go @@ -0,0 +1,54 @@ +package collector + +import ( + "github.com/go-kit/kit/log" + "github.com/tencentyun/tencentcloud-exporter/pkg/metric" +) + +const ( + NacosNamespace = "TSE/NACOS" + NacosInstanceidKey = "NacosInstanceId" +) + +func init() { + registerHandler(NacosNamespace, defaultHandlerEnabled, NewNacosHandler) +} + +type NacosHandler struct { + baseProductHandler +} + +func (h *NacosHandler) IsMetricMetaVaild(meta *metric.TcmMeta) bool { + return true +} + +func (h *NacosHandler) GetNamespace() string { + return NacosNamespace +} + +func (h *NacosHandler) IsMetricVaild(m *metric.TcmMetric) bool { + _, ok := excludeMetricName[m.Meta.MetricName] + if ok { + return false + } + p, err := m.Meta.GetPeriod(m.Conf.StatPeriodSeconds) + if err != nil { + return false + } + if p != m.Conf.StatPeriodSeconds { + return false + } + return true +} + +func NewNacosHandler(c *TcProductCollector, logger log.Logger) (handler ProductHandler, err error) { + handler = &NacosHandler{ + baseProductHandler{ + monitorQueryKey: NacosInstanceidKey, + collector: c, + logger: logger, + }, + } + return + +} diff --git a/pkg/collector/handler_tdmq.go b/pkg/collector/handler_tdmq.go new file mode 100644 index 0000000..d9d0b4e --- /dev/null +++ b/pkg/collector/handler_tdmq.go @@ -0,0 +1,213 @@ +package collector + +import ( + "fmt" + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/tencentyun/tencentcloud-exporter/pkg/instance" + "github.com/tencentyun/tencentcloud-exporter/pkg/metric" + "github.com/tencentyun/tencentcloud-exporter/pkg/util" + "time" +) + +const ( + TdmqNamespace = "QCE/TDMQ" + TdmqInstanceidKey = "tenant" +) + +func init() { + registerHandler(TdmqNamespace, defaultHandlerEnabled, NewTdmqHandler) +} + +type tdmqHandler struct { + baseProductHandler + namespaceRepo instance.TdmqTcInstanceRocketMQNameSpacesRepository + topicRepo instance.TdmqTcInstanceRocketMQTopicsRepository +} + +func (h *tdmqHandler) IsMetricMetaVaild(meta *metric.TcmMeta) bool { + return true +} + +func (h *tdmqHandler) GetNamespace() string { + return TdmqNamespace +} + +func (h *tdmqHandler) IsMetricVaild(m *metric.TcmMetric) bool { + _, ok := excludeMetricName[m.Meta.MetricName] + if ok { + return false + } + p, err := m.Meta.GetPeriod(m.Conf.StatPeriodSeconds) + if err != nil { + return false + } + if p != m.Conf.StatPeriodSeconds { + return false + } + return true +} + +func (h *tdmqHandler) GetSeries(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + if m.Conf.IsIncludeOnlyInstance() { + return h.GetSeriesByOnly(m) + } + + if m.Conf.IsIncludeAllInstance() { + return h.GetSeriesByAll(m) + } + + if m.Conf.IsCustomQueryDimensions() { + return h.GetSeriesByCustom(m) + } + + return nil, fmt.Errorf("must config all_instances or only_include_instances or custom_query_dimensions") +} + +func (h *tdmqHandler) GetSeriesByOnly(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + for _, insId := range m.Conf.OnlyIncludeInstances { + ins, err := h.collector.InstanceRepo.Get(insId) + if err != nil { + level.Error(h.logger).Log("msg", "Instance not found", "id", insId) + continue + } + sl, err := h.getSeriesByMetricType(m, ins) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", ins.GetInstanceId()) + continue + } + slist = append(slist, sl...) + } + return slist, nil +} + +func (h *tdmqHandler) GetSeriesByAll(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + insList, err := h.collector.InstanceRepo.ListByFilters(m.Conf.InstanceFilters) + if err != nil { + return nil, err + } + for _, ins := range insList { + if len(m.Conf.ExcludeInstances) != 0 && util.IsStrInList(m.Conf.ExcludeInstances, ins.GetInstanceId()) { + continue + } + sl, err := h.getSeriesByMetricType(m, ins) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", ins.GetInstanceId()) + continue + } + slist = append(slist, sl...) + } + return slist, nil +} + +func (h *tdmqHandler) GetSeriesByCustom(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + for _, ql := range m.Conf.CustomQueryDimensions { + v, ok := ql[h.monitorQueryKey] + if !ok { + level.Error(h.logger).Log( + "msg", fmt.Sprintf("not found %s in queryDimensions", h.monitorQueryKey), + "ql", fmt.Sprintf("%v", ql)) + continue + } + ins, err := h.collector.InstanceRepo.Get(v) + if err != nil { + level.Error(h.logger).Log("msg", "Instance not found", "err", err, "id", v) + continue + } + + sl, err := h.getSeriesByMetricType(m, ins) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", ins.GetInstanceId()) + continue + } + slist = append(slist, sl...) + } + return slist, nil +} + +func (h *tdmqHandler) getSeriesByMetricType(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var dimensions []string + for _, v := range m.Meta.SupportDimensions { + dimensions = append(dimensions, v) + } + if util.IsStrInList(dimensions, "environmentId") { + return h.getNamespaceSeries(m, ins) + } else { + return h.getInstanceSeries(m, ins) + } +} + +func (h *tdmqHandler) getInstanceSeries(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var series []*metric.TcmSeries + + ql := map[string]string{ + h.monitorQueryKey: ins.GetMonitorQueryKey(), + } + s, err := metric.NewTcmSeries(m, ql, ins) + if err != nil { + return nil, err + } + series = append(series, s) + + return series, nil +} + +func (h *tdmqHandler) getNamespaceSeries(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var series []*metric.TcmSeries + namespacesResp, err := h.namespaceRepo.GetRocketMQNamespacesInfo(ins.GetInstanceId()) + if err != nil { + return nil, err + } + for _, namespace := range namespacesResp.Response.Namespaces { + topicsResp, err := h.topicRepo.GetRocketMQTopicsInfo(ins.GetInstanceId(), *namespace.NamespaceId) + if err != nil { + return nil, err + } + for _, topic := range topicsResp.Response.Topics { + ql := map[string]string{ + "tenantId": ins.GetMonitorQueryKey(), + "environmentId": *namespace.NamespaceId, + "topicName": *topic.Name, + } + s, err := metric.NewTcmSeries(m, ql, ins) + if err != nil { + return nil, err + } + series = append(series, s) + } + } + return series, nil +} + +func NewTdmqHandler(c *TcProductCollector, logger log.Logger) (handler ProductHandler, err error) { + namespaceRepo, err := instance.NewTdmqTcInstanceRocketMQNameSpacesRepository(c.Conf, logger) + if err != nil { + return nil, err + } + relodInterval := time.Duration(c.ProductConf.RelodIntervalMinutes * int64(time.Minute)) + namespaceRepoCahe := instance.NewTcTdmqInstanceNamespaceCache(namespaceRepo, relodInterval, logger) + + topicRepo, err := instance.NewTdmqTcInstanceRocketMQTopicsRepository(c.Conf, logger) + if err != nil { + return nil, err + } + topicRepoCahe := instance.NewTcTdmqInstanceTopicsCache(topicRepo, relodInterval, logger) + + handler = &tdmqHandler{ + baseProductHandler: baseProductHandler{ + monitorQueryKey: TdmqInstanceidKey, + collector: c, + logger: logger, + }, + namespaceRepo: namespaceRepoCahe, + topicRepo: topicRepoCahe, + } + return + +} diff --git a/pkg/collector/handler_vpngw.go b/pkg/collector/handler_vpngw.go new file mode 100644 index 0000000..630b489 --- /dev/null +++ b/pkg/collector/handler_vpngw.go @@ -0,0 +1,54 @@ +package collector + +import ( + "github.com/go-kit/kit/log" + "github.com/tencentyun/tencentcloud-exporter/pkg/metric" +) + +const ( + VpngwNamespace = "QCE/VPNGW" + VpngwInstanceidKey = "vpnGwId" +) + +func init() { + registerHandler(VpngwNamespace, defaultHandlerEnabled, NewVpngwHandler) +} + +type VpngwHandler struct { + baseProductHandler +} + +func (h *VpngwHandler) IsMetricMetaVaild(meta *metric.TcmMeta) bool { + return true +} + +func (h *VpngwHandler) GetNamespace() string { + return ZookeeperNamespace +} + +func (h *VpngwHandler) IsMetricVaild(m *metric.TcmMetric) bool { + _, ok := excludeMetricName[m.Meta.MetricName] + if ok { + return false + } + p, err := m.Meta.GetPeriod(m.Conf.StatPeriodSeconds) + if err != nil { + return false + } + if p != m.Conf.StatPeriodSeconds { + return false + } + return true +} + +func NewVpngwHandler(c *TcProductCollector, logger log.Logger) (handler ProductHandler, err error) { + handler = &tdmqHandler{ + baseProductHandler: baseProductHandler{ + monitorQueryKey: VpngwInstanceidKey, + collector: c, + logger: logger, + }, + } + return + +} diff --git a/pkg/collector/handler_vpnx.go b/pkg/collector/handler_vpnx.go new file mode 100644 index 0000000..f12c963 --- /dev/null +++ b/pkg/collector/handler_vpnx.go @@ -0,0 +1,54 @@ +package collector + +import ( + "github.com/go-kit/kit/log" + "github.com/tencentyun/tencentcloud-exporter/pkg/metric" +) + +const ( + VpnxNamespace = "QCE/VPNX" + VpnxInstanceidKey = "vpnConnId" +) + +func init() { + registerHandler(VpnxNamespace, defaultHandlerEnabled, NewVpnxHandler) +} + +type VpnxHandler struct { + baseProductHandler +} + +func (h *VpnxHandler) IsMetricMetaVaild(meta *metric.TcmMeta) bool { + return true +} + +func (h *VpnxHandler) GetNamespace() string { + return ZookeeperNamespace +} + +func (h *VpnxHandler) IsMetricVaild(m *metric.TcmMetric) bool { + _, ok := excludeMetricName[m.Meta.MetricName] + if ok { + return false + } + p, err := m.Meta.GetPeriod(m.Conf.StatPeriodSeconds) + if err != nil { + return false + } + if p != m.Conf.StatPeriodSeconds { + return false + } + return true +} + +func NewVpnxHandler(c *TcProductCollector, logger log.Logger) (handler ProductHandler, err error) { + handler = &tdmqHandler{ + baseProductHandler: baseProductHandler{ + monitorQueryKey: VpnxInstanceidKey, + collector: c, + logger: logger, + }, + } + return + +} diff --git a/pkg/collector/handler_zookeeper.go b/pkg/collector/handler_zookeeper.go new file mode 100644 index 0000000..285a52a --- /dev/null +++ b/pkg/collector/handler_zookeeper.go @@ -0,0 +1,53 @@ +package collector + +import ( + "github.com/go-kit/kit/log" + "github.com/tencentyun/tencentcloud-exporter/pkg/metric" +) + +const ( + ZookeeperNamespace = "TSE/ZOOKEEPER" + ZookeeperInstanceidKey = "InstanceId" +) + +func init() { + registerHandler(ZookeeperNamespace, defaultHandlerEnabled, NewZookeeperHandler) +} + +type ZookeeperHandler struct { + baseProductHandler +} + +func (h *ZookeeperHandler) IsMetricMetaVaild(meta *metric.TcmMeta) bool { + return true +} + +func (h *ZookeeperHandler) GetNamespace() string { + return ZookeeperNamespace +} + +func (h *ZookeeperHandler) IsMetricVaild(m *metric.TcmMetric) bool { + _, ok := excludeMetricName[m.Meta.MetricName] + if ok { + return false + } + p, err := m.Meta.GetPeriod(m.Conf.StatPeriodSeconds) + if err != nil { + return false + } + if p != m.Conf.StatPeriodSeconds { + return false + } + return true +} + +func NewZookeeperHandler(c *TcProductCollector, logger log.Logger) (handler ProductHandler, err error) { + handler = &ZookeeperHandler{ + baseProductHandler{ + monitorQueryKey: ZookeeperInstanceidKey, + collector: c, + logger: logger, + }, + } + return +} diff --git a/pkg/config/config.go b/pkg/config/config.go index 630dfba..28c06eb 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -55,7 +55,13 @@ var ( "lighthouse": "QCE/LIGHTHOUSE", "ckafka": "QCE/CKAFKA", "tdmysql": "QCE/TDMYSQL", - "lb": "QCE/LB", // for eip + "lb": "QCE/LB", // for eip + "tdmq": "QCE/TDMQ", // for tdmq + // "zookeeper": "TSE/ZOOKEEPER", // for zookeeper + // "nacos": "TSE/NACOS", // for nacos + "vpngw": "QCE/VPNGW", // for vpngw + "vpnx": "QCE/VPNX", // for vpnx + "cynosdb_mysql": "QCE/CYNOSDB_MYSQL", // for cynosdb_mysql } SupportStatisticsTypes = map[string]bool{ @@ -67,9 +73,10 @@ var ( ) type TencentCredential struct { - AccessKey string `yaml:"access_key"` - SecretKey string `yaml:"secret_key"` - Region string `yaml:"region"` + AccessKey string `yaml:"access_key"` + SecretKey string `yaml:"secret_key"` + Region string `yaml:"region"` + IsInternal bool `yaml:"is_internal"` } type TencentMetric struct { diff --git a/pkg/instance/cache.go b/pkg/instance/cache.go index 013281f..e4646c8 100644 --- a/pkg/instance/cache.go +++ b/pkg/instance/cache.go @@ -1,10 +1,12 @@ package instance import ( + "fmt" "sync" "time" sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/redis/v20180412" + tdmq "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tdmq/v20200217" "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" @@ -154,3 +156,85 @@ func NewTcRedisInstanceNodeCache(repo RedisTcInstanceNodeRepository, reloadInter } return cache } + +// tdmq +type TcTdmqInstanceNamespaceCache struct { + Raw TdmqTcInstanceRocketMQNameSpacesRepository + cache map[string]*tdmq.DescribeRocketMQNamespacesResponse + lastReloadTime map[string]time.Time + reloadInterval time.Duration + mu sync.Mutex + + logger log.Logger +} + +func (c *TcTdmqInstanceNamespaceCache) GetRocketMQNamespacesInfo(instanceId string) (*tdmq.DescribeRocketMQNamespacesResponse, error) { + lrtime, exists := c.lastReloadTime[instanceId] + if exists && time.Now().Sub(lrtime) < c.reloadInterval { + namespace, ok := c.cache[instanceId] + if ok { + return namespace, nil + } + } + + namespace, err := c.Raw.GetRocketMQNamespacesInfo(instanceId) + if err != nil { + return nil, err + } + c.cache[instanceId] = namespace + c.lastReloadTime[instanceId] = time.Now() + level.Debug(c.logger).Log("msg", "Get RocketMQ Namespaces info from api", "instanceId", instanceId) + return namespace, nil +} + +func NewTcTdmqInstanceNamespaceCache(repo TdmqTcInstanceRocketMQNameSpacesRepository, reloadInterval time.Duration, logger log.Logger) TdmqTcInstanceRocketMQNameSpacesRepository { + cache := &TcTdmqInstanceNamespaceCache{ + Raw: repo, + cache: map[string]*tdmq.DescribeRocketMQNamespacesResponse{}, + lastReloadTime: map[string]time.Time{}, + reloadInterval: reloadInterval, + logger: logger, + } + return cache +} + +type TcTdmqInstanceTopicsCache struct { + Raw TdmqTcInstanceRocketMQTopicsRepository + cache map[string]*tdmq.DescribeRocketMQTopicsResponse + lastReloadTime map[string]time.Time + reloadInterval time.Duration + mu sync.Mutex + + logger log.Logger +} + +func (c *TcTdmqInstanceTopicsCache) GetRocketMQTopicsInfo(instanceId string, namespaceId string) (*tdmq.DescribeRocketMQTopicsResponse, error) { + lrtime, exists := c.lastReloadTime[instanceId] + if exists && time.Now().Sub(lrtime) < c.reloadInterval { + topic, ok := c.cache[instanceId] + if ok { + return topic, nil + } + } + + topic, err := c.Raw.GetRocketMQTopicsInfo(instanceId, namespaceId) + if err != nil { + return nil, err + } + instanceIdNamspace := fmt.Sprintf("%v-%v", instanceId, namespaceId) + c.cache[instanceIdNamspace] = topic + c.lastReloadTime[instanceId] = time.Now() + level.Debug(c.logger).Log("msg", "Get RocketMQ Namespaces info from api", "instanceId", instanceId) + return topic, nil +} + +func NewTcTdmqInstanceTopicsCache(repo TdmqTcInstanceRocketMQTopicsRepository, reloadInterval time.Duration, logger log.Logger) TdmqTcInstanceRocketMQTopicsRepository { + cache := &TcTdmqInstanceTopicsCache{ + Raw: repo, + cache: map[string]*tdmq.DescribeRocketMQTopicsResponse{}, + lastReloadTime: map[string]time.Time{}, + reloadInterval: reloadInterval, + logger: logger, + } + return cache +} diff --git a/pkg/instance/instance_cynosdb.go b/pkg/instance/instance_cynosdb.go new file mode 100644 index 0000000..5afc80a --- /dev/null +++ b/pkg/instance/instance_cynosdb.go @@ -0,0 +1,34 @@ +package instance + +import ( + "fmt" + "reflect" + + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb/v20190107" +) + +type CynosdbTcInstance struct { + baseTcInstance + meta *sdk.CynosdbInstance +} + +func (ins *CynosdbTcInstance) GetMeta() interface{} { + return ins.meta +} + +func NewCynosdbTcInstance(instanceId string, meta *sdk.CynosdbInstance) (ins *CynosdbTcInstance, err error) { + if instanceId == "" { + return nil, fmt.Errorf("instanceId is empty ") + } + if meta == nil { + return nil, fmt.Errorf("meta is empty ") + } + ins = &CynosdbTcInstance{ + baseTcInstance: baseTcInstance{ + instanceId: instanceId, + value: reflect.ValueOf(*meta), + }, + meta: meta, + } + return +} diff --git a/pkg/instance/instance_tdmq.go b/pkg/instance/instance_tdmq.go new file mode 100644 index 0000000..edbc532 --- /dev/null +++ b/pkg/instance/instance_tdmq.go @@ -0,0 +1,34 @@ +package instance + +import ( + "fmt" + "reflect" + + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tdmq/v20200217" +) + +type TdmqTcInstance struct { + baseTcInstance + meta *sdk.RocketMQClusterDetail +} + +func (ins *TdmqTcInstance) GetMeta() interface{} { + return ins.meta +} + +func NewTdmqTcInstance(instanceId string, meta *sdk.RocketMQClusterDetail) (ins *TdmqTcInstance, err error) { + if instanceId == "" { + return nil, fmt.Errorf("instanceId is empty ") + } + if meta == nil { + return nil, fmt.Errorf("meta is empty ") + } + ins = &TdmqTcInstance{ + baseTcInstance: baseTcInstance{ + instanceId: instanceId, + value: reflect.ValueOf(*meta), + }, + meta: meta, + } + return +} diff --git a/pkg/instance/instance_tse.go b/pkg/instance/instance_tse.go new file mode 100644 index 0000000..2c45a11 --- /dev/null +++ b/pkg/instance/instance_tse.go @@ -0,0 +1,34 @@ +package instance + +import ( + "fmt" + "reflect" + + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse/v20201207" +) + +type TseTcInstance struct { + baseTcInstance + meta *sdk.SREInstance +} + +func (ins *TseTcInstance) GetMeta() interface{} { + return ins.meta +} + +func NewTseTcInstance(instanceId string, meta *sdk.SREInstance) (ins *TseTcInstance, err error) { + if instanceId == "" { + return nil, fmt.Errorf("instanceId is empty ") + } + if meta == nil { + return nil, fmt.Errorf("meta is empty ") + } + ins = &TseTcInstance{ + baseTcInstance: baseTcInstance{ + instanceId: instanceId, + value: reflect.ValueOf(*meta), + }, + meta: meta, + } + return +} diff --git a/pkg/instance/instance_vpngw.go b/pkg/instance/instance_vpngw.go new file mode 100644 index 0000000..b1f9753 --- /dev/null +++ b/pkg/instance/instance_vpngw.go @@ -0,0 +1,34 @@ +package instance + +import ( + "fmt" + "reflect" + + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +type VpngwTcInstance struct { + baseTcInstance + meta *sdk.VpnGateway +} + +func (ins *VpngwTcInstance) GetMeta() interface{} { + return ins.meta +} + +func NewVpngwTcInstance(instanceId string, meta *sdk.VpnGateway) (ins *VpngwTcInstance, err error) { + if instanceId == "" { + return nil, fmt.Errorf("instanceId is empty ") + } + if meta == nil { + return nil, fmt.Errorf("meta is empty ") + } + ins = &VpngwTcInstance{ + baseTcInstance: baseTcInstance{ + instanceId: instanceId, + value: reflect.ValueOf(*meta), + }, + meta: meta, + } + return +} diff --git a/pkg/instance/instance_vpnx.go b/pkg/instance/instance_vpnx.go new file mode 100644 index 0000000..5f3decd --- /dev/null +++ b/pkg/instance/instance_vpnx.go @@ -0,0 +1,34 @@ +package instance + +import ( + "fmt" + "reflect" + + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +type VpnxTcInstance struct { + baseTcInstance + meta *sdk.VpnConnection +} + +func (ins *VpnxTcInstance) GetMeta() interface{} { + return ins.meta +} + +func NewVpnxTcInstance(instanceId string, meta *sdk.VpnConnection) (ins *VpnxTcInstance, err error) { + if instanceId == "" { + return nil, fmt.Errorf("instanceId is empty ") + } + if meta == nil { + return nil, fmt.Errorf("meta is empty ") + } + ins = &VpnxTcInstance{ + baseTcInstance: baseTcInstance{ + instanceId: instanceId, + value: reflect.ValueOf(*meta), + }, + meta: meta, + } + return +} diff --git a/pkg/instance/repository_cynosdb.go b/pkg/instance/repository_cynosdb.go new file mode 100644 index 0000000..3f89618 --- /dev/null +++ b/pkg/instance/repository_cynosdb.go @@ -0,0 +1,102 @@ +package instance + +import ( + "fmt" + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb/v20190107" + + "github.com/tencentyun/tencentcloud-exporter/pkg/client" + "github.com/tencentyun/tencentcloud-exporter/pkg/config" +) + +func init() { + registerRepository("QCE/CYNOSDB_MYSQL", NewCynosdbTcInstanceRepository) +} + +var dbType = "MYSQL" +var status = "running" + +type CynosdbTcInstanceRepository struct { + client *sdk.Client + logger log.Logger +} + +func (repo *CynosdbTcInstanceRepository) GetInstanceKey() string { + return "InstanceId" +} + +func (repo *CynosdbTcInstanceRepository) Get(id string) (instance TcInstance, err error) { + level.Info(repo.logger).Log("start CynosdbTcInstanceRepository") + req := sdk.NewDescribeInstancesRequest() + req.InstanceIds = []*string{&id} + req.DbType = &dbType + req.Status = &status + resp, err := repo.client.DescribeInstances(req) + if err != nil { + return + } + if len(resp.Response.InstanceSet) != 1 { + return nil, fmt.Errorf("Response instanceDetails size != 1, id=%s ", id) + } + meta := resp.Response.InstanceSet[0] + instance, err = NewCynosdbTcInstance(id, meta) + if err != nil { + return + } + return +} + +func (repo *CynosdbTcInstanceRepository) ListByIds(id []string) (instances []TcInstance, err error) { + return +} + +func (repo *CynosdbTcInstanceRepository) ListByFilters(filters map[string]string) (instances []TcInstance, err error) { + req := sdk.NewDescribeInstancesRequest() + var offset int64 = 0 + var limit int64 = 100 + var total int64 = -1 + + req.Offset = &offset + req.Limit = &limit + req.DbType = &dbType + req.Status = &status +getMoreInstances: + resp, err := repo.client.DescribeInstances(req) + if err != nil { + return + } + if total == -1 { + total = int64(*resp.Response.TotalCount) + } + for _, meta := range resp.Response.InstanceSet { + level.Info(repo.logger).Log("InstanceSet", *meta.InstanceId) + ins, e := NewCynosdbTcInstance(*meta.InstanceId, meta) + if e != nil { + level.Error(repo.logger).Log("msg", "Create Cynosdb instance fail", "id", *meta.InstanceId) + continue + } + instances = append(instances, ins) + + } + offset += limit + if offset < total { + req.Offset = &offset + goto getMoreInstances + } + + return +} + + +func NewCynosdbTcInstanceRepository(c *config.TencentConfig, logger log.Logger) (repo TcInstanceRepository, err error) { + cli, err := client.NewCynosdbClient(c) + if err != nil { + return + } + repo = &CynosdbTcInstanceRepository{ + client: cli, + logger: logger, + } + return +} diff --git a/pkg/instance/repository_tdmq.go b/pkg/instance/repository_tdmq.go new file mode 100644 index 0000000..838add7 --- /dev/null +++ b/pkg/instance/repository_tdmq.go @@ -0,0 +1,159 @@ +package instance + +import ( + "fmt" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tdmq/v20200217" + + "github.com/tencentyun/tencentcloud-exporter/pkg/client" + "github.com/tencentyun/tencentcloud-exporter/pkg/config" +) + +func init() { + registerRepository("QCE/TDMQ", NewTdmqTcInstanceRepository) +} + +type TdmqTcInstanceRepository struct { + client *sdk.Client + logger log.Logger +} + +func (repo *TdmqTcInstanceRepository) GetInstanceKey() string { + return "InstanceId" +} + +func (repo *TdmqTcInstanceRepository) Get(id string) (instance TcInstance, err error) { + req := sdk.NewDescribeRocketMQClustersRequest() + req.ClusterIdList = []*string{&id} + resp, err := repo.client.DescribeRocketMQClusters(req) + if err != nil { + return + } + if len(resp.Response.ClusterList) != 1 { + return nil, fmt.Errorf("Response instanceDetails size != 1, id=%s ", id) + } + meta := resp.Response.ClusterList[0] + instance, err = NewTdmqTcInstance(id, meta) + if err != nil { + return + } + return +} + +func (repo *TdmqTcInstanceRepository) ListByIds(id []string) (instances []TcInstance, err error) { + return +} + +func (repo *TdmqTcInstanceRepository) ListByFilters(filters map[string]string) (instances []TcInstance, err error) { + req := sdk.NewDescribeRocketMQClustersRequest() + var offset uint64 = 0 + var limit uint64 = 100 + var total int64 = -1 + + req.Offset = &offset + req.Limit = &limit + +getMoreInstances: + resp, err := repo.client.DescribeRocketMQClusters(req) + if err != nil { + return + } + if total == -1 { + total = int64(*resp.Response.TotalCount) + } + for _, meta := range resp.Response.ClusterList { + ins, e := NewTdmqTcInstance(*meta.Info.ClusterId, meta) + if e != nil { + level.Error(repo.logger).Log("msg", "Create tdmq instance fail", "id", *meta.Info.ClusterId) + continue + } + instances = append(instances, ins) + } + offset += limit + if offset < uint64(total) { + req.Offset = &offset + goto getMoreInstances + } + + return +} + +// RocketMQNameSpaces +type TdmqTcInstanceRocketMQNameSpacesRepository interface { + GetRocketMQNamespacesInfo(instanceId string) (*sdk.DescribeRocketMQNamespacesResponse, error) +} + +type TdmqTcInstanceRocketMQNameSpacesRepositoryImpl struct { + client *sdk.Client + logger log.Logger +} + +func (repo *TdmqTcInstanceRocketMQNameSpacesRepositoryImpl) GetRocketMQNamespacesInfo(instanceId string) (*sdk.DescribeRocketMQNamespacesResponse, error) { + req := sdk.NewDescribeRocketMQNamespacesRequest() + var offset uint64 = 0 + var limit uint64 = 100 + req.Limit = &limit + req.Offset = &offset + req.ClusterId = common.StringPtr(instanceId) + return repo.client.DescribeRocketMQNamespaces(req) +} + +func NewTdmqTcInstanceRocketMQNameSpacesRepository(c *config.TencentConfig, logger log.Logger) (TdmqTcInstanceRocketMQNameSpacesRepository, error) { + cli, err := client.NewTDMQClient(c) + if err != nil { + return nil, err + } + repo := &TdmqTcInstanceRocketMQNameSpacesRepositoryImpl{ + client: cli, + logger: logger, + } + return repo, nil +} + +// RocketMQTopics +type TdmqTcInstanceRocketMQTopicsRepository interface { + GetRocketMQTopicsInfo(instanceId string, namespaceId string) (*sdk.DescribeRocketMQTopicsResponse, error) +} + +type TdmqTcInstanceRocketMQTopicsRepositoryImpl struct { + client *sdk.Client + logger log.Logger +} + +func (repo *TdmqTcInstanceRocketMQTopicsRepositoryImpl) GetRocketMQTopicsInfo(instanceId string, namespaceId string) (*sdk.DescribeRocketMQTopicsResponse, error) { + req := sdk.NewDescribeRocketMQTopicsRequest() + var offset uint64 = 0 + var limit uint64 = 100 + req.Limit = &limit + req.Offset = &offset + req.ClusterId = common.StringPtr(instanceId) + req.NamespaceId = common.StringPtr(namespaceId) + return repo.client.DescribeRocketMQTopics(req) +} + +func NewTdmqTcInstanceRocketMQTopicsRepository(c *config.TencentConfig, logger log.Logger) (TdmqTcInstanceRocketMQTopicsRepository, error) { + cli, err := client.NewTDMQClient(c) + if err != nil { + return nil, err + } + repo := &TdmqTcInstanceRocketMQTopicsRepositoryImpl{ + client: cli, + logger: logger, + } + return repo, nil +} + +func NewTdmqTcInstanceRepository(c *config.TencentConfig, logger log.Logger) (repo TcInstanceRepository, err error) { + cli, err := client.NewTDMQClient(c) + if err != nil { + return + } + repo = &TdmqTcInstanceRepository{ + client: cli, + logger: logger, + } + return +} diff --git a/pkg/instance/repository_tse.go b/pkg/instance/repository_tse.go new file mode 100644 index 0000000..95afcca --- /dev/null +++ b/pkg/instance/repository_tse.go @@ -0,0 +1,123 @@ +package instance + +import ( + "fmt" + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse/v20201207" + + "github.com/tencentyun/tencentcloud-exporter/pkg/client" + "github.com/tencentyun/tencentcloud-exporter/pkg/config" +) + +func init() { + registerRepository("TSE/ZOOKEEPER", NewTseTcInstanceRepository) + registerRepository("TSE/NACOS", NewTseTcInstanceRepository) +} + +type TseTcInstanceRepository struct { + client *sdk.Client + logger log.Logger +} + +func (repo *TseTcInstanceRepository) GetInstanceKey() string { + return "InstanceId" +} + +func (repo *TseTcInstanceRepository) Get(id string) (instance TcInstance, err error) { + req := sdk.NewDescribeSREInstancesRequest() + // req.Filters.Name = []*string{&id} + resp, err := repo.client.DescribeSREInstances(req) + if err != nil { + return + } + if len(resp.Response.Content) != 1 { + return nil, fmt.Errorf("Response instanceDetails size != 1, id=%s ", id) + } + meta := resp.Response.Content[0] + instance, err = NewTseTcInstance(id, meta) + if err != nil { + return + } + return +} + +func (repo *TseTcInstanceRepository) ListByIds(id []string) (instances []TcInstance, err error) { + return +} + +func (repo *TseTcInstanceRepository) ListByFilters(filters map[string]string) (instances []TcInstance, err error) { + req := sdk.NewDescribeSREInstancesRequest() + var offset int64 = 0 + var limit int64 = 100 + var total int64 = -1 + + req.Offset = &offset + req.Limit = &limit + +getMoreInstances: + resp, err := repo.client.DescribeSREInstances(req) + if err != nil { + return + } + if total == -1 { + total = int64(*resp.Response.TotalCount) + } + for _, meta := range resp.Response.Content { + ins, e := NewTseTcInstance(*meta.InstanceId, meta) + if e != nil { + level.Error(repo.logger).Log("msg", "Create tse instance fail", "id", *meta.InstanceId) + continue + } + instances = append(instances, ins) + } + offset += limit + if offset < total { + req.Offset = &offset + goto getMoreInstances + } + + return +} + +// type TseTcInstanceZookeeperRepository interface { +// GetZookeeperPodInfo(instanceId string) (*sdk.DescribeZookeeperReplicasResponse, error) +// } +// +// type RedisTcInstanceZookeeperRepositoryImpl struct { +// client *sdk.Client +// logger log.Logger +// } +// +// func (repo *RedisTcInstanceZookeeperRepositoryImpl) GetZookeeperPodInfo(instanceId string) (*sdk.DescribeZookeeperReplicasResponse, error) { +// req := sdk.NewDescribeZookeeperReplicasRequest() +// req.InstanceId = common.StringPtr(instanceId) +// return repo.client.DescribeZookeeperReplicas(req) +// } +// +// type TseTcInstanceNacosRepository interface { +// GetZookeeperPodInfo(instanceId string) (*sdk.DescribeNacosReplicasResponse, error) +// } +// +// type RedisTcInstanceNacosRepositoryImpl struct { +// client *sdk.Client +// logger log.Logger +// } +// +// func (repo *RedisTcInstanceNacosRepositoryImpl) GetNacosPodInfo(instanceId string) (*sdk.DescribeNacosReplicasResponse, error) { +// req := sdk.NewDescribeNacosReplicasRequest() +// req.InstanceId = common.StringPtr(instanceId) +// return repo.client.DescribeNacosReplicas(req) +// } + +func NewTseTcInstanceRepository(c *config.TencentConfig, logger log.Logger) (repo TcInstanceRepository, err error) { + cli, err := client.NewTseClient(c) + if err != nil { + return + } + repo = &TseTcInstanceRepository{ + client: cli, + logger: logger, + } + return +} diff --git a/pkg/instance/repository_vpngw.go b/pkg/instance/repository_vpngw.go new file mode 100644 index 0000000..ca3347f --- /dev/null +++ b/pkg/instance/repository_vpngw.go @@ -0,0 +1,93 @@ +package instance + +import ( + "fmt" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + + "github.com/tencentyun/tencentcloud-exporter/pkg/client" + "github.com/tencentyun/tencentcloud-exporter/pkg/config" +) + +func init() { + registerRepository("QCE/VPNGW", NewVpngwTcInstanceRepository) +} + +type VpngwTcInstanceRepository struct { + client *sdk.Client + logger log.Logger +} + +func (repo *VpngwTcInstanceRepository) GetInstanceKey() string { + return "InstanceId" +} + +func (repo *VpngwTcInstanceRepository) Get(id string) (instance TcInstance, err error) { + req := sdk.NewDescribeVpnGatewaysRequest() + // req.Filters.Name = []*string{&id} + resp, err := repo.client.DescribeVpnGateways(req) + if err != nil { + return + } + if len(resp.Response.VpnGatewaySet) != 1 { + return nil, fmt.Errorf("Response instanceDetails size != 1, id=%s ", id) + } + meta := resp.Response.VpnGatewaySet[0] + instance, err = NewVpngwTcInstance(id, meta) + if err != nil { + return + } + return +} + +func (repo *VpngwTcInstanceRepository) ListByIds(id []string) (instances []TcInstance, err error) { + return +} + +func (repo *VpngwTcInstanceRepository) ListByFilters(filters map[string]string) (instances []TcInstance, err error) { + req := sdk.NewDescribeVpnGatewaysRequest() + var offset uint64 = 0 + var limit uint64 = 100 + var total int64 = -1 + + req.Offset = &offset + req.Limit = &limit + +getMoreInstances: + resp, err := repo.client.DescribeVpnGateways(req) + if err != nil { + return + } + if total == -1 { + total = int64(*resp.Response.TotalCount) + } + for _, meta := range resp.Response.VpnGatewaySet { + ins, e := NewVpngwTcInstance(*meta.VpnGatewayId, meta) + if e != nil { + level.Error(repo.logger).Log("msg", "Create vpngw instance fail", "id", *meta.VpnGatewayId) + continue + } + instances = append(instances, ins) + } + offset += limit + if offset < uint64(total) { + req.Offset = &offset + goto getMoreInstances + } + + return +} + +func NewVpngwTcInstanceRepository(c *config.TencentConfig, logger log.Logger) (repo TcInstanceRepository, err error) { + cli, err := client.NewVpvClient(c) + if err != nil { + return + } + repo = &VpngwTcInstanceRepository{ + client: cli, + logger: logger, + } + return +} diff --git a/pkg/instance/repository_vpnx.go b/pkg/instance/repository_vpnx.go new file mode 100644 index 0000000..55dfc88 --- /dev/null +++ b/pkg/instance/repository_vpnx.go @@ -0,0 +1,93 @@ +package instance + +import ( + "fmt" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + + "github.com/tencentyun/tencentcloud-exporter/pkg/client" + "github.com/tencentyun/tencentcloud-exporter/pkg/config" +) + +func init() { + registerRepository("QCE/VPNX", NewVpnxTcInstanceRepository) +} + +type VpnxTcInstanceRepository struct { + client *sdk.Client + logger log.Logger +} + +func (repo *VpnxTcInstanceRepository) GetInstanceKey() string { + return "InstanceId" +} + +func (repo *VpnxTcInstanceRepository) Get(id string) (instance TcInstance, err error) { + req := sdk.NewDescribeVpnConnectionsRequest() + // req.Filters.Name = []*string{&id} + resp, err := repo.client.DescribeVpnConnections(req) + if err != nil { + return + } + if len(resp.Response.VpnConnectionSet) != 1 { + return nil, fmt.Errorf("Response instanceDetails size != 1, id=%s ", id) + } + meta := resp.Response.VpnConnectionSet[0] + instance, err = NewVpnxTcInstance(id, meta) + if err != nil { + return + } + return +} + +func (repo *VpnxTcInstanceRepository) ListByIds(id []string) (instances []TcInstance, err error) { + return +} + +func (repo *VpnxTcInstanceRepository) ListByFilters(filters map[string]string) (instances []TcInstance, err error) { + req := sdk.NewDescribeVpnConnectionsRequest() + var offset uint64 = 0 + var limit uint64 = 100 + var total int64 = -1 + + req.Offset = &offset + req.Limit = &limit + +getMoreInstances: + resp, err := repo.client.DescribeVpnConnections(req) + if err != nil { + return + } + if total == -1 { + total = int64(*resp.Response.TotalCount) + } + for _, meta := range resp.Response.VpnConnectionSet { + ins, e := NewVpnxTcInstance(*meta.VpnConnectionId, meta) + if e != nil { + level.Error(repo.logger).Log("msg", "Create vpnx instance fail", "id", *meta.VpnConnectionId) + continue + } + instances = append(instances, ins) + } + offset += limit + if offset < uint64(total) { + req.Offset = &offset + goto getMoreInstances + } + + return +} + +func NewVpnxTcInstanceRepository(c *config.TencentConfig, logger log.Logger) (repo TcInstanceRepository, err error) { + cli, err := client.NewVpvClient(c) + if err != nil { + return + } + repo = &VpnxTcInstanceRepository{ + client: cli, + logger: logger, + } + return +} diff --git a/pkg/metric/sample.go b/pkg/metric/sample.go index 507f973..9783b18 100644 --- a/pkg/metric/sample.go +++ b/pkg/metric/sample.go @@ -23,7 +23,7 @@ func (s *TcmSamples) GetLatestPoint() (point *TcmSample, err error) { if len(s.Samples) == 1 { return s.Samples[0], nil } else { - return s.Samples[len(s.Samples)-2], nil + return s.Samples[len(s.Samples)-1], nil } } diff --git a/qcloud_exporter b/qcloud_exporter new file mode 100755 index 0000000..c9d7979 Binary files /dev/null and b/qcloud_exporter differ