Skip to content
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

r/api_gateway_usage_plan - change api_stages to set to fix ordering change #14345

Merged
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
250 changes: 161 additions & 89 deletions aws/resource_aws_api_gateway_usage_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func resourceAwsApiGatewayUsagePlan() *schema.Resource {
},

"api_stages": {
Type: schema.TypeList,
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -71,13 +71,9 @@ func resourceAwsApiGatewayUsagePlan() *schema.Resource {
},

"period": {
Type: schema.TypeString,
Required: true, // Required as not removable
ValidateFunc: validation.StringInSlice([]string{
apigateway.QuotaPeriodTypeDay,
apigateway.QuotaPeriodTypeWeek,
apigateway.QuotaPeriodTypeMonth,
}, false),
Type: schema.TypeString,
Required: true, // Required as not removable
ValidateFunc: validation.StringInSlice(apigateway.QuotaPeriodType_Values(), false),
},
},
},
Expand All @@ -90,15 +86,17 @@ func resourceAwsApiGatewayUsagePlan() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"burst_limit": {
Type: schema.TypeInt,
Default: 0,
Optional: true,
Type: schema.TypeInt,
Default: 0,
Optional: true,
AtLeastOneOf: []string{"throttle_settings.0.burst_limit", "throttle_settings.0.rate_limit"},
},

"rate_limit": {
Type: schema.TypeFloat,
Default: 0,
Optional: true,
Type: schema.TypeFloat,
Default: 0,
Optional: true,
AtLeastOneOf: []string{"throttle_settings.0.burst_limit", "throttle_settings.0.rate_limit"},
},
},
},
Expand Down Expand Up @@ -129,78 +127,27 @@ func resourceAwsApiGatewayUsagePlanCreate(d *schema.ResourceData, meta interface
params.Description = aws.String(v.(string))
}

