diff --git a/tencentcloud/resource_tc_address_template_group.go b/tencentcloud/resource_tc_address_template_group.go index b5831cb72b..9646e82ae9 100644 --- a/tencentcloud/resource_tc_address_template_group.go +++ b/tencentcloud/resource_tc_address_template_group.go @@ -6,7 +6,7 @@ Example Usage ```hcl resource "tencentcloud_address_template_group" "foo" { name = "group-test" - addresses = ["ipl-axaf24151","ipl-axaf24152"] + template_ids = ["ipl-axaf24151","ipl-axaf24152"] } ``` diff --git a/tencentcloud/resource_tc_clb_listener.go b/tencentcloud/resource_tc_clb_listener.go index 4631e30f24..7a776f84aa 100644 --- a/tencentcloud/resource_tc_clb_listener.go +++ b/tencentcloud/resource_tc_clb_listener.go @@ -526,11 +526,17 @@ func resourceTencentCloudClbListenerRead(d *schema.ResourceData, meta interface{ _ = d.Set("clb_id", clbId) _ = d.Set("listener_id", instance.ListenerId) - _ = d.Set("listener_name", instance.ListenerName) - _ = d.Set("target_type", instance.TargetType) _ = d.Set("port", instance.Port) _ = d.Set("protocol", instance.Protocol) - _ = d.Set("session_expire_time", instance.SessionExpireTime) + if instance.ListenerName != nil { + _ = d.Set("listener_name", instance.ListenerName) + } + if instance.TargetType != nil { + _ = d.Set("target_type", instance.TargetType) + } + if instance.SessionExpireTime != nil { + _ = d.Set("session_expire_time", instance.SessionExpireTime) + } if *instance.Protocol == CLB_LISTENER_PROTOCOL_TCP || *instance.Protocol == CLB_LISTENER_PROTOCOL_TCPSSL || *instance.Protocol == CLB_LISTENER_PROTOCOL_UDP { _ = d.Set("scheduler", instance.Scheduler) } @@ -543,20 +549,48 @@ func resourceTencentCloudClbListenerRead(d *schema.ResourceData, meta interface{ healthCheckSwitch = true } _ = d.Set("health_check_switch", healthCheckSwitch) - _ = d.Set("health_check_interval_time", instance.HealthCheck.IntervalTime) - _ = d.Set("health_check_time_out", instance.HealthCheck.TimeOut) - _ = d.Set("health_check_health_num", instance.HealthCheck.HealthNum) - _ = d.Set("health_check_unhealth_num", instance.HealthCheck.UnHealthNum) - _ = d.Set("health_check_port", instance.HealthCheck.CheckPort) - _ = d.Set("health_check_type", instance.HealthCheck.CheckType) - _ = d.Set("health_check_http_code", instance.HealthCheck.HttpCode) - _ = d.Set("health_check_http_path", instance.HealthCheck.HttpCheckPath) - _ = d.Set("health_check_http_domain", instance.HealthCheck.HttpCheckDomain) - _ = d.Set("health_check_http_method", instance.HealthCheck.HttpCheckMethod) - _ = d.Set("health_check_http_version", instance.HealthCheck.HttpVersion) - _ = d.Set("health_check_context_type", instance.HealthCheck.ContextType) - _ = d.Set("health_check_send_context", instance.HealthCheck.SendContext) - _ = d.Set("health_check_recv_context", instance.HealthCheck.RecvContext) + if instance.HealthCheck.IntervalTime != nil { + _ = d.Set("health_check_interval_time", instance.HealthCheck.IntervalTime) + } + if instance.HealthCheck.TimeOut != nil { + _ = d.Set("health_check_time_out", instance.HealthCheck.TimeOut) + } + if instance.HealthCheck.HealthNum != nil { + _ = d.Set("health_check_health_num", instance.HealthCheck.HealthNum) + } + if instance.HealthCheck.UnHealthNum != nil { + _ = d.Set("health_check_unhealth_num", instance.HealthCheck.UnHealthNum) + } + if instance.HealthCheck.CheckPort != nil { + _ = d.Set("health_check_port", instance.HealthCheck.CheckPort) + } + if instance.HealthCheck.CheckType != nil { + _ = d.Set("health_check_type", instance.HealthCheck.CheckType) + } + if instance.HealthCheck.HttpCode != nil { + _ = d.Set("health_check_http_code", instance.HealthCheck.HttpCode) + } + if instance.HealthCheck.HttpCheckPath != nil { + _ = d.Set("health_check_http_path", instance.HealthCheck.HttpCheckPath) + } + if instance.HealthCheck.HttpCheckDomain != nil { + _ = d.Set("health_check_http_domain", instance.HealthCheck.HttpCheckDomain) + } + if instance.HealthCheck.HttpCheckMethod != nil { + _ = d.Set("health_check_http_method", instance.HealthCheck.HttpCheckMethod) + } + if instance.HealthCheck.HttpVersion != nil { + _ = d.Set("health_check_http_version", instance.HealthCheck.HttpVersion) + } + if instance.HealthCheck.ContextType != nil { + _ = d.Set("health_check_context_type", instance.HealthCheck.ContextType) + } + if instance.HealthCheck.SendContext != nil { + _ = d.Set("health_check_send_context", instance.HealthCheck.SendContext) + } + if instance.HealthCheck.RecvContext != nil { + _ = d.Set("health_check_recv_context", instance.HealthCheck.RecvContext) + } } if instance.Certificate != nil { diff --git a/tencentcloud/resource_tc_kubernetes_cluster.go b/tencentcloud/resource_tc_kubernetes_cluster.go index 83eaaf3aa5..cc1173656c 100644 --- a/tencentcloud/resource_tc_kubernetes_cluster.go +++ b/tencentcloud/resource_tc_kubernetes_cluster.go @@ -2025,14 +2025,13 @@ func resourceTencentCloudTkeClusterCreate(d *schema.ResourceData, meta interface name := dMap["name"].(string) param := dMap["param"].(string) addon := &tke.ExtensionAddon{ - AddonName: helper.String(name), + AddonName: helper.String(name), AddonParam: helper.String(param), } extensionAddons = append(extensionAddons, addon) } } - service := TkeService{client: meta.(*TencentCloudClient).apiV3Conn} id, err := service.CreateCluster(ctx, basic, advanced, cvms, iAdvanced, cidrSet, tags, existInstances, &overrideSettings, iDiskMountSettings, extensionAddons) if err != nil { diff --git a/tencentcloud/resource_tc_security_group_lite_rule.go b/tencentcloud/resource_tc_security_group_lite_rule.go index 8f6cca523e..d317867a7f 100644 --- a/tencentcloud/resource_tc_security_group_lite_rule.go +++ b/tencentcloud/resource_tc_security_group_lite_rule.go @@ -17,6 +17,9 @@ resource "tencentcloud_security_group_lite_rule" "foo" { "ACCEPT#192.168.1.0/24#80#TCP", "DROP#8.8.8.8#80,90#UDP", "ACCEPT#0.0.0.0/0#80-90#TCP", + "ACCEPT#sg-7ixn3foj/0#80-90#TCP", + "ACCEPT#ipm-epjq5kn0/0#80-90#TCP", + "ACCEPT#ipmg-3loavam6/0#80-90#TCP", ] egress = [ @@ -65,13 +68,13 @@ func resourceTencentCloudSecurityGroupLiteRule() *schema.Resource { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, - Description: "Ingress rules set. A rule must match the following format: [action]#[cidr_ip]#[port]#[protocol]. The available value of 'action' is `ACCEPT` and `DROP`. The 'cidr_ip' must be an IP address network or segment. The 'port' valid format is `80`, `80,443`, `80-90` or `ALL`. The available value of 'protocol' is `TCP`, `UDP`, `ICMP` and `ALL`. When 'protocol' is `ICMP` or `ALL`, the 'port' must be `ALL`.", + Description: "Ingress rules set. A rule must match the following format: [action]#[source]#[port]#[protocol]. The available value of 'action' is `ACCEPT` and `DROP`. The 'source' can be an IP address network, segment, security group ID and Address Template ID. The 'port' valid format is `80`, `80,443`, `80-90` or `ALL`. The available value of 'protocol' is `TCP`, `UDP`, `ICMP` and `ALL`. When 'protocol' is `ICMP` or `ALL`, the 'port' must be `ALL`.", }, "egress": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, - Description: "Egress rules set. A rule must match the following format: [action]#[cidr_ip]#[port]#[protocol]. The available value of 'action' is `ACCEPT` and `DROP`. The 'cidr_ip' must be an IP address network or segment. The 'port' valid format is `80`, `80,443`, `80-90` or `ALL`. The available value of 'protocol' is `TCP`, `UDP`, `ICMP` and `ALL`. When 'protocol' is `ICMP` or `ALL`, the 'port' must be `ALL`.", + Description: "Egress rules set. A rule must match the following format: [action]#[source]#[port]#[protocol]. The available value of 'action' is `ACCEPT` and `DROP`. The 'source' can be an IP address network, segment, security group ID and Address Template ID. The 'port' valid format is `80`, `80,443`, `80-90` or `ALL`. The available value of 'protocol' is `TCP`, `UDP`, `ICMP` and `ALL`. When 'protocol' is `ICMP` or `ALL`, the 'port' must be `ALL`.", }, }, } diff --git a/tencentcloud/resource_tc_security_group_lite_rule_test.go b/tencentcloud/resource_tc_security_group_lite_rule_test.go index ed1daa1a7d..34f388da67 100644 --- a/tencentcloud/resource_tc_security_group_lite_rule_test.go +++ b/tencentcloud/resource_tc_security_group_lite_rule_test.go @@ -124,6 +124,22 @@ func TestAccTencentCloudSecurityGroupLiteRule_update(t *testing.T) { resource.TestCheckResourceAttr("tencentcloud_security_group_lite_rule.foo", "egress.#", "0"), ), }, + { + Config: testAccSecurityGroupLiteRuleUpdate6, + Check: resource.ComposeTestCheckFunc( + testAccCheckSecurityGroupLiteRuleExists("tencentcloud_security_group_lite_rule.foo", &liteRuleId), + resource.TestCheckResourceAttrSet("tencentcloud_security_group_lite_rule.foo", "security_group_id"), + resource.TestCheckResourceAttr("tencentcloud_security_group_lite_rule.foo", "ingress.#", "5"), + resource.TestCheckResourceAttrSet("tencentcloud_security_group_lite_rule.foo", "ingress.0"), + resource.TestCheckResourceAttrSet("tencentcloud_security_group_lite_rule.foo", "ingress.1"), + resource.TestCheckResourceAttr("tencentcloud_security_group_lite_rule.foo", "ingress.2", "ACCEPT#0.0.0.0/0#80-90#TCP"), + resource.TestCheckResourceAttr("tencentcloud_security_group_lite_rule.foo", "ingress.3", "DROP#8.8.8.8#80,90#UDP"), + resource.TestCheckResourceAttrSet("tencentcloud_security_group_lite_rule.foo", "ingress.4"), + resource.TestCheckResourceAttr("tencentcloud_security_group_lite_rule.foo", "egress.#", "2"), + resource.TestCheckResourceAttr("tencentcloud_security_group_lite_rule.foo", "egress.0", "ACCEPT#192.168.0.0/16#ALL#TCP"), + resource.TestCheckResourceAttrSet("tencentcloud_security_group_lite_rule.foo", "egress.1"), + ), + }, }, }) } @@ -274,3 +290,42 @@ resource "tencentcloud_security_group_lite_rule" "foo" { security_group_id = tencentcloud_security_group.foo.id } ` +const testAccSecurityGroupLiteRuleUpdate6 = ` +resource "tencentcloud_security_group" "foo" { + name = "ci-temp-test-sg" +} + +resource "tencentcloud_security_group" "group1" { + name = "tf-test-sec" +} + +resource "tencentcloud_address_template" "addr-foo" { + name = "tf-test-addr" + addresses = ["10.0.0.1", "10.0.1.0/24", "10.0.0.1-10.0.0.100"] +} + +resource "tencentcloud_address_template" "addr-bar" { + name = "cam-user-test" + addresses = ["10.0.2.1", "10.0.3.0/24"] +} + +resource "tencentcloud_address_template_group" "foo" { + name = "group-test" + template_ids = [tencentcloud_address_template.addr-foo.id, tencentcloud_address_template.addr-bar.id] +} + +resource "tencentcloud_security_group_lite_rule" "foo" { + security_group_id = tencentcloud_security_group.foo.id + ingress = [ + "ACCEPT#${tencentcloud_address_template_group.foo.id}#8080#TCP", + "DROP#${tencentcloud_address_template.addr-foo.id}#8080#TCP", + "ACCEPT#0.0.0.0/0#80-90#TCP", + "DROP#8.8.8.8#80,90#UDP", + "ACCEPT#${tencentcloud_security_group.group1.id}#80#TCP", + ] + egress = [ + "ACCEPT#192.168.0.0/16#ALL#TCP", + "ACCEPT#${tencentcloud_security_group.group1.id}#ALL#TCP", + ] +} +` diff --git a/tencentcloud/resource_tc_tdmq_namespace_role_attachment.go b/tencentcloud/resource_tc_tdmq_namespace_role_attachment.go index 6eb2dc0986..9c74bdb588 100644 --- a/tencentcloud/resource_tc_tdmq_namespace_role_attachment.go +++ b/tencentcloud/resource_tc_tdmq_namespace_role_attachment.go @@ -199,7 +199,7 @@ func resourceTencentCloudTdmqNamespaceRoleAttachmentUpdate(d *schema.ResourceDat service := TdmqService{client: meta.(*TencentCloudClient).apiV3Conn} var ( - permissions [] *string + permissions []*string ) old, now := d.GetChange("permissions") if d.HasChange("permissions") { @@ -237,7 +237,6 @@ func resourceTencentCloudTdmqNamespaceRoleAttachmentDelete(d *schema.ResourceDat roleName := idSplit[1] clusterId := d.Get("cluster_id").(string) - service := TdmqService{client: meta.(*TencentCloudClient).apiV3Conn} err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { diff --git a/tencentcloud/resource_tc_tdmq_role.go b/tencentcloud/resource_tc_tdmq_role.go index 21f6772f2a..42beff7896 100644 --- a/tencentcloud/resource_tc_tdmq_role.go +++ b/tencentcloud/resource_tc_tdmq_role.go @@ -89,9 +89,9 @@ func resourceTencentCloudTdmqRoleCreate(d *schema.ResourceData, meta interface{} tdmqService := TdmqService{client: meta.(*TencentCloudClient).apiV3Conn} var ( - roleName string - clusterId string - remark string + roleName string + clusterId string + remark string ) if temp, ok := d.GetOk("role_name"); ok { roleName = temp.(string) @@ -164,7 +164,7 @@ func resourceTencentCloudTdmqRoleUpdate(d *schema.ResourceData, meta interface{} service := TdmqService{client: meta.(*TencentCloudClient).apiV3Conn} var ( - remark string + remark string ) old, now := d.GetChange("remark") if d.HasChange("remark") { diff --git a/tencentcloud/service_tencentcloud_tdmq.go b/tencentcloud/service_tencentcloud_tdmq.go index ecd3178516..384c7e1419 100644 --- a/tencentcloud/service_tencentcloud_tdmq.go +++ b/tencentcloud/service_tencentcloud_tdmq.go @@ -384,7 +384,7 @@ func (me *TdmqService) DeleteTdmqTopic(ctx context.Context, environId string, to } }() var ( - topicRecord tdmq.TopicRecord + topicRecord tdmq.TopicRecord ) topicRecord.TopicName = &topicName topicRecord.EnvironmentId = &environId @@ -655,4 +655,4 @@ func (me *TdmqService) DeleteTdmqNamespaceRoleAttachment(ctx context.Context, en return err } return -} \ No newline at end of file +} diff --git a/tencentcloud/service_tencentcloud_vpc.go b/tencentcloud/service_tencentcloud_vpc.go index 17b95d166b..0f6db45fcd 100644 --- a/tencentcloud/service_tencentcloud_vpc.go +++ b/tencentcloud/service_tencentcloud_vpc.go @@ -73,13 +73,20 @@ type VpcRouteTableBasicInfo struct { } type VpcSecurityGroupLiteRule struct { - action string - cidrIp string - port string - protocol string - nestedSecurityGroupId string // if rule is a nested security group, other attrs will be ignored + action string + cidrIp string + port string + protocol string + addressId string + addressGroupId string + securityGroupId string } +var securityGroupIdRE = regexp.MustCompile("^sg-\\w{8}$") +var ipAddressIdRE = regexp.MustCompile("^ipm-\\w{8}$") +var ipAddressGroupIdRE = regexp.MustCompile("^ipmg-\\w{8}$") +var portRE = regexp.MustCompile(`^(\d{1,5},)*\d{1,5}$|^\d{1,5}-\d{1,5}$`) + // acl rule type VpcACLRule struct { action string @@ -95,11 +102,56 @@ type VpcEniIP struct { } func (rule VpcSecurityGroupLiteRule) String() string { - if rule.nestedSecurityGroupId != "" { - return rule.nestedSecurityGroupId + + var source string + + if rule.cidrIp != "" { + source = rule.cidrIp + } + if rule.securityGroupId != "" { + source = rule.securityGroupId } + if rule.addressId != "" { + source = rule.addressId + } + if rule.addressGroupId != "" { + source = rule.addressGroupId + } + + return fmt.Sprintf("%s#%s#%s#%s", rule.action, source, rule.port, rule.protocol) +} + +func getSecurityGroupPolicies(rules []VpcSecurityGroupLiteRule) []*vpc.SecurityGroupPolicy { + policies := make([]*vpc.SecurityGroupPolicy, 0) + + for i := range rules { + rule := rules[i] + policy := &vpc.SecurityGroupPolicy{ + Protocol: &rule.protocol, + Action: &rule.action, + } + + if rule.securityGroupId != "" { + policy.SecurityGroupId = &rule.securityGroupId + } else if rule.addressId != "" || rule.addressGroupId != "" { + policy.AddressTemplate = &vpc.AddressTemplateSpecification{} + if rule.addressId != "" { + policy.AddressTemplate.AddressId = &rule.addressId + } + if rule.addressGroupId != "" { + policy.AddressTemplate.AddressGroupId = &rule.addressGroupId + } + } else { + policy.CidrBlock = &rule.cidrIp + } + + if rule.port != "" { + policy.Port = &rule.port + } - return fmt.Sprintf("%s#%s#%s#%s", rule.action, rule.cidrIp, rule.port, rule.protocol) + policies = append(policies, policy) + } + return policies } type VpcService struct { @@ -1447,34 +1499,8 @@ func (me *VpcService) modifyLiteRulesInSecurityGroup(ctx context.Context, sgId s request := vpc.NewModifySecurityGroupPoliciesRequest() request.SecurityGroupId = &sgId request.SecurityGroupPolicySet = new(vpc.SecurityGroupPolicySet) - - for i := range egress { - policy := &vpc.SecurityGroupPolicy{ - Protocol: &egress[i].protocol, - CidrBlock: &egress[i].cidrIp, - Action: &egress[i].action, - } - - if egress[i].port != "" { - policy.Port = &egress[i].port - } - - request.SecurityGroupPolicySet.Egress = append(request.SecurityGroupPolicySet.Egress, policy) - } - - for i := range ingress { - policy := &vpc.SecurityGroupPolicy{ - Protocol: &ingress[i].protocol, - CidrBlock: &ingress[i].cidrIp, - Action: &ingress[i].action, - } - - if ingress[i].port != "" { - policy.Port = &ingress[i].port - } - - request.SecurityGroupPolicySet.Ingress = append(request.SecurityGroupPolicySet.Ingress, policy) - } + request.SecurityGroupPolicySet.Egress = getSecurityGroupPolicies(egress) + request.SecurityGroupPolicySet.Ingress = getSecurityGroupPolicies(ingress) return resource.Retry(writeRetryTimeout, func() *resource.RetryError { ratelimit.Check(request.GetAction()) @@ -1496,26 +1522,10 @@ func (me *VpcService) DeleteLiteRules(ctx context.Context, sgId string, rules [] request.SecurityGroupId = &sgId request.SecurityGroupPolicySet = new(vpc.SecurityGroupPolicySet) - polices := make([]*vpc.SecurityGroupPolicy, 0, len(rules)) - - for i := range rules { - policy := &vpc.SecurityGroupPolicy{ - Protocol: &rules[i].protocol, - CidrBlock: &rules[i].cidrIp, - Action: &rules[i].action, - } - - if rules[i].port != "" { - policy.Port = &rules[i].port - } - - polices = append(polices, policy) - } - if isIngress { - request.SecurityGroupPolicySet.Ingress = polices + request.SecurityGroupPolicySet.Ingress = getSecurityGroupPolicies(rules) } else { - request.SecurityGroupPolicySet.Egress = polices + request.SecurityGroupPolicySet.Egress = getSecurityGroupPolicies(rules) } return resource.Retry(writeRetryTimeout, func() *resource.RetryError { @@ -1572,7 +1582,6 @@ func (me *VpcService) DescribeSecurityGroupPolices(ctx context.Context, sgId str if nilFields := CheckNil(in, map[string]string{ "Protocol": "protocol", "Port": "port", - "CidrBlock": "cidr ip", "Action": "action", "SecurityGroupId": "nested security group id", }); len(nilFields) > 0 { @@ -1580,20 +1589,26 @@ func (me *VpcService) DescribeSecurityGroupPolices(ctx context.Context, sgId str log.Printf("[CRITAL]%s %v", logId, err) } - ingress = append(ingress, VpcSecurityGroupLiteRule{ - protocol: strings.ToUpper(*in.Protocol), - port: *in.Port, - cidrIp: *in.CidrBlock, - action: *in.Action, - nestedSecurityGroupId: *in.SecurityGroupId, - }) + liteRule := VpcSecurityGroupLiteRule{ + protocol: strings.ToUpper(*in.Protocol), + port: *in.Port, + cidrIp: *in.CidrBlock, + action: *in.Action, + securityGroupId: *in.SecurityGroupId, + } + + if in.AddressTemplate != nil { + liteRule.addressId = *in.AddressTemplate.AddressId + liteRule.addressGroupId = *in.AddressTemplate.AddressGroupId + } + + ingress = append(ingress, liteRule) } for _, eg := range policySet.Egress { if nilFields := CheckNil(eg, map[string]string{ "Protocol": "protocol", "Port": "port", - "CidrBlock": "cidr ip", "Action": "action", "SecurityGroupId": "nested security group id", }); len(nilFields) > 0 { @@ -1601,13 +1616,20 @@ func (me *VpcService) DescribeSecurityGroupPolices(ctx context.Context, sgId str log.Printf("[CRITAL]%s %v", logId, err) } - egress = append(egress, VpcSecurityGroupLiteRule{ - protocol: strings.ToUpper(*eg.Protocol), - port: *eg.Port, - cidrIp: *eg.CidrBlock, - action: *eg.Action, - nestedSecurityGroupId: *eg.SecurityGroupId, - }) + liteRule := VpcSecurityGroupLiteRule{ + protocol: strings.ToUpper(*eg.Protocol), + port: *eg.Port, + action: *eg.Action, + cidrIp: *eg.CidrBlock, + securityGroupId: *eg.SecurityGroupId, + } + + if eg.AddressTemplate != nil { + liteRule.addressId = *eg.AddressTemplate.AddressId + liteRule.addressGroupId = *eg.AddressTemplate.AddressGroupId + } + + egress = append(egress, liteRule) } exist = true @@ -1806,7 +1828,24 @@ func parseRule(str string) (liteRule VpcSecurityGroupLiteRule, err error) { return } - liteRule.action, liteRule.cidrIp, liteRule.port, liteRule.protocol = split[0], split[1], split[2], split[3] + var ( + source string + // source is "sg-xxxxxx" / "ipm-xxxxxx" / "ipmg-xxxxxx" formatted + isInstanceIdSource = true + ) + + liteRule.action, source, liteRule.port, liteRule.protocol = split[0], split[1], split[2], split[3] + + if securityGroupIdRE.MatchString(source) { + liteRule.securityGroupId = source + } else if ipAddressIdRE.MatchString(source) { + liteRule.addressId = source + } else if ipAddressGroupIdRE.MatchString(source) { + liteRule.addressGroupId = source + } else { + isInstanceIdSource = false + liteRule.cidrIp = source + } switch liteRule.action { default: @@ -1815,14 +1854,14 @@ func parseRule(str string) (liteRule VpcSecurityGroupLiteRule, err error) { case "ACCEPT", "DROP": } - if net.ParseIP(liteRule.cidrIp) == nil { + if net.ParseIP(liteRule.cidrIp) == nil && !isInstanceIdSource { if _, _, err = net.ParseCIDR(liteRule.cidrIp); err != nil { err = fmt.Errorf("invalid cidr_ip %s, allow cidr_ip format is `8.8.8.8` or `10.0.1.0/24`", liteRule.cidrIp) return } } - if liteRule.port != "ALL" && !regexp.MustCompile(`^(\d{1,5},)*\d{1,5}$|^\d{1,5}-\d{1,5}$`).MatchString(liteRule.port) { + if liteRule.port != "ALL" && !portRE.MatchString(liteRule.port) { err = fmt.Errorf("invalid port %s, allow port format is `ALL`, `53`, `80,443` or `80-90`", liteRule.port) return } diff --git a/website/docs/r/address_template_group.html.markdown b/website/docs/r/address_template_group.html.markdown index 46e4e51405..ef1a2bacaf 100644 --- a/website/docs/r/address_template_group.html.markdown +++ b/website/docs/r/address_template_group.html.markdown @@ -15,8 +15,8 @@ Provides a resource to manage address template group. ```hcl resource "tencentcloud_address_template_group" "foo" { - name = "group-test" - addresses = ["ipl-axaf24151", "ipl-axaf24152"] + name = "group-test" + template_ids = ["ipl-axaf24151", "ipl-axaf24152"] } ``` diff --git a/website/docs/r/security_group_lite_rule.html.markdown b/website/docs/r/security_group_lite_rule.html.markdown index 5efd7ec9c2..446d197937 100644 --- a/website/docs/r/security_group_lite_rule.html.markdown +++ b/website/docs/r/security_group_lite_rule.html.markdown @@ -27,6 +27,9 @@ resource "tencentcloud_security_group_lite_rule" "foo" { "ACCEPT#192.168.1.0/24#80#TCP", "DROP#8.8.8.8#80,90#UDP", "ACCEPT#0.0.0.0/0#80-90#TCP", + "ACCEPT#sg-7ixn3foj/0#80-90#TCP", + "ACCEPT#ipm-epjq5kn0/0#80-90#TCP", + "ACCEPT#ipmg-3loavam6/0#80-90#TCP", ] egress = [ @@ -42,8 +45,8 @@ resource "tencentcloud_security_group_lite_rule" "foo" { The following arguments are supported: * `security_group_id` - (Required, ForceNew) ID of the security group. -* `egress` - (Optional) Egress rules set. A rule must match the following format: [action]#[cidr_ip]#[port]#[protocol]. The available value of 'action' is `ACCEPT` and `DROP`. The 'cidr_ip' must be an IP address network or segment. The 'port' valid format is `80`, `80,443`, `80-90` or `ALL`. The available value of 'protocol' is `TCP`, `UDP`, `ICMP` and `ALL`. When 'protocol' is `ICMP` or `ALL`, the 'port' must be `ALL`. -* `ingress` - (Optional) Ingress rules set. A rule must match the following format: [action]#[cidr_ip]#[port]#[protocol]. The available value of 'action' is `ACCEPT` and `DROP`. The 'cidr_ip' must be an IP address network or segment. The 'port' valid format is `80`, `80,443`, `80-90` or `ALL`. The available value of 'protocol' is `TCP`, `UDP`, `ICMP` and `ALL`. When 'protocol' is `ICMP` or `ALL`, the 'port' must be `ALL`. +* `egress` - (Optional) Egress rules set. A rule must match the following format: [action]#[source]#[port]#[protocol]. The available value of 'action' is `ACCEPT` and `DROP`. The 'source' can be an IP address network, segment, security group ID and Address Template ID. The 'port' valid format is `80`, `80,443`, `80-90` or `ALL`. The available value of 'protocol' is `TCP`, `UDP`, `ICMP` and `ALL`. When 'protocol' is `ICMP` or `ALL`, the 'port' must be `ALL`. +* `ingress` - (Optional) Ingress rules set. A rule must match the following format: [action]#[source]#[port]#[protocol]. The available value of 'action' is `ACCEPT` and `DROP`. The 'source' can be an IP address network, segment, security group ID and Address Template ID. The 'port' valid format is `80`, `80,443`, `80-90` or `ALL`. The available value of 'protocol' is `TCP`, `UDP`, `ICMP` and `ALL`. When 'protocol' is `ICMP` or `ALL`, the 'port' must be `ALL`. ## Attributes Reference