Skip to content

Commit 54ff0c6

Browse files
authored
feat: add PrometheusRecordRule (#1207)
* feat: add PrometheusRecordRule * feat: add PrometheusRecordRule * fix: Fix specification issues * feat: Add test cases * feat: add PrometheusRecordRule * feat: add doc * fix: Modify config * fix: Modify field conf * fix: Modify field conf * fix: Modify ut * fix: Modify ut * fix: merge master * fix: Code structure adjustment * fix: modify provider Co-authored-by: arunma <arunma@tencent.com>
1 parent 9b8f8ca commit 54ff0c6

10 files changed

+541
-1
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,5 @@ require (
6868
github.com/yangwenmai/ratelimit v0.0.0-20180104140304-44221c2292e1
6969
github.com/zclconf/go-cty v1.4.2 // indirect
7070
golang.org/x/sys v0.0.0-20200523222454-059865788121 // indirect
71+
gopkg.in/yaml.v2 v2.2.8 // indirect
7172
)

tencentcloud/commom_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tencentcloud
22

33
import (
4+
"reflect"
45
"testing"
56

67
sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
@@ -127,3 +128,18 @@ func TestIsExpectError(t *testing.T) {
127128
assert.Equalf(t, isExpectError(err, unExpectedMatchHead), false, "")
128129
assert.Equalf(t, isExpectError(err, unExpectedShort), false, "")
129130
}
131+
132+
func TestYamlParser(t *testing.T) {
133+
yamlStr := `test`
134+
yaml, err := YamlParser(yamlStr)
135+
assert.Equalf(t, err != nil, true, "")
136+
assert.Equalf(t, yaml == nil, true, "")
137+
138+
yamlStr1 := `version: v1
139+
name: test-name
140+
desc: this is a description`
141+
yaml1, err1 := YamlParser(yamlStr1)
142+
assert.Equalf(t, err1, nil, "")
143+
assert.Equalf(t, reflect.TypeOf(yaml1).String(), "map[interface {}]interface {}", "")
144+
assert.Equalf(t, yaml1["name"], "test-name", "")
145+
}

tencentcloud/common.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
1919
"github.com/pkg/errors"
2020
sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
21+
"gopkg.in/yaml.v2"
2122
)
2223

2324
const FILED_SP = "#"
@@ -339,3 +340,12 @@ func (g *GoRoutineLimit) Run(f func()) {
339340
<-g.Chan
340341
}()
341342
}
343+
344+
// YamlParser yaml syntax Parser
345+
func YamlParser(config string) (map[interface{}]interface{}, error) {
346+
m := make(map[interface{}]interface{})
347+
if err := yaml.Unmarshal([]byte(config), &m); err != nil {
348+
return nil, err
349+
}
350+
return m, nil
351+
}

