Skip to content

Commit 0763a5f

Browse files
authored
feat(ske): add refresh_before field to ske_kubeconfig resource (#1000)
1 parent 5f71eef commit 0763a5f

File tree

6 files changed

+64
-24
lines changed

6 files changed

+64
-24
lines changed

docs/resources/ske_kubeconfig.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ SKE kubeconfig resource schema. Must have a `region` specified in the provider c
1616
resource "stackit_ske_kubeconfig" "example" {
1717
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
1818
cluster_name = "example-cluster"
19-
refresh = true
19+
20+
refresh = true
21+
expiration = 7200 # 2 hours
22+
refresh_before = 3600 # 1 hour
2023
}
2124
```
2225

@@ -32,6 +35,7 @@ resource "stackit_ske_kubeconfig" "example" {
3235

3336
- `expiration` (Number) Expiration time of the kubeconfig, in seconds. Defaults to `3600`
3437
- `refresh` (Boolean) If set to true, the provider will check if the kubeconfig has expired and will generated a new valid one in-place
38+
- `refresh_before` (Number) Number of seconds before expiration to trigger refresh of the kubeconfig at. Only used if refresh is set to true.
3539
- `region` (String) The resource region. If not defined, the provider region is used.
3640

3741
### Read-Only
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
resource "stackit_ske_kubeconfig" "example" {
22
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
33
cluster_name = "example-cluster"
4-
refresh = true
4+
5+
refresh = true
6+
expiration = 7200 # 2 hours
7+
refresh_before = 3600 # 1 hour
58
}

stackit/internal/services/ske/kubeconfig/resource.go

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
skeUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/ske/utils"
1111

1212
"github.com/google/uuid"
13+
"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
1314
"github.com/hashicorp/terraform-plugin-framework/path"
1415
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1516
"github.com/hashicorp/terraform-plugin-log/tflog"
@@ -38,16 +39,17 @@ var (
3839
)
3940

4041
type Model struct {
41-
Id types.String `tfsdk:"id"` // needed by TF
42-
ClusterName types.String `tfsdk:"cluster_name"`
43-
ProjectId types.String `tfsdk:"project_id"`
44-
KubeconfigId types.String `tfsdk:"kube_config_id"` // uuid generated internally because kubeconfig has no identifier
45-
Kubeconfig types.String `tfsdk:"kube_config"`
46-
Expiration types.Int64 `tfsdk:"expiration"`
47-
Refresh types.Bool `tfsdk:"refresh"`
48-
ExpiresAt types.String `tfsdk:"expires_at"`
49-
CreationTime types.String `tfsdk:"creation_time"`
50-
Region types.String `tfsdk:"region"`
42+
Id types.String `tfsdk:"id"` // needed by TF
43+
ClusterName types.String `tfsdk:"cluster_name"`
44+
ProjectId types.String `tfsdk:"project_id"`
45+
KubeconfigId types.String `tfsdk:"kube_config_id"` // uuid generated internally because kubeconfig has no identifier
46+
Kubeconfig types.String `tfsdk:"kube_config"`
47+
Expiration types.Int64 `tfsdk:"expiration"`
48+
Refresh types.Bool `tfsdk:"refresh"`
49+
RefreshBefore types.Int64 `tfsdk:"refresh_before"`
50+
ExpiresAt types.String `tfsdk:"expires_at"`
51+
CreationTime types.String `tfsdk:"creation_time"`
52+
Region types.String `tfsdk:"region"`
5153
}
5254

5355
// NewKubeconfigResource is a helper function to simplify the provider implementation.
@@ -94,6 +96,7 @@ func (r *kubeconfigResource) Schema(_ context.Context, _ resource.SchemaRequest,
9496
"expiration": "Expiration time of the kubeconfig, in seconds. Defaults to `3600`",
9597
"expires_at": "Timestamp when the kubeconfig expires",
9698
"refresh": "If set to true, the provider will check if the kubeconfig has expired and will generated a new valid one in-place",
99+
"refresh_before": "Number of seconds before expiration to trigger refresh of the kubeconfig at. Only used if refresh is set to true.",
97100
"creation_time": "Date-time when the kubeconfig was created",
98101
"region": "The resource region. If not defined, the provider region is used.",
99102
}
@@ -155,6 +158,16 @@ func (r *kubeconfigResource) Schema(_ context.Context, _ resource.SchemaRequest,
155158
boolplanmodifier.RequiresReplace(),
156159
},
157160
},
161+
"refresh_before": schema.Int64Attribute{
162+
Description: descriptions["refresh_before"],
163+
Optional: true,
164+
PlanModifiers: []planmodifier.Int64{
165+
int64planmodifier.UseStateForUnknown(),
166+
},
167+
Validators: []validator.Int64{
168+
int64validator.AtLeast(1),
169+
},
170+
},
158171
"kube_config": schema.StringAttribute{
159172
Description: descriptions["kube_config"],
160173
Computed: true,
@@ -442,6 +455,9 @@ func checkHasExpired(model *Model, currentTime time.Time) (bool, error) {
442455
if err != nil {
443456
return false, fmt.Errorf("converting expiresAt field to timestamp: %w", err)
444457
}
458+
if !model.RefreshBefore.IsNull() {
459+
expiresAt = expiresAt.Add(-time.Duration(model.RefreshBefore.ValueInt64()) * time.Second)
460+
}
445461
if expiresAt.Before(currentTime) {
446462
return true, nil
447463
}

stackit/internal/services/ske/kubeconfig/resource_test.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ func TestMapFields(t *testing.T) {
2626
Kubeconfig: utils.Ptr("kubeconfig"),
2727
},
2828
Model{
29-
ClusterName: types.StringValue("name"),
30-
ProjectId: types.StringValue("pid"),
31-
Kubeconfig: types.StringValue("kubeconfig"),
32-
Expiration: types.Int64Null(),
33-
Refresh: types.BoolNull(),
34-
ExpiresAt: types.StringValue("2024-02-07T16:42:12Z"),
35-
CreationTime: types.StringValue("2024-02-05T14:40:12Z"),
36-
Region: types.StringValue(testRegion),
29+
ClusterName: types.StringValue("name"),
30+
ProjectId: types.StringValue("pid"),
31+
Kubeconfig: types.StringValue("kubeconfig"),
32+
Expiration: types.Int64Null(),
33+
Refresh: types.BoolNull(),
34+
RefreshBefore: types.Int64Null(),
35+
ExpiresAt: types.StringValue("2024-02-07T16:42:12Z"),
36+
CreationTime: types.StringValue("2024-02-05T14:40:12Z"),
37+
Region: types.StringValue(testRegion),
3738
},
3839
true,
3940
},
@@ -169,6 +170,17 @@ func TestCheckHasExpired(t *testing.T) {
169170
expected: false,
170171
expectedError: false,
171172
},
173+
{
174+
description: "not expired but refresh_before reached",
175+
inputModel: &Model{
176+
Refresh: types.BoolValue(true),
177+
RefreshBefore: types.Int64Value(int64(time.Hour.Seconds())),
178+
ExpiresAt: types.StringValue(time.Now().Add(1 * time.Hour).Format(time.RFC3339)), // in one hour
179+
},
180+
currentTime: time.Now(),
181+
expected: true,
182+
expectedError: false,
183+
},
172184
{
173185
description: "invalid time",
174186
inputModel: &Model{

stackit/internal/services/ske/ske_acc_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ var testConfigVarsMax = config.Variables{
8686
"region": config.StringVariable(testutil.Region),
8787
"expiration": config.StringVariable("3600"),
8888
"refresh": config.StringVariable("true"),
89+
"refresh_before": config.StringVariable("600"),
8990
"dns_zone_name": config.StringVariable("acc-" + acctest.RandStringFromCharSet(6, acctest.CharSetAlpha)),
9091
"dns_name": config.StringVariable("acc-" + acctest.RandStringFromCharSet(6, acctest.CharSetAlpha) + ".runs.onstackit.cloud"),
9192
}
@@ -301,6 +302,8 @@ func TestAccSKEMax(t *testing.T) {
301302
"stackit_ske_cluster.cluster", "name",
302303
),
303304
resource.TestCheckResourceAttr("stackit_ske_kubeconfig.kubeconfig", "expiration", testutil.ConvertConfigVariable(testConfigVarsMax["expiration"])),
305+
resource.TestCheckResourceAttr("stackit_ske_kubeconfig.kubeconfig", "refresh", testutil.ConvertConfigVariable(testConfigVarsMax["refresh"])),
306+
resource.TestCheckResourceAttr("stackit_ske_kubeconfig.kubeconfig", "refresh_before", testutil.ConvertConfigVariable(testConfigVarsMax["refresh_before"])),
304307
resource.TestCheckResourceAttrSet("stackit_ske_kubeconfig.kubeconfig", "expires_at"),
305308
),
306309
},

stackit/internal/services/ske/testdata/resource-max.tf

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ variable "maintenance_end" {}
3232
variable "region" {}
3333
variable "expiration" {}
3434
variable "refresh" {}
35+
variable "refresh_before" {}
3536
variable "dns_zone_name" {}
3637
variable "dns_name" {}
3738

@@ -94,10 +95,11 @@ resource "stackit_ske_cluster" "cluster" {
9495
}
9596

9697
resource "stackit_ske_kubeconfig" "kubeconfig" {
97-
project_id = stackit_ske_cluster.cluster.project_id
98-
cluster_name = stackit_ske_cluster.cluster.name
99-
expiration = var.expiration
100-
refresh = var.refresh
98+
project_id = stackit_ske_cluster.cluster.project_id
99+
cluster_name = stackit_ske_cluster.cluster.name
100+
expiration = var.expiration
101+
refresh = var.refresh
102+
refresh_before = var.refresh_before
101103
}
102104

103105
data "stackit_ske_cluster" "cluster" {

0 commit comments

Comments
 (0)