Skip to content

Commit 5c3e7aa

Browse files
[CES]: v2 dashboards and one click alarms (#905)
1 parent fa9e018 commit 5c3e7aa

File tree

13 files changed

+741
-0
lines changed

13 files changed

+741
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package v2
2+
3+
import (
4+
"testing"
5+
6+
"github.com/opentelekomcloud/gophertelekomcloud/acceptance/clients"
7+
"github.com/opentelekomcloud/gophertelekomcloud/openstack/ces/v2/dashboards"
8+
th "github.com/opentelekomcloud/gophertelekomcloud/testhelper"
9+
)
10+
11+
func TestDashboardsCRUD(t *testing.T) {
12+
client, err := clients.NewCesV2Client()
13+
th.AssertNoErr(t, err)
14+
15+
t.Log("Attempting to create dashboard")
16+
dashboardId, err := dashboards.Create(client, dashboards.CreateOpts{
17+
DashboardName: "test-dashboard-acc",
18+
})
19+
th.AssertNoErr(t, err)
20+
t.Logf("Created dashboard: %s", dashboardId)
21+
22+
t.Log("Attempting to copy dashboard")
23+
copyDashboardId, err := dashboards.Create(client, dashboards.CreateOpts{
24+
DashboardName: "test-dashboard-copy-acc",
25+
DashboardId: dashboardId,
26+
})
27+
th.AssertNoErr(t, err)
28+
t.Logf("Copied dashboard: %s", copyDashboardId)
29+
30+
t.Cleanup(func() {
31+
t.Log("Attempting to batch delete dashboards")
32+
results, err := dashboards.BatchDelete(client, dashboards.BatchDeleteOpts{
33+
DashboardIds: []string{dashboardId, copyDashboardId},
34+
})
35+
th.AssertNoErr(t, err)
36+
for _, result := range results {
37+
t.Logf("Delete result: ID=%s, Status=%s", result.DashboardId, result.RetStatus)
38+
}
39+
})
40+
41+
t.Log("Attempting to list dashboards")
42+
dashboardsList, err := dashboards.List(client, dashboards.ListOpts{})
43+
th.AssertNoErr(t, err)
44+
t.Logf("Found %d dashboards", len(dashboardsList))
45+
46+
found := 0
47+
for _, d := range dashboardsList {
48+
if d.DashboardId == dashboardId || d.DashboardId == copyDashboardId {
49+
found++
50+
t.Logf("Dashboard: ID=%s, Name=%s, Creator=%s",
51+
d.DashboardId, d.DashboardName, d.CreatorName)
52+
}
53+
}
54+
th.AssertEquals(t, found, 2)
55+
56+
t.Log("Attempting to modify dashboard")
57+
err = dashboards.Update(client, dashboardId, dashboards.UpdateOpts{
58+
DashboardName: "test-dashboard-updated-acc",
59+
})
60+
th.AssertNoErr(t, err)
61+
62+
t.Log("Attempting to verify dashboard update")
63+
dashboardsList, err = dashboards.List(client, dashboards.ListOpts{
64+
DashboardId: dashboardId,
65+
})
66+
th.AssertNoErr(t, err)
67+
th.AssertEquals(t, len(dashboardsList), 1)
68+
th.AssertEquals(t, dashboardsList[0].DashboardName, "test-dashboard-updated-acc")
69+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package v2
2+
3+
import (
4+
"testing"
5+
6+
"github.com/opentelekomcloud/gophertelekomcloud/acceptance/clients"
7+
"github.com/opentelekomcloud/gophertelekomcloud/openstack/ces/v2/oneclickalarms"
8+
th "github.com/opentelekomcloud/gophertelekomcloud/testhelper"
9+
)
10+
11+
func TestOneClickAlarmsList(t *testing.T) {
12+
client, err := clients.NewCesV2Client()
13+
th.AssertNoErr(t, err)
14+
15+
t.Log("Attempting to list one-click alarms")
16+
alarmsList, err := oneclickalarms.List(client)
17+
th.AssertNoErr(t, err)
18+
t.Logf("Found %d one-click alarms", len(alarmsList))
19+
}
20+
21+
func TestOneClickAlarmsCRUD(t *testing.T) {
22+
client, err := clients.NewCesV2Client()
23+
th.AssertNoErr(t, err)
24+
25+
t.Log("Attempting to enable one-click monitoring for ECS")
26+
createOpts := oneclickalarms.CreateOpts{
27+
OneClickAlarmId: "ECSSystemOneClickAlarm",
28+
DimensionNames: oneclickalarms.DimensionNames{
29+
Metric: []string{"instance_id"},
30+
Event: []string{},
31+
},
32+
NotificationEnabled: false,
33+
}
34+
35+
oneClickAlarmId, err := oneclickalarms.Create(client, createOpts)
36+
th.AssertNoErr(t, err)
37+
t.Logf("Enabled one-click monitoring: %s", oneClickAlarmId)
38+
39+
t.Cleanup(func() {
40+
t.Log("Attempting to disable one-click monitoring")
41+
_, err := oneclickalarms.BatchDelete(client, oneclickalarms.BatchDeleteOpts{
42+
OneClickAlarmIds: []string{oneClickAlarmId},
43+
})
44+
th.AssertNoErr(t, err)
45+
})
46+
47+
t.Log("Attempting to list one-click alarms to verify creation")
48+
alarmsList, err := oneclickalarms.List(client)
49+
th.AssertNoErr(t, err)
50+
51+
found := false
52+
for _, alarm := range alarmsList {
53+
if alarm.OneClickAlarmId == oneClickAlarmId && alarm.Enabled {
54+
found = true
55+
t.Logf("Found enabled one-click alarm: %s, Namespace: %s", alarm.OneClickAlarmId, alarm.Namespace)
56+
break
57+
}
58+
}
59+
th.AssertEquals(t, found, true)
60+
61+
t.Log("Attempting to get alarm rules for one-click monitoring")
62+
alarmRules, err := oneclickalarms.ListAlarmRules(client, oneClickAlarmId)
63+
th.AssertNoErr(t, err)
64+
t.Logf("Found %d alarm rules", len(alarmRules))
65+
th.AssertEquals(t, len(alarmRules) > 0, true)
66+
67+
alarmRule := alarmRules[0]
68+
t.Logf("First alarm rule: ID=%s, Name=%s, Enabled=%v",
69+
alarmRule.AlarmId, alarmRule.Name, alarmRule.Enabled)
70+
71+
t.Log("Attempting to disable alarm rule")
72+
_, err = oneclickalarms.BatchEnableAlarmRules(client, oneClickAlarmId, oneclickalarms.BatchEnableAlarmRulesOpts{
73+
AlarmIds: []string{alarmRule.AlarmId},
74+
AlarmEnabled: false,
75+
})
76+
th.AssertNoErr(t, err)
77+
78+
t.Log("Attempting to enable alarm rule")
79+
_, err = oneclickalarms.BatchEnableAlarmRules(client, oneClickAlarmId, oneclickalarms.BatchEnableAlarmRulesOpts{
80+
AlarmIds: []string{alarmRule.AlarmId},
81+
AlarmEnabled: true,
82+
})
83+
th.AssertNoErr(t, err)
84+
85+
th.AssertEquals(t, len(alarmRule.Policies) > 0, true)
86+
policy := alarmRule.Policies[0]
87+
t.Logf("First policy: ID=%s, MetricName=%s, Enabled=%v",
88+
policy.AlarmPolicyId, policy.MetricName, policy.Enabled)
89+
90+
t.Log("Attempting to disable alarm policy")
91+
_, err = oneclickalarms.BatchEnablePolicies(client, oneClickAlarmId, alarmRule.AlarmId, oneclickalarms.BatchEnablePoliciesOpts{
92+
AlarmPolicyIds: []string{policy.AlarmPolicyId},
93+
Enabled: false,
94+
})
95+
th.AssertNoErr(t, err)
96+
97+
t.Log("Attempting to enable alarm policy")
98+
_, err = oneclickalarms.BatchEnablePolicies(client, oneClickAlarmId, alarmRule.AlarmId, oneclickalarms.BatchEnablePoliciesOpts{
99+
AlarmPolicyIds: []string{policy.AlarmPolicyId},
100+
Enabled: true,
101+
})
102+
th.AssertNoErr(t, err)
103+
104+
t.Log("Attempting to update notifications")
105+
err = oneclickalarms.UpdateNotifications(client, oneClickAlarmId, oneclickalarms.UpdateNotificationsOpts{
106+
NotificationEnabled: false,
107+
NotificationBeginTime: "00:00",
108+
NotificationEndTime: "23:59",
109+
})
110+
th.AssertNoErr(t, err)
111+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package dashboards
2+
3+
import (
4+
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
5+
"github.com/opentelekomcloud/gophertelekomcloud/internal/build"
6+
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
7+
)
8+
9+
// BatchDeleteOpts contains the options for batch deleting dashboards.
10+
type BatchDeleteOpts struct {
11+
// Specifies the list of dashboard IDs to delete.
12+
// A maximum of 30 dashboard IDs are supported.
13+
DashboardIds []string `json:"dashboard_ids,omitempty"`
14+
}
15+
16+
// BatchDeleteResult represents the result of deleting a single dashboard.
17+
type BatchDeleteResult struct {
18+
// Specifies the dashboard ID.
19+
DashboardId string `json:"dashboard_id"`
20+
// Specifies the deletion result.
21+
// Possible values: successful, error
22+
RetStatus string `json:"ret_status"`
23+
// Specifies the error message if deletion failed.
24+
ErrorMsg string `json:"error_msg,omitempty"`
25+
}
26+
27+
// BatchDelete batch deletes dashboards.
28+
func BatchDelete(client *golangsdk.ServiceClient, opts BatchDeleteOpts) ([]BatchDeleteResult, error) {
29+
b, err := build.RequestBody(opts, "")
30+
if err != nil {
31+
return nil, err
32+
}
33+
34+
// POST /v2/{project_id}/dashboards/batch-delete
35+
raw, err := client.Post(client.ServiceURL("dashboards", "batch-delete"), b, nil, &golangsdk.RequestOpts{
36+
OkCodes: []int{200},
37+
})
38+
if err != nil {
39+
return nil, err
40+
}
41+
42+
var res struct {
43+
Dashboards []BatchDeleteResult `json:"dashboards"`
44+
}
45+
err = extract.Into(raw.Body, &res)
46+
return res.Dashboards, err
47+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package dashboards
2+
3+
import (
4+
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
5+
"github.com/opentelekomcloud/gophertelekomcloud/internal/build"
6+
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
7+
)
8+
9+
// CreateOpts contains the options for creating or copying a dashboard.
10+
type CreateOpts struct {
11+
// Specifies the dashboard name.
12+
// It can contain 1 to 128 characters.
13+
// Only letters, digits, underscores (_), hyphens (-), and Chinese characters are allowed.
14+
DashboardName string `json:"dashboard_name" required:"true"`
15+
// Specifies the enterprise project ID.
16+
// The value can be a UUID or "0".
17+
EnterpriseId string `json:"enterprise_id,omitempty"`
18+
// Specifies the dashboard ID to copy from.
19+
// If this parameter is specified, the dashboard is copied.
20+
// The value starts with "db" and is followed by 22 characters.
21+
DashboardId string `json:"dashboard_id,omitempty"`
22+
// Specifies how many graphs will be displayed in each row.
23+
// Possible values: 0, 1, 2, 3. Default: 0
24+
// 0 indicates auto layout.
25+
RowWidgetNum *int `json:"row_widget_num,omitempty"`
26+
}
27+
28+
// Create creates a new dashboard or copies an existing one.
29+
func Create(client *golangsdk.ServiceClient, opts CreateOpts) (string, error) {
30+
b, err := build.RequestBody(opts, "")
31+
if err != nil {
32+
return "", err
33+
}
34+
35+
// POST /v2/{project_id}/dashboards
36+
raw, err := client.Post(client.ServiceURL("dashboards"), b, nil, &golangsdk.RequestOpts{
37+
OkCodes: []int{201},
38+
})
39+
if err != nil {
40+
return "", err
41+
}
42+
43+
var res struct {
44+
DashboardId string `json:"dashboard_id"`
45+
}
46+
err = extract.Into(raw.Body, &res)
47+
return res.DashboardId, err
48+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package dashboards
2+
3+
import (
4+
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
5+
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
6+
)
7+
8+
// ListOpts contains the options for querying dashboards.
9+
type ListOpts struct {
10+
// Specifies whether to filter by favorite status.
11+
// This parameter requires enterprise_id to be specified.
12+
IsFavorite *bool `q:"is_favorite,omitempty"`
13+
// Specifies the dashboard name for filtering.
14+
// It can contain 1 to 128 characters.
15+
DashboardName string `q:"dashboard_name,omitempty"`
16+
// Specifies the dashboard ID for filtering.
17+
// The value starts with "db" and is followed by 22 characters.
18+
DashboardId string `q:"dashboard_id,omitempty"`
19+
// Specifies the enterprise project ID.
20+
EnterpriseId string `q:"enterprise_id,omitempty"`
21+
}
22+
23+
// Dashboard represents a dashboard in the list response.
24+
type Dashboard struct {
25+
// Specifies the dashboard ID.
26+
DashboardId string `json:"dashboard_id"`
27+
// Specifies the dashboard name.
28+
DashboardName string `json:"dashboard_name"`
29+
// Specifies the enterprise project ID.
30+
EnterpriseId string `json:"enterprise_id"`
31+
// Specifies the name of the user who created the dashboard.
32+
CreatorName string `json:"creator_name"`
33+
// Specifies the time when the dashboard was created.
34+
// The value is a UNIX timestamp in milliseconds.
35+
CreateTime int64 `json:"create_time"`
36+
// Specifies how many graphs will be displayed in each row.
37+
// Possible values: 0, 1, 2, 3. Default: 3
38+
RowWidgetNum int `json:"row_widget_num"`
39+
// Specifies whether the dashboard is a favorite.
40+
IsFavorite bool `json:"is_favorite"`
41+
}
42+
43+
// List queries dashboards.
44+
func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Dashboard, error) {
45+
url, err := golangsdk.NewURLBuilder().
46+
WithEndpoints("dashboards").
47+
WithQueryParams(&opts).
48+
Build()
49+
if err != nil {
50+
return nil, err
51+
}
52+
53+
// GET /v2/{project_id}/dashboards
54+
raw, err := client.Get(client.ServiceURL(url.String()), nil, &golangsdk.RequestOpts{
55+
MoreHeaders: map[string]string{"Content-Type": "application/json"},
56+
})
57+
if err != nil {
58+
return nil, err
59+
}
60+
61+
var res struct {
62+
Dashboards []Dashboard `json:"dashboards"`
63+
}
64+
err = extract.Into(raw.Body, &res)
65+
return res.Dashboards, err
66+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package dashboards
2+
3+
import (
4+
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
5+
"github.com/opentelekomcloud/gophertelekomcloud/internal/build"
6+
)
7+
8+
// UpdateOpts contains the options for modifying a dashboard.
9+
type UpdateOpts struct {
10+
// Specifies the dashboard name.
11+
// It can contain 1 to 128 characters.
12+
// Only letters, digits, underscores (_), hyphens (-), and Chinese characters are allowed.
13+
DashboardName string `json:"dashboard_name,omitempty"`
14+
// Specifies whether the dashboard is a favorite.
15+
IsFavorite *bool `json:"is_favorite,omitempty"`
16+
// Specifies how many graphs will be displayed in each row.
17+
// Possible values: 0, 1, 2, 3. Default: 3
18+
// 0 indicates auto layout.
19+
RowWidgetNum *int `json:"row_widget_num,omitempty"`
20+
}
21+
22+
// Update modifies a dashboard.
23+
func Update(client *golangsdk.ServiceClient, dashboardId string, opts UpdateOpts) error {
24+
b, err := build.RequestBody(opts, "")
25+
if err != nil {
26+
return err
27+
}
28+
29+
// PUT /v2/{project_id}/dashboards/{dashboard_id}
30+
_, err = client.Put(client.ServiceURL("dashboards", dashboardId), b, nil, &golangsdk.RequestOpts{
31+
OkCodes: []int{204},
32+
})
33+
return err
34+
}

0 commit comments

Comments
 (0)