Skip to content

fix(clb): [121675660] tencentcloud_clb_listener support multi_cert_info #3081

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/3081.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/tencentcloud_clb_listener: support `multi_cert_info`
```
100 changes: 86 additions & 14 deletions tencentcloud/services/clb/resource_tc_clb_listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,20 +181,46 @@ func ResourceTencentCloudClbListener() *schema.Resource {
Description: "Specifies the type of health check source IP. `0` (default): CLB VIP. `1`: 100.64 IP range.",
},
"certificate_ssl_mode": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: tccommon.ValidateAllowedStringValue(CERT_SSL_MODE),
Description: "Type of certificate. Valid values: `UNIDIRECTIONAL`, `MUTUAL`. NOTES: Only supports listeners of `HTTPS` and `TCP_SSL` protocol and must be set when it is available.",
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"multi_cert_info"},
ValidateFunc: tccommon.ValidateAllowedStringValue(CERT_SSL_MODE),
Description: "Type of certificate. Valid values: `UNIDIRECTIONAL`, `MUTUAL`. NOTES: Only supports listeners of `HTTPS` and `TCP_SSL` protocol and must be set when it is available.",
},
"certificate_id": {
Type: schema.TypeString,
Optional: true,
Description: "ID of the server certificate. NOTES: Only supports listeners of `HTTPS` and `TCP_SSL` protocol and must be set when it is available.",
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"multi_cert_info"},
Description: "ID of the server certificate. NOTES: Only supports listeners of `HTTPS` and `TCP_SSL` protocol and must be set when it is available.",
},
"certificate_ca_id": {
Type: schema.TypeString,
Optional: true,
Description: "ID of the client certificate. NOTES: Only supports listeners of `HTTPS` and `TCP_SSL` protocol and must be set when the ssl mode is `MUTUAL`.",
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"multi_cert_info"},
Description: "ID of the client certificate. NOTES: Only supports listeners of `HTTPS` and `TCP_SSL` protocol and must be set when the ssl mode is `MUTUAL`.",
},
"multi_cert_info": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
ConflictsWith: []string{"certificate_ssl_mode", "certificate_id", "certificate_ca_id"},
Description: "Certificate information. You can specify multiple server-side certificates with different algorithm types. This parameter is only applicable to HTTPS listeners with the SNI feature not enabled. Certificate and MultiCertInfo cannot be specified at the same time.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ssl_mode": {
Type: schema.TypeString,
Required: true,
ValidateFunc: tccommon.ValidateAllowedStringValue(CERT_SSL_MODE),
Description: "Authentication type. Values: UNIDIRECTIONAL (one-way authentication), MUTUAL (two-way authentication).",
},
"cert_id_list": {
Type: schema.TypeSet,
Required: true,
Description: "List of server certificate ID.",
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
"session_expire_time": {
Type: schema.TypeInt,
Expand Down Expand Up @@ -307,6 +333,20 @@ func resourceTencentCloudClbListenerCreate(d *schema.ResourceData, meta interfac
return fmt.Errorf("[CHECK][CLB listener][Create] check: certificated need to be set when protocol is TCPSSL")
}
}

multiCertificateSetFlag, multiCertInput, certErr := checkMultiCertificateInputPara(ctx, d, meta)
if certErr != nil {
return certErr
}

if multiCertificateSetFlag {
request.MultiCertInfo = multiCertInput
} else {
if protocol == CLB_LISTENER_PROTOCOL_TCPSSL {
return fmt.Errorf("[CHECK][CLB listener][Create] check: certificated need to be set when protocol is TCPSSL")
}
}

scheduler := ""
if v, ok := d.GetOk("scheduler"); ok {
if v == CLB_LISTENER_SCHEDULER_IP_HASH {
Expand Down Expand Up @@ -527,10 +567,32 @@ func resourceTencentCloudClbListenerRead(d *schema.ResourceData, meta interface{
}

if instance.Certificate != nil {
_ = d.Set("certificate_ssl_mode", instance.Certificate.SSLMode)
_ = d.Set("certificate_id", instance.Certificate.CertId)
if instance.Certificate.CertCaId != nil {
_ = d.Set("certificate_ca_id", instance.Certificate.CertCaId)
// check single cert or multi cert
if instance.Certificate.ExtCertIds != nil && len(instance.Certificate.ExtCertIds) > 0 {
multiCertInfo := make([]map[string]interface{}, 0, 1)
multiCert := make(map[string]interface{}, 0)
certIds := make([]string, 0)
if instance.Certificate.SSLMode != nil {
multiCert["ssl_mode"] = *instance.Certificate.SSLMode
}

if instance.Certificate.CertId != nil {
certIds = append(certIds, *instance.Certificate.CertId)
}

for _, item := range instance.Certificate.ExtCertIds {
certIds = append(certIds, *item)
}

multiCert["cert_id_list"] = certIds
multiCertInfo = append(multiCertInfo, multiCert)
_ = d.Set("multi_cert_info", multiCertInfo)
} else {
_ = d.Set("certificate_ssl_mode", instance.Certificate.SSLMode)
_ = d.Set("certificate_id", instance.Certificate.CertId)
if instance.Certificate.CertCaId != nil {
_ = d.Set("certificate_ca_id", instance.Certificate.CertCaId)
}
}
}

Expand Down Expand Up @@ -637,6 +699,16 @@ func resourceTencentCloudClbListenerUpdate(d *schema.ResourceData, meta interfac
request.Certificate = certificateInput
}

multiCertificateSetFlag, multiCertInput, certErr := checkMultiCertificateInputPara(ctx, d, meta)
if certErr != nil {
return certErr
}

if multiCertificateSetFlag {
changed = true
request.MultiCertInfo = multiCertInput
}

if d.HasChange("target_type") {
changed = true
targetType := d.Get("target_type").(string)
Expand Down
22 changes: 21 additions & 1 deletion tencentcloud/services/clb/resource_tc_clb_listener.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ resource "tencentcloud_clb_listener" "listener_tcp"{
}
```

