feat(resourcemanager): add folder resource/datasource (#975)

* feat(resourcemanager): add folder resource/datasource

* feat(resourcemanager): add created_at and updated_at attributes to resourcemanager project/folder

---------

Signed-off-by: Mauritz Uphoff <mauritz.uphoff@stackit.cloud>
This commit is contained in:
Mauritz Uphoff 2025-09-17 09:53:48 +02:00 committed by GitHub
parent 27e4ef0227
commit 813b8c0e81
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 1844 additions and 171 deletions

View file

@ -6,6 +6,7 @@ import (
"net/http"
"regexp"
"strings"
"time"
resourcemanagerUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/resourcemanager/utils"
@ -51,6 +52,8 @@ type Model struct {
ContainerParentId types.String `tfsdk:"parent_container_id"`
Name types.String `tfsdk:"name"`
Labels types.Map `tfsdk:"labels"`
CreationTime types.String `tfsdk:"creation_time"`
UpdateTime types.String `tfsdk:"update_time"`
}
type ResourceModel struct {
@ -92,7 +95,7 @@ func (r *projectResource) Configure(ctx context.Context, req resource.ConfigureR
func (r *projectResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
descriptions := map[string]string{
"main": fmt.Sprintf("%s\n\n%s",
"Resource Manager project resource schema. To use this resource, it is required that you set the service account email in the provider configuration.",
"Resource Manager project resource schema.",
"-> In case you're getting started with an empty STACKIT organization and want to use this resource to create projects in it, check out [this guide](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/stackit_org_service_account) for how to create a service account which you can use for authentication in the STACKIT Terraform provider.",
),
"id": "Terraform's internal resource ID. It is structured as \"`container_id`\".",
@ -102,6 +105,8 @@ func (r *projectResource) Schema(_ context.Context, _ resource.SchemaRequest, re
"name": "Project name.",
"labels": "Labels are key-value string pairs which can be attached to a resource container. A label key must match the regex [A-ZÄÜÖa-zäüöß0-9_-]{1,64}. A label value must match the regex ^$|[A-ZÄÜÖa-zäüöß0-9_-]{1,64}. \nTo create a project within a STACKIT Network Area, setting the label `networkArea=<networkAreaID>` is required. This can not be changed after project creation.",
"owner_email": "Email address of the owner of the project. This value is only considered during creation. Changing it afterwards will have no effect.",
"creation_time": "Date-time at which the project was created.",
"update_time": "Date-time at which the project was last modified.",
}
resp.Schema = schema.Schema{
@ -170,6 +175,14 @@ func (r *projectResource) Schema(_ context.Context, _ resource.SchemaRequest, re
Description: descriptions["owner_email"],
Required: true,
},
"creation_time": schema.StringAttribute{
Description: descriptions["creation_time"],
Computed: true,
},
"update_time": schema.StringAttribute{
Description: descriptions["update_time"],
Computed: true,
},
},
}
}
@ -409,6 +422,8 @@ func mapProjectFields(ctx context.Context, projectResp *resourcemanager.GetProje
model.ContainerId = types.StringValue(containerId)
model.Name = types.StringPointerValue(projectResp.Name)
model.Labels = labels
model.CreationTime = types.StringValue(projectResp.CreationTime.Format(time.RFC3339))
model.UpdateTime = types.StringValue(projectResp.UpdateTime.Format(time.RFC3339))
if state != nil {
diags := diag.Diagnostics{}
@ -418,6 +433,8 @@ func mapProjectFields(ctx context.Context, projectResp *resourcemanager.GetProje
diags.Append(state.SetAttribute(ctx, path.Root("container_id"), model.ContainerId)...)
diags.Append(state.SetAttribute(ctx, path.Root("name"), model.Name)...)
diags.Append(state.SetAttribute(ctx, path.Root("labels"), model.Labels)...)
diags.Append(state.SetAttribute(ctx, path.Root("creation_time"), model.CreationTime)...)
diags.Append(state.SetAttribute(ctx, path.Root("update_time"), model.UpdateTime)...)
if diags.HasError() {
return fmt.Errorf("update terraform state: %w", core.DiagsToError(diags))
}