Skip to content

Commit

Permalink
[CES] Reimplement Alarm Rules v1 API (#381)
Browse files Browse the repository at this point in the history
[CES] Reimplement Alarm Rules v1 API

What this PR does / why we need it
Implement Alarm Rules v1 API
Which issue this PR fixes
fixes #378
Special notes for your reviewer
=== RUN   TestAlarms
--- PASS: TestAlarms (1.93s)
PASS

Reviewed-by: Anton Sidelnikov <None>
Reviewed-by: Aloento <None>
Reviewed-by: Anton Kachurin <None>
  • Loading branch information
Aloento committed Aug 12, 2022
1 parent 357238e commit 12350de
Show file tree
Hide file tree
Showing 10 changed files with 295 additions and 211 deletions.
61 changes: 61 additions & 0 deletions acceptance/openstack/ces/v1/alarms_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package v1

import (
"testing"

"github.com/opentelekomcloud/gophertelekomcloud/acceptance/clients"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/ces/v1/alarms"
th "github.com/opentelekomcloud/gophertelekomcloud/testhelper"
)

func TestAlarms(t *testing.T) {
client, err := clients.NewCesV1Client()
th.AssertNoErr(t, err)

alarmsRes, err := alarms.ListAlarms(client, alarms.ListAlarmsOpts{
Limit: 10,
Order: "desc",
})

th.AssertNoErr(t, err)
th.AssertEquals(t, alarmsRes.MetaData.Count <= 10, true)

f := false
newAlarm, err := alarms.CreateAlarm(client, alarms.CreateAlarmOpts{
AlarmName: "alarm-acc-test",
Metric: alarms.MetricForAlarm{
Namespace: "SYS.VPC",
MetricName: "upstream_bandwidth",
Dimensions: []alarms.MetricsDimension{
{
Name: "bandwidth_id",
Value: "026c495c-fake-test-8b11-a113ba530d11",
},
},
},
Condition: alarms.Condition{
ComparisonOperator: ">=",
Count: 3,
Filter: "average",
Period: 300,
Value: 4000000,
},
AlarmEnabled: &f,
AlarmActionEnabled: &f,
})
th.AssertNoErr(t, err)

t.Cleanup(func() {
err = alarms.DeleteAlarm(client, newAlarm)
th.AssertNoErr(t, err)
})

err = alarms.UpdateAlarmAction(client, newAlarm, alarms.ModifyAlarmActionRequest{
AlarmEnabled: true,
})
th.AssertNoErr(t, err)

showAlarm, err := alarms.ShowAlarm(client, newAlarm)
th.AssertNoErr(t, err)
th.AssertEquals(t, showAlarm[0].AlarmEnabled, true)
}
62 changes: 62 additions & 0 deletions openstack/ces/v1/alarms/create_alarm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package alarms

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
)

type CreateAlarmOpts struct {
// Specifies the alarm rule name.
// Enter 1 to 128 characters. Only letters, digits, underscores (_), and hyphens (-) are allowed.
AlarmName string `json:"alarm_name"`
// Provides supplementary information about the alarm rule. Enter 0 to 256 characters.
AlarmDescription string `json:"alarm_description,omitempty"`
// Specifies the alarm metric.
Metric MetricForAlarm `json:"metric"`
// Specifies the alarm triggering condition.
Condition Condition `json:"condition"`
// Specifies whether to enable the alarm.
AlarmEnabled *bool `json:"alarm_enabled,omitempty"`
// Specifies whether to enable the action to be triggered by an alarm. The default value is true.
AlarmActionEnabled *bool `json:"alarm_action_enabled,omitempty"`
// Specifies the alarm severity. Possible values are 1, 2 (default), 3 and 4,
// indicating critical, major, minor, and informational, respectively.
AlarmLevel int `json:"alarm_level,omitempty"`
// Specifies the action to be triggered by an alarm.
AlarmActions []AlarmActions `json:"alarm_actions,omitempty"`
// Specifies the action to be triggered after the alarm is cleared.
OkActions []AlarmActions `json:"ok_actions,omitempty"`
}

