feat(region): add ecloud monitor metric

This commit is contained in:
zhaoxiangchun
2021-04-15 18:11:41 +08:00
parent 1e05d5e997
commit 1883e72597
4 changed files with 194 additions and 24 deletions
+9 -24
View File
@@ -215,6 +215,14 @@ func (ec *SEcloudClient) doList(ctx context.Context, r IRequest, result interfac
}
func (ec *SEcloudClient) request(ctx context.Context, r IRequest) (jsonutils.JSONObject, error) {
jrbody, err := ec.doRequest(ctx, r)
if err != nil {
return nil, err
}
return r.ForMateResponseBody(jrbody)
}
func (ec *SEcloudClient) doRequest(ctx context.Context, r IRequest) (jsonutils.JSONObject, error) {
// sign
ec.completeSingParams(r)
signature := ec.signer.Sign(ec.buildStringToSign(r), "BC_SIGNATURE&")
@@ -263,30 +271,7 @@ func (ec *SEcloudClient) request(ctx context.Context, r IRequest) (jsonutils.JSO
return nil, errors.Wrapf(err, "unable to parsing json: %s", rbody)
}
}
if !jrbody.Contains("state") {
return nil, ErrMissKey{
Key: "state",
Jo: jrbody,
}
}
state, _ := jrbody.GetString("state")
switch state {
case "OK":
if !jrbody.Contains("body") {
return nil, ErrMissKey{
Key: "body",
Jo: jrbody,
}
}
body, _ := jrbody.Get("body")
return body, nil
default:
if jrbody.Contains("errorMessage") {
msg, _ := jrbody.GetString("errorMessage")
return nil, &httputils.JSONClientError{Code: 400, Details: msg}
}
return nil, &httputils.JSONClientError{Code: 400, Details: jrbody.String()}
}
return jrbody, nil
}
type ErrMissKey struct {
+135
View File
@@ -0,0 +1,135 @@
package ecloud
import (
"context"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/timeutils"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/httperrors"
)
const (
MONITOR_FETCH_REQUEST_ACTION = "v1.dawn.monitor.fetch"
MONITOR_PRODUCT_REQUEST_ACTION = "v1.dawn.monitor.products"
MONITOR_FETCH_SERVER_PATH = "/api/edw/edw/api"
REQUEST_SUCCESS_CODE = "000000"
)
var (
noMetricRegion = []string{"guangzhou-2", "beijing-1", "hunan-1"}
portRegionMap = map[string][]string{
"8443": []string{"wuxi-1", "dongguan-1", "yaan-1", "zhengzhou-1", "beijing-2", "zhuzhou-1", "jinan-1",
"xian-1", "shanghai-1", "chongqing-1", "ningbo-1"},
"18080": []string{"tianjin-1", "jilin-1", "hubei-1", "jiangxi-1", "gansu-1", "shanxi-1", "liaoning-1",
"yunnan-2", "hebei-1", "fujian-1", "guangxi-1", "anhui-1", "huhehaote-1", "guiyang-1"},
}
)
type Metric struct {
Name string `json:"MetricName"`
}
type MetricData struct {
Entitys []Entity `json:"entity"`
}
type Entity struct {
ResourceID string `json:"resourceId"`
MetricName string `json:"metricName"`
MetricNameCN string `json:"metricNameCn"`
Unit string `json:"unit"`
MaxValue int64 `json:"maxValue"`
AvgValue int64 `json:"avgValue"`
MinValue int64 `json:"minValue"`
Granularity string `json:"granularity"`
PolymerizeType string `json:"polymerizeType"`
SelectedMetricItem interface{} `json:"selectedMetricItem"`
MetricItems interface{} `json:"metricItems"`
IsChildnode bool `json:"isChildnode"`
Datapoints []Datapoint `json:"datapoints"`
}
type Datapoint []string
type SMonitorRequest struct {
SApiRequest
}
func NewMonitorRequest(regionId string, serverPath string, query map[string]string, data jsonutils.JSONObject) *SMonitorRequest {
apiRequest := NewApiRequest(regionId, serverPath, query, data)
return &SMonitorRequest{*apiRequest}
}
func (rr *SMonitorRequest) GetPort() string {
for port, regions := range portRegionMap {
if utils.IsInStringArray(rr.GetRegionId(), regions) {
return port
}
}
return "8443"
}
func (br *SMonitorRequest) ForMateResponseBody(jrbody jsonutils.JSONObject) (jsonutils.JSONObject, error) {
code, _ := jrbody.GetString("code")
if code != REQUEST_SUCCESS_CODE {
message, _ := jrbody.(*jsonutils.JSONDict).GetString("message")
return nil, httperrors.NewBadRequestError("rep body code is :%s, message:%s,body:%v", code, message, jrbody)
}
if jrbody == nil || !jrbody.Contains("entity") {
return nil, ErrMissKey{
Key: "entity",
Jo: jrbody,
}
}
return jrbody, nil
}
func (r *SRegion) DescribeMetricList(productType string, metrics []Metric, resourceId string,
since time.Time, until time.Time) (MetricData, error) {
metricData := MetricData{
Entitys: make([]Entity, 0),
}
if utils.IsInStringArray(r.GetId(), noMetricRegion) {
return metricData, httperrors.NewInputParameterError("region:%s no support pull metric at the moment", r.GetName())
}
if metrics == nil || len(metrics) == 0 {
return metricData, httperrors.NewInputParameterError("metrics is empty")
}
params := map[string]string{
"eAction": MONITOR_FETCH_REQUEST_ACTION,
}
getBody := jsonutils.NewDict()
getBody.Set("startTime", jsonutils.NewString(since.Format(timeutils.MysqlTimeFormat)))
getBody.Set("endTime", jsonutils.NewString(until.Format(timeutils.MysqlTimeFormat)))
getBody.Set("productType", jsonutils.NewString(productType))
getBody.Set("resourceId", jsonutils.NewString(resourceId))
getBody.Set("metrics", jsonutils.Marshal(&metrics))
request := NewMonitorRequest(r.ID, MONITOR_FETCH_SERVER_PATH, params, getBody)
err := r.client.doGet(context.Background(), request, &metricData)
if err != nil {
return metricData, errors.Wrap(err, "client doGet error")
}
return metricData, nil
}
func (r *SRegion) GetProductTypes() (jsonutils.JSONObject, error) {
params := map[string]string{
"eAction": MONITOR_PRODUCT_REQUEST_ACTION,
}
request := NewMonitorRequest(r.ID, MONITOR_FETCH_SERVER_PATH, params, nil)
rtn := jsonutils.NewDict()
err := r.client.doGet(context.Background(), request, rtn)
if err != nil {
return nil, errors.Wrap(err, "client doGet error")
}
return rtn, nil
}
+30
View File
@@ -22,6 +22,8 @@ import (
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/util/httputils"
)
type IRequest interface {
@@ -42,6 +44,7 @@ type IRequest interface {
GetHTTPSInsecure() bool
SetHTTPSInsecure(bool)
GetUserAgent() map[string]string
ForMateResponseBody(jrbody jsonutils.JSONObject) (jsonutils.JSONObject, error)
}
type SJSONRequest struct {
@@ -225,3 +228,30 @@ func (br *SBaseRequest) SetHTTPSInsecure(isInsecure bool) {
func (br *SBaseRequest) GetUserAgent() map[string]string {
return nil
}
func (br *SBaseRequest) ForMateResponseBody(jrbody jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if jrbody == nil || !jrbody.Contains("state") {
return nil, ErrMissKey{
Key: "state",
Jo: jrbody,
}
}
state, _ := jrbody.GetString("state")
switch state {
case "OK":
if !jrbody.Contains("body") {
return nil, ErrMissKey{
Key: "body",
Jo: jrbody,
}
}
body, _ := jrbody.Get("body")
return body, nil
default:
if jrbody.Contains("errorMessage") {
msg, _ := jrbody.GetString("errorMessage")
return nil, &httputils.JSONClientError{Code: 400, Details: msg}
}
return nil, &httputils.JSONClientError{Code: 400, Details: jrbody.String()}
}
}
+20
View File
@@ -0,0 +1,20 @@
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/ecloud"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type PListOptions struct {
}
shellutils.R(&PListOptions{}, "server-producttype-list", "List productTypes", func(cli *ecloud.SRegion,
args *PListOptions) error {
prod, e := cli.GetProductTypes()
if e != nil {
return e
}
printObject(prod)
return nil
})
}