HTTPS Listener
HTTPS Listener with sigle certificate

```hcl
resource "tencentcloud_clb_listener" "HTTPS_listener" {
Expand All @@ -118,6 +118,26 @@ resource "tencentcloud_clb_listener" "HTTPS_listener" {
}
```

HTTPS Listener with multi certificates

```hcl
resource "tencentcloud_clb_listener" "HTTPS_listener" {
clb_id = "lb-l6cp6jt4"
listener_name = "test_listener"
port = "80"
protocol = "HTTPS"
sni_switch = true

multi_cert_info {
ssl_mode = "UNIDIRECTIONAL"
cert_id_list = [
"LCYouprI",
"JVO1alRN"
]
}
}
```

TCP SSL Listener

```hcl
Expand Down
31 changes: 31 additions & 0 deletions tencentcloud/services/clb/service_tencentcloud_clb.go
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,37 @@ func checkCertificateInputPara(ctx context.Context, d *schema.ResourceData, meta
}
return
}

func checkMultiCertificateInputPara(ctx context.Context, d *schema.ResourceData, meta interface{}) (multiCertificateSetFlag bool, multiCertPara *clb.MultiCertInfo, errRet error) {
multiCertificateSetFlag = false
var multiCertInfo clb.MultiCertInfo

if dMap, ok := helper.InterfacesHeadMap(d, "multi_cert_info"); ok {
if tmp, ok := dMap["ssl_mode"].(string); ok {
multiCertInfo.SSLMode = helper.String(tmp)
}

if tmp, ok := dMap["cert_id_list"]; ok {
tmpList := tmp.(*schema.Set).List()
if len(tmpList) < 1 {
errRet = fmt.Errorf("`cert_id_list` cannot be empty.")
return
}

for _, item := range tmpList {
var certInfo clb.CertInfo
certInfo.CertId = helper.String(item.(string))
multiCertInfo.CertList = append(multiCertInfo.CertList, &certInfo)
}
}

multiCertificateSetFlag = true
multiCertPara = &multiCertInfo
}

return
}

func processRetryErrMsg(err error) *resource.RetryError {
if e, ok := err.(*sdkErrors.TencentCloudSDKError); ok {
for _, msg := range []string{
Expand Down
Loading
Loading