Skip to content

Commit

Permalink
Merge branch 'main' into feat/tsuru_certificate_issuer
Browse files Browse the repository at this point in the history
  • Loading branch information
wpjunior authored Dec 11, 2024
2 parents cc37ef1 + 3aebde1 commit 72394d5
Show file tree
Hide file tree
Showing 5 changed files with 400 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"go.testEnvVars": {
"TF_ACC": "1",
"TF_ACC_TERRAFORM_VERSION": "1.4.4"
}
}
63 changes: 62 additions & 1 deletion internal/provider/resource_tsuru_app_autoscale.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,31 @@ func resourceTsuruApplicationAutoscale() *schema.Resource {
Optional: true,
AtLeastOneOf: []string{"cpu_average", "schedule", "prometheus"},
},
"scale_down": {
Type: schema.TypeList,
Description: "Behavior of the auto scale down",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"units": {
Type: schema.TypeInt,
Optional: true,
Description: "Number of units to scale down",
},
"percentage": {
Type: schema.TypeInt,
Optional: true,
Description: "Percentage of units to scale down",
},
"stabilization_window": {
Type: schema.TypeInt,
Optional: true,
Description: "Stabilization window in seconds",
},
},
},
Optional: true,
AtLeastOneOf: []string{"cpu_average", "schedule", "prometheus"},
},
},
}
}
Expand Down Expand Up @@ -167,6 +192,9 @@ func resourceTsuruApplicationAutoscaleSet(ctx context.Context, d *schema.Resourc
Process: process,
MinUnits: int32(minUnits),
MaxUnits: int32(maxUnits),
Behavior: tsuru_client.AutoScaleSpecBehavior{
ScaleDown: tsuru_client.AutoScaleSpecBehaviorScaleDown{},
},
}

if cpu, ok := d.GetOk("cpu_average"); ok {
Expand All @@ -186,6 +214,10 @@ func resourceTsuruApplicationAutoscaleSet(ctx context.Context, d *schema.Resourc
autoscale.Prometheus = prometheus
}
}
if m, ok := d.GetOk("scale_down"); ok {
scaleDown := scaleDownFromResourceData(m)
autoscale.Behavior.ScaleDown = scaleDown
}

err = resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
_, err = provider.TsuruClient.AppApi.AutoScaleAdd(ctx, app, autoscale)
Expand Down Expand Up @@ -225,6 +257,8 @@ func resourceTsuruApplicationAutoscaleRead(ctx context.Context, d *schema.Resour

retryCount := 0
maxRetries := 5

_, proposed := d.GetChange("scale_down")
// autoscale info reflects near realtime
err = resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
retryCount++
Expand Down Expand Up @@ -254,7 +288,7 @@ func resourceTsuruApplicationAutoscaleRead(ctx context.Context, d *schema.Resour

d.Set("schedule", flattenSchedules(autoscale.Schedules))
d.Set("prometheus", flattenPrometheus(autoscale.Prometheus, d))

d.Set("scale_down", flattenScaleDown(autoscale.Behavior.ScaleDown, proposed))
return nil
}

Expand Down Expand Up @@ -394,6 +428,33 @@ func prometheusFromResourceData(meta interface{}) []tsuru_client.AutoScalePromet
return prometheus
}

func scaleDownFromResourceData(meta interface{}) tsuru_client.AutoScaleSpecBehaviorScaleDown {
scaleDownMeta := meta.([]interface{})
if len(scaleDownMeta) == 0 {
return tsuru_client.AutoScaleSpecBehaviorScaleDown{}
}
scaleDown := tsuru_client.AutoScaleSpecBehaviorScaleDown{}
for _, iFace := range scaleDownMeta {
sd := iFace.(map[string]interface{})
if v, ok := sd["percentage"]; ok {
if val, ok := v.(int); ok {
scaleDown.PercentagePolicyValue = int32(val)

Check failure on line 441 in internal/provider/resource_tsuru_app_autoscale.go

View workflow job for this annotation

GitHub Actions / build

cannot use int32(val) (value of type int32) as *int32 value in assignment
}
}
if v, ok := sd["units"]; ok {
if val, ok := v.(int); ok {
scaleDown.UnitsPolicyValue = int32(val)

Check failure on line 446 in internal/provider/resource_tsuru_app_autoscale.go

View workflow job for this annotation

GitHub Actions / build

cannot use int32(val) (value of type int32) as *int32 value in assignment
}
}
if v, ok := sd["stabilization_window"]; ok {
if val, ok := v.(int); ok {
scaleDown.StabilizationWindow = int32(val)

Check failure on line 451 in internal/provider/resource_tsuru_app_autoscale.go

View workflow job for this annotation

GitHub Actions / build

cannot use int32(val) (value of type int32) as *int32 value in assignment
}
}
}
return scaleDown
}