type MetricForAlarm struct {
// Specifies the namespace of a service.
// The value must be in the service.item format and can contain 3 to 32 characters.
// service and item each must start with a letter and contain only letters, digits, and underscores (_).
Namespace string `json:"namespace"`
// Specifies the metric name.
// Start with a letter. Enter 1 to 64 characters. Only letters, digits, and underscores (_) are allowed.
MetricName string `json:"metric_name"`
// Specifies the list of metric dimensions.
Dimensions []MetricsDimension `json:"dimensions,omitempty"`
// Specifies the resource group ID selected during the alarm rule creation.
ResourceGroupId string `json:"resource_group_id,omitempty"`
}

func CreateAlarm(client *golangsdk.ServiceClient, opts CreateAlarmOpts) (string, error) {
reqBody, err := golangsdk.BuildRequestBody(opts, "")
if err != nil {
return "", err
}

// POST /V1.0/{project_id}/alarms
raw, err := client.Post(client.ServiceURL("alarms"), reqBody, nil, nil)
if err != nil {
return "", err
}

var s struct {
AlarmId string `json:"alarm_id"`
}
err = extract.Into(raw.Body, &s)
return s.AlarmId, err
}
9 changes: 9 additions & 0 deletions openstack/ces/v1/alarms/delete_alarm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package alarms

import golangsdk "github.com/opentelekomcloud/gophertelekomcloud"

func DeleteAlarm(client *golangsdk.ServiceClient, id string) (err error) {
// DELETE /V1.0/{project_id}/alarms/{alarm_id}
_, err = client.Delete(client.ServiceURL("alarms", id), nil)
return
}
36 changes: 36 additions & 0 deletions openstack/ces/v1/alarms/list_alarms.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package alarms

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
)

type ListAlarmsOpts struct {
// The value ranges from 1 to 100, and is 100 by default.
// This parameter is used to limit the number of query results.
Limit int `q:"limit"`
// Specifies the result sorting method, which is sorted by timestamp.
// The default value is desc.
// asc: The query results are displayed in the ascending order.
// desc: The query results are displayed in the descending order.
Order string `q:"order"`
// Specifies the first queried alarm to be displayed on a page.
Start string `q:"start"`
}

func ListAlarms(client *golangsdk.ServiceClient, opts ListAlarmsOpts) (*ListAlarmsResponse, error) {
query, err := golangsdk.BuildQueryString(opts)
if err != nil {
return nil, err
}

// GET /V1.0/{project_id}/alarms
raw, err := client.Get(client.ServiceURL("alarms")+query.String(), nil, nil)
if err != nil {
return nil, err
}

var s ListAlarmsResponse
err = extract.Into(raw.Body, &s)
return &s, err
}
88 changes: 88 additions & 0 deletions openstack/ces/v1/alarms/results.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package alarms

type ListAlarmsResponse struct {
MetricAlarms []MetricAlarms `json:"metric_alarms,omitempty"`
MetaData MetaData `json:"meta_data,omitempty"`
}

type MetaData struct {
Count int `json:"count"`
Total int `json:"total"`
Marker string `json:"marker"`
}

type MetricAlarms struct {
// Specifies the alarm rule name.
AlarmName string `json:"alarm_name"`
// Provides supplementary information about the alarm rule.
AlarmDescription string `json:"alarm_description,omitempty"`
// Specifies the alarm metric.
Metric MetricForAlarm `json:"metric"`
// Specifies the alarm triggering condition.
Condition Condition `json:"condition"`
// Specifies whether to enable the alarm rule.
AlarmEnabled bool `json:"alarm_enabled,omitempty"`
// Specifies the alarm severity. Possible values are 1, 2, 3 and 4, indicating critical, major, minor, and informational, respectively.
AlarmLevel int `json:"alarm_level,omitempty"`
// Specifies whether to enable the action to be triggered by an alarm.
AlarmActionEnabled bool `json:"alarm_action_enabled,omitempty"`
// Specifies the action to be triggered by an alarm.
AlarmActions []AlarmActions `json:"alarm_actions,omitempty"`
// Specifies the action to be triggered after the alarm is cleared.
OkActions []AlarmActions `json:"ok_actions,omitempty"`
// Specifies the alarm rule ID.
AlarmId string `json:"alarm_id"`
// Specifies when the alarm status changed. The value is a UNIX timestamp and the unit is ms.
UpdateTime int64 `json:"update_time"`
// Specifies the alarm status. The value can be:
//
// ok: The alarm status is normal.
// alarm: An alarm is generated.
// insufficient_data: The required data is insufficient.
AlarmState string `json:"alarm_state"`
}

