Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish up project_user and project_group resources #101

Merged
merged 3 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
11 changes: 8 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
## 1.4.0 (not yet released)
## 1.4.0 (March 4, 2024)

FEATURES:

* **New Resource:** `project_user` - Separate resource to manage project memberships for users.
* **New Resource:** `project_group` - Separate resource to project project memberships for groups.
* resource/project: Add `cd ..` attribute to toggle if `project` resource should use its `member` or not to manage project users. Should be set to `true` when using in conjunction with `project_user` resource.
* resource/project: Add `use_project_group_resource` attribute to toggle if `project` resource should use its `group` or not to manage project users. Should be set to `true` when using in conjunction with `project_group` resource.
* resource/project: Add `use_project_user_resource` attribute to toggle if `project` resource should use its `member` or not to manage project users. Should be set to `false` to continue using existing `member` attribute.
* resource/project: Add `use_project_group_resource` attribute to toggle if `project` resource should use its `group` or not to manage project users. Should be set to `false` to continue using existing `group` attribute.
* resource/project: Switch default value for `use_project_role_resource` attribute to `true` so new provider practioners won't need to explicity set this attribute to use `project_role` resource.

Issue: [#83](https://github.com/jfrog/terraform-provider-project/issues/83), [#98](https://github.com/jfrog/terraform-provider-project/issues/98)

PR: [#101](https://github.com/jfrog/terraform-provider-project/pull/101)

## 1.3.5 (Feburary 9, 2024)

Expand Down
12 changes: 12 additions & 0 deletions pkg/project/membership_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ func TestAccProject_membership(t *testing.T) {
index_resources = true
}

use_project_user_resource = false

member {
name = "{{ .username1 }}"
roles = ["{{ .developeRole }}"]
Expand All @@ -60,6 +62,8 @@ func TestAccProject_membership(t *testing.T) {
index_resources = true
}

use_project_user_resource = false

member {
name = "{{ .username1 }}"
roles = ["{{ .developeRole }}", "{{ .contributorRole }}"]
Expand All @@ -82,6 +86,8 @@ func TestAccProject_membership(t *testing.T) {
manage_resources = true
index_resources = true
}

use_project_user_resource = false
}
`, params)

Expand Down Expand Up @@ -177,6 +183,8 @@ func TestAccProject_group(t *testing.T) {
index_resources = true
}

use_project_group_resource = false

group {
name = "{{ .group1 }}"
roles = ["{{ .developeRole }}"]
Expand All @@ -195,6 +203,8 @@ func TestAccProject_group(t *testing.T) {
index_resources = true
}

use_project_group_resource = false

group {
name = "{{ .group1 }}"
roles = ["{{ .developeRole }}", "{{ .contributorRole }}"]
Expand All @@ -217,6 +227,8 @@ func TestAccProject_group(t *testing.T) {
manage_resources = true
index_resources = true
}

use_project_group_resource = false
}
`, params)

Expand Down
42 changes: 0 additions & 42 deletions pkg/project/project_group.go

This file was deleted.

45 changes: 0 additions & 45 deletions pkg/project/project_user.go

This file was deleted.

8 changes: 4 additions & 4 deletions pkg/project/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ var updateRepos = func(ctx context.Context, projectKey string, terraformRepoKeys
return nil, fmt.Errorf("failed to add repos for project: %s", addErr)
}

deleteErr := deleteRepos(ctx, projectKey, repoKeysToBeDeleted, m)
deleteErr := deleteRepos(ctx, repoKeysToBeDeleted, m)
if deleteErr != nil {
return nil, fmt.Errorf("failed to delete repos for project: %s", deleteErr)
}
Expand Down Expand Up @@ -139,7 +139,7 @@ var addRepo = func(ctx context.Context, projectKey string, repoKey RepoKey, req
return err
}

var deleteRepos = func(ctx context.Context, projectKey string, repoKeys []RepoKey, m interface{}) error {
var deleteRepos = func(ctx context.Context, repoKeys []RepoKey, m interface{}) error {
tflog.Debug(ctx, fmt.Sprintf("deleteRepos: %s", repoKeys))

req := m.(util.ProvderMetadata).Client.R().
Expand All @@ -148,7 +148,7 @@ var deleteRepos = func(ctx context.Context, projectKey string, repoKeys []RepoKe
AddRetryCondition(retryOnSpecificMsgBody("Web server is returning an unknown error"))

for _, repoKey := range repoKeys {
err := deleteRepo(ctx, projectKey, repoKey, req)
err := deleteRepo(ctx, repoKey, req)
if err != nil {
return fmt.Errorf("failed to delete repo %s: %s", repoKey, err)
}
Expand All @@ -157,7 +157,7 @@ var deleteRepos = func(ctx context.Context, projectKey string, repoKeys []RepoKe
return nil
}

var deleteRepo = func(ctx context.Context, projectKey string, repoKey RepoKey, req *resty.Request) error {
var deleteRepo = func(ctx context.Context, repoKey RepoKey, req *resty.Request) error {
tflog.Debug(ctx, fmt.Sprintf("deleteRepo: %s", repoKey))

type Error struct {
Expand Down
38 changes: 20 additions & 18 deletions pkg/project/resource_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,8 @@ func projectResource() *schema.Resource {
"use_project_role_resource": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "When set to true, this resource will ignore the `roles` attributes and allow roles to be managed by `project_role` resource instead. Default to false.",
Default: true,
Description: "When set to true, this resource will ignore the `roles` attributes and allow roles to be managed by `project_role` resource instead. Default to `true`.",
},
},
)
Expand Down Expand Up @@ -297,6 +297,12 @@ func projectResource() *schema.Resource {
Description: "Member of the project. Element has one to one mapping with the [JFrog Project Users API](https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API#ArtifactoryRESTAPI-UpdateUserinProject).",
Deprecated: "Replaced by `project_user` resource. This should not be used in combination with `project_user` resource. Use `use_project_user_resource` attribute to control which resource manages project roles.",
},
"use_project_user_resource": {
Type: schema.TypeBool,
Optional: true,
Default: true,
Description: "When set to true, this resource will ignore the `member` attributes and allow users to be managed by `project_user` resource instead. Default to `true`.",
},
"group": {
Type: schema.TypeSet,
Optional: true,
Expand All @@ -319,17 +325,11 @@ func projectResource() *schema.Resource {
Description: "Project group. Element has one to one mapping with the [JFrog Project Groups API](https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API#ArtifactoryRESTAPI-UpdateGroupinProject)",
Deprecated: "Replaced by `project_group` resource. This should not be used in combination with `project_group` resource. Use `use_project_group_resource` attribute to control which resource manages project roles.",
},
"use_project_user_resource": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "When set to true, this resource will ignore the `member` attributes and allow users to be managed by `project_user` resource instead. Default to false.",
},
"use_project_group_resource": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "When set to true, this resource will ignore the `group` attributes and allow users to be managed by `project_group` resource instead. Default to false.",
Default: true,
Description: "When set to true, this resource will ignore the `group` attributes and allow users to be managed by `project_group` resource instead. Default to `true`.",
},
},
)
Expand Down Expand Up @@ -466,7 +466,9 @@ func projectResource() *schema.Resource {
return diag.FromErr(err)
}

_, err = m.(util.ProvderMetadata).Client.R().SetBody(project).Post(projectsUrl)
_, err = m.(util.ProvderMetadata).Client.R().
SetBody(project).
Post(projectsUrl)
if err != nil {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -534,7 +536,7 @@ func projectResource() *schema.Resource {
}
}

useProjectUserResource := data.Get("use_project_role_resource").(bool)
useProjectUserResource := data.Get("use_project_user_resource").(bool)
if !useProjectUserResource {
_, err = updateMembers(ctx, data.Id(), usersMembershipType, users, m)
if err != nil {
Expand Down Expand Up @@ -567,7 +569,7 @@ func projectResource() *schema.Resource {
return diag.FromErr(err)
}

deleteErr := deleteRepos(ctx, data.Id(), repos, m)
deleteErr := deleteRepos(ctx, repos, m)
if deleteErr != nil {
return diag.FromErr(fmt.Errorf("failed to delete repos for project: %s", deleteErr))
}
Expand Down Expand Up @@ -607,16 +609,16 @@ func projectResource() *schema.Resource {
}

var resourceStateUpgradeV1 = func(ctx context.Context, rawState map[string]any, meta any) (map[string]any, error) {
// set use_project_role_resource to true for existing state so the resource will continue
// using `roles` attribute until explicitly set to false
rawState["use_project_role_resource"] = true
// set use_project_role_resource to false for existing state so the resource will continue
// using `roles` attribute until explicitly set to true
rawState["use_project_role_resource"] = false
return rawState, nil
}

var resourceStateUpgradeV2 = func(ctx context.Context, rawState map[string]any, meta any) (map[string]any, error) {
// like in v1 where the project_role was introduced, just for project_user and project_group
rawState["use_project_user_resource"] = true
rawState["use_project_group_resource"] = true
rawState["use_project_user_resource"] = false
rawState["use_project_group_resource"] = false
return rawState, nil
}

Expand Down
33 changes: 33 additions & 0 deletions pkg/project/resource_project_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ import (

const projectGroupsUrl = "access/api/v1/projects/{projectKey}/groups/{name}"

type ProjectGroup struct {
ProjectKey string `json:"-"`
Name string `json:"name"`
Roles []string `json:"roles"`
}

func (m ProjectGroup) Id() string {
return fmt.Sprintf(`%s:%s`, m.ProjectKey, m.Name)
}

func projectGroupResource() *schema.Resource {
var projectGroupSchema = map[string]*schema.Schema{
"project_key": {
Expand All @@ -26,6 +36,7 @@ func projectGroupResource() *schema.Resource {
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotEmpty),
Description: "The name of an artifactory group.",
},
Expand All @@ -37,6 +48,28 @@ func projectGroupResource() *schema.Resource {
},
}

var unpackProjectGroup = func(d *schema.ResourceData) ProjectGroup {
return ProjectGroup{
ProjectKey: d.Get("project_key").(string),
Name: d.Get("name").(string),
Roles: util.CastToStringArr(d.Get("roles").(*schema.Set).List()),
}
}

var packProjectGroup = func(_ context.Context, data *schema.ResourceData, m ProjectGroup) diag.Diagnostics {
setValue := util.MkLens(data)

setValue("name", m.Name)
setValue("project_key", m.ProjectKey)
errors := setValue("roles", m.Roles)

if len(errors) > 0 {
return diag.Errorf("failed to pack project member %q", errors)
}

return nil
}

var readProjectGroup = func(ctx context.Context, data *schema.ResourceData, m interface{}) diag.Diagnostics {
projectGroup := unpackProjectGroup(data)
var loadedProjectGroup ProjectGroup
Expand Down
10 changes: 7 additions & 3 deletions pkg/project/resource_project_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ func TestAccProjectGroup(t *testing.T) {
block_deployments_on_limit = true
email_notification = false

lifecycle {
ignore_changes = ["member"]
}
use_project_group_resource = true
}

resource "project_group" "{{ .group }}" {
Expand All @@ -72,6 +70,12 @@ func TestAccProjectGroup(t *testing.T) {
return verifyProjectUser(group, projectKey, request)
}),
ProviderFactories: testAccProviders(),
ExternalProviders: map[string]resource.ExternalProvider{
"artifactory": {
Source: "jfrog/artifactory",
VersionConstraint: "10.1.4",
},
},
Steps: []resource.TestStep{
{
Config: config,
Expand Down
2 changes: 1 addition & 1 deletion pkg/project/resource_project_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func projectRoleResource() *schema.Resource {
},
}

var packRole = func(ctx context.Context, data *schema.ResourceData, role Role, projectKey string) diag.Diagnostics {
var packRole = func(_ context.Context, data *schema.ResourceData, role Role, projectKey string) diag.Diagnostics {
setValue := util.MkLens(data)

setValue("name", role.Name)
Expand Down
3 changes: 2 additions & 1 deletion pkg/project/resource_project_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ func TestAccProjectRole_full(t *testing.T) {
manage_resources = true
index_resources = true
}
use_project_role_resource = true
}

resource "project_role" "{{ .name }}" {
Expand Down Expand Up @@ -107,6 +106,8 @@ func TestAccProjectRole_conflict_with_project(t *testing.T) {
manage_resources = true
index_resources = true
}

use_project_role_resource = false
}

resource "project_role" "{{ .name }}" {
Expand Down
Loading
Loading