Skip to content

Commit 89b92c7

Browse files
authored
Craft tsuru_certificate_issuer resource (#62)
* Craft tsuru_certificate_issuer resource * refactor: simplify logic in resourceTsuruCertificateIssuerRead function * Fix merge with new go-tsuruclient * Fix tests of TestFluentDown
1 parent 3aebde1 commit 89b92c7

9 files changed

+324
-40
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/labstack/echo/v4 v4.9.1
1010
github.com/pkg/errors v0.9.1
1111
github.com/stretchr/testify v1.9.0
12-
github.com/tsuru/go-tsuruclient v0.0.0-20241029183502-e219a905d873
12+
github.com/tsuru/go-tsuruclient v0.0.0-20241122210020-b97d66b89165
1313
github.com/tsuru/tsuru-client v0.0.0-20240325204824-8c0dc602a5be
1414
k8s.io/apimachinery v0.26.2
1515
)

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
206206
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
207207
github.com/tsuru/gnuflag v0.0.0-20151217162021-86b8c1b864aa h1:JlLQP1xa13a994p/Aau2e3K9xXYaHNoNvTDVIMHSUa4=
208208
github.com/tsuru/gnuflag v0.0.0-20151217162021-86b8c1b864aa/go.mod h1:UibOSvkMFKRe/eiwktAPAvQG8L+p8nYsECJvu3Dgw7I=
209-
github.com/tsuru/go-tsuruclient v0.0.0-20241029183502-e219a905d873 h1:Rs3urDCvqLpmGpUKOJNRiOCij/A+EcemdeOaGmGcs/E=
210-
github.com/tsuru/go-tsuruclient v0.0.0-20241029183502-e219a905d873/go.mod h1:qwh/KJ6ypa2GISRI79XFOHhnSjGOe1cZVPHF3nfrf18=
209+
github.com/tsuru/go-tsuruclient v0.0.0-20241122210020-b97d66b89165 h1:sDC3Z+/pfdviUdLIH2Tcxa2tVR6FSiTRIR0kWkK8iiQ=
210+
github.com/tsuru/go-tsuruclient v0.0.0-20241122210020-b97d66b89165/go.mod h1:qwh/KJ6ypa2GISRI79XFOHhnSjGOe1cZVPHF3nfrf18=
211211
github.com/tsuru/tablecli v0.0.0-20190131152944-7ded8a3383c6 h1:1XDdWFAjIbCSG1OjN9v9KdWhuM8UtYlFcfHe/Ldkchk=
212212
github.com/tsuru/tablecli v0.0.0-20190131152944-7ded8a3383c6/go.mod h1:ztYpOhW+u1k21FEqp7nZNgpWbr0dUKok5lgGCZi+1AQ=
213213
github.com/tsuru/tsuru v0.0.0-20240325190920-410c71393b77 h1:cuWFjNLaemdQZhojqJbb/rOXO97tlcPeLAHg/x+EQGk=

internal/provider/provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ func Provider() *schema.Provider {
7070
"tsuru_app_deploy": resourceTsuruApplicationDeploy(),
7171
"tsuru_app": resourceTsuruApplication(),
7272

73+
"tsuru_certificate_issuer": resourceTsuruCertificateIssuer(),
74+
7375
"tsuru_job": resourceTsuruJob(),
7476
"tsuru_job_env": resourceTsuruJobEnvironment(),
7577
"tsuru_job_deploy": resourceTsuruJobDeploy(),

internal/provider/resource_tsuru_app_autoscale.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1717
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1818
"github.com/pkg/errors"
19+
"k8s.io/utils/ptr"
1920

2021
tsuru_client "github.com/tsuru/go-tsuruclient/pkg/tsuru"
2122
)
@@ -438,17 +439,17 @@ func scaleDownFromResourceData(meta interface{}) tsuru_client.AutoScaleSpecBehav
438439
sd := iFace.(map[string]interface{})
439440
if v, ok := sd["percentage"]; ok {
440441
if val, ok := v.(int); ok {
441-
scaleDown.PercentagePolicyValue = int32(val)
442+
scaleDown.PercentagePolicyValue = ptr.To(int32(val))
442443
}
443444
}
444445
if v, ok := sd["units"]; ok {
445446
if val, ok := v.(int); ok {
446-
scaleDown.UnitsPolicyValue = int32(val)
447+
scaleDown.UnitsPolicyValue = ptr.To(int32(val))
447448
}
448449
}
449450
if v, ok := sd["stabilization_window"]; ok {
450451
if val, ok := v.(int); ok {
451-
scaleDown.StabilizationWindow = int32(val)
452+
scaleDown.StabilizationWindow = ptr.To(int32(val))
452453
}
453454
}
454455
}

