Skip to content

Commit d469e63

Browse files
authored
Merge pull request #1584 from ioito/hotfix/qx-ksyun-metric
fix(ksyun): metric data
2 parents ad68a79 + 3588e5a commit d469e63

File tree

2 files changed

+86
-28
lines changed

2 files changed

+86
-28
lines changed

pkg/multicloud/ksyun/ksyun.go

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const (
4747
KSYUN_DEFAULT_API_VERSION = "2016-03-04"
4848
KSYUN_RDS_API_VERSION = "2016-07-01"
4949
KSYUN_SKS_API_VERSION = "2015-11-01"
50-
KSYUN_MONITOR_API_VERSION = "2023-07-12"
50+
KSYUN_MONITOR_API_VERSION = "2018-11-14"
5151
)
5252

5353
type KsyunClientConfig struct {
@@ -137,7 +137,7 @@ func (cli *SKsyunClient) getUrl(service, regionId string) (string, error) {
137137
case "kec", "tag", "krds":
138138
return fmt.Sprintf("https://%s.%s.api.ksyun.com", service, regionId), nil
139139
case "monitor":
140-
return fmt.Sprintf("https://%s.api.ksyun.com/v4/", service), nil
140+
return fmt.Sprintf("https://%s.api.ksyun.com", service), nil
141141
}
142142
return "", errors.Wrapf(cloudprovider.ErrNotSupported, "service %s", service)
143143
}
@@ -233,21 +233,27 @@ func (cli *SKsyunClient) Do(req *http.Request) (*http.Response, error) {
233233
client := cli.getDefaultClient()
234234
req.Header.Set("Accept", "application/json")
235235

236-
if req.Method == "POST" {
236+
if req.Method == "POST" || req.Method == "PUT" || req.Method == "DELETE" && req.Body != nil {
237237
cred := credentials.NewStaticCredentials(cli.accessKeyId, cli.accessKeySecret, "")
238238
sig := v4.NewSigner(cred)
239-
sig.DisableRequestBodyOverwrite = false
240239
var body io.ReadSeeker = nil
241-
if req.Body != nil {
242-
bodyBytes, err := io.ReadAll(req.Body)
243-
if err != nil {
244-
return nil, errors.Wrapf(err, "ReadAll")
245-
}
246-
req.Header.Set("Content-Length", fmt.Sprintf("%d", len(bodyBytes)))
247-
req.ContentLength = int64(len(bodyBytes))
248-
req.Body = io.NopCloser(bytes.NewReader(bodyBytes))
249-
body = bytes.NewReader(bodyBytes)
240+
bodyBytes, err := io.ReadAll(req.Body)
241+
if err != nil {
242+
return nil, errors.Wrapf(err, "ReadAll")
243+
}
244+
body = bytes.NewReader(bodyBytes)
245+
246+
v4Req, err := http.NewRequestWithContext(cli.ctx, req.Method, req.URL.String(), body)
247+
if err != nil {
248+
return nil, errors.Wrapf(err, "NewRequestWithContext")
250249
}
250+
v4Req.Header.Set("Accept", "application/json")
251+
v4Req.Header.Set("X-Amz-Date", time.Now().UTC().Format("20060102T150405Z"))
252+
v4Req.Header.Set("Content-Type", req.Header.Get("Content-Type"))
253+
v4Req.Header.Set("Host", req.URL.Host)
254+
v4Req.Header.Set("User-Agent", req.Header.Get("User-Agent"))
255+
v4Req.ContentLength = int64(len(bodyBytes))
256+
251257
service, regionId := "", KSYUN_DEFAULT_REGION
252258
urlInfo := strings.Split(req.URL.Host, ".")
253259
if len(urlInfo) < 2 {
@@ -257,11 +263,11 @@ func (cli *SKsyunClient) Do(req *http.Request) (*http.Response, error) {
257263
if urlInfo[1] != "api" {
258264
regionId = urlInfo[1]
259265
}
260-
_, err := sig.Sign(req, body, service, regionId, time.Now())
266+
_, err = sig.Sign(v4Req, body, service, regionId, time.Now())
261267
if err != nil {
262268
return nil, errors.Wrapf(err, "sign")
263269
}
264-
return client.Do(req)
270+
return client.Do(v4Req)
265271
}
266272

267273
signature, err := cli.sign(req)
@@ -324,14 +330,16 @@ func (cli *SKsyunClient) request(service, regionId, apiName, apiVersion string,
324330
values := url.Values{}
325331
values.Set("Action", apiName)
326332
values.Set("Version", apiVersion)
333+
values.Set("Service", service)
327334

328335
method := httputils.GET
329-
if service == "monitor" {
336+
if apiName == "GetMetricStatisticsBatch" {
330337
method = httputils.POST
331-
} else {
338+
}
339+
340+
if method == httputils.GET {
332341
values.Set("Accesskey", cli.accessKeyId)
333342
values.Set("SignatureMethod", "HMAC-SHA256")
334-
values.Set("Service", service)
335343
values.Set("Format", "json")
336344
values.Set("SignatureVersion", "1.0")
337345
values.Set("Timestamp", time.Now().UTC().Format("2006-01-02T15:04:05Z"))

pkg/multicloud/ksyun/monitor.go

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package ksyun
1616

1717
import (
18+
"time"
19+
1820
"yunion.io/x/cloudmux/pkg/cloudprovider"
1921
"yunion.io/x/jsonutils"
2022
"yunion.io/x/log"
@@ -34,23 +36,36 @@ func (cli *SKsyunClient) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cl
3436
}
3537
}
3638

39+
type SMetric struct {
40+
Instance string
41+
Datapoints struct {
42+
Member []struct {
43+
Average float64
44+
Timestamp time.Time
45+
UnixTimestamp int64
46+
}
47+
}
48+
Label string
49+
}
50+
3751
func (cli *SKsyunClient) GetEcsMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
3852
params := map[string]interface{}{
3953
"Namespace": "KEC",
4054
"StartTime": opts.StartTime.Format("2006-01-02T15:04:05Z"),
4155
"EndTime": opts.EndTime.Format("2006-01-02T15:04:05Z"),
42-
"Period": "60",
4356
"Aggregate": []string{"Average"},
4457
"Metrics": []map[string]interface{}{
4558
{
46-
"Dimensions": []map[string]interface{}{
47-
{
48-
"Name": "instance_id",
49-
"Value": opts.ResourceId,
50-
},
51-
},
5259
"InstanceID": opts.ResourceId,
53-
"MetricName": "vm.memory.size[pavailable]",
60+
"MetricName": "cpu.utilizition.total",
61+
},
62+
{
63+
"InstanceID": opts.ResourceId,
64+
"MetricName": "memory.utilizition.total",
65+
},
66+
{
67+
"InstanceID": opts.ResourceId,
68+
"MetricName": "vfs.fs.size",
5469
},
5570
},
5671
}
@@ -59,6 +74,41 @@ func (cli *SKsyunClient) GetEcsMetrics(opts *cloudprovider.MetricListOptions) ([
5974
if err != nil {
6075
return nil, err
6176
}
62-
log.Errorf("DescribeMetricData %s", resp.PrettyString())
63-
return []cloudprovider.MetricValues{}, nil
77+
78+
metrics := struct {
79+
GetMetricStatisticsBatchResults []SMetric
80+
}{}
81+
82+
err = resp.Unmarshal(&metrics)
83+
if err != nil {
84+
return nil, err
85+
}
86+
ret := []cloudprovider.MetricValues{}
87+
for _, metric := range metrics.GetMetricStatisticsBatchResults {
88+
values := []cloudprovider.MetricValue{}
89+
for _, value := range metric.Datapoints.Member {
90+
values = append(values, cloudprovider.MetricValue{
91+
Timestamp: value.Timestamp,
92+
Value: value.Average,
93+
})
94+
}
95+
metricValue := cloudprovider.MetricValues{
96+
Id: metric.Instance,
97+
Values: values,
98+
}
99+
switch metric.Label {
100+
case "cpu.utilizition.total":
101+
metricValue.MetricType = cloudprovider.VM_METRIC_TYPE_CPU_USAGE
102+
case "memory.utilizition.total":
103+
metricValue.MetricType = cloudprovider.VM_METRIC_TYPE_MEM_USAGE
104+
case "vfs.fs.size":
105+
metricValue.MetricType = cloudprovider.VM_METRIC_TYPE_DISK_USAGE
106+
default:
107+
log.Errorf("invalid metric label %s", metric.Label)
108+
continue
109+
}
110+
ret = append(ret, metricValue)
111+
}
112+
113+
return ret, nil
64114
}

0 commit comments

Comments
 (0)