alicloud/service_alicloud_api_gateway.go (595 lines of code) (raw):
package alicloud
import (
"fmt"
"log"
"regexp"
"strconv"
"time"
"github.com/PaesslerAG/jsonpath"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/services/cloudapi"
"github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity"
)
type CloudApiService struct {
client *connectivity.AliyunClient
}
func (s *CloudApiService) DescribeApiGatewayGroup(id string) (*cloudapi.DescribeApiGroupResponse, error) {
apiGroup := &cloudapi.DescribeApiGroupResponse{}
request := cloudapi.CreateDescribeApiGroupRequest()
request.RegionId = s.client.RegionId
request.GroupId = id
raw, err := s.client.WithCloudApiClient(func(cloudApiClient *cloudapi.Client) (interface{}, error) {
return cloudApiClient.DescribeApiGroup(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"NotFoundApiGroup"}) {
return apiGroup, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return apiGroup, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
apiGroup, _ = raw.(*cloudapi.DescribeApiGroupResponse)
if apiGroup.GroupId == "" {
return apiGroup, WrapErrorf(NotFoundErr("ApiGatewayGroup", id), NotFoundMsg, ProviderERROR)
}
return apiGroup, nil
}
func (s *CloudApiService) WaitForApiGatewayGroup(id string, status Status, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
object, err := s.DescribeApiGatewayGroup(id)
if err != nil {
if NotFoundError(err) {
if status == Deleted {
return nil
}
} else {
return WrapError(err)
}
}
if string(object.GroupId) == id && status != Deleted {
return nil
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, string(object.GroupId), id, ProviderERROR)
}
}
}
func (s *CloudApiService) DescribeApiGatewayApp(id string) (*cloudapi.DescribeAppResponse, error) {
app := &cloudapi.DescribeAppResponse{}
request := cloudapi.CreateDescribeAppRequest()
request.RegionId = s.client.RegionId
request.AppId = requests.Integer(id)
raw, err := s.client.WithCloudApiClient(func(cloudApiClient *cloudapi.Client) (interface{}, error) {
return cloudApiClient.DescribeApp(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"NotFoundApp"}) {
return app, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return app, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
app, _ = raw.(*cloudapi.DescribeAppResponse)
return app, nil
}
func (s *CloudApiService) WaitForApiGatewayApp(id string, status Status, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
object, err := s.DescribeApiGatewayApp(id)
if err != nil {
if NotFoundError(err) {
if status == Deleted {
return nil
}
} else {
return WrapError(err)
}
}
if fmt.Sprint(object.AppId) == id && status != Deleted {
return nil
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, fmt.Sprint(object.AppId), id, ProviderERROR)
}
}
}
func (s *CloudApiService) DescribeApiGatewayApi(id string) (*cloudapi.DescribeApiResponse, error) {
api := &cloudapi.DescribeApiResponse{}
parts, err := ParseResourceId(id, 2)
if err != nil {
return api, WrapError(err)
}
request := cloudapi.CreateDescribeApiRequest()
request.RegionId = s.client.RegionId
request.ApiId = parts[1]
request.GroupId = parts[0]
raw, err := s.client.WithCloudApiClient(func(cloudApiClient *cloudapi.Client) (interface{}, error) {
return cloudApiClient.DescribeApi(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"NotFoundApiGroup", "NotFoundApi"}) {
return api, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return api, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
api, _ = raw.(*cloudapi.DescribeApiResponse)
if api.ApiId == "" {
return api, WrapErrorf(NotFoundErr("ApiGatewayApi", id), NotFoundMsg, ProviderERROR)
}
return api, nil
}
func (s *CloudApiService) WaitForApiGatewayApi(id string, status Status, timeout int) error {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
object, err := s.DescribeApiGatewayApi(id)
if err != nil {
if NotFoundError(err) {
if status == Deleted {
return nil
}
}
return WrapError(err)
}
respId := fmt.Sprintf("%s%s%s", object.GroupId, COLON_SEPARATED, object.ApiId)
if respId == id && status != Deleted {
return nil
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, respId, id, ProviderERROR)
}
}
}
func (s *CloudApiService) DescribeApiGatewayAppAttachment(id string) (*cloudapi.AuthorizedApp, error) {
app := &cloudapi.AuthorizedApp{}
request := cloudapi.CreateDescribeAuthorizedAppsRequest()
request.RegionId = s.client.RegionId
parts, err := ParseResourceId(id, 4)
if err != nil {
return app, WrapError(err)
}
request.GroupId = parts[0]
request.ApiId = parts[1]
request.StageName = parts[3]
appId, _ := strconv.ParseInt(parts[2], 10, 64)
var allApps []cloudapi.AuthorizedApp
for {
raw, err := s.client.WithCloudApiClient(func(cloudApiClient *cloudapi.Client) (interface{}, error) {
return cloudApiClient.DescribeAuthorizedApps(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"NotFoundApiGroup", "NotFoundApi"}) {
return app, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return app, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
response, _ := raw.(*cloudapi.DescribeAuthorizedAppsResponse)
allApps = append(allApps, response.AuthorizedApps.AuthorizedApp...)
if len(allApps) < PageSizeLarge {
break
}
page, err := getNextpageNumber(request.PageNumber)
if err != nil {
return app, WrapError(err)
}
request.PageNumber = page
}
var filteredAppsTemp []cloudapi.AuthorizedApp
for _, app := range allApps {
if app.AppId == appId {
filteredAppsTemp = append(filteredAppsTemp, app)
}
}
if len(filteredAppsTemp) < 1 {
return app, WrapErrorf(NotFoundErr("ApigatewayAppAttachment", id), NotFoundMsg, ProviderERROR)
}
app = &filteredAppsTemp[0]
return app, nil
}
func (s *CloudApiService) DescribeApiGatewayPluginAttachment(id string) (*cloudapi.PluginAttribute, error) {
plugin := &cloudapi.PluginAttribute{}
request := cloudapi.CreateDescribePluginsByApiRequest()
request.RegionId = s.client.RegionId
parts, err := ParseResourceId(id, 4)
if err != nil {
return plugin, WrapError(err)
}
request.GroupId = parts[0]
request.ApiId = parts[1]
request.StageName = parts[3]
pluginId := parts[2]
var allPlugins []cloudapi.PluginAttribute
for {
raw, err := s.client.WithCloudApiClient(func(cloudApiClient *cloudapi.Client) (interface{}, error) {
return cloudApiClient.DescribePluginsByApi(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"NotFoundApiGroup", "NotFoundApi"}) {
return plugin, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return plugin, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
response, _ := raw.(*cloudapi.DescribePluginsByApiResponse)
allPlugins = append(allPlugins, response.Plugins.PluginAttribute...)
if len(allPlugins) < PageSizeLarge {
break
}
page, err := getNextpageNumber(request.PageNumber)
if err != nil {
return plugin, WrapError(err)
}
request.PageNumber = page
}
var filteredPluginsTemp []cloudapi.PluginAttribute
for _, plugin := range allPlugins {
if plugin.PluginId == pluginId {
filteredPluginsTemp = append(filteredPluginsTemp, plugin)
}
}
if len(filteredPluginsTemp) < 1 {
return plugin, WrapErrorf(NotFoundErr("ApiGatewayPluginAttachment", id), NotFoundMsg, ProviderERROR)
}
plugin = &filteredPluginsTemp[0]
return plugin, nil
}
func (s *CloudApiService) DescribeApiGatewayVpcAccess(id string) (*cloudapi.VpcAccessAttribute, error) {
vpc := &cloudapi.VpcAccessAttribute{}
request := cloudapi.CreateDescribeVpcAccessesRequest()
request.RegionId = s.client.RegionId
parts, err := ParseResourceId(id, 4)
if err != nil {
return vpc, WrapError(err)
}
var allVpcs []cloudapi.VpcAccessAttribute
for {
raw, err := s.client.WithCloudApiClient(func(cloudApiClient *cloudapi.Client) (interface{}, error) {
return cloudApiClient.DescribeVpcAccesses(request)
})
if err != nil {
return vpc, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
response, _ := raw.(*cloudapi.DescribeVpcAccessesResponse)
allVpcs = append(allVpcs, response.VpcAccessAttributes.VpcAccessAttribute...)
if len(allVpcs) < PageSizeLarge {
break
}
if page, err := getNextpageNumber(request.PageNumber); err != nil {
return vpc, WrapError(err)
} else {
request.PageNumber = page
}
}
var filteredVpcsTemp []cloudapi.VpcAccessAttribute
for _, vpc := range allVpcs {
iPort, _ := strconv.Atoi(parts[3])
if vpc.Port == iPort && vpc.InstanceId == parts[2] && vpc.VpcId == parts[1] && vpc.Name == parts[0] {
filteredVpcsTemp = append(filteredVpcsTemp, vpc)
}
}
if len(filteredVpcsTemp) < 1 {
return vpc, WrapErrorf(NotFoundErr("ApiGatewayVpcAccess", id), NotFoundMsg, ProviderERROR)
}
return &filteredVpcsTemp[0], nil
}
func (s *CloudApiService) WaitForApiGatewayAppAttachment(id string, status Status, timeout int) (err error) {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
parts, err := ParseResourceId(id, 4)
if err != nil {
return WrapError(err)
}
appIds := parts[2]
for {
object, err := s.DescribeApiGatewayAppAttachment(id)
if err != nil {
if NotFoundError(err) {
if status == Deleted {
return nil
}
} else {
return WrapError(err)
}
}
if strconv.FormatInt(object.AppId, 10) == appIds && status != Deleted {
return nil
}
if time.Now().After(deadline) {
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, strconv.FormatInt(object.AppId, 10), appIds, ProviderERROR)
}
time.Sleep(DefaultIntervalShort * time.Second)
}
}
func (s *CloudApiService) DescribeDeployedApi(id string, stageName string) (*cloudapi.DescribeDeployedApiResponse, error) {
api := &cloudapi.DescribeDeployedApiResponse{}
request := cloudapi.CreateDescribeDeployedApiRequest()
request.RegionId = s.client.RegionId
parts, err := ParseResourceId(id, 2)
if err != nil {
return api, WrapError(err)
}
request.ApiId = parts[1]
request.GroupId = parts[0]
request.StageName = stageName
raw, err := s.client.WithCloudApiClient(func(cloudApiClient *cloudapi.Client) (interface{}, error) {
return cloudApiClient.DescribeDeployedApi(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"NotFoundApiGroup", "NotFoundApi", "NotFoundStage"}) {
return api, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return api, WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
api, _ = raw.(*cloudapi.DescribeDeployedApiResponse)
return api, nil
}
func (s *CloudApiService) DeployedApi(id string, stageName string) (err error) {
request := cloudapi.CreateDeployApiRequest()
request.RegionId = s.client.RegionId
parts, err := ParseResourceId(id, 2)
if err != nil {
return WrapError(err)
}
request.ApiId = parts[1]
request.GroupId = parts[0]
request.StageName = stageName
request.Description = DeployCommonDescription
raw, err := s.client.WithCloudApiClient(func(cloudApiClient *cloudapi.Client) (interface{}, error) {
return cloudApiClient.DeployApi(request)
})
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
return
}
func (s *CloudApiService) AbolishApi(id string, stageName string) (err error) {
request := cloudapi.CreateAbolishApiRequest()
request.RegionId = s.client.RegionId
parts, err := ParseResourceId(id, 2)
if err != nil {
return WrapError(err)
}
request.ApiId = parts[1]
request.GroupId = parts[0]
request.StageName = stageName
raw, err := s.client.WithCloudApiClient(func(cloudApiClient *cloudapi.Client) (interface{}, error) {
return cloudApiClient.AbolishApi(request)
})
if err != nil {
if IsExpectedErrors(err, []string{"NotFoundApiGroup", "NotFoundApi", "NotFoundStage"}) {
return WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
return
}
func (s *CloudApiService) DescribeTags(resourceId string, resourceTags map[string]interface{}, resourceType TagResourceType) (tags []cloudapi.TagResource, err error) {
request := cloudapi.CreateListTagResourcesRequest()
request.RegionId = s.client.RegionId
request.ResourceType = string(resourceType)
request.ResourceId = &[]string{resourceId}
if resourceTags != nil && len(resourceTags) > 0 {
var reqTags []cloudapi.ListTagResourcesTag
for key, value := range resourceTags {
reqTags = append(reqTags, cloudapi.ListTagResourcesTag{
Key: key,
Value: value.(string),
})
}
request.Tag = &reqTags
}
raw, err := s.client.WithCloudApiClient(func(cloudApiClient *cloudapi.Client) (interface{}, error) {
return cloudApiClient.ListTagResources(request)
})
if err != nil {
err = WrapErrorf(err, DefaultErrorMsg, resourceId, request.GetActionName(), AlibabaCloudSdkGoERROR)
return
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
response, _ := raw.(*cloudapi.ListTagResourcesResponse)
return response.TagResources.TagResource, nil
}
func (s *CloudApiService) 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 := cloudapi.CreateUntagResourcesRequest()
request.ResourceId = &[]string{d.Id()}
request.ResourceType = string(resourceType)
request.TagKey = &tagKey
request.RegionId = s.client.RegionId
raw, err := s.client.WithCloudApiClient(func(client *cloudapi.Client) (interface{}, error) {
return client.UntagResources(request)
})
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
}
if len(create) > 0 {
request := cloudapi.CreateTagResourcesRequest()
request.ResourceId = &[]string{d.Id()}
request.Tag = &create
request.ResourceType = string(resourceType)
request.RegionId = s.client.RegionId
raw, err := s.client.WithCloudApiClient(func(client *cloudapi.Client) (interface{}, error) {
return client.TagResources(request)
})
if err != nil {
return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
}
d.SetPartial("tags")
return nil
}
func (s *CloudApiService) tagsToMap(tags []cloudapi.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 *CloudApiService) ignoreTag(t cloudapi.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 *CloudApiService) diffTags(oldTags, newTags []cloudapi.TagResourcesTag) ([]cloudapi.TagResourcesTag, []cloudapi.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 []cloudapi.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 *CloudApiService) tagsFromMap(m map[string]interface{}) []cloudapi.TagResourcesTag {
result := make([]cloudapi.TagResourcesTag, 0, len(m))
for k, v := range m {
result = append(result, cloudapi.TagResourcesTag{
Key: k,
Value: v.(string),
})
}
return result
}
func (s *CloudApiService) DescribeApiGatewayBackend(id string) (object map[string]interface{}, err error) {
client := s.client
request := map[string]interface{}{
"BackendId": id,
}
var response map[string]interface{}
action := "DescribeBackendInfo"
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
resp, err := client.RpcPost("CloudAPI", "2016-07-14", action, nil, request, true)
if err != nil {
if NeedRetry(err) {
wait()
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
response = resp
addDebug(action, response, request)
return nil
})
if err != nil {
if IsExpectedErrors(err, []string{"NotFoundBackend"}) {
return object, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR)
}
return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR)
}
v, err := jsonpath.Get("$.BackendInfo", response)
if err != nil {
return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.BackendInfo", response)
}
return v.(map[string]interface{}), nil
}
func (s *CloudApiService) DescribeApiGatewayLogConfig(id string) (object map[string]interface{}, err error) {
var response map[string]interface{}
client := s.client
action := "DescribeLogConfig"
request := map[string]interface{}{
"LogType": id,
}
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
response, err = client.RpcPost("CloudAPI", "2016-07-14", 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("$.LogInfos.LogInfo", response)
if err != nil {
return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.LogInfos.LogInfo", response)
}
if len(v.([]interface{})) < 1 {
return object, WrapErrorf(NotFoundErr("ApiGateway", id), NotFoundWithResponse, response)
} else {
if fmt.Sprint(v.([]interface{})[0].(map[string]interface{})["LogType"]) != id {
return object, WrapErrorf(NotFoundErr("ApiGateway", id), NotFoundWithResponse, response)
}
}
object = v.([]interface{})[0].(map[string]interface{})
return object, nil
}
func (s *CloudApiService) DescribeApiGatewayModel(id string) (object map[string]interface{}, err error) {
var response map[string]interface{}
action := "DescribeModels"
client := s.client
parts, err := ParseResourceId(id, 2)
if err != nil {
return nil, WrapError(err)
}
request := map[string]interface{}{
"GroupId": parts[0],
"ModelName": parts[1],
}
wait := incrementalWait(3*time.Second, 3*time.Second)
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
response, err = client.RpcPost("CloudAPI", "2016-07-14", 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("$.ModelDetails.ModelDetail", response)
if err != nil {
return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.ModelDetails.ModelDetail", response)
}
if len(v.([]interface{})) < 1 {
return object, WrapErrorf(NotFoundErr("ApiGateway", id), NotFoundWithResponse, response)
} else {
if fmt.Sprint(v.([]interface{})[0].(map[string]interface{})["ModelName"]) != parts[1] {
return object, WrapErrorf(NotFoundErr("ApiGateway", id), NotFoundWithResponse, response)
}
}
object = v.([]interface{})[0].(map[string]interface{})
return object, nil
}