Skip to content

Commit

Permalink
Merge pull request #14345 from DrFaust92/r/api_gateway_usage_plan_mul…
Browse files Browse the repository at this point in the history
…ti_stage

r/api_gateway_usage_plan - change `api_stages` to set to fix ordering change
  • Loading branch information
gdavison authored Oct 29, 2020
2 parents 6292399 + 23eaafb commit 31cbed4
Show file tree
Hide file tree
Showing 3 changed files with 293 additions and 250 deletions.
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

0 comments on commit 31cbed4

Please sign in to comment.