From 780de0e4292c712d5d67bf00028318c0b808f1c3 Mon Sep 17 00:00:00 2001 From: arunma Date: Mon, 22 Aug 2022 22:27:57 +0800 Subject: [PATCH 1/4] feat: add resource cluster agent --- tencentcloud/provider.go | 2 + ...source_tc_monitor_tmp_tke_cluster_agent.go | 348 ++++++++++++++++++ tencentcloud/service_tencentcloud_tke.go | 85 +++++ ...onitor_tmp_tke_cluster_agent.html.markdown | 65 ++++ website/tencentcloud.erb | 9 +- 5 files changed, 506 insertions(+), 3 deletions(-) create mode 100644 tencentcloud/resource_tc_monitor_tmp_tke_cluster_agent.go create mode 100644 website/docs/r/monitor_tmp_tke_cluster_agent.html.markdown diff --git a/tencentcloud/provider.go b/tencentcloud/provider.go index 400e208fa3..830c115eef 100644 --- a/tencentcloud/provider.go +++ b/tencentcloud/provider.go @@ -438,6 +438,7 @@ Monitor tencentcloud_monitor_alarm_notice tencentcloud_monitor_tmp_tke_record_rule_yaml tencentcloud_monitor_tmp_tke_global_notification + tencentcloud_monitor_tmp_tke_cluster_agent PostgreSQL Data Source @@ -1101,6 +1102,7 @@ func Provider() terraform.ResourceProvider { "tencentcloud_monitor_tmp_recording_rule": resourceTencentCloudMonitorTmpRecordingRule(), "tencentcloud_monitor_tmp_tke_template": resourceTencentCloudMonitorTmpTkeTemplate(), "tencentcloud_monitor_tmp_tke_alert_policy": resourceTencentCloudMonitorTmpTkeAlertPolicy(), + "tencentcloud_monitor_tmp_tke_cluster_agent": resourceTencentCloudMonitorTmpTkeClusterAgent(), "tencentcloud_monitor_tmp_tke_config": resourceTencentCloudMonitorTmpTkeConfig(), "tencentcloud_monitor_tmp_tke_record_rule_yaml": resourceTencentCloudMonitorTmpTkeRecordRuleYaml(), "tencentcloud_monitor_tmp_tke_global_notification": resourceTencentCloudMonitorTmpTkeGlobalNotification(), diff --git a/tencentcloud/resource_tc_monitor_tmp_tke_cluster_agent.go b/tencentcloud/resource_tc_monitor_tmp_tke_cluster_agent.go new file mode 100644 index 0000000000..a53fe67292 --- /dev/null +++ b/tencentcloud/resource_tc_monitor_tmp_tke_cluster_agent.go @@ -0,0 +1,348 @@ +/* +Provides a resource to create a tmp tke cluster agent + +Example Usage + +```hcl + +resource "tencentcloud_monitor_tmp_tke_cluster_agent" "tmpClusterAgent" { + instance_id = "prom-xxx" + + agents { + region = "ap-xxx" + cluster_type = "eks" + cluster_id = "cls-xxx" + enable_external = false + } +} + +*/ +package tencentcloud + +import ( + "context" + "fmt" + "log" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + tke "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tke/v20180525" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func resourceTencentCloudMonitorTmpTkeClusterAgent() *schema.Resource { + return &schema.Resource{ + Read: resourceTencentCloudMonitorTmpTkeClusterAgentRead, + Create: resourceTencentCloudMonitorTmpTkeClusterAgentCreate, + Delete: resourceTencentCloudMonitorTmpTkeClusterAgentDelete, + Schema: map[string]*schema.Schema{ + "instance_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Instance Id.", + }, + + "agents": { + Type: schema.TypeList, + MaxItems: 1, + Required: true, + ForceNew: true, + Description: "agent list.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Required: true, + Description: "Limitation of region.", + }, + "cluster_type": { + Type: schema.TypeString, + Required: true, + Description: "Type of cluster.", + }, + "cluster_id": { + Type: schema.TypeString, + Required: true, + Description: "An id identify the cluster, like `cls-xxxxxx`.", + }, + "enable_external": { + Type: schema.TypeBool, + Required: true, + Description: "Whether to enable the public network CLB.", + }, + "in_cluster_pod_config": { + Type: schema.TypeMap, + Optional: true, + Description: "Pod configuration for components deployed in the cluster.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "host_net": { + Type: schema.TypeBool, + Required: true, + Description: "Whether to use HostNetWork.", + }, + "node_selector": { + Type: schema.TypeList, + Optional: true, + Description: "Specify the pod to run the node.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + Description: "The pod configuration name of the component deployed in the cluster.", + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: "Pod configuration values for components deployed in the cluster.", + }, + }, + }, + }, + "tolerations": { + Type: schema.TypeList, + Optional: true, + Description: "Tolerate Stain.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Optional: true, + Description: "The taint key to which the tolerance applies.", + }, + "operator": { + Type: schema.TypeString, + Optional: true, + Description: "key-value relationship.", + }, + "effect": { + Type: schema.TypeString, + Optional: true, + Description: "blemish effect to match.", + }, + }, + }, + }, + }, + }, + }, + "external_labels": { + Type: schema.TypeList, + Optional: true, + Description: "All metrics collected by the cluster will carry these labels.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Indicator name.", + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: "Index value.", + }, + }, + }, + }, + "not_install_basic_scrape": { + Type: schema.TypeBool, + Optional: true, + Description: "Whether to install the default collection configuration.", + }, + "not_scrape": { + Type: schema.TypeBool, + Optional: true, + Description: "Whether to collect indicators, true means drop all indicators, false means collect default indicators.", + }, + }, + }, + }, + }, + } +} + +func resourceTencentCloudMonitorTmpTkeClusterAgentCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_monitor_tmp_tke_global_notification.create")() + defer inconsistentCheck(d, meta)() + + logId := getLogId(contextNil) + + request := tke.NewCreatePrometheusClusterAgentRequest() + + instanceId := "" + if v, ok := d.GetOk("instance_id"); ok { + instanceId = v.(string) + request.InstanceId = helper.String(v.(string)) + } + + clusterId := "" + clusterType := "" + if dMap, ok := helper.InterfacesHeadMap(d, "agents"); ok { + prometheusClusterAgent := tke.PrometheusClusterAgentBasic{} + if v, ok := dMap["region"]; ok { + prometheusClusterAgent.Region = helper.String(v.(string)) + } + if v, ok := dMap["cluster_type"]; ok { + clusterType = v.(string) + prometheusClusterAgent.ClusterType = helper.String(v.(string)) + } + if v, ok := dMap["cluster_id"]; ok { + clusterId = v.(string) + prometheusClusterAgent.ClusterId = helper.String(v.(string)) + } + if v, ok := dMap["enable_external"]; ok { + prometheusClusterAgent.EnableExternal = helper.Bool(v.(bool)) + } + if v, ok := dMap["in_cluster_pod_config"]; ok { + podConfig := v.(map[string]interface{}) + var clusterAgentPodConfig *tke.PrometheusClusterAgentPodConfig + if vv, ok := podConfig["host_net"]; ok { + clusterAgentPodConfig.HostNet = helper.Bool(vv.(bool)) + } + if vv, ok := podConfig["node_selector"]; ok { + labelsList := vv.([]interface{}) + nodeSelectorKV := make([]*tke.Label, 0, len(labelsList)) + for _, labels := range labelsList { + label := labels.(map[string]interface{}) + var kv tke.Label + kv.Name = helper.String(label["name"].(string)) + kv.Value = helper.String(label["value"].(string)) + nodeSelectorKV = append(nodeSelectorKV, &kv) + } + clusterAgentPodConfig.NodeSelector = nodeSelectorKV + } + if vv, ok := podConfig["tolerations"]; ok { + tolerationList := vv.([]interface{}) + tolerations := make([]*tke.Toleration, 0, len(tolerationList)) + for _, t := range tolerationList { + tolerationMap := t.(map[string]interface{}) + var toleration tke.Toleration + toleration.Key = helper.String(tolerationMap["key"].(string)) + toleration.Operator = helper.String(tolerationMap["operator"].(string)) + toleration.Effect = helper.String(tolerationMap["effect"].(string)) + tolerations = append(tolerations, &toleration) + } + clusterAgentPodConfig.Tolerations = tolerations + } + prometheusClusterAgent.InClusterPodConfig = clusterAgentPodConfig + } + if v, ok := dMap["external_labels"]; ok { + labelsList := v.([]interface{}) + externalKV := make([]*tke.Label, 0, len(labelsList)) + for _, labels := range labelsList { + label := labels.(map[string]interface{}) + var kv tke.Label + kv.Name = helper.String(label["name"].(string)) + kv.Value = helper.String(label["value"].(string)) + externalKV = append(externalKV, &kv) + } + prometheusClusterAgent.ExternalLabels = externalKV + } + if v, ok := dMap["not_install_basic_scrape"]; ok { + prometheusClusterAgent.NotInstallBasicScrape = helper.Bool(v.(bool)) + } + if v, ok := dMap["not_scrape"]; ok { + prometheusClusterAgent.NotScrape = helper.Bool(v.(bool)) + } + var prometheusClusterAgents []*tke.PrometheusClusterAgentBasic + prometheusClusterAgents = append(prometheusClusterAgents, &prometheusClusterAgent) + request.Agents = prometheusClusterAgents + } + + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseTkeClient().CreatePrometheusClusterAgent(request) + if e != nil { + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s create tke cluster agent failed, reason:%+v", logId, err) + return err + } + + d.SetId(strings.Join([]string{instanceId, clusterId, clusterType}, FILED_SP)) + + return resourceTencentCloudMonitorTmpTkeClusterAgentRead(d, meta) +} + +func resourceTencentCloudMonitorTmpTkeClusterAgentRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_monitor_tmp_tke_global_notification.read")() + defer inconsistentCheck(d, meta)() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), logIdKey, logId) + + service := TkeService{client: meta.(*TencentCloudClient).apiV3Conn} + + ids := strings.Split(d.Id(), FILED_SP) + if len(ids) != 3 { + return fmt.Errorf("id is broken, id is %s", d.Id()) + } + + instanceId := ids[0] + clusterId := ids[1] + clusterType := ids[2] + + clusterAgent, err := service.DescribeTmpTkeClusterAgentsById(ctx, instanceId, clusterId, clusterType) + + if err != nil { + return err + } + + if clusterAgent == nil { + d.SetId("") + return fmt.Errorf("resource `global_notification` %s does not exist", instanceId) + } + + _ = d.Set("cluster_id", clusterAgent.ClusterId) + _ = d.Set("cluster_type", clusterAgent.ClusterType) + _ = d.Set("status", clusterAgent.Status) + _ = d.Set("cluster_name", clusterAgent.ClusterName) + if clusterAgent.ExternalLabels != nil { + clusterAgentList := clusterAgent.ExternalLabels + result := make([]map[string]interface{}, 0, len(clusterAgentList)) + for _, v := range clusterAgentList { + mapping := map[string]interface{}{ + "name": v.Name, + "value": v.Value, + } + result = append(result, mapping) + } + _ = d.Set("external_labels", result) + } + + return nil +} + +func resourceTencentCloudMonitorTmpTkeClusterAgentDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_monitor_tmp_tke_global_notification.delete")() + defer inconsistentCheck(d, meta)() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), logIdKey, logId) + service := TkeService{client: meta.(*TencentCloudClient).apiV3Conn} + + ids := strings.Split(d.Id(), FILED_SP) + if len(ids) != 3 { + return fmt.Errorf("id is broken, id is %s", d.Id()) + } + + instanceId := ids[0] + clusterId := ids[1] + clusterType := ids[2] + + if err := service.DeletePrometheusClusterAgent(ctx, instanceId, clusterId, clusterType); err != nil { + return err + } + + return nil +} diff --git a/tencentcloud/service_tencentcloud_tke.go b/tencentcloud/service_tencentcloud_tke.go index 543943d0b4..145d184bb5 100644 --- a/tencentcloud/service_tencentcloud_tke.go +++ b/tencentcloud/service_tencentcloud_tke.go @@ -1989,6 +1989,8 @@ func (me *TkeService) DeletePrometheusRecordRuleYaml(ctx context.Context, id, na logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) return err } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) return } @@ -2087,3 +2089,86 @@ func (me *TkeService) ModifyTkeTmpGlobalNotification(ctx context.Context, instan return } + +func (me *TkeService) DescribeTmpTkeClusterAgentsById(ctx context.Context, instanceId, clusterId, clusterType string) (agents *tke.PrometheusAgentOverview, errRet error) { + var ( + logId = getLogId(ctx) + request = tke.NewDescribePrometheusClusterAgentsRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, "query object", request.ToJsonString(), errRet.Error()) + } + }() + + request.InstanceId = &instanceId + ratelimit.Check(request.GetAction()) + + var offset uint64 = 0 + var pageSize uint64 = 100 + + for { + request.Offset = &offset + request.Limit = &pageSize + ratelimit.Check(request.GetAction()) + response, err := me.client.UseTkeClient().DescribePrometheusClusterAgents(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.Agents) < 1 { + break + } + for _, v := range response.Response.Agents { + if *v.ClusterId == clusterId && *v.ClusterType == clusterType { + return v, nil + } + } + if len(response.Response.Agents) < int(pageSize) { + break + } + offset += pageSize + } + + return +} + +func (me *TkeService) DeletePrometheusClusterAgent(ctx context.Context, instanceId, clusterId, clusterType string) (errRet error) { + logId := getLogId(ctx) + request := tke.NewDeletePrometheusClusterAgentRequest() + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + //request.InstanceId = &instanceId + //request.Agents = append( + // request.Agents, + // &tke.PrometheusClusterAgentBasic{ + // ClusterId: &clusterId, + // ClusterType: &clusterType, + // }, + //) + + ratelimit.Check(request.GetAction()) + response, err := me.client.UseTkeClient().DeletePrometheusClusterAgent(request) + if err != nil { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + return err + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + return +} diff --git a/website/docs/r/monitor_tmp_tke_cluster_agent.html.markdown b/website/docs/r/monitor_tmp_tke_cluster_agent.html.markdown new file mode 100644 index 0000000000..bc295a494d --- /dev/null +++ b/website/docs/r/monitor_tmp_tke_cluster_agent.html.markdown @@ -0,0 +1,65 @@ +--- +subcategory: "Monitor" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_monitor_tmp_tke_cluster_agent" +sidebar_current: "docs-tencentcloud-resource-monitor_tmp_tke_cluster_agent" +description: |- + Provides a resource to create a tmp tke cluster agent +--- + +# tencentcloud_monitor_tmp_tke_cluster_agent + +Provides a resource to create a tmp tke cluster agent + +## Example Usage + + + +## Argument Reference + +The following arguments are supported: + +* `agents` - (Required, List, ForceNew) agent list. +* `instance_id` - (Required, String, ForceNew) Instance Id. + +The `agents` object supports the following: + +* `cluster_id` - (Required, String) An id identify the cluster, like `cls-xxxxxx`. +* `cluster_type` - (Required, String) Type of cluster. +* `enable_external` - (Required, Bool) Whether to enable the public network CLB. +* `region` - (Required, String) Limitation of region. +* `external_labels` - (Optional, List) All metrics collected by the cluster will carry these labels. +* `in_cluster_pod_config` - (Optional, Map) Pod configuration for components deployed in the cluster. +* `not_install_basic_scrape` - (Optional, Bool) Whether to install the default collection configuration. +* `not_scrape` - (Optional, Bool) Whether to collect indicators, true means drop all indicators, false means collect default indicators. + +The `external_labels` object supports the following: + +* `name` - (Required, String) Indicator name. +* `value` - (Optional, String) Index value. + +The `in_cluster_pod_config` object supports the following: + +* `host_net` - (Required, Bool) Whether to use HostNetWork. +* `node_selector` - (Optional, List) Specify the pod to run the node. +* `tolerations` - (Optional, List) Tolerate Stain. + +The `node_selector` object supports the following: + +* `name` - (Optional, String) The pod configuration name of the component deployed in the cluster. +* `value` - (Optional, String) Pod configuration values for components deployed in the cluster. + +The `tolerations` object supports the following: + +* `effect` - (Optional, String) blemish effect to match. +* `key` - (Optional, String) The taint key to which the tolerance applies. +* `operator` - (Optional, String) key-value relationship. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the resource. + + + diff --git a/website/tencentcloud.erb b/website/tencentcloud.erb index f9e89dabaa..ef70e17add 100644 --- a/website/tencentcloud.erb +++ b/website/tencentcloud.erb @@ -1155,14 +1155,17 @@ tencentcloud_monitor_tmp_tke_alert_policy
  • - tencentcloud_monitor_tmp_tke_config + tencentcloud_monitor_tmp_tke_cluster_agent
  • - tencentcloud_monitor_tmp_tke_record_rule_yaml + tencentcloud_monitor_tmp_tke_config
  • tencentcloud_monitor_tmp_tke_global_notification
  • +
  • + tencentcloud_monitor_tmp_tke_record_rule_yaml +
  • tencentcloud_monitor_tmp_tke_template
  • @@ -1477,7 +1480,7 @@
  • TEM