if s, ok := d.GetOk("api_stages"); ok {
stages := s.([]interface{})
as := make([]*apigateway.ApiStage, 0)

for _, v := range stages {
sv := v.(map[string]interface{})
stage := &apigateway.ApiStage{}

if v, ok := sv["api_id"].(string); ok && v != "" {
stage.ApiId = aws.String(v)
}

if v, ok := sv["stage"].(string); ok && v != "" {
stage.Stage = aws.String(v)
}

as = append(as, stage)
}

if len(as) > 0 {
params.ApiStages = as
}
if v, ok := d.GetOk("api_stages"); ok && v.(*schema.Set).Len() > 0 {
params.ApiStages = expandApiGatewayUsageApiStages(v.(*schema.Set))
}

if v, ok := d.GetOk("quota_settings"); ok {
settings := v.([]interface{})
q, ok := settings[0].(map[string]interface{})

if errors := validateApiGatewayUsagePlanQuotaSettings(q); len(errors) > 0 {
return fmt.Errorf("Error validating the quota settings: %v", errors)
if errs := validateApiGatewayUsagePlanQuotaSettings(q); len(errs) > 0 {
return fmt.Errorf("error validating the quota settings: %v", errs)
}

if !ok {
return errors.New("At least one field is expected inside quota_settings")
}

qs := &apigateway.QuotaSettings{}

if sv, ok := q["limit"].(int); ok {
qs.Limit = aws.Int64(int64(sv))
}

if sv, ok := q["offset"].(int); ok {
qs.Offset = aws.Int64(int64(sv))
}

if sv, ok := q["period"].(string); ok && sv != "" {
qs.Period = aws.String(sv)
}

params.Quota = qs
params.Quota = expandApiGatewayUsageQuotaSettings(v.([]interface{}))
}

if v, ok := d.GetOk("throttle_settings"); ok {
settings := v.([]interface{})
q, ok := settings[0].(map[string]interface{})

if !ok {
return errors.New("At least one field is expected inside throttle_settings")
}

ts := &apigateway.ThrottleSettings{}

if sv, ok := q["burst_limit"].(int); ok {
ts.BurstLimit = aws.Int64(int64(sv))
}

if sv, ok := q["rate_limit"].(float64); ok {
ts.RateLimit = aws.Float64(sv)
}

params.Throttle = ts
params.Throttle = expandApiGatewayUsageThrottleSettings(v.([]interface{}))
}

if v, ok := d.GetOk("tags"); ok {
Expand All @@ -209,10 +156,10 @@ func resourceAwsApiGatewayUsagePlanCreate(d *schema.ResourceData, meta interface

up, err := conn.CreateUsagePlan(params)
if err != nil {
return fmt.Errorf("Error creating API Gateway Usage Plan: %s", err)
return fmt.Errorf("error creating API Gateway Usage Plan: %w", err)
}

d.SetId(*up.Id)
d.SetId(aws.StringValue(up.Id))

// Handle case of adding the product code since not addable when
// creating the Usage Plan initially.
Expand All @@ -230,7 +177,7 @@ func resourceAwsApiGatewayUsagePlanCreate(d *schema.ResourceData, meta interface

_, err = conn.UpdateUsagePlan(updateParameters)
if err != nil {
return fmt.Errorf("Error creating the API Gateway Usage Plan product code: %s", err)
return fmt.Errorf("error creating the API Gateway Usage Plan product code: %w", err)
}
}

Expand All @@ -256,7 +203,7 @@ func resourceAwsApiGatewayUsagePlanRead(d *schema.ResourceData, meta interface{}
}

if err := d.Set("tags", keyvaluetags.ApigatewayKeyValueTags(up.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
return fmt.Errorf("error setting tags: %s", err)
return fmt.Errorf("error setting tags: %w", err)
}

arn := arn.ARN{
Expand All @@ -273,19 +220,19 @@ func resourceAwsApiGatewayUsagePlanRead(d *schema.ResourceData, meta interface{}

if up.ApiStages != nil {
if err := d.Set("api_stages", flattenApiGatewayUsageApiStages(up.ApiStages)); err != nil {
return fmt.Errorf("Error setting api_stages error: %#v", err)
return fmt.Errorf("error setting api_stages error: %w", err)
}
}

if up.Throttle != nil {
if err := d.Set("throttle_settings", flattenApiGatewayUsagePlanThrottling(up.Throttle)); err != nil {
return fmt.Errorf("Error setting throttle_settings error: %#v", err)
return fmt.Errorf("error setting throttle_settings error: %w", err)
}
}

if up.Quota != nil {
if err := d.Set("quota_settings", flattenApiGatewayUsagePlanQuota(up.Quota)); err != nil {
return fmt.Errorf("Error setting quota_settings error: %#v", err)
return fmt.Errorf("error setting quota_settings error: %w", err)
}
}

Expand Down Expand Up @@ -333,12 +280,12 @@ func resourceAwsApiGatewayUsagePlanUpdate(d *schema.ResourceData, meta interface

if d.HasChange("api_stages") {
o, n := d.GetChange("api_stages")
old := o.([]interface{})
new := n.([]interface{})
os := o.(*schema.Set).List()
ns := n.(*schema.Set).List()

// Remove every stages associated. Simpler to remove and add new ones,
// since there are no replacings.
for _, v := range old {
for _, v := range os {
m := v.(map[string]interface{})
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String(apigateway.OpRemove),
Expand All @@ -348,8 +295,8 @@ func resourceAwsApiGatewayUsagePlanUpdate(d *schema.ResourceData, meta interface
}

// Handle additions
if len(new) > 0 {
for _, v := range new {
if len(ns) > 0 {
for _, v := range ns {
m := v.(map[string]interface{})
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String(apigateway.OpAdd),
Expand Down Expand Up @@ -467,7 +414,7 @@ func resourceAwsApiGatewayUsagePlanUpdate(d *schema.ResourceData, meta interface
if d.HasChange("tags") {
o, n := d.GetChange("tags")
if err := keyvaluetags.ApigatewayUpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
return fmt.Errorf("error updating tags: %s", err)
return fmt.Errorf("error updating tags: %w", err)
}
}

Expand All @@ -478,7 +425,7 @@ func resourceAwsApiGatewayUsagePlanUpdate(d *schema.ResourceData, meta interface

_, err := conn.UpdateUsagePlan(params)
if err != nil {
return fmt.Errorf("Error updating API Gateway Usage Plan: %s", err)
return fmt.Errorf("error updating API Gateway Usage Plan: %w", err)
}

return resourceAwsApiGatewayUsagePlanRead(d, meta)
Expand All @@ -490,10 +437,10 @@ func resourceAwsApiGatewayUsagePlanDelete(d *schema.ResourceData, meta interface
// Removing existing api stages associated
if apistages, ok := d.GetOk("api_stages"); ok {
log.Printf("[DEBUG] Deleting API Stages associated with Usage Plan: %s", d.Id())
stages := apistages.([]interface{})
stages := apistages.(*schema.Set)
operations := []*apigateway.PatchOperation{}

for _, v := range stages {
for _, v := range stages.List() {
sv := v.(map[string]interface{})

operations = append(operations, &apigateway.PatchOperation{
Expand All @@ -508,7 +455,7 @@ func resourceAwsApiGatewayUsagePlanDelete(d *schema.ResourceData, meta interface
PatchOperations: operations,
})
if err != nil {
return fmt.Errorf("Error removing API Stages associated with Usage Plan: %s", err)
return fmt.Errorf("error removing API Stages associated with Usage Plan: %w", err)
}
}

Expand All @@ -519,9 +466,134 @@ func resourceAwsApiGatewayUsagePlanDelete(d *schema.ResourceData, meta interface
})

if err != nil {
return fmt.Errorf("Error deleting API gateway usage plan: %s", err)
return fmt.Errorf("error deleting API gateway usage plan: %w", err)
}

return nil

}

func expandApiGatewayUsageApiStages(s *schema.Set) []*apigateway.ApiStage {
stages := []*apigateway.ApiStage{}

for _, stageRaw := range s.List() {
stage := &apigateway.ApiStage{}
mStage := stageRaw.(map[string]interface{})

if v, ok := mStage["api_id"].(string); ok && v != "" {
stage.ApiId = aws.String(v)
}

if v, ok := mStage["stage"].(string); ok && v != "" {
stage.Stage = aws.String(v)
}

stages = append(stages, stage)
}

return stages
}

func expandApiGatewayUsageQuotaSettings(l []interface{}) *apigateway.QuotaSettings {
if len(l) == 0 {
return nil
}

m := l[0].(map[string]interface{})

qs := &apigateway.QuotaSettings{}

if v, ok := m["limit"].(int); ok {
qs.Limit = aws.Int64(int64(v))
}

if v, ok := m["offset"].(int); ok {
qs.Offset = aws.Int64(int64(v))
}

if v, ok := m["period"].(string); ok && v != "" {
qs.Period = aws.String(v)
}

return qs
}

func expandApiGatewayUsageThrottleSettings(l []interface{}) *apigateway.ThrottleSettings {
if len(l) == 0 {
return nil
}

m := l[0].(map[string]interface{})

ts := &apigateway.ThrottleSettings{}

if sv, ok := m["burst_limit"].(int); ok {
ts.BurstLimit = aws.Int64(int64(sv))
}

if sv, ok := m["rate_limit"].(float64); ok {
ts.RateLimit = aws.Float64(sv)
}

return ts
}

func flattenApiGatewayUsageApiStages(s []*apigateway.ApiStage) []map[string]interface{} {
stages := make([]map[string]interface{}, 0)

for _, bd := range s {
if bd.ApiId != nil && bd.Stage != nil {
stage := make(map[string]interface{})
stage["api_id"] = aws.StringValue(bd.ApiId)
stage["stage"] = aws.StringValue(bd.Stage)

stages = append(stages, stage)
}
}

if len(stages) > 0 {
return stages
}

return nil
}

func flattenApiGatewayUsagePlanThrottling(s *apigateway.ThrottleSettings) []map[string]interface{} {
settings := make(map[string]interface{})

if s == nil {
return nil
}

if s.BurstLimit != nil {
settings["burst_limit"] = aws.Int64Value(s.BurstLimit)
}

if s.RateLimit != nil {
settings["rate_limit"] = aws.Float64Value(s.RateLimit)
}

return []map[string]interface{}{settings}
}

func flattenApiGatewayUsagePlanQuota(s *apigateway.QuotaSettings) []map[string]interface{} {
settings := make(map[string]interface{})

if s == nil {
return nil
}

if s.Limit != nil {
settings["limit"] = aws.Int64Value(s.Limit)
}

if s.Offset != nil {
settings["offset"] = aws.Int64Value(s.Offset)
}

if s.Period != nil {
settings["period"] = aws.StringValue(s.Period)
}

return []map[string]interface{}{settings}
}
Loading