alicloud/service_alicloud_cen.go (386 lines of code) (raw):

package alicloud import ( "fmt" "strings" "time" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "strconv" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" "github.com/aliyun/alibaba-cloud-sdk-go/services/cbn" "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" ) type CenService struct { client *connectivity.AliyunClient } const DefaultCenTimeout = 60 const DefaultCenTimeoutLong = 180 const ChildInstanceTypeVpc = "VPC" const ChildInstanceTypeVbr = "VBR" const ChildInstanceTypeCcn = "CCN" func (s *CenService) DescribeCenInstanceAttachment(id string) (*cbn.ChildInstance, error) { c := &cbn.ChildInstance{} request := cbn.CreateDescribeCenAttachedChildInstancesRequest() request.RegionId = s.client.RegionId cenId, instanceId, err := s.GetCenIdAndAnotherId(id) if err != nil { return c, WrapError(err) } request.CenId = cenId for pageNum := 1; ; pageNum++ { request.PageNumber = requests.NewInteger(pageNum) var raw interface{} wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(5*time.Minute, func() *resource.RetryError { raw, err = s.client.WithCbnClient(func(cbnClient *cbn.Client) (interface{}, error) { return cbnClient.DescribeCenAttachedChildInstances(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 { if IsExpectedErrors(err, []string{"ParameterInstanceId"}) { return nil, WrapErrorf(NotFoundErr("CEN Instance Attachment", instanceId), NotFoundMsg, ProviderERROR) } return c, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), ProviderERROR) } response, _ := raw.(*cbn.DescribeCenAttachedChildInstancesResponse) instanceList := response.ChildInstances.ChildInstance for instanceNum := 0; instanceNum <= len(instanceList)-1; instanceNum++ { if instanceList[instanceNum].ChildInstanceId == instanceId { return &instanceList[instanceNum], nil } } if pageNum*response.PageSize >= response.TotalCount { return c, WrapErrorf(NotFoundErr("CEN Instance Attachment", instanceId), NotFoundMsg, ProviderERROR) } } } func (s *CenService) WaitForCenInstanceAttachment(id string, status Status, timeout int) error { deadline := time.Now().Add(time.Duration(timeout) * time.Second) for { object, err := s.DescribeCenInstanceAttachment(id) if err != nil { if NotFoundError(err) { if status == Deleted { return nil } } else { return WrapError(err) } } if object.Status == "Attached" { break } if time.Now().After(deadline) { return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, object.Status, status, ProviderERROR) } time.Sleep(DefaultIntervalShort * time.Second) } return nil } func (s *CenService) DescribeCenBandwidthPackage(id string) (c cbn.CenBandwidthPackage, err error) { request := cbn.CreateDescribeCenBandwidthPackagesRequest() request.RegionId = s.client.RegionId values := []string{id} filters := []cbn.DescribeCenBandwidthPackagesFilter{{ Key: "CenBandwidthPackageId", Value: &values, }} request.Filter = &filters var raw interface{} wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(10*time.Minute, func() *resource.RetryError { raw, err = s.client.WithCbnClient(func(cbnClient *cbn.Client) (interface{}, error) { return cbnClient.DescribeCenBandwidthPackages(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 { if IsExpectedErrors(err, []string{"ParameterCenInstanceId"}) { return c, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR) } return c, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR) } response, _ := raw.(*cbn.DescribeCenBandwidthPackagesResponse) if len(response.CenBandwidthPackages.CenBandwidthPackage) <= 0 || response.CenBandwidthPackages.CenBandwidthPackage[0].CenBandwidthPackageId != id { return c, WrapErrorf(NotFoundErr("CEN Bandwidth Package", id), NotFoundMsg, ProviderERROR) } c = response.CenBandwidthPackages.CenBandwidthPackage[0] return c, nil } func (s *CenService) WaitForCenBandwidthPackage(id string, status Status, bandwidth, timeout int) error { deadline := time.Now().Add(time.Duration(timeout) * time.Second) for { object, err := s.DescribeCenBandwidthPackage(id) if err != nil { if NotFoundError(err) { if status == Deleted { return nil } } else { return WrapError(err) } } if object.Status == string(status) && strconv.FormatInt(object.Bandwidth, 10) == strconv.Itoa(bandwidth) { return nil } if time.Now().After(deadline) { return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, object.Status, status, ProviderERROR) } time.Sleep(DefaultIntervalShort * time.Second) } } func (s *CenService) DescribeCenBandwidthPackageAttachment(id string) (c cbn.CenBandwidthPackage, err error) { object, err := s.DescribeCenBandwidthPackage(id) if err != nil { return c, WrapError(err) } if len(object.CenIds.CenId) != 1 || object.Status != string(InUse) { return c, WrapErrorf(NotFoundErr("CenBandwidthPackageAttachment", id), NotFoundMsg, ProviderERROR) } return object, nil } func (s *CenService) WaitForCenBandwidthPackageAttachment(id string, status Status, timeout int) error { deadline := time.Now().Add(time.Duration(timeout) * time.Second) for { object, err := s.DescribeCenBandwidthPackageAttachment(id) if err != nil { if NotFoundError(err) { if status == Deleted { return nil } } else { return WrapError(err) } } if object.Status == string(status) { break } if time.Now().After(deadline) { return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, object.Status, status, ProviderERROR) } time.Sleep(DefaultIntervalShort * time.Second) } return nil } func (s *CenService) SetCenInterRegionBandwidthLimit(cenId, localRegionId, oppositeRegionId string, bandwidthLimit int) (err error) { request := cbn.CreateSetCenInterRegionBandwidthLimitRequest() request.RegionId = s.client.RegionId request.CenId = cenId request.LocalRegionId = localRegionId request.OppositeRegionId = oppositeRegionId request.BandwidthLimit = requests.NewInteger(bandwidthLimit) raw, err := s.client.WithCbnClient(func(cbnClient *cbn.Client) (interface{}, error) { return cbnClient.SetCenInterRegionBandwidthLimit(request) }) if err != nil { if IsExpectedErrors(err, []string{"InvalidOperation.CenInstanceStatus"}) { return WrapError(err) } return WrapErrorf(err, DefaultErrorMsg, "alicloud_cen_bandwidth_limit", request.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) return nil } func (s *CenService) DescribeCenBandwidthLimit(id string) (c cbn.CenInterRegionBandwidthLimit, err error) { request := cbn.CreateDescribeCenInterRegionBandwidthLimitsRequest() request.RegionId = s.client.RegionId paras, err := s.GetCenAndRegionIds(id) if err != nil { return c, WrapError(err) } cenId := paras[0] localRegionId := paras[1] oppositeRegionId := paras[2] if strings.Compare(localRegionId, oppositeRegionId) > 0 { localRegionId, oppositeRegionId = oppositeRegionId, localRegionId } request.CenId = cenId for pageNum := 1; ; pageNum++ { request.PageNumber = requests.NewInteger(pageNum) request.PageSize = requests.NewInteger(PageSizeLarge) var raw interface{} wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(10*time.Minute, func() *resource.RetryError { raw, err = s.client.WithCbnClient(func(cbnClient *cbn.Client) (interface{}, error) { return cbnClient.DescribeCenInterRegionBandwidthLimits(request) }) if err != nil { if NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) if err != nil { return c, WrapErrorf(err, DefaultErrorMsg, "alicloud_cen_bandwidth_limit", request.GetActionName(), AlibabaCloudSdkGoERROR) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) response, _ := raw.(*cbn.DescribeCenInterRegionBandwidthLimitsResponse) cenBandwidthLimitList := response.CenInterRegionBandwidthLimits.CenInterRegionBandwidthLimit for limitNum := 0; limitNum <= len(cenBandwidthLimitList)-1; limitNum++ { ifMatch := cenBandwidthLimitList[limitNum].LocalRegionId == localRegionId && cenBandwidthLimitList[limitNum].OppositeRegionId == oppositeRegionId if !ifMatch { ifMatch = cenBandwidthLimitList[limitNum].LocalRegionId == oppositeRegionId && cenBandwidthLimitList[limitNum].OppositeRegionId == localRegionId } if ifMatch { return cenBandwidthLimitList[limitNum], nil } } if pageNum*response.PageSize >= response.TotalCount { return c, WrapErrorf(NotFoundErr("CenBandwidthLimit", id), NotFoundMsg, ProviderERROR) } } } func (s *CenService) CenBandwidthLimitStateRefreshFunc(id string, failStates []string) resource.StateRefreshFunc { return func() (interface{}, string, error) { object, err := s.DescribeCenBandwidthLimit(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 object.Status == failState { return object, object.Status, WrapError(Error(FailedToReachTargetStatus, object.Status)) } } return object, object.Status, nil } } func (s *CenService) CreateCenRouteEntryParas(vtbId string) (childInstanceId string, instanceType string, err error) { vpcService := VpcService{s.client} //Query VRouterId and judge whether it is a vbr vtb1, err := vpcService.QueryRouteTableById(vtbId) if err != nil { return childInstanceId, instanceType, WrapError(err) } if strings.HasPrefix(vtb1.VRouterId, "vbr") { return vtb1.VRouterId, ChildInstanceTypeVbr, nil } //if the VRouterId belonged to a VPC, get the VPC ID vtb2, err := vpcService.DescribeRouteTable(vtbId) if err != nil { return childInstanceId, instanceType, WrapError(err) } return fmt.Sprint(vtb2["VpcId"]), ChildInstanceTypeVpc, nil } func (s *CenService) DescribeCenRouteEntry(id string) (c cbn.PublishedRouteEntry, err error) { parts, err := ParseResourceId(id, 3) if err != nil { return c, WrapError(err) } cenId := parts[0] vtbId := parts[1] cidr := parts[2] childInstanceId, childInstanceType, err := s.CreateCenRouteEntryParas(vtbId) if err != nil { return c, WrapError(err) } request := cbn.CreateDescribePublishedRouteEntriesRequest() request.RegionId = s.client.RegionId request.CenId = cenId request.ChildInstanceId = childInstanceId request.ChildInstanceType = childInstanceType request.ChildInstanceRegionId = s.client.RegionId request.ChildInstanceRouteTableId = vtbId request.DestinationCidrBlock = cidr var raw interface{} wait := incrementalWait(3*time.Second, 3*time.Second) err = resource.Retry(5*time.Minute, func() *resource.RetryError { raw, err = s.client.WithCbnClient(func(cbnClient *cbn.Client) (interface{}, error) { return cbnClient.DescribePublishedRouteEntries(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 { if IsExpectedErrors(err, []string{"ParameterIllegal", "ParameterIllegal.CenInstanceId", "Instance.NotExist"}) { return c, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR) } return c, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR) } response, _ := raw.(*cbn.DescribePublishedRouteEntriesResponse) if len(response.PublishedRouteEntries.PublishedRouteEntry) <= 0 || response.PublishedRouteEntries.PublishedRouteEntry[0].PublishStatus == string(NOPUBLISHED) { return c, WrapErrorf(NotFoundErr("CenRouteEntries", id), NotFoundMsg, ProviderERROR) } c = response.PublishedRouteEntries.PublishedRouteEntry[0] return c, nil } func (s *CenService) WaitForCenRouterEntry(id string, status Status, timeout int) error { deadline := time.Now().Add(time.Duration(timeout) * time.Second) for { object, err := s.DescribeCenRouteEntry(id) if err != nil { if NotFoundError(err) { if status == Deleted { return nil } } else { return WrapError(err) } } if object.PublishStatus == string(status) { break } if time.Now().After(deadline) { return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, object.PublishStatus, string(status), ProviderERROR) } time.Sleep(DefaultIntervalShort * time.Second) } return nil } func (s *CenService) GetCenIdAndAnotherId(id string) (string, string, error) { parts := strings.Split(id, COLON_SEPARATED) if len(parts) != 2 { return "", "", fmt.Errorf("invalid resource id") } return parts[0], parts[1], nil } func (s *CenService) GetCenAndRegionIds(id string) (retString []string, err error) { parts := strings.Split(id, COLON_SEPARATED) if len(parts) != 3 { return retString, fmt.Errorf("invalid resource id") } return parts, nil } func (s *CenService) CenInstanceAttachmentStateRefreshFunc(id string, failStates []string) resource.StateRefreshFunc { return func() (interface{}, string, error) { object, err := s.DescribeCenInstanceAttachment(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 object.Status == failState { return object, object.Status, WrapError(Error(FailedToReachTargetStatus, object.Status)) } } return object, object.Status, nil } }