alicloud/service_alicloud_slb.go (1,076 lines of code) (raw):
package alicloud
import (
"encoding/json"
"fmt"
"log"
"regexp"
"strconv"
"strings"
"time"
"github.com/PaesslerAG/jsonpath"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/slb"
"github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
type SlbService struct {
client *connectivity.AliyunClient
}
type SlbTag struct {
TagKey string
TagValue string
}
const max_num_per_time = 50
const tags_max_num_per_time = 5
const tags_max_page_size = 50
func (s *SlbService) BuildSlbCommonRequest() (*requests.CommonRequest, error) {
// Get product code from the built request
slbReq := slb.CreateCreateLoadBalancerRequest()
req, err := s.client.NewCommonRequest(slbReq.GetProduct(), slbReq.GetLocationServiceCode(), strings.ToUpper(string(Https)), connectivity.ApiVersion20140515)
if err != nil {
return req, WrapError(err)
}
req.RegionId = s.client.RegionId
return req, err
}
func (s *SlbService) DescribeSlb(id string) (*slb.DescribeLoadBalancerAttributeResponse, error) {
response := &slb.DescribeLoadBalancerAttributeResponse{}
request := slb.CreateDescribeLoadBalancerAttributeRequest()
request.RegionId = s.client.RegionId
request.LoadBalancerId = id
raw, err := s.client.WithSlbClient(func(slbClient *slb.Client) (interface{}, error) {
return slbClient.DescribeLoadBalancerAttribute(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"InvalidLoadBalancerId.NotFound"}) {
err = WrapErrorf(NotFoundErr("Slb", id), NotFoundMsg, AlibabaCloudSdkGoERROR)
} else {
err = WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
return response, err
}
addDebug(request.GetActionName(), raw, request.RpcRequest)
response, _ = raw.(*slb.DescribeLoadBalancerAttributeResponse)
if response.LoadBalancerId == "" {
err = WrapErrorf(NotFoundErr("Slb", id), NotFoundMsg, ProviderERROR)
}
return response, err
}
func (s *SlbService) DescribeSlbRule(id string) (object map[string]interface{}, err error) {
var response map[string]interface{}
client := s.client
action := "DescribeRuleAttribute"
request := map[string]interface{}{
"RuleId": id,
"RegionId": s.client.RegionId,
}
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
response, err = client.RpcGet("Slb", "2014-05-15", action, request, nil)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
if IsExpectedErrors(err, []string{"InvalidRuleId.NotFound"}) {
return response, WrapErrorf(NotFoundErr("SlbRule", id), NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR)
}
if fmt.Sprint(response["RuleId"]) != id {
return response, WrapErrorf(NotFoundErr("SlbRule", id), NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return response, nil
}
func (s *SlbService) DescribeSlbServerGroup(id string) (*slb.DescribeVServerGroupAttributeResponse, error) {
response := &slb.DescribeVServerGroupAttributeResponse{}
request := slb.CreateDescribeVServerGroupAttributeRequest()
request.RegionId = s.client.RegionId
request.VServerGroupId = id
raw, err := s.client.WithSlbClient(func(slbClient *slb.Client) (interface{}, error) {
return slbClient.DescribeVServerGroupAttribute(request)
})
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
if err != nil {
if IsExpectedErrors(err, []string{"The specified VServerGroupId does not exist", "InvalidParameter"}) {
return response, WrapErrorf(NotFoundErr("Slb:ServerGroup", id), NotFoundMsg, ProviderERROR, response.RequestId)
}
return response, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
response, _ = raw.(*slb.DescribeVServerGroupAttributeResponse)
if response.VServerGroupId == "" {
return response, WrapErrorf(NotFoundErr("Slb:ServerGroup", id), NotFoundMsg, ProviderERROR, response.RequestId)
}
return response, err
}
func (s *SlbService) DescribeSlbMasterSlaveServerGroup(id string) (*slb.DescribeMasterSlaveServerGroupAttributeResponse, error) {
response := &slb.DescribeMasterSlaveServerGroupAttributeResponse{}
request := slb.CreateDescribeMasterSlaveServerGroupAttributeRequest()
request.RegionId = s.client.RegionId
request.MasterSlaveServerGroupId = id
raw, err := s.client.WithSlbClient(func(slbClient *slb.Client) (interface{}, error) {
return slbClient.DescribeMasterSlaveServerGroupAttribute(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"The specified MasterSlaveGroupId does not exist", "InvalidParameter"}) {
return response, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return response, WrapErrorf(err, DefaultDebugMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
response, _ = raw.(*slb.DescribeMasterSlaveServerGroupAttributeResponse)
if response.MasterSlaveServerGroupId == "" {
return response, WrapErrorf(NotFoundErr("SlbMasterSlaveServerGroup", id), NotFoundMsg, ProviderERROR)
}
return response, err
}
func (s *SlbService) DescribeSlbBackendServer(id string) (*slb.DescribeLoadBalancerAttributeResponse, error) {
response := &slb.DescribeLoadBalancerAttributeResponse{}
request := slb.CreateDescribeLoadBalancerAttributeRequest()
request.RegionId = s.client.RegionId
request.LoadBalancerId = id
raw, err := s.client.WithSlbClient(func(slbClient *slb.Client) (interface{}, error) {
return slbClient.DescribeLoadBalancerAttribute(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"InvalidLoadBalancerId.NotFound"}) {
err = WrapErrorf(NotFoundErr("SlbBackendServers", id), NotFoundMsg, AlibabaCloudSdkGoERROR)
} else {
err = WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
return response, err
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
response, _ = raw.(*slb.DescribeLoadBalancerAttributeResponse)
if response.LoadBalancerId == "" {
err = WrapErrorf(NotFoundErr("SlbBackendServers", id), NotFoundMsg, ProviderERROR)
}
return response, err
}
func (s *SlbService) DescribeSlbListener(id string) (listener map[string]interface{}, err error) {
parts, err := ParseSlbListenerId(id)
if err != nil {
return nil, WrapError(err)
}
protocol := parts[1]
request, err := s.BuildSlbCommonRequest()
request.RegionId = s.client.RegionId
if err != nil {
err = WrapError(err)
return
}
request.ApiName = fmt.Sprintf("DescribeLoadBalancer%sListenerAttribute", strings.ToUpper(string(protocol)))
request.QueryParams["LoadBalancerId"] = parts[0]
port, _ := strconv.Atoi(parts[2])
request.QueryParams["ListenerPort"] = string(requests.NewInteger(port))
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
raw, err := s.client.WithSlbClient(func(slbClient *slb.Client) (interface{}, error) {
return slbClient.ProcessCommonRequest(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"The specified resource does not exist"}) {
return resource.NonRetryableError(WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR))
} else if IsExpectedErrors(err, SlbIsBusy) {
return resource.RetryableError(WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR))
}
return resource.NonRetryableError(WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR))
}
addDebug(request.GetActionName(), raw, request, request.QueryParams)
response, _ := raw.(*responses.CommonResponse)
if err = json.Unmarshal(response.GetHttpContentBytes(), &listener); err != nil {
return resource.NonRetryableError(WrapError(err))
}
if port, ok := listener["ListenerPort"]; ok && port.(float64) > 0 {
return nil
} else {
return resource.RetryableError(WrapErrorf(NotFoundErr("SlbListener", id), NotFoundMsg, ProviderERROR))
}
})
return
}
func (s *SlbService) DescribeSlbAcl(id string) (object map[string]interface{}, err error) {
var response map[string]interface{}
client := s.client
action := "DescribeAccessControlListAttribute"
request := map[string]interface{}{
"RegionId": s.client.RegionId,
"AclId": id,
}
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
response, err = client.RpcPost("Slb", "2014-05-15", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
if IsExpectedErrors(err, []string{"AclNotExist"}) {
return object, WrapErrorf(NotFoundErr("SLB:Acl", id), NotFoundMsg, ProviderERROR, fmt.Sprint(response["RequestId"]))
}
return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR)
}
v, err := jsonpath.Get("$", response)
if err != nil {
return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$", response)
}
object = v.(map[string]interface{})
return object, nil
}
func (s *SlbService) WaitForSlb(id string, status Status, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
object, err := s.DescribeSlb(id)
if err != nil {
if NotFoundError(err) {
if status == Deleted {
return nil
}
} else {
return WrapError(err)
}
} else if strings.ToLower(object.LoadBalancerStatus) == strings.ToLower(string(status)) {
//TODO
break
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, object.LoadBalancerStatus, status, ProviderERROR)
}
time.Sleep(DefaultIntervalShort * time.Second)
}
return nil
}
func (s *SlbService) WaitForSlbListener(id string, status Status, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
object, err := s.DescribeSlbListener(id)
if err != nil && !IsExpectedErrors(err, []string{"InvalidLoadBalancerId.NotFound"}) {
if NotFoundError(err) {
if status == Deleted {
return nil
}
} else {
return WrapError(err)
}
}
gotStatus := ""
if value, ok := object["Status"]; ok {
gotStatus = strings.ToLower(value.(string))
}
if gotStatus == strings.ToLower(string(status)) {
//TODO
break
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, gotStatus, status, ProviderERROR)
}
time.Sleep(DefaultIntervalShort * time.Second)
}
return nil
}
func (s *SlbService) WaitForSlbRule(id string, status Status, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
object, err := s.DescribeSlbRule(id)
if err != nil {
if NotFoundError(err) {
if status == Deleted {
return nil
}
} else {
return WrapError(err)
}
}
if object["RuleId"] == id && status != Deleted {
break
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, "", id, ProviderERROR)
}
time.Sleep(DefaultIntervalShort * time.Second)
}
return nil
}
func (s *SlbService) WaitForSlbServerGroup(id string, status Status, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
object, err := s.DescribeSlbServerGroup(id)
if err != nil {
if NotFoundError(err) {
if status == Deleted {
return nil
}
} else {
return WrapError(err)
}
}
if object.VServerGroupId == id {
break
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, object.VServerGroupId, id, ProviderERROR)
}
time.Sleep(DefaultIntervalShort * time.Second)
}
return nil
}
func (s *SlbService) WaitForSlbMasterSlaveServerGroup(id string, status Status, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
object, err := s.DescribeSlbMasterSlaveServerGroup(id)
if err != nil {
if NotFoundError(err) {
if status == Deleted {
return nil
}
} else {
return WrapError(err)
}
}
if object.MasterSlaveServerGroupId == id && status != Deleted {
break
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, object.MasterSlaveServerGroupId, id, ProviderERROR)
}
time.Sleep(DefaultIntervalShort * time.Second)
}
return nil
}
func (s *SlbService) WaitSlbAttribute(id string, instanceSet *schema.Set, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
RETRY:
object, err := s.DescribeSlb(id)
if err != nil {
if NotFoundError(err) {
return nil
}
return WrapError(err)
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, Null, id, ProviderERROR)
}
servers := object.BackendServers.BackendServer
if len(servers) > 0 {
for _, s := range servers {
if instanceSet.Contains(s.ServerId) {
goto RETRY
}
}
}
return nil
}
func (s *SlbService) slbRemoveAccessControlListEntryPerTime(list []interface{}, id string) error {
request := slb.CreateRemoveAccessControlListEntryRequest()
request.RegionId = s.client.RegionId
request.AclId = id
b, err := json.Marshal(list)
if err != nil {
return WrapError(err)
}
request.AclEntrys = string(b)
raw, err := s.client.WithSlbClient(func(slbClient *slb.Client) (interface{}, error) {
return slbClient.RemoveAccessControlListEntry(request)
})
if err != nil {
if !IsExpectedErrors(err, []string{"AclEntryEmpty"}) {
return WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
return nil
}
func (s *SlbService) SlbRemoveAccessControlListEntry(list []interface{}, aclId string) error {
num := len(list)
if num <= 0 {
return nil
}
t := (num + max_num_per_time - 1) / max_num_per_time
for i := 0; i < t; i++ {
start := i * max_num_per_time
end := (i + 1) * max_num_per_time
if end > num {
end = num
}
slice := list[start:end]
if err := s.slbRemoveAccessControlListEntryPerTime(slice, aclId); err != nil {
return err
}
}
return nil
}
func (s *SlbService) slbAddAccessControlListEntryPerTime(list []interface{}, id string) error {
request := slb.CreateAddAccessControlListEntryRequest()
request.RegionId = s.client.RegionId
request.AclId = id
b, err := json.Marshal(list)
if err != nil {
return WrapError(err)
}
request.AclEntrys = string(b)
raw, err := s.client.WithSlbClient(func(slbClient *slb.Client) (interface{}, error) {
return slbClient.AddAccessControlListEntry(request)
})
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
return nil
}
func (s *SlbService) SlbAddAccessControlListEntry(list []interface{}, aclId string) error {
num := len(list)
if num <= 0 {
return nil
}
t := (num + max_num_per_time - 1) / max_num_per_time
for i := 0; i < t; i++ {
start := i * max_num_per_time
end := (i + 1) * max_num_per_time
if end > num {
end = num
}
slice := list[start:end]
if err := s.slbAddAccessControlListEntryPerTime(slice, aclId); err != nil {
return err
}
}
return nil
}
// Flattens an array of slb.AclEntry into a []map[string]string
func (s *SlbService) FlattenSlbAclEntryMappings(list []slb.AclEntry) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(list))
for _, i := range list {
l := map[string]interface{}{
"entry": i.AclEntryIP,
"comment": i.AclEntryComment,
}
result = append(result, l)
}
return result
}
// Flattens an array of slb.AclEntry into a []map[string]string
func (s *SlbService) flattenSlbRelatedListenerMappings(list []slb.RelatedListener) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(list))
for _, i := range list {
l := map[string]interface{}{
"load_balancer_id": i.LoadBalancerId,
"protocol": i.Protocol,
"frontend_port": i.ListenerPort,
"acl_type": i.AclType,
}
result = append(result, l)
}
return result
}
func (s *SlbService) DescribeSlbCACertificate(id string) (*slb.CACertificate, error) {
certificate := &slb.CACertificate{}
request := slb.CreateDescribeCACertificatesRequest()
request.RegionId = s.client.RegionId
request.CACertificateId = id
raw, err := s.client.WithSlbClient(func(slbClient *slb.Client) (interface{}, error) {
return slbClient.DescribeCACertificates(request)
})
if err != nil {
return certificate, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
response, _ := raw.(*slb.DescribeCACertificatesResponse)
if len(response.CACertificates.CACertificate) < 1 {
return certificate, WrapErrorf(NotFoundErr("SlbCACertificate", id), NotFoundMsg, ProviderERROR)
}
return &response.CACertificates.CACertificate[0], nil
}
func (s *SlbService) WaitForSlbCACertificate(id string, status Status, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
object, err := s.DescribeSlbCACertificate(id)
if err != nil {
if NotFoundError(err) {
if status == Deleted {
return nil
}
} else {
return WrapError(err)
}
} else {
break
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, object.CACertificateId, id, ProviderERROR)
}
}
return nil
}
func (s *SlbService) DescribeSlbServerCertificate(id string) (*slb.ServerCertificate, error) {
certificate := &slb.ServerCertificate{}
request := slb.CreateDescribeServerCertificatesRequest()
request.RegionId = s.client.RegionId
request.ServerCertificateId = id
raw, err := s.client.WithSlbClient(func(slbClient *slb.Client) (interface{}, error) {
return slbClient.DescribeServerCertificates(request)
})
if err != nil {
return certificate, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
response, _ := raw.(*slb.DescribeServerCertificatesResponse)
if len(response.ServerCertificates.ServerCertificate) < 1 || response.ServerCertificates.ServerCertificate[0].ServerCertificateId != id {
return certificate, WrapErrorf(NotFoundErr("SlbServerCertificate", id), NotFoundMsg, ProviderERROR)
}
return &response.ServerCertificates.ServerCertificate[0], nil
}
func (s *SlbService) WaitForSlbServerCertificate(id string, status Status, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
object, err := s.DescribeSlbServerCertificate(id)
if err != nil {
if NotFoundError(err) {
if status == Deleted {
return nil
}
} else {
return WrapError(err)
}
}
if object.ServerCertificateId == id {
break
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, object.ServerCertificateId, id, ProviderERROR)
}
}
return nil
}
func toSlbTagsString(tags []Tag) string {
slbTags := make([]SlbTag, 0, len(tags))
for _, tag := range tags {
slbTag := SlbTag{
TagKey: tag.Key,
TagValue: tag.Value,
}
slbTags = append(slbTags, slbTag)
}
b, _ := json.Marshal(slbTags)
return string(b)
}
func (s *SlbService) DescribeDomainExtensionAttribute(domainExtensionId string) (*slb.DescribeDomainExtensionAttributeResponse, error) {
response := &slb.DescribeDomainExtensionAttributeResponse{}
request := slb.CreateDescribeDomainExtensionAttributeRequest()
request.DomainExtensionId = domainExtensionId
var raw interface{}
var err error
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
raw, err = s.client.WithSlbClient(func(slbClient *slb.Client) (interface{}, error) {
return slbClient.DescribeDomainExtensionAttribute(request)
})
if err != nil {
if IsExpectedErrors(err, []string{AliyunGoClientFailure, "ServiceUnavailable", Throttling}) {
time.Sleep(10 * time.Second)
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
return nil
})
if err != nil {
if IsExpectedErrors(err, []string{"InvalidParameter.DomainExtensionId", "InvalidParameter"}) {
return response, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return response, WrapErrorf(err, DefaultErrorMsg, domainExtensionId, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
response, _ = raw.(*slb.DescribeDomainExtensionAttributeResponse)
if response.DomainExtensionId != domainExtensionId {
return response, WrapErrorf(NotFoundErr("SLBDomainExtension", domainExtensionId), NotFoundMsg, ProviderERROR)
}
return response, nil
}
func (s *SlbService) WaitForSlbDomainExtension(id string, status Status, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
_, err := s.DescribeDomainExtensionAttribute(id)
if err != nil {
if NotFoundError(err) {
if status == Deleted {
return nil
}
} else {
return WrapError(err)
}
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, Null, string(status), ProviderERROR)
}
}
}
func (s *SlbService) setInstanceTags(d *schema.ResourceData, resourceType TagResourceType) error {
oraw, nraw := d.GetChange("tags")
o := oraw.(map[string]interface{})
n := nraw.(map[string]interface{})
create, remove := s.diffTags(s.tagsFromMap(o), s.tagsFromMap(n))
if len(remove) > 0 {
var tagKey []string
for _, v := range remove {
tagKey = append(tagKey, v.Key)
}
request := slb.CreateUntagResourcesRequest()
request.ResourceId = &[]string{d.Id()}
request.ResourceType = string(resourceType)
request.TagKey = &tagKey
request.RegionId = s.client.RegionId
wait := incrementalWait(1*time.Second, 1*time.Second)
err := resource.Retry(10*time.Minute, func() *resource.RetryError {
raw, err := s.client.WithSlbClient(func(client *slb.Client) (interface{}, error) {
return client.UntagResources(request)
})
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
return nil
})
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
}
}
if len(create) > 0 {
request := slb.CreateTagResourcesRequest()
request.ResourceId = &[]string{d.Id()}
request.Tag = &create
request.ResourceType = string(resourceType)
request.RegionId = s.client.RegionId
wait := incrementalWait(1*time.Second, 1*time.Second)
err := resource.Retry(10*time.Minute, func() *resource.RetryError {
raw, err := s.client.WithSlbClient(func(client *slb.Client) (interface{}, error) {
return client.TagResources(request)
})
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
return nil
})
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
}
}
d.SetPartial("tags")
return nil
}
func (s *SlbService) tagsToMap(tags []slb.TagResource) map[string]string {
result := make(map[string]string)
for _, t := range tags {
if !s.ignoreTag(t) {
result[t.TagKey] = t.TagValue
}
}
return result
}
func (s *SlbService) ignoreTag(t slb.TagResource) bool {
filter := []string{"^aliyun", "^acs:", "^http://", "^https://"}
for _, v := range filter {
log.Printf("[DEBUG] Matching prefix %v with %v\n", v, t.TagKey)
ok, _ := regexp.MatchString(v, t.TagKey)
if ok {
log.Printf("[DEBUG] Found Alibaba Cloud specific t %s (val: %s), ignoring.\n", t.TagKey, t.TagValue)
return true
}
}
return false
}
func (s *SlbService) diffTags(oldTags, newTags []slb.TagResourcesTag) ([]slb.TagResourcesTag, []slb.TagResourcesTag) {
// First, we're creating everything we have
create := make(map[string]interface{})
for _, t := range newTags {
create[t.Key] = t.Value
}
// Build the list of what to remove
var remove []slb.TagResourcesTag
for _, t := range oldTags {
old, ok := create[t.Key]
if !ok || old != t.Value {
// Delete it!
remove = append(remove, t)
}
}
return s.tagsFromMap(create), remove
}
func (s *SlbService) tagsFromMap(m map[string]interface{}) []slb.TagResourcesTag {
result := make([]slb.TagResourcesTag, 0, len(m))
for k, v := range m {
result = append(result, slb.TagResourcesTag{
Key: k,
Value: v.(string),
})
}
return result
}
func (s *SlbService) ListTagResources(id string, resourceType string) (object interface{}, err error) {
client := s.client
action := "ListTagResources"
request := map[string]interface{}{
"RegionId": s.client.RegionId,
"ResourceType": resourceType,
"ResourceId.1": id,
}
tags := make([]interface{}, 0)
var response map[string]interface{}
for {
wait := incrementalWait(3*time.Second, 5*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
response, err := client.RpcPost("Slb", "2014-05-15", action, nil, request, false)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
addDebug(action, response, request)
v, err := jsonpath.Get("$.TagResources.TagResource", response)
if err != nil {
return resource.NonRetryableError(WrapErrorf(err, FailedGetAttributeMsg, id, "$.TagResources.TagResource", response))
}
if v != nil {
tags = append(tags, v.([]interface{})...)
}
return nil
})
if err != nil {
err = WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR)
return
}
if response["NextToken"] == nil {
break
}
request["NextToken"] = response["NextToken"]
}
return tags, nil
}
func (s *SlbService) SetResourceTags(d *schema.ResourceData, resourceType string) error {
if d.HasChange("tags") {
added, removed := parsingTags(d)
client := s.client
removedTagKeys := make([]string, 0)
for _, v := range removed {
if !ignoredTags(v, "") {
removedTagKeys = append(removedTagKeys, v)
}
}
if len(removedTagKeys) > 0 {
action := "UntagResources"
request := map[string]interface{}{
"RegionId": s.client.RegionId,
"ResourceType": resourceType,
"ResourceId.1": d.Id(),
}
for i, key := range removedTagKeys {
request[fmt.Sprintf("TagKey.%d", i+1)] = key
}
wait := incrementalWait(2*time.Second, 1*time.Second)
err := resource.Retry(10*time.Minute, func() *resource.RetryError {
response, err := client.RpcPost("Slb", "2014-05-15", action, nil, request, false)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
addDebug(action, response, request)
return nil
})
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
}
if len(added) > 0 {
action := "TagResources"
request := map[string]interface{}{
"RegionId": s.client.RegionId,
"ResourceType": resourceType,
"ResourceId.1": d.Id(),
}
count := 1
for key, value := range added {
request[fmt.Sprintf("Tag.%d.Key", count)] = key
request[fmt.Sprintf("Tag.%d.Value", count)] = value
count++
}
wait := incrementalWait(2*time.Second, 1*time.Second)
err := resource.Retry(10*time.Minute, func() *resource.RetryError {
response, err := client.RpcPost("Slb", "2014-05-15", action, nil, request, false)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
addDebug(action, response, request)
return nil
})
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR)
}
}
d.SetPartial("tags")
}
return nil
}
func (s *SlbService) DescribeSlbLoadBalancer(id string) (object map[string]interface{}, err error) {
var response map[string]interface{}
client := s.client
action := "DescribeLoadBalancerAttribute"
request := map[string]interface{}{
"RegionId": s.client.RegionId,
"LoadBalancerId": id,
}
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
response, err = client.RpcPost("Slb", "2014-05-15", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
addDebug(action, response, request)
return nil
})
if err != nil {
if IsExpectedErrors(err, []string{"InvalidLoadBalancerId.NotFound"}) {
return object, WrapErrorf(NotFoundErr("SLB:LoadBalancer", id), NotFoundMsg, ProviderERROR, fmt.Sprint(response["RequestId"]))
}
return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR)
}
v, err := jsonpath.Get("$", response)
if err != nil {
return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$", response)
}
object = v.(map[string]interface{})
return object, nil
}
func (s *SlbService) SlbLoadBalancerStateRefreshFunc(id string, failStates []string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
object, err := s.DescribeSlbLoadBalancer(id)
if err != nil {
if NotFoundError(err) {
// Set this to nil as if we didn't find anything.
return nil, "", nil
}
return nil, "", WrapError(err)
}
for _, failState := range failStates {
if fmt.Sprint(object["LoadBalancerStatus"]) == failState {
return object, fmt.Sprint(object["LoadBalancerStatus"]), WrapError(Error(FailedToReachTargetStatus, fmt.Sprint(object["LoadBalancerStatus"])))
}
}
return object, fmt.Sprint(object["LoadBalancerStatus"]), nil
}
}
func (s *SlbService) DescribeSlbCaCertificate(id string) (object map[string]interface{}, err error) {
var response map[string]interface{}
client := s.client
action := "DescribeCACertificates"
request := map[string]interface{}{
"RegionId": s.client.RegionId,
"CACertificateId": id,
}
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
response, err = client.RpcPost("Slb", "2014-05-15", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
addDebug(action, response, request)
return nil
})
if err != nil {
return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR)
}
v, err := jsonpath.Get("$.CACertificates.CACertificate", response)
if err != nil {
return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.CACertificates.CACertificate", response)
}
if len(v.([]interface{})) < 1 {
return object, WrapErrorf(NotFoundErr("SLB", id), NotFoundWithResponse, response)
} else {
if v.([]interface{})[0].(map[string]interface{})["CACertificateId"].(string) != id {
return object, WrapErrorf(NotFoundErr("SLB", id), NotFoundWithResponse, response)
}
}
object = v.([]interface{})[0].(map[string]interface{})
return object, nil
}
func (s *SlbService) DescribeSlbTlsCipherPolicy(id string) (object map[string]interface{}, err error) {
var response map[string]interface{}
client := s.client
action := "ListTLSCipherPolicies"
request := map[string]interface{}{
"RegionId": s.client.RegionId,
"TLSCipherPolicyId": id,
}
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
response, err = client.RpcPost("Slb", "2014-05-15", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR)
}
v, err := jsonpath.Get("$.TLSCipherPolicies", response)
if err != nil {
return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.TLSCipherPolicies", response)
}
if len(v.([]interface{})) < 1 {
return object, WrapErrorf(NotFoundErr("SLB", id), NotFoundWithResponse, response)
} else {
if fmt.Sprint(v.([]interface{})[0].(map[string]interface{})["InstanceId"]) != id {
return object, WrapErrorf(NotFoundErr("SLB", id), NotFoundWithResponse, response)
}
}
object = v.([]interface{})[0].(map[string]interface{})
return object, nil
}
func (s *SlbService) convertAclEntriesToString(v []interface{}) (string, error) {
arrayMaps := make([]interface{}, len(v))
for i, vv := range v {
item := vv.(map[string]interface{})
temp := map[string]interface{}{
"comment": item["comment"],
"entry": item["entry"],
}
arrayMaps[i] = temp
}
maps, err := json.Marshal(arrayMaps)
if err != nil {
return "", WrapError(err)
}
return string(maps), nil
}
func (s *SlbService) DescribeSlbAclEntryAttachment(id string) (object map[string]interface{}, err error) {
var response map[string]interface{}
client := s.client
parts, err := ParseResourceId(id, 2)
if err != nil {
return object, WrapError(err)
}
action := "DescribeAccessControlListAttribute"
request := map[string]interface{}{
"RegionId": s.client.RegionId,
"AclId": parts[0],
}
idExist := false
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
response, err = client.RpcPost("Slb", "2014-05-15", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
if IsExpectedErrors(err, []string{"AclNotExist"}) {
return object, WrapErrorf(NotFoundErr("SLB", id), NotFoundWithResponse, response)
}
return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR)
}
v, err := jsonpath.Get("$.AclEntrys.AclEntry", response)
if err != nil {
return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.AclEntrys.AclEntry", response)
}
if len(v.([]interface{})) < 1 {
return object, WrapErrorf(NotFoundErr("SLB", id), NotFoundWithResponse, response)
}
for _, v := range v.([]interface{}) {
if fmt.Sprint(v.(map[string]interface{})["AclEntryIP"]) == parts[1] {
idExist = true
return v.(map[string]interface{}), nil
}
}
if !idExist {
return object, WrapErrorf(NotFoundErr("SLB", id), NotFoundWithResponse, response)
}
return object, nil
}
func (s *SlbService) DescribeSlbServerGroupServerAttachment(id string) (object map[string]interface{}, err error) {
var response map[string]interface{}
client := s.client
parts, err := ParseResourceId(id, 3)
if err != nil {
return object, WrapError(err)
}
action := "DescribeVServerGroupAttribute"
request := map[string]interface{}{
"RegionId": s.client.RegionId,
"VServerGroupId": parts[0],
}
idExist := false
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
response, err = client.RpcPost("Slb", "2014-05-15", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
addDebug(action, response, request)
if err != nil {
if IsExpectedErrors(err, []string{"The specified VServerGroupId does not exist", "InvalidParameter"}) {
return object, WrapErrorf(NotFoundErr("SLB", id), NotFoundWithResponse, response)
}
return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR)
}
resp, err := jsonpath.Get("$.BackendServers.BackendServer", response)
if err != nil {
return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.BackendServers.BackendServer", response)
}
if v, ok := resp.([]interface{}); !ok || len(v) < 1 {
return object, WrapErrorf(NotFoundErr("Slb:ServerGroupServerAttachment", id), NotFoundWithResponse, response)
}
for _, v := range resp.([]interface{}) {
if fmt.Sprint(v.(map[string]interface{})["ServerId"]) == parts[1] && fmt.Sprint(v.(map[string]interface{})["Port"]) == parts[2] {
idExist = true
return v.(map[string]interface{}), nil
}
}
if !idExist {
return object, WrapErrorf(NotFoundErr("Slb:ServerGroupServerAttachment", id), NotFoundWithResponse, response)
}
return object, nil
}