feat(ske): add ephemeral ske kubeconfig#1448
Conversation
e7a7211 to
21ffd96
Compare
21ffd96 to
42e7091
Compare
|
|
638204f to
ad810c1
Compare
cd6a220 to
0d06641
Compare
0d06641 to
72e2165
Compare
|
This PR was marked as stale after 7 days of inactivity and will be closed after another 7 days of further inactivity. If this PR should be kept open, just add a comment, remove the stale label or push new commits to it. |
72e2165 to
23b550f
Compare
dd0520a to
08623d4
Compare
08623d4 to
096316e
Compare
096316e to
7e5049b
Compare
| ) | ||
|
|
||
| const ( | ||
| defaultKubeconfigExpiration = 1800 |
There was a problem hiding this comment.
| defaultKubeconfigExpiration = 1800 | |
| defaultKubeconfigExpirationSeconds = 1800 |
Please add a time unit to that one
There was a problem hiding this comment.
Removed entirely. Per your feedback on the broader expiration approach, the custom 1800s default was dropped altogether. The API default of 3600s (1h) is now used when no expiration is specified, documented in the schema description.
| }, | ||
| "expiration": schema.Int64Attribute{ | ||
| Description: "Expiration time of the kubeconfig in seconds. Must be between `600` (10m) and `14400` (4h). " + | ||
| "Defaults to `1800` (30m) for optimal security during Terraform operations, which is more restrictive than the API default of `3600` (1h).", |
There was a problem hiding this comment.
| "Defaults to `1800` (30m) for optimal security during Terraform operations, which is more restrictive than the API default of `3600` (1h).", | |
| "Defaults to `1800` (30m) for optimal security during Terraform operations.", |
Isn't the point of Terraform that users don't have to care about the underlying APIs? 😄
| // Defaulted to 1800s (30m) for better security than the API default (3600s). | ||
| expiration := conversion.Int64ValueToPointer(model.Expiration) | ||
| if expiration == nil { | ||
| expiration = new(int64) |
There was a problem hiding this comment.
| expiration = new(int64) | |
| expiration = new(int64(defaultKubeconfigExpiration)) |
| *expirationStringPtr = strconv.FormatInt(*expiration, 10) | ||
| } | ||
|
|
||
| payload := ske.CreateKubeconfigPayload{ |
There was a problem hiding this comment.
If you turn the order around you don't need the ugly expirationStringPtr variable.
payload := ske.CreateKubeconfigPayload{}
if expiration != nil {
payload.ExpirationSeconds = new(strconv.FormatInt(*expiration, 10))
}But I have so many questions in my mind here.
- Why is
ExpirationSecondsa string in the API? - Why is the
expirationparameter in thisgetKubeconfigfunction implementation a pointer type? I thought there was a default expiration time? What you're doing is critical since you risk that there's no expiration set by accident.
There was a problem hiding this comment.
Both addressed: getKubeconfig now takes ske.DefaultAPI (interface, not *ske.APIClient) and *int64. When nil, no ExpirationSeconds is sent and the API uses its default. The expirationStringPtr variable is gone, replaced with a local expirationStr scoped to the if expiration != nil block:
payload := ske.CreateKubeconfigPayload{}
if expiration != nil {
expirationStr := strconv.FormatInt(*expiration, 10)
payload.ExpirationSeconds = &expirationStr
}| for _, tt := range tests { | ||
| t.Run(tt.description, func(t *testing.T) { | ||
| server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
| expectedPath := fmt.Sprintf("/v2/projects/%s/regions/%s/clusters/%s/kubeconfig", projectId, region, clusterName) |
There was a problem hiding this comment.
I don't think this is needed, please use the SDK mocks instead if possible. See the link below for reference.
There was a problem hiding this comment.
Done. The test now uses ske.DefaultAPIServiceMock with CreateKubeconfigExecuteMock.
| project_id = var.project_id | ||
| # cluster_name is unknown during the plan phase because stackit_ske_cluster.cluster.id is computed. | ||
| # This forces Terraform to defer the Open call until the Apply phase, after the cluster is ready. | ||
| cluster_name = stackit_ske_cluster.cluster.id != "" ? stackit_ske_cluster.cluster.name : "" |
There was a problem hiding this comment.
I don't think this will work as you expect it. The internal id attribute of the cluster resource might be already set BEFORE the cluster creation wait handler is called / finished.
There was a problem hiding this comment.
This isn't currently the case, but I would like to see some actual long-term working strategy here please.
There was a problem hiding this comment.
The cluster Create implementation: id is not set early. Only project_id, region, and name are written to state before the wait handler. The id attribute is only populated by mapFields, which runs after CreateClusterWaitHandler
So the ternary on id is safe:
- During plan for a new cluster: id is unknown (UseStateForUnknown, not yet in state), ternary is unknown, ephemeral Open is deferred to apply
- During apply: id is only set once the wait handler finishes and mapFields runs, cluster is guaranteed to exist when the ephemeral resource opens
Imo there is no better long-term strategy unless SKE introduces a UUID cluster identifier in the future. The problem is fundamentally unsolvable as long as the user can set the unique identifier (name) that is used in the Terraform state.
| project_id = var.project_id | ||
| # cluster_name is unknown during the plan phase because stackit_ske_cluster.cluster.id is computed. | ||
| # This forces Terraform to defer the Open call until the Apply phase, after the cluster is ready. | ||
| cluster_name = stackit_ske_cluster.cluster.id != "" ? stackit_ske_cluster.cluster.name : "" |
| # if inputs are known, which would trigger a 404 before the cluster exists. | ||
| ephemeral "stackit_ske_kubeconfig" "example" { | ||
| project_id = stackit_ske_cluster.example.project_id | ||
| cluster_name = stackit_ske_cluster.example.id != "" ? stackit_ske_cluster.example.name : "" |
657b307 to
00866b7
Compare
|
@h3adex please mark my conversations you adressed with your latest changes as resolved so this PR doesn't become a mess of open comments. Thanks. |
00866b7 to
7120e8b
Compare
|
@rubenhoenle only rebased. I'll try to update this PR this month. Currently busy covering multiple topics. Will update you once I covered your comments. |
Signed-off-by: Mauritz Uphoff <mauritz.uphoff@stackit.cloud>
Signed-off-by: Mauritz Uphoff <mauritz.uphoff@stackit.cloud>
98eace1 to
6ee1d50
Compare

Description
This PR adds the
stackit_ske_kubeconfigephemeral resource. The default expiration has been reduced to 30 minutes. Since these credentials only need to persist for the duration of a Terraform run, where even slow Helm deployments rarely exceed a 10-15 minute window, a 60-minute expiration is excessive.Tested example code:
https://professional-service.git.onstackit.cloud/professional-service-best-practices/professional-service/pulls/18
Checklist
make fmtexamples/directory)make generate-docs(will be checked by CI)make test(will be checked by CI)make lint(will be checked by CI)