func flattenSchedules(schedules []tsuru_client.AutoScaleSchedule) []interface{} {
result := []interface{}{}

Expand Down
132 changes: 132 additions & 0 deletions internal/provider/resource_tsuru_app_autoscale_flatten.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright 2024 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package provider

import (
"fmt"
"reflect"

tsuru_client "github.com/tsuru/go-tsuruclient/pkg/tsuru"
)

type flattenScaleDownBehavior struct {
PERCENTAGE_VALUE int32
PERCENTAGE_LABEL string
STABILIZATION_WINDOW_VALUE int32
STABILIZATION_WINDOW_LABEL string
UNITS_VALUE int32
UNITS_LABEL string
ScaleDownRead tsuru_client.AutoScaleSpecBehaviorScaleDown
Proposed interface{}
}

func flattenScaleDown(scaleDownRead tsuru_client.AutoScaleSpecBehaviorScaleDown, proposed interface{}) interface{} {
fsd := &flattenScaleDownBehavior{
PERCENTAGE_VALUE: 10,
PERCENTAGE_LABEL: "percentage",
STABILIZATION_WINDOW_VALUE: 300,
STABILIZATION_WINDOW_LABEL: "stabilization_window",
UNITS_VALUE: 3,
UNITS_LABEL: "units",
ScaleDownRead: scaleDownRead,
Proposed: proposed,
}
return fsd.execute()
}

func (fsd *flattenScaleDownBehavior) execute() interface{} {
if fsd.ScaleDownRead == (tsuru_client.AutoScaleSpecBehaviorScaleDown{}) {
return nil
}
proposedList, err := fsd.convertToMapSlice(fsd.Proposed)
if err != nil {
return []map[string]interface{}{{
"percentage": fsd.ScaleDownRead.PercentagePolicyValue,
"stabilization_window": fsd.ScaleDownRead.StabilizationWindow,
"units": fsd.ScaleDownRead.UnitsPolicyValue,
}}
}
if value, ok := fsd.noInputParameters(proposedList); ok {
return value
}
return fsd.withInputParameters(proposedList)
}

func (fsd *flattenScaleDownBehavior) withInputParameters(proposedList []map[string]interface{}) (value []map[string]interface{}) {
scaleDownCurrent := []map[string]interface{}{{}}
percentage, ok := fsd.findScaleDownInProposedList(proposedList, fsd.PERCENTAGE_LABEL)
if ok && percentage != 0 || fsd.ScaleDownRead.PercentagePolicyValue != int32(fsd.PERCENTAGE_VALUE) {

Check failure on line 60 in internal/provider/resource_tsuru_app_autoscale_flatten.go

View workflow job for this annotation

GitHub Actions / build

invalid operation: fsd.ScaleDownRead.PercentagePolicyValue != int32(fsd.PERCENTAGE_VALUE) (mismatched types *int32 and int32)
scaleDownCurrent[0][fsd.PERCENTAGE_LABEL] = fsd.ScaleDownRead.PercentagePolicyValue
}
stabilizationWindow, ok := fsd.findScaleDownInProposedList(proposedList, fsd.STABILIZATION_WINDOW_LABEL)
if ok && stabilizationWindow != 0 || fsd.ScaleDownRead.StabilizationWindow != int32(fsd.STABILIZATION_WINDOW_VALUE) {

Check failure on line 64 in internal/provider/resource_tsuru_app_autoscale_flatten.go

View workflow job for this annotation

GitHub Actions / build

invalid operation: fsd.ScaleDownRead.StabilizationWindow != int32(fsd.STABILIZATION_WINDOW_VALUE) (mismatched types *int32 and int32)
scaleDownCurrent[0][fsd.STABILIZATION_WINDOW_LABEL] = fsd.ScaleDownRead.StabilizationWindow
}
units, ok := fsd.findScaleDownInProposedList(proposedList, fsd.UNITS_LABEL)
if ok && units != 0 || fsd.ScaleDownRead.UnitsPolicyValue != int32(fsd.UNITS_VALUE) {

Check failure on line 68 in internal/provider/resource_tsuru_app_autoscale_flatten.go

View workflow job for this annotation

GitHub Actions / build

invalid operation: fsd.ScaleDownRead.UnitsPolicyValue != int32(fsd.UNITS_VALUE) (mismatched types *int32 and int32)
scaleDownCurrent[0][fsd.UNITS_LABEL] = fsd.ScaleDownRead.UnitsPolicyValue
}
return scaleDownCurrent
}

func (fsd *flattenScaleDownBehavior) noInputParameters(proposedList []map[string]interface{}) (value interface{}, ok bool) {
if len(proposedList) != 0 {
return nil, false
}
scaleDownCurrent := []map[string]interface{}{{}}
if fsd.ScaleDownRead.PercentagePolicyValue != fsd.PERCENTAGE_VALUE {

Check failure on line 79 in internal/provider/resource_tsuru_app_autoscale_flatten.go

View workflow job for this annotation

GitHub Actions / build

invalid operation: fsd.ScaleDownRead.PercentagePolicyValue != fsd.PERCENTAGE_VALUE (mismatched types *int32 and int32)
scaleDownCurrent[0][fsd.PERCENTAGE_LABEL] = fsd.ScaleDownRead.PercentagePolicyValue
}
if fsd.ScaleDownRead.StabilizationWindow != fsd.STABILIZATION_WINDOW_VALUE {

Check failure on line 82 in internal/provider/resource_tsuru_app_autoscale_flatten.go

View workflow job for this annotation

GitHub Actions / build

invalid operation: fsd.ScaleDownRead.StabilizationWindow != fsd.STABILIZATION_WINDOW_VALUE (mismatched types *int32 and int32)
scaleDownCurrent[0][fsd.STABILIZATION_WINDOW_LABEL] = fsd.ScaleDownRead.StabilizationWindow
}
if fsd.ScaleDownRead.UnitsPolicyValue != fsd.UNITS_VALUE {

Check failure on line 85 in internal/provider/resource_tsuru_app_autoscale_flatten.go

View workflow job for this annotation

GitHub Actions / build

invalid operation: fsd.ScaleDownRead.UnitsPolicyValue != fsd.UNITS_VALUE (mismatched types *int32 and int32)
scaleDownCurrent[0][fsd.UNITS_LABEL] = fsd.ScaleDownRead.UnitsPolicyValue
}
if fsd.isScaleDownEmpty(scaleDownCurrent) {
return nil, true
}
return scaleDownCurrent, true
}

func (fsd *flattenScaleDownBehavior) findScaleDownInProposedList(proposedList []map[string]interface{}, key string) (value int, ok bool) {
for _, item := range proposedList {
if v, ok := item[key]; ok {
return v.(int), true
}
}
return 0, false
}

func (fsd *flattenScaleDownBehavior) convertToMapSlice(input interface{}) ([]map[string]interface{}, error) {
var result []map[string]interface{}
if reflect.TypeOf(input).Kind() != reflect.Slice {
return nil, fmt.Errorf("scale down: invalid input type, slice expected")
}
for _, item := range input.([]interface{}) {
if mapItem, ok := item.(map[string]interface{}); ok {
result = append(result, mapItem)
} else {
return []map[string]interface{}{}, nil
}
}
return result, nil
}

func (fsd *flattenScaleDownBehavior) isScaleDownEmpty(param []map[string]interface{}) bool {
if len(param) != 1 {
return false
}
if _, ok := param[0][fsd.PERCENTAGE_LABEL]; ok {
return false
}
if _, ok := param[0][fsd.STABILIZATION_WINDOW_LABEL]; ok {
return false
}
if _, ok := param[0][fsd.UNITS_LABEL]; ok {
return false
}
return true
}
96 changes: 96 additions & 0 deletions internal/provider/resource_tsuru_app_autoscale_scale_down_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright 2024 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package provider

import (
"testing"

"github.com/stretchr/testify/assert"
tsuru_client "github.com/tsuru/go-tsuruclient/pkg/tsuru"
)

func TestFluentDown(t *testing.T) {
assert := assert.New(t)
tests := []struct {
scaleDownRead tsuru_client.AutoScaleSpecBehaviorScaleDown
scaleDownInput interface{}
expected interface{}
}{
{
scaleDownRead: tsuru_client.AutoScaleSpecBehaviorScaleDown{
UnitsPolicyValue: 3,
PercentagePolicyValue: 10,
StabilizationWindow: 300,
},
scaleDownInput: []interface{}{},
expected: nil,
},

{
scaleDownRead: tsuru_client.AutoScaleSpecBehaviorScaleDown{
UnitsPolicyValue: 3,
PercentagePolicyValue: 10,
StabilizationWindow: 300,
},
scaleDownInput: []interface{}{
map[string]interface{}{"units": 3},
},
expected: []map[string]interface{}{{
"units": int32(3),
}},
},
{
scaleDownRead: tsuru_client.AutoScaleSpecBehaviorScaleDown{
UnitsPolicyValue: 3,
PercentagePolicyValue: 10,
StabilizationWindow: 300,
},
scaleDownInput: []interface{}{
map[string]interface{}{"units": 3},
map[string]interface{}{"stabilization_window": 300},
map[string]interface{}{"percentage": 10},
},
expected: []map[string]interface{}{{
"units": int32(3),
"stabilization_window": int32(300),
"percentage": int32(10),
}},
},
{
scaleDownRead: tsuru_client.AutoScaleSpecBehaviorScaleDown{
UnitsPolicyValue: 21,
PercentagePolicyValue: 21,
StabilizationWindow: 21,
},
scaleDownInput: []interface{}{
map[string]interface{}{"units": 3},
map[string]interface{}{"stabilization_window": 300},
map[string]interface{}{"percentage": 10},
},
expected: []map[string]interface{}{{
"units": int32(21),
"stabilization_window": int32(21),
"percentage": int32(21),
}},
},
{
scaleDownRead: tsuru_client.AutoScaleSpecBehaviorScaleDown{
UnitsPolicyValue: 21,
PercentagePolicyValue: 21,
StabilizationWindow: 21,
},
scaleDownInput: []interface{}{},
expected: []map[string]interface{}{{
"units": int32(21),
"stabilization_window": int32(21),
"percentage": int32(21),
}},
},
}
for _, test := range tests {
readToDiff := flattenScaleDown(test.scaleDownRead, test.scaleDownInput)
assert.Equal(test.expected, readToDiff)
}
}
Loading

0 comments on commit 72394d5

Please sign in to comment.