type MetricsDimension struct {
// Specifies the dimension. For example, the ECS dimension is instance_id.
Name string `json:"name"`
// Specifies the dimension value, for example, an ECS ID.
Value string `json:"value"`
}

type Condition struct {
// Specifies the operator of alarm thresholds. Possible values are >, =, <, >=, and <=.
ComparisonOperator string `json:"comparison_operator"`
// Specifies the number of consecutive occurrence times that the alarm policy was met.
// The value ranges from 1 to 5.
Count int `json:"count"`
// Specifies the data rollup method. The following methods are supported:
//
// average: Cloud Eye calculates the average value of metric data within a rollup period.
// max: Cloud Eye calculates the maximum value of metric data within a rollup period.
// min: Cloud Eye calculates the minimum value of metric data within a rollup period.
// sum: Cloud Eye calculates the sum of metric data within a rollup period.
// variance: Cloud Eye calculates the variance value of metric data within a rollup period.
Filter string `json:"filter"`
// Specifies the interval (seconds) for checking whether the configured alarm rules are met.
Period int `json:"period"`
// Specifies the data unit. Enter up to 32 characters.
Unit string `json:"unit,omitempty"`
// Specifies the alarm threshold. The value ranges from 0 to Number. MAX_VALUE (1.7976931348623157e+108).
//
// For detailed thresholds, see the value range of each metric in the appendix.
// For example, you can set ECS cpu_util in Services Interconnected with Cloud Eye to 80.
Value float64 `json:"value"`
}

type AlarmActions struct {
// Specifies the alarm notification type.
// notification: indicates that a notification will be sent.
// autoscaling: indicates that a scaling action will be triggered.
Type string `json:"type"`
// Specifies the list of objects to be notified if the alarm status changes.
// You can configure up to 5 object IDs. You can obtain the topicUrn value from SMN in the following format:
// urn:smn:([a-z]|[A-Z]|[0-9]|\-){1,32}:([a-z]|[A-Z]|[0-9]){32}:([a-z]|[A-Z]|[0-9]|\-|\_){1,256}.
// If you set type to notification, you must specify notificationList.
// If you set type to autoscaling, you must set notificationList to [].
NotificationList []string `json:"notificationList"`
}
18 changes: 18 additions & 0 deletions openstack/ces/v1/alarms/show_alarm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package alarms

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
)

func ShowAlarm(client *golangsdk.ServiceClient, id string) ([]MetricAlarms, error) {
// GET /V1.0/{project_id}/alarms/{alarm_id}
raw, err := client.Get(client.ServiceURL("alarms", id), nil, nil)
if err != nil {
return nil, err
}

var res []MetricAlarms
err = extract.IntoSlicePtr(raw.Body, &res, "metric_alarms")
return res, err
}
21 changes: 21 additions & 0 deletions openstack/ces/v1/alarms/update_alarm_action.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package alarms

import golangsdk "github.com/opentelekomcloud/gophertelekomcloud"

type ModifyAlarmActionRequest struct {
// Specifies whether the alarm rule is enabled.
AlarmEnabled bool `json:"alarm_enabled"`
}

func UpdateAlarmAction(client *golangsdk.ServiceClient, id string, req ModifyAlarmActionRequest) (err error) {
reqBody, err := golangsdk.BuildRequestBody(req, "")
if err != nil {
return
}

// PUT /V1.0/{project_id}/alarms/{alarm_id}/action
_, err = client.Put(client.ServiceURL("alarms", id, "action"), reqBody, nil, &golangsdk.RequestOpts{
OkCodes: []int{204},
})
return
}

0 comments on commit 12350de

Please sign in to comment.