internal/provider/resource_tsuru_app_autoscale_flatten.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ func (fsd *flattenScaleDownBehavior) execute() interface{} {
5757
func (fsd *flattenScaleDownBehavior) withInputParameters(proposedList []map[string]interface{}) (value []map[string]interface{}) {
5858
scaleDownCurrent := []map[string]interface{}{{}}
5959
percentage, ok := fsd.findScaleDownInProposedList(proposedList, fsd.PERCENTAGE_LABEL)
60-
if ok && percentage != 0 || fsd.ScaleDownRead.PercentagePolicyValue != int32(fsd.PERCENTAGE_VALUE) {
60+
if ok && percentage != 0 || int32Value(fsd.ScaleDownRead.PercentagePolicyValue) != int32(fsd.PERCENTAGE_VALUE) {
6161
scaleDownCurrent[0][fsd.PERCENTAGE_LABEL] = fsd.ScaleDownRead.PercentagePolicyValue
6262
}
6363
stabilizationWindow, ok := fsd.findScaleDownInProposedList(proposedList, fsd.STABILIZATION_WINDOW_LABEL)
64-
if ok && stabilizationWindow != 0 || fsd.ScaleDownRead.StabilizationWindow != int32(fsd.STABILIZATION_WINDOW_VALUE) {
64+
if ok && stabilizationWindow != 0 || int32Value(fsd.ScaleDownRead.StabilizationWindow) != int32(fsd.STABILIZATION_WINDOW_VALUE) {
6565
scaleDownCurrent[0][fsd.STABILIZATION_WINDOW_LABEL] = fsd.ScaleDownRead.StabilizationWindow
6666
}
6767
units, ok := fsd.findScaleDownInProposedList(proposedList, fsd.UNITS_LABEL)
68-
if ok && units != 0 || fsd.ScaleDownRead.UnitsPolicyValue != int32(fsd.UNITS_VALUE) {
68+
if ok && units != 0 || int32Value(fsd.ScaleDownRead.UnitsPolicyValue) != int32(fsd.UNITS_VALUE) {
6969
scaleDownCurrent[0][fsd.UNITS_LABEL] = fsd.ScaleDownRead.UnitsPolicyValue
7070
}
7171
return scaleDownCurrent
@@ -76,13 +76,13 @@ func (fsd *flattenScaleDownBehavior) noInputParameters(proposedList []map[string
7676
return nil, false
7777
}
7878
scaleDownCurrent := []map[string]interface{}{{}}
79-
if fsd.ScaleDownRead.PercentagePolicyValue != fsd.PERCENTAGE_VALUE {
79+
if int32Value(fsd.ScaleDownRead.PercentagePolicyValue) != fsd.PERCENTAGE_VALUE {
8080
scaleDownCurrent[0][fsd.PERCENTAGE_LABEL] = fsd.ScaleDownRead.PercentagePolicyValue
8181
}
82-
if fsd.ScaleDownRead.StabilizationWindow != fsd.STABILIZATION_WINDOW_VALUE {
82+
if int32Value(fsd.ScaleDownRead.StabilizationWindow) != fsd.STABILIZATION_WINDOW_VALUE {
8383
scaleDownCurrent[0][fsd.STABILIZATION_WINDOW_LABEL] = fsd.ScaleDownRead.StabilizationWindow
8484
}
85-
if fsd.ScaleDownRead.UnitsPolicyValue != fsd.UNITS_VALUE {
85+
if int32Value(fsd.ScaleDownRead.UnitsPolicyValue) != fsd.UNITS_VALUE {
8686
scaleDownCurrent[0][fsd.UNITS_LABEL] = fsd.ScaleDownRead.UnitsPolicyValue
8787
}
8888
if fsd.isScaleDownEmpty(scaleDownCurrent) {
@@ -91,6 +91,13 @@ func (fsd *flattenScaleDownBehavior) noInputParameters(proposedList []map[string
9191
return scaleDownCurrent, true
9292
}
9393

94+
func int32Value(ptr *int32) int32 {
95+
if ptr != nil {
96+
return *ptr
97+
}
98+
return 0
99+
}
100+
94101
func (fsd *flattenScaleDownBehavior) findScaleDownInProposedList(proposedList []map[string]interface{}, key string) (value int, ok bool) {
95102
for _, item := range proposedList {
96103
if v, ok := item[key]; ok {

internal/provider/resource_tsuru_app_autoscale_scale_down_test.go

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/stretchr/testify/assert"
1111
tsuru_client "github.com/tsuru/go-tsuruclient/pkg/tsuru"
12+
"k8s.io/utils/ptr"
1213
)
1314

1415
func TestFluentDown(t *testing.T) {
@@ -20,72 +21,72 @@ func TestFluentDown(t *testing.T) {
2021
}{
2122
{
2223
scaleDownRead: tsuru_client.AutoScaleSpecBehaviorScaleDown{
23-
UnitsPolicyValue: 3,
24-
PercentagePolicyValue: 10,
25-
StabilizationWindow: 300,
24+
UnitsPolicyValue: ptr.To(int32(3)),
25+
PercentagePolicyValue: ptr.To(int32(10)),
26+
StabilizationWindow: ptr.To(int32(300)),
2627
},
2728
scaleDownInput: []interface{}{},
2829
expected: nil,
2930
},
3031

3132
{
3233
scaleDownRead: tsuru_client.AutoScaleSpecBehaviorScaleDown{
33-
UnitsPolicyValue: 3,
34-
PercentagePolicyValue: 10,
35-
StabilizationWindow: 300,
34+
UnitsPolicyValue: ptr.To(int32(3)),
35+
PercentagePolicyValue: ptr.To(int32(10)),
36+
StabilizationWindow: ptr.To(int32(300)),
3637
},
3738
scaleDownInput: []interface{}{
3839
map[string]interface{}{"units": 3},
3940
},
4041
expected: []map[string]interface{}{{
41-
"units": int32(3),
42+
"units": ptr.To(int32(3)),
4243
}},
4344
},
4445
{
4546
scaleDownRead: tsuru_client.AutoScaleSpecBehaviorScaleDown{
46-
UnitsPolicyValue: 3,
47-
PercentagePolicyValue: 10,
48-
StabilizationWindow: 300,
47+
UnitsPolicyValue: ptr.To(int32(3)),
48+
PercentagePolicyValue: ptr.To(int32(10)),
49+
StabilizationWindow: ptr.To(int32(300)),
4950
},
5051
scaleDownInput: []interface{}{
5152
map[string]interface{}{"units": 3},
5253
map[string]interface{}{"stabilization_window": 300},
5354
map[string]interface{}{"percentage": 10},
5455
},
5556
expected: []map[string]interface{}{{
56-
"units": int32(3),
57-
"stabilization_window": int32(300),
58-
"percentage": int32(10),
57+
"units": ptr.To(int32(3)),
58+
"stabilization_window": ptr.To(int32(300)),
59+
"percentage": ptr.To(int32(10)),
5960
}},
6061
},
6162
{
6263
scaleDownRead: tsuru_client.AutoScaleSpecBehaviorScaleDown{
63-
UnitsPolicyValue: 21,
64-
PercentagePolicyValue: 21,
65-
StabilizationWindow: 21,
64+
UnitsPolicyValue: ptr.To(int32(21)),
65+
PercentagePolicyValue: ptr.To(int32(21)),
66+
StabilizationWindow: ptr.To(int32(21)),
6667
},
6768
scaleDownInput: []interface{}{
6869
map[string]interface{}{"units": 3},
6970
map[string]interface{}{"stabilization_window": 300},
7071
map[string]interface{}{"percentage": 10},
7172
},
7273
expected: []map[string]interface{}{{
73-
"units": int32(21),
74-
"stabilization_window": int32(21),
75-
"percentage": int32(21),
74+
"units": ptr.To(int32(21)),
75+
"stabilization_window": ptr.To(int32(21)),
76+
"percentage": ptr.To(int32(21)),
7677
}},
7778
},
7879
{
7980
scaleDownRead: tsuru_client.AutoScaleSpecBehaviorScaleDown{
80-
UnitsPolicyValue: 21,
81-
PercentagePolicyValue: 21,
82-
StabilizationWindow: 21,
81+
UnitsPolicyValue: ptr.To(int32(21)),
82+
PercentagePolicyValue: ptr.To(int32(21)),
83+
StabilizationWindow: ptr.To(int32(21)),
8384
},
8485
scaleDownInput: []interface{}{},
8586
expected: []map[string]interface{}{{
86-
"units": int32(21),
87-
"stabilization_window": int32(21),
88-
"percentage": int32(21),
87+
"units": ptr.To(int32(21)),
88+
"stabilization_window": ptr.To(int32(21)),
89+
"percentage": ptr.To(int32(21)),
8990
}},
9091
},
9192
}

internal/provider/resource_tsuru_app_autoscale_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
echo "github.com/labstack/echo/v4"
1616
"github.com/stretchr/testify/assert"
1717
"github.com/tsuru/go-tsuruclient/pkg/tsuru"
18+
"k8s.io/utils/ptr"
1819
)
1920

2021
func TestAccResourceTsuruAppAutoscalePercentage(t *testing.T) {
@@ -753,9 +754,9 @@ func TestAccResourceTsuruAppAutoscaleScaleDown(t *testing.T) {
753754
AverageCPU: "800m",
754755
Behavior: tsuru.AutoScaleSpecBehavior{
755756
ScaleDown: tsuru.AutoScaleSpecBehaviorScaleDown{
756-
StabilizationWindow: 80,
757-
UnitsPolicyValue: 5,
758-
PercentagePolicyValue: 15,
757+
StabilizationWindow: ptr.To(int32(80)),
758+
UnitsPolicyValue: ptr.To(int32(5)),
759+
PercentagePolicyValue: ptr.To(int32(15)),
759760
},
760761
},
761762
}})
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// Copyright 2024 tsuru authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package provider
6+
7+
import (
8+
"context"
9+
"sort"
10+
"time"
11+
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
13+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
14+
"github.com/tsuru/go-tsuruclient/pkg/tsuru"
15+
)
16+
17+
func resourceTsuruCertificateIssuer() *schema.Resource {
18+
return &schema.Resource{
19+
Description: "Set a issuer to generate certificates to a tsuru application",
20+
CreateContext: resourceTsuruCertificateIssuerSet,
21+
ReadContext: resourceTsuruCertificateIssuerRead,
22+
DeleteContext: resourceTsuruCertificateIssuerUnset,
23+
Timeouts: &schema.ResourceTimeout{
24+
Create: schema.DefaultTimeout(60 * time.Minute),
25+
Update: schema.DefaultTimeout(60 * time.Minute),
26+
Delete: schema.DefaultTimeout(60 * time.Minute),
27+
},
28+
Importer: &schema.ResourceImporter{
29+
StateContext: resourceTsuruApplicationImport,
30+
},
31+
Schema: map[string]*schema.Schema{
32+
"app": {
33+
Type: schema.TypeString,
34+
Description: "Application name",
35+
Required: true,
36+
ForceNew: true,
37+
},
38+
39+
"cname": {
40+
Type: schema.TypeString,
41+
Description: "Application CNAME",
42+
Required: true,
43+
ForceNew: true,
44+
},
45+
46+
"issuer": {
47+
Type: schema.TypeString,
48+
Description: "Certificate Issuer",
49+
Required: true,
50+
ForceNew: true,
51+
},
52+
53+
"router": {
54+
Type: schema.TypeList,
55+
Description: "Routers that are using the certificate",
56+
Computed: true,
57+
Elem: &schema.Schema{Type: schema.TypeString},
58+
},
59+
60+
"certificate": {
61+
Type: schema.TypeList,
62+
Description: "Certificate Generated by Issuer, filled after the certificate is ready",
63+
Computed: true,
64+
Elem: &schema.Schema{Type: schema.TypeString},
65+
},
66+
67+
"ready": {
68+
Type: schema.TypeBool,
69+
Description: "If the certificate is ready",
70+
Computed: true,
71+
},
72+
},
73+
}
74+
}
75+
76+
func resourceTsuruCertificateIssuerSet(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
77+
provider := meta.(*tsuruProvider)
78+
79+
app := d.Get("app").(string)
80+
cname := d.Get("cname").(string)
81+
issuer := d.Get("issuer").(string)
82+
83+
_, err := provider.TsuruClient.AppApi.AppSetCertIssuer(context.Background(), app, tsuru.CertIssuerSetData{
84+
Cname: cname,
85+
Issuer: issuer,
86+
})
87+
88+
if err != nil {
89+
return diag.Errorf("unable to set certificate issuer: %v", err)
90+
}
91+
92+
d.SetId(app + "::" + cname + "::" + issuer)
93+
94+
return resourceTsuruCertificateIssuerRead(ctx, d, meta)
95+
}
96+
97+
func resourceTsuruCertificateIssuerUnset(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
98+
provider := meta.(*tsuruProvider)
99+
parts, err := IDtoParts(d.Id(), 3)
100+
if err != nil {
101+
return diag.FromErr(err)
102+
}
103+
app := parts[0]
104+
cname := parts[1]
105+
106+
_, err = provider.TsuruClient.AppApi.AppUnsetCertIssuer(context.Background(), app, cname)
107+
108+
if err != nil {
109+
return diag.Errorf("unable to unset certificate issuer: %v", err)
110+
}
111+
112+
return resourceTsuruCertificateIssuerRead(ctx, d, meta)
113+
}
114+
115+
func resourceTsuruCertificateIssuerRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
116+
provider := meta.(*tsuruProvider)
117+
parts, err := IDtoParts(d.Id(), 3)
118+
if err != nil {
119+
return diag.FromErr(err)
120+
}
121+
app := parts[0]
122+
cname := parts[1]
123+
issuer := parts[2]
124+
125+
certificates, _, err := provider.TsuruClient.AppApi.AppGetCertificates(context.Background(), app)
126+
if err != nil {
127+
return diag.FromErr(err)
128+
}
129+
130+
usedRouters := []string{}
131+
usedCertificates := []string{}
132+
133+
for routerName, router := range certificates.Routers {
134+
cnameInRouter, ok := router.Cnames[cname]
135+
if !ok {
136+
continue
137+
}
138+
139+
if cnameInRouter.Issuer != issuer {
140+
continue
141+
}
142+
usedRouters = append(usedRouters, routerName)
143+
144+
if cnameInRouter.Certificate != "" {
145+
usedCertificates = append(usedCertificates, cnameInRouter.Certificate)
146+
}
147+
}
148+
149+
sort.Strings(usedRouters)
150+
sort.Strings(usedCertificates)
151+
152+
d.Set("app", app)
153+
d.Set("cname", cname)
154+
d.Set("issuer", issuer)
155+
156+
d.Set("router", usedRouters)
157+
d.Set("certificate", usedCertificates)
158+
d.Set("ready", len(usedCertificates) > 0)
159+
160+
return nil
161+
}

0 commit comments

Comments
 (0)