Skip to content

Commit

Permalink
Add projectId to resource manager project, fix value conversion error
Browse files Browse the repository at this point in the history
  • Loading branch information
vicentepinto98 committed Dec 12, 2023
1 parent dc3c348 commit 97c60ae
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 5 deletions.
22 changes: 21 additions & 1 deletion stackit/internal/services/resourcemanager/project/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var (

type ModelData struct {
Id types.String `tfsdk:"id"` // needed by TF
ProjectId types.String `tfsdk:"project_id"`
ContainerId types.String `tfsdk:"container_id"`
ContainerParentId types.String `tfsdk:"parent_container_id"`
Name types.String `tfsdk:"name"`
Expand Down Expand Up @@ -90,8 +91,9 @@ func (d *projectDataSource) Schema(_ context.Context, _ datasource.SchemaRequest
descriptions := map[string]string{
"main": "Resource Manager project data source schema.",
"id": "Terraform's internal data source. ID. It is structured as \"`container_id`\".",
"project_id": "Project ID. It is an UUID.",
"container_id": "Project container ID.",
"parent_container_id": "Parent container ID",
"parent_container_id": "Parent resource container ID. Both container ID (user-friendly) and UUID are supported",
"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}`,
}
Expand All @@ -103,6 +105,14 @@ func (d *projectDataSource) Schema(_ context.Context, _ datasource.SchemaRequest
Description: descriptions["id"],
Computed: true,
},
"project_id": schema.StringAttribute{
Description: descriptions["project_id"],
Optional: true,
Computed: true,
Validators: []validator.String{
validate.UUID(),
},
},
"container_id": schema.StringAttribute{
Description: descriptions["container_id"],
Required: true,
Expand Down Expand Up @@ -184,6 +194,15 @@ func mapDataFields(ctx context.Context, projectResp *resourcemanager.ProjectResp
return fmt.Errorf("model input is nil")
}

var projectId string
if model.ProjectId.ValueString() != "" {
projectId = model.ProjectId.ValueString()
} else if projectResp.ProjectId != nil {
projectId = *projectResp.ProjectId
} else {
return fmt.Errorf("project id not present")
}

var containerId string
if model.ContainerId.ValueString() != "" {
containerId = model.ContainerId.ValueString()
Expand All @@ -204,6 +223,7 @@ func mapDataFields(ctx context.Context, projectResp *resourcemanager.ProjectResp
}

model.Id = types.StringValue(containerId)
model.ProjectId = types.StringValue(projectId)
model.ContainerId = types.StringValue(containerId)
model.ContainerParentId = types.StringPointerValue(projectResp.Parent.ContainerId)
model.Name = types.StringPointerValue(projectResp.Name)
Expand Down
35 changes: 32 additions & 3 deletions stackit/internal/services/resourcemanager/project/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"regexp"
"strings"

"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
Expand Down Expand Up @@ -39,6 +40,7 @@ const (

type Model struct {
Id types.String `tfsdk:"id"` // needed by TF
ProjectId types.String `tfsdk:"project_id"`
ContainerId types.String `tfsdk:"container_id"`
ContainerParentId types.String `tfsdk:"parent_container_id"`
Name types.String `tfsdk:"name"`
Expand Down Expand Up @@ -102,10 +104,11 @@ func (r *projectResource) Configure(ctx context.Context, req resource.ConfigureR
// Schema defines the schema for the resource.
func (r *projectResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
descriptions := map[string]string{
"main": "Resource Manager project resource schema.",
"main": "Resource Manager project resource schema. To use this resource, it is required that you set the service account email in the provider configuration.",
"id": "Terraform's internal resource ID. It is structured as \"`container_id`\".",
"project_id": "Project ID. It is an UUID.",
"container_id": "Project container ID. Globally unique, user-friendly identifier.",
"parent_container_id": "Parent container ID",
"parent_container_id": "Parent resource container ID. Both container ID (user-friendly) and UUID are supported",
"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}",
"owner_email": "Email address of the owner of the project. This value is only considered during creation. Changing it afterwards will have no effect.",
Expand All @@ -121,6 +124,16 @@ func (r *projectResource) Schema(_ context.Context, _ resource.SchemaRequest, re
stringplanmodifier.UseStateForUnknown(),
},
},
"project_id": schema.StringAttribute{
Description: descriptions["project_id"],
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
Validators: []validator.String{
validate.UUID(),
},
},
"container_id": schema.StringAttribute{
Description: descriptions["container_id"],
Computed: true,
Expand Down Expand Up @@ -357,6 +370,15 @@ func mapFields(ctx context.Context, projectResp *resourcemanager.ProjectResponse
return fmt.Errorf("model input is nil")
}

var projectId string
if model.ProjectId.ValueString() != "" {
projectId = model.ProjectId.ValueString()
} else if projectResp.ProjectId != nil {
projectId = *projectResp.ProjectId
} else {
return fmt.Errorf("project id not present")
}

var containerId string
if model.ContainerId.ValueString() != "" {
containerId = model.ContainerId.ValueString()
Expand All @@ -377,9 +399,16 @@ func mapFields(ctx context.Context, projectResp *resourcemanager.ProjectResponse
}

model.Id = types.StringValue(containerId)
model.ProjectId = types.StringValue(projectId)
model.ContainerId = types.StringValue(containerId)
if projectResp.Parent != nil {
model.ContainerParentId = types.StringPointerValue(projectResp.Parent.ContainerId)
if _, err := uuid.Parse(model.ContainerParentId.ValueString()); err != nil {
// the provided containerParentId is the UUID identifier
model.ContainerParentId = types.StringPointerValue(projectResp.Parent.Id)
} else {
// the provided containerParentId is the user-friendly container id
model.ContainerParentId = types.StringPointerValue(projectResp.Parent.ContainerId)
}
} else {
model.ContainerParentId = types.StringNull()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func TestAccResourceManagerResource(t *testing.T) {
Check: resource.ComposeAggregateTestCheckFunc(
// Project data
resource.TestCheckResourceAttrSet("stackit_resourcemanager_project.project", "container_id"),
resource.TestCheckResourceAttrSet("stackit_resourcemanager_project.project", "project_id"),
resource.TestCheckResourceAttr("stackit_resourcemanager_project.project", "name", projectResource["name"]),
resource.TestCheckResourceAttr("stackit_resourcemanager_project.project", "parent_container_id", projectResource["parent_container_id"]),
resource.TestCheckResourceAttr("stackit_resourcemanager_project.project", "labels.%", "1"),
Expand Down Expand Up @@ -116,6 +117,7 @@ func TestAccResourceManagerResource(t *testing.T) {
Check: resource.ComposeAggregateTestCheckFunc(
// Project data
resource.TestCheckResourceAttrSet("stackit_resourcemanager_project.project", "container_id"),
resource.TestCheckResourceAttrSet("stackit_resourcemanager_project.project", "project_id"),
resource.TestCheckResourceAttr("stackit_resourcemanager_project.project", "name", fmt.Sprintf("%s-new", projectResource["name"])),
resource.TestCheckResourceAttr("stackit_resourcemanager_project.project", "parent_container_id", projectResource["parent_container_id"]),
resource.TestCheckResourceAttr("stackit_resourcemanager_project.project", "labels.%", "2"),
Expand Down
2 changes: 1 addition & 1 deletion stackit/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func (p *Provider) Schema(_ context.Context, _ provider.SchemaRequest, resp *pro
"service_account_key": "Service account key used for authentication. If set alongside private key, the key flow will be used to authenticate all operations.",
"private_key_path": "Path for the private RSA key used for authentication. If set alongside the service account key, the key flow will be used to authenticate all operations.",
"private_key": "Private RSA key used for authentication. If set alongside the service account key, the key flow will be used to authenticate all operations.",
"service_account_email": "Service account email. It can also be set using the environment variable STACKIT_SERVICE_ACCOUNT_EMAIL",
"service_account_email": "Service account email. It can also be set using the environment variable STACKIT_SERVICE_ACCOUNT_EMAIL. It is required if you want to use the resource manager project resource.",
"region": "Region will be used as the default location for regional services. Not all services require a region, some are global",
"dns_custom_endpoint": "Custom endpoint for the DNS service",
"postgresql_custom_endpoint": "Custom endpoint for the PostgreSQL service",
Expand Down

0 comments on commit 97c60ae

Please sign in to comment.