tencentcloud/provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ Monitor
436436
tencentcloud_monitor_tmp_tke_alert_policy
437437
tencentcloud_monitor_tmp_tke_config
438438
tencentcloud_monitor_alarm_notice
439+
tencentcloud_monitor_tmp_tke_record_rule_yaml
439440
440441
PostgreSQL
441442
Data Source
@@ -1100,6 +1101,7 @@ func Provider() terraform.ResourceProvider {
11001101
"tencentcloud_monitor_tmp_tke_template": resourceTencentCloudMonitorTmpTkeTemplate(),
11011102
"tencentcloud_monitor_tmp_tke_alert_policy": resourceTencentCloudMonitorTmpTkeAlertPolicy(),
11021103
"tencentcloud_monitor_tmp_tke_config": resourceTencentCloudMonitorTmpTkeConfig(),
1104+
"tencentcloud_monitor_tmp_tke_record_rule_yaml": resourceTencentCloudMonitorTmpTkeRecordRuleYaml(),
11031105
"tencentcloud_mongodb_standby_instance": resourceTencentCloudMongodbStandbyInstance(),
11041106
"tencentcloud_elasticsearch_instance": resourceTencentCloudElasticsearchInstance(),
11051107
"tencentcloud_postgresql_instance": resourceTencentCloudPostgresqlInstance(),
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
/*
2+
Provides a resource to create a tke tmpRecordRule
3+
4+
Example Usage
5+
6+
```hcl
7+
8+
resource "resourceTencentCloudMonitorTmpTkeRecordRuleYaml" "foo" {
9+
instance_id = ""
10+
content = <<-EOT
11+
apiVersion: monitoring.coreos.com/v1
12+
kind: PrometheusRule
13+
metadata:
14+
name: example-record
15+
spec:
16+
groups:
17+
- name: kube-apiserver.rules
18+
rules:
19+
- expr: sum(metrics_test)
20+
labels:
21+
verb: read
22+
record: 'apiserver_request:burnrate1d'
23+
EOT
24+
}
25+
26+
*/
27+
package tencentcloud
28+
29+
import (
30+
"context"
31+
"fmt"
32+
"log"
33+
"strings"
34+
35+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
36+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
37+
tke "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tke/v20180525"
38+
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
39+
)
40+
41+
func resourceTencentCloudMonitorTmpTkeRecordRuleYaml() *schema.Resource {
42+
return &schema.Resource{
43+
Read: resourceTencentCloudTkeTmpRecordRuleYamlRead,
44+
Create: resourceTencentCloudTkeTmpRecordRuleYamlCreate,
45+
Update: resourceTencentCloudTkeTmpRecordRuleYamlUpdate,
46+
Delete: resourceTencentCloudTkeTmpRecordRuleYamlDelete,
47+
//Importer: &schema.ResourceImporter{
48+
// State: schema.ImportStatePassthrough,
49+
//},
50+
Schema: map[string]*schema.Schema{
51+
"instance_id": {
52+
Type: schema.TypeString,
53+
Required: true,
54+
Description: "Instance Id.",
55+
},
56+
57+
"content": {
58+
Type: schema.TypeString,
59+
Required: true,
60+
ValidateFunc: validateYaml,
61+
Description: "Contents of record rules in yaml format.",
62+
},
63+
64+
"name": {
65+
Type: schema.TypeString,
66+
Computed: true,
67+
Description: "Name of the instance.",
68+
},
69+
70+
"update_time": {
71+
Type: schema.TypeString,
72+
Computed: true,
73+
Description: "Last modified time of record rule.",
74+
},
75+
76+
"template_id": {
77+
Type: schema.TypeString,
78+
Computed: true,
79+
Description: "Used for the argument, if the configuration comes to the template, the template id.",
80+
},
81+
82+
"cluster_id": {
83+
Type: schema.TypeString,
84+
Computed: true,
85+
Description: "An ID identify the cluster, like cls-xxxxxx.",
86+
},
87+
},
88+
}
89+
}
90+
91+
func resourceTencentCloudTkeTmpRecordRuleYamlCreate(d *schema.ResourceData, meta interface{}) error {
92+
defer logElapsed("resource.tencentcloud_monitor_tmp_tke_record_rule_yaml.create")()
93+
defer inconsistentCheck(d, meta)()
94+
95+
logId := getLogId(contextNil)
96+
97+
request := tke.NewCreatePrometheusRecordRuleYamlRequest()
98+
99+
if v, ok := d.GetOk("instance_id"); ok {
100+
request.InstanceId = helper.String(v.(string))
101+
}
102+
103+
tmpRecordRuleName := ""
104+
if v, ok := d.GetOk("content"); ok {
105+
m, _ := YamlParser(v.(string))
106+
metadata := m["metadata"]
107+
if metadata != nil {
108+
if metadata.(map[interface{}]interface{})["name"] != nil {
109+
tmpRecordRuleName = metadata.(map[interface{}]interface{})["name"].(string)
110+
}
111+
}
112+
request.Content = helper.String(v.(string))
113+
}
114+
115+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
116+
result, e := meta.(*TencentCloudClient).apiV3Conn.UseTkeClient().CreatePrometheusRecordRuleYaml(request)
117+
if e != nil {
118+
return retryError(e)
119+
} else {
120+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n",
121+
logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
122+
}
123+
return nil
124+
})
125+
126+
if err != nil {
127+
log.Printf("[CRITAL]%s create tke tmpRecordRule failed, reason:%+v", logId, err)
128+
return err
129+
}
130+
131+
instanceId := *request.InstanceId
132+
d.SetId(strings.Join([]string{instanceId, tmpRecordRuleName}, FILED_SP))
133+
return resourceTencentCloudTkeTmpRecordRuleYamlRead(d, meta)
134+
}
135+
136+
func resourceTencentCloudTkeTmpRecordRuleYamlRead(d *schema.ResourceData, meta interface{}) error {
137+
defer logElapsed("resource.tencentcloud_monitor_tmp_tke_record_rule_yaml.read")()
138+
defer inconsistentCheck(d, meta)()
139+
140+
logId := getLogId(contextNil)
141+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
142+
143+
ids := strings.Split(d.Id(), FILED_SP)
144+
if len(ids) != 2 {
145+
return fmt.Errorf("id is broken, id is %s", d.Id())
146+
}
147+
148+
instanceId := ids[0]
149+
name := ids[1]
150+
151+
recordRuleService := TkeService{client: meta.(*TencentCloudClient).apiV3Conn}
152+
request, err := recordRuleService.DescribePrometheusRecordRuleByName(ctx, instanceId, name)
153+
if err != nil {
154+
err = resource.Retry(readRetryTimeout, func() *resource.RetryError {
155+
request, err = recordRuleService.DescribePrometheusRecordRuleByName(ctx, instanceId, name)
156+
if err != nil {
157+
return retryError(err)
158+
}
159+
return nil
160+
})
161+
}
162+
if err != nil {
163+
return err
164+
}
165+
166+
recordRules := request.Response.Records
167+
if len(recordRules) == 0 {
168+
d.SetId("")
169+
return nil
170+
}
171+
172+
recordRule := recordRules[0]
173+
if recordRule == nil {
174+
return nil
175+
}
176+
_ = d.Set("instance_id", instanceId)
177+
_ = d.Set("name", recordRule.Name)
178+
_ = d.Set("update_time", recordRule.UpdateTime)
179+
_ = d.Set("template_id", recordRule.TemplateId)
180+
//_ = d.Set("content", recordRule.Content)
181+
_ = d.Set("cluster_id", recordRule.ClusterId)
182+
183+
return nil
184+
}
185+
186+
func resourceTencentCloudTkeTmpRecordRuleYamlUpdate(d *schema.ResourceData, meta interface{}) error {
187+
defer logElapsed("resource.tencentcloud_monitor_tmp_tke_record_rule_yaml.update")()
188+
defer inconsistentCheck(d, meta)()
189+
190+
logId := getLogId(contextNil)
191+
192+
request := tke.NewModifyPrometheusRecordRuleYamlRequest()
193+
194+
ids := strings.Split(d.Id(), FILED_SP)
195+
if len(ids) != 2 {
196+
return fmt.Errorf("id is broken, id is %s", d.Id())
197+
}
198+
199+
request.InstanceId = &ids[0]
200+
request.Name = &ids[1]
201+
202+
if d.HasChange("content") {
203+
if v, ok := d.GetOk("content"); ok {
204+
request.Content = helper.String(v.(string))
205+
206+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
207+
result, e := meta.(*TencentCloudClient).apiV3Conn.UseTkeClient().ModifyPrometheusRecordRuleYaml(request)
208+
if e != nil {
209+
return retryError(e)
210+
} else {
211+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n",
212+
logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
213+
}
214+
return nil
215+
})
216+
217+
if err != nil {
218+
return err
219+
}
220+
221+
return resourceTencentCloudTkeTmpRecordRuleYamlRead(d, meta)
222+
}
223+
}
224+
225+
return nil
226+
}
227+
228+
func resourceTencentCloudTkeTmpRecordRuleYamlDelete(d *schema.ResourceData, meta interface{}) error {
229+
defer logElapsed("resource.tencentcloud_monitor_tmp_tke_record_rule_yaml.delete")()
230+
defer inconsistentCheck(d, meta)()
231+
232+
logId := getLogId(contextNil)
233+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
234+
235+
ids := strings.Split(d.Id(), FILED_SP)
236+
if len(ids) != 2 {
237+
return fmt.Errorf("id is broken, id is %s", d.Id())
238+
}
239+
240+
service := TkeService{client: meta.(*TencentCloudClient).apiV3Conn}
241+
if err := service.DeletePrometheusRecordRuleYaml(ctx, ids[0], ids[1]); err != nil {
242+
return err
243+
}
244+
245+
return nil
246+
}

0 commit comments

Comments
 (0)