Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -584,11 +584,9 @@ linters:
- path: internal/provider/tag_projects_resource.go
linters:
- gocognit
- godox
- path: internal/provider/tag_policies_resource.go
linters:
- gocognit
- godox
- path: internal/provider/component_resource.go
linters:
- revive
Expand Down
2 changes: 1 addition & 1 deletion docs/resources/tag_policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ resource "dependencytrack_tag_policies" "example" {

### Required

- `policies` (List of String) Policy UUIDs to which to apply tag. Sorted by policy name.
- `policies` (List of String) Policy UUIDs to which to apply tag.
- `tag` (String) Name of the Tag.

### Read-Only
Expand Down
2 changes: 1 addition & 1 deletion docs/resources/tag_projects.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ resource "dependencytrack_tag_projects" "example" {

### Required

- `projects` (List of String) Project UUIDs to which to apply tag. Sorted by project name.
- `projects` (List of String) Project UUIDs to which to apply tag.
- `tag` (String) Name of the Tag. Must be lowercase.

### Read-Only
Expand Down
36 changes: 22 additions & 14 deletions internal/provider/tag_policies_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package provider
import (
"context"
"fmt"
"strings"

dtrack "github.com/DependencyTrack/client-go"
"github.com/google/uuid"
Expand Down Expand Up @@ -61,8 +62,7 @@ func (*tagPoliciesResource) Schema(_ context.Context, _ resource.SchemaRequest,
},
},
"policies": schema.ListAttribute{
// TODO: Use `ListUnorderedEqual` to remove requirement for this to be sorted.
Description: "Policy UUIDs to which to apply tag. Sorted by policy name.",
Description: "Policy UUIDs to which to apply tag.",
Required: true,
ElementType: types.StringType,
},
Expand Down Expand Up @@ -146,7 +146,7 @@ func (r *tagPoliciesResource) Create(ctx context.Context, req resource.CreateReq
tflog.Debug(ctx, "Created Tag Policies", map[string]any{
"id": plan.ID.ValueString(),
"tag": plan.Tag.ValueString(),
"policies": Map(plan.Policies, func(item types.String) string { return item.ValueString() }),
"policies": Map(plan.Policies, types.String.ValueString),
})
}

Expand All @@ -162,7 +162,7 @@ func (r *tagPoliciesResource) Read(ctx context.Context, req resource.ReadRequest
tflog.Debug(ctx, "Reading Tag Policies", map[string]any{
"tag": tagName,
"policies.#": len(state.Policies),
"policies": Map(state.Policies, func(item types.String) string { return item.ValueString() }),
"policies": Map(state.Policies, types.String.ValueString),
})

taggedPoliciesInfo, err := dtrack.FetchAll(func(po dtrack.PageOptions) (dtrack.Page[dtrack.TaggedPolicyListResponseItem], error) {
Expand All @@ -176,12 +176,20 @@ func (r *tagPoliciesResource) Read(ctx context.Context, req resource.ReadRequest
return
}

statePolicies := Map(taggedPoliciesInfo, func(info dtrack.TaggedPolicyListResponseItem) types.String {
return types.StringValue(info.UUID.String())
})

if SliceUnorderedEqual(statePolicies, state.Policies, func(a, b types.String) int {
return strings.Compare(a.ValueString(), b.ValueString())
}) {
statePolicies = state.Policies
}

state = tagPoliciesResourceModel{
ID: types.StringValue(tagName),
Tag: types.StringValue(tagName),
Policies: Map(taggedPoliciesInfo, func(info dtrack.TaggedPolicyListResponseItem) types.String {
return types.StringValue(info.UUID.String())
}),
ID: types.StringValue(tagName),
Tag: types.StringValue(tagName),
Policies: statePolicies,
}

diags = resp.State.Set(ctx, &state)
Expand All @@ -192,7 +200,7 @@ func (r *tagPoliciesResource) Read(ctx context.Context, req resource.ReadRequest
tflog.Debug(ctx, "Read Tag Policies", map[string]any{
"id": state.ID.ValueString(),
"tag": state.Tag.ValueString(),
"policies": Map(state.Policies, func(v types.String) string { return v.ValueString() }),
"policies": Map(state.Policies, types.String.ValueString),
})
}

Expand All @@ -209,7 +217,7 @@ func (r *tagPoliciesResource) Update(ctx context.Context, req resource.UpdateReq
"id": plan.ID.ValueString(),
"tag": tagName,
"policies.#": len(plan.Policies),
"policies": Map(plan.Policies, func(item types.String) string { return item.ValueString() }),
"policies": Map(plan.Policies, types.String.ValueString),
})

currentPoliciesInfo, err := dtrack.FetchAll(func(po dtrack.PageOptions) (dtrack.Page[dtrack.TaggedPolicyListResponseItem], error) {
Expand Down Expand Up @@ -280,7 +288,7 @@ func (r *tagPoliciesResource) Update(ctx context.Context, req resource.UpdateReq
tflog.Debug(ctx, "Updated Tag Policies", map[string]any{
"id": plan.ID.ValueString(),
"tag": plan.Tag.ValueString(),
"policies": Map(plan.Policies, func(t types.String) string { return t.ValueString() }),
"policies": Map(plan.Policies, types.String.ValueString),
})
}

Expand All @@ -297,7 +305,7 @@ func (r *tagPoliciesResource) Delete(ctx context.Context, req resource.DeleteReq
"id": state.ID.ValueString(),
"tag": tagName,
"policies.#": len(state.Policies),
"policies": Map(state.Policies, func(item types.String) string { return item.ValueString() }),
"policies": Map(state.Policies, types.String.ValueString),
})

currentPoliciesInfo, err := dtrack.FetchAll(func(po dtrack.PageOptions) (dtrack.Page[dtrack.TaggedPolicyListResponseItem], error) {
Expand All @@ -324,7 +332,7 @@ func (r *tagPoliciesResource) Delete(ctx context.Context, req resource.DeleteReq
tflog.Debug(ctx, "Deleted Tag Policies", map[string]any{
"id": state.ID.ValueString(),
"tag": tagName,
"policies": Map(state.Policies, func(policy types.String) string { return policy.ValueString() }),
"policies": Map(state.Policies, types.String.ValueString),
})
}

Expand Down
83 changes: 82 additions & 1 deletion internal/provider/tag_policies_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ func TestAccTagPoliciesResource(t *testing.T) {
Steps: []resource.TestStep{
// Create and Read testing.
{
// Use Project to create the Tag, due to `dependencytrack_tag` being 4.13+.
Config: providerConfig + `
resource "dependencytrack_project" "test" {
name = "Tag_Polcies_Resource_Project"
name = "Tag_Policies_Resource_Project"
tags = ["test_tag_policies_tag"]
}
resource "dependencytrack_policy" "test" {
Expand Down Expand Up @@ -97,3 +98,83 @@ resource "dependencytrack_tag_policies" "test" {
},
})
}

func TestAccTagPoliciesResourcePoliciesUnordered(t *testing.T) {
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and Read testing.
{
// Use Project to create the Tag, due to `dependencytrack_tag` being 4.13+.
Config: providerConfig + `
resource "dependencytrack_project" "test" {
name = "Tag_Policies_Resources_Unordered"
tags = ["test_tag_policies_unordered"]
}
resource "dependencytrack_policy" "a" {
name = "A"
operator = "ANY"
violation = "FAIL"
}
resource "dependencytrack_policy" "z" {
name = "z"
operator = "ANY"
violation = "FAIL"
}
resource "dependencytrack_tag_policies" "test" {
tag = "test_tag_policies_unordered"
policies = [
dependencytrack_policy.z.id,
dependencytrack_policy.a.id,
]
depends_on = [dependencytrack_project.test]
}
`,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("dependencytrack_tag_policies.test", "policies.#", "2"),
resource.TestCheckResourceAttrPair("dependencytrack_tag_policies.test", "policies.0", "dependencytrack_policy.z", "id"),
resource.TestCheckResourceAttrPair("dependencytrack_tag_policies.test", "policies.1", "dependencytrack_policy.a", "id"),
),
},
// Update and Read testing.
{
Config: providerConfig + `
resource "dependencytrack_project" "test" {
name = "Tag_Policies_Resources_Unordered"
tags = ["test_tag_policies_unordered"]
}
resource "dependencytrack_policy" "a" {
name = "A"
operator = "ANY"
violation = "FAIL"
}
resource "dependencytrack_policy" "z" {
name = "Z"
operator = "ANY"
violation = "FAIL"
}
resource "dependencytrack_policy" "b" {
name = "B"
operator = "ANY"
violation = "FAIL"
}
resource "dependencytrack_tag_policies" "test" {
tag = "test_tag_policies_unordered"
policies = [
dependencytrack_policy.z.id,
dependencytrack_policy.a.id,
dependencytrack_policy.b.id
]
depends_on = [dependencytrack_project.test]
}
`,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("dependencytrack_tag_policies.test", "policies.#", "3"),
resource.TestCheckResourceAttrPair("dependencytrack_tag_policies.test", "policies.0", "dependencytrack_policy.z", "id"),
resource.TestCheckResourceAttrPair("dependencytrack_tag_policies.test", "policies.1", "dependencytrack_policy.a", "id"),
resource.TestCheckResourceAttrPair("dependencytrack_tag_policies.test", "policies.2", "dependencytrack_policy.b", "id"),
),
},
},
})
}
44 changes: 25 additions & 19 deletions internal/provider/tag_projects_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package provider
import (
"context"
"fmt"
"strings"

dtrack "github.com/DependencyTrack/client-go"
"github.com/google/uuid"
Expand Down Expand Up @@ -61,8 +62,7 @@ func (*tagProjectsResource) Schema(_ context.Context, _ resource.SchemaRequest,
},
},
"projects": schema.ListAttribute{
// TODO: Use `ListUnorderedEqual` to remove requirement for this to be sorted.
Description: "Project UUIDs to which to apply tag. Sorted by project name.",
Description: "Project UUIDs to which to apply tag.",
Required: true,
ElementType: types.StringType,
},
Expand Down Expand Up @@ -146,7 +146,7 @@ func (r *tagProjectsResource) Create(ctx context.Context, req resource.CreateReq
tflog.Debug(ctx, "Created Tag Projects", map[string]any{
"id": plan.ID.ValueString(),
"tag": plan.Tag.ValueString(),
"projects": Map(plan.Projects, func(item types.String) string { return item.ValueString() }),
"projects": Map(plan.Projects, types.String.ValueString),
})
}

Expand All @@ -163,7 +163,7 @@ func (r *tagProjectsResource) Read(ctx context.Context, req resource.ReadRequest
"id": state.ID.ValueString(),
"tag": tagName,
"projects.#": len(state.Projects),
"projects": Map(state.Projects, func(item types.String) string { return item.ValueString() }),
"projects": Map(state.Projects, types.String.ValueString),
})

taggedProjectsInfo, err := dtrack.FetchAll(func(po dtrack.PageOptions) (dtrack.Page[dtrack.TaggedProjectListResponseItem], error) {
Expand All @@ -177,12 +177,20 @@ func (r *tagProjectsResource) Read(ctx context.Context, req resource.ReadRequest
return
}

stateProjects := Map(taggedProjectsInfo, func(info dtrack.TaggedProjectListResponseItem) types.String {
return types.StringValue(info.UUID.String())
})

if SliceUnorderedEqual(stateProjects, state.Projects, func(a, b types.String) int {
return strings.Compare(a.ValueString(), b.ValueString())
}) {
stateProjects = state.Projects
}

state = tagProjectsResourceModel{
ID: types.StringValue(tagName),
Tag: types.StringValue(tagName),
Projects: Map(taggedProjectsInfo, func(info dtrack.TaggedProjectListResponseItem) types.String {
return types.StringValue(info.UUID.String())
}),
ID: types.StringValue(tagName),
Tag: types.StringValue(tagName),
Projects: stateProjects,
}

diags = resp.State.Set(ctx, &state)
Expand All @@ -193,7 +201,7 @@ func (r *tagProjectsResource) Read(ctx context.Context, req resource.ReadRequest
tflog.Debug(ctx, "Read Tag Projects", map[string]any{
"id": state.ID.ValueString(),
"tag": state.Tag.ValueString(),
"projects": Map(state.Projects, func(v types.String) string { return v.ValueString() }),
"projects": Map(state.Projects, types.String.ValueString),
})
}

Expand All @@ -210,7 +218,7 @@ func (r *tagProjectsResource) Update(ctx context.Context, req resource.UpdateReq
"id": plan.ID.ValueString(),
"tag": tagName,
"projects.#": len(plan.Projects),
"projects": Map(plan.Projects, func(item types.String) string { return item.ValueString() }),
"projects": Map(plan.Projects, types.String.ValueString),
})

currentProjectsInfo, err := dtrack.FetchAll(func(po dtrack.PageOptions) (dtrack.Page[dtrack.TaggedProjectListResponseItem], error) {
Expand Down Expand Up @@ -281,7 +289,7 @@ func (r *tagProjectsResource) Update(ctx context.Context, req resource.UpdateReq
tflog.Debug(ctx, "Updated Tag Projects", map[string]any{
"id": plan.ID.ValueString(),
"tag": plan.Tag.ValueString(),
"projects": Map(plan.Projects, func(t types.String) string { return t.ValueString() }),
"projects": Map(plan.Projects, types.String.ValueString),
})
}

Expand All @@ -298,7 +306,7 @@ func (r *tagProjectsResource) Delete(ctx context.Context, req resource.DeleteReq
"id": state.ID.ValueString(),
"tag": tagName,
"projects.#": len(state.Projects),
"projects": Map(state.Projects, func(t types.String) string { return t.ValueString() }),
"projects": Map(state.Projects, types.String.ValueString),
})

currentProjectsInfo, err := dtrack.FetchAll(func(po dtrack.PageOptions) (dtrack.Page[dtrack.TaggedProjectListResponseItem], error) {
Expand All @@ -323,11 +331,9 @@ func (r *tagProjectsResource) Delete(ctx context.Context, req resource.DeleteReq
return
}
tflog.Debug(ctx, "Deleted Tag Projects", map[string]any{
"id": state.ID.ValueString(),
"tag": tagName,
"projects": Map(state.Projects, func(project types.String) string {
return project.ValueString()
}),
"id": state.ID.ValueString(),
"tag": tagName,
"projects": Map(state.Projects, types.String.ValueString),
})
}

Expand All @@ -353,7 +359,7 @@ func (r *tagProjectsResource) Configure(_ context.Context, req resource.Configur
if !ok {
resp.Diagnostics.AddError(
"Unexpected Configure Type",
fmt.Sprintf("Expected provider.clientInfo, got %T. Please report this issue to the provider developer.", req.ProviderData),
fmt.Sprintf("Expected provider.clientDebug, got %T. Please report this issue to the provider developer.", req.ProviderData),
)
return
}
Expand Down
Loading