From 16ad0c6a9d104fea9421553bdd76d6389c5efe4c Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Mon, 29 Jul 2024 13:59:44 -0700 Subject: [PATCH 1/4] Add 'read_only' attribute to support sharing in read-only mode --- .../resource_project_share_repository.go | 16 +++++++ .../resource_project_share_repository_test.go | 3 ++ ...ource_project_share_repository_with_all.go | 18 +++++++- ..._project_share_repository_with_all_test.go | 43 +++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/pkg/project/resource/resource_project_share_repository.go b/pkg/project/resource/resource_project_share_repository.go index f8639c0f..aee3eb05 100644 --- a/pkg/project/resource/resource_project_share_repository.go +++ b/pkg/project/resource/resource_project_share_repository.go @@ -10,6 +10,8 @@ import ( "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -35,6 +37,7 @@ type ProjectShareRepositoryResource struct { type ProjectShareRepositoryResourceModel struct { RepoKey types.String `tfsdk:"repo_key"` TargetProjectKey types.String `tfsdk:"target_project_key"` + ReadOnly types.Bool `tfsdk:"read_only"` } func (r *ProjectShareRepositoryResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { @@ -64,6 +67,15 @@ func (r *ProjectShareRepositoryResource) Schema(ctx context.Context, req resourc }, Description: "The project key to which the repository should be shared with.", }, + "read_only": schema.BoolAttribute{ + Optional: true, + Computed: true, + Default: booldefault.StaticBool(false), + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + Description: "Share repository with a Project in Read-Only mode to avoid any changes or modifications of the shared content.", + }, }, Description: "Share a local or remote repository with a list of projects. Project Members of the target project are granted actions to the shared repository according to their Roles and Role actions assigned in the target Project. Requires a user assigned with the 'Administer the Platform' role.\n\n" + "->Only available for Artifactory 7.90.1 or later.", @@ -114,6 +126,7 @@ func (r *ProjectShareRepositoryResource) Create(ctx context.Context, req resourc "repo_key": plan.RepoKey.ValueString(), "target_project_key": plan.TargetProjectKey.ValueString(), }). + SetQueryParam("readOnly", fmt.Sprintf("%t", plan.ReadOnly.ValueBool())). SetError(&projectError). Put(shareWithTargetProject) @@ -174,6 +187,8 @@ func (r *ProjectShareRepositoryResource) Read(ctx context.Context, req resource. state.TargetProjectKey = types.StringNull() } + state.ReadOnly = types.BoolValue(status.SharedReadOnly) + // Save updated data into Terraform state resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) } @@ -203,6 +218,7 @@ func (r *ProjectShareRepositoryResource) Delete(ctx context.Context, req resourc "repo_key": state.RepoKey.ValueString(), "target_project_key": state.TargetProjectKey.ValueString(), }). + SetQueryParam("readOnly", fmt.Sprintf("%t", state.ReadOnly.ValueBool())). SetError(&projectError). Delete(shareWithTargetProject) diff --git a/pkg/project/resource/resource_project_share_repository_test.go b/pkg/project/resource/resource_project_share_repository_test.go index a000845a..5b25c2b9 100644 --- a/pkg/project/resource/resource_project_share_repository_test.go +++ b/pkg/project/resource/resource_project_share_repository_test.go @@ -67,6 +67,7 @@ func TestAccProjectShareRepository_full(t *testing.T) { resource "project_share_repository" "{{ .resource_name }}" { repo_key = artifactory_local_generic_repository.{{ .repo_key }}.key target_project_key = project.{{ .project_name_1 }}.key + read_only = true } ` @@ -123,6 +124,7 @@ func TestAccProjectShareRepository_full(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(fqrn, "repo_key", params["repo_key"]), resource.TestCheckResourceAttr(fqrn, "target_project_key", params["project_key_1"]), + resource.TestCheckResourceAttr(fqrn, "read_only", "true"), ), }, { @@ -130,6 +132,7 @@ func TestAccProjectShareRepository_full(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(fqrn, "repo_key", updateParams["repo_key"]), resource.TestCheckResourceAttr(fqrn, "target_project_key", updateParams["project_key_2"]), + resource.TestCheckResourceAttr(fqrn, "read_only", "false"), ), }, { diff --git a/pkg/project/resource/resource_project_share_repository_with_all.go b/pkg/project/resource/resource_project_share_repository_with_all.go index f6c7f15b..02f8f9c8 100644 --- a/pkg/project/resource/resource_project_share_repository_with_all.go +++ b/pkg/project/resource/resource_project_share_repository_with_all.go @@ -8,6 +8,8 @@ import ( "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -31,7 +33,8 @@ type ProjectShareRepositoryWithAllResource struct { } type ProjectShareRepositoryWithAllResourceModel struct { - RepoKey types.String `tfsdk:"repo_key"` + RepoKey types.String `tfsdk:"repo_key"` + ReadOnly types.Bool `tfsdk:"read_only"` } func (r *ProjectShareRepositoryWithAllResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { @@ -51,6 +54,15 @@ func (r *ProjectShareRepositoryWithAllResource) Schema(ctx context.Context, req }, Description: "The key of the repository.", }, + "read_only": schema.BoolAttribute{ + Optional: true, + Computed: true, + Default: booldefault.StaticBool(false), + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + Description: "Share repository with all Projects in Read-Only mode to avoid any changes or modifications of the shared content.", + }, }, Description: "Share a local or remote repository with all projects. Project Members of the target project are granted actions to the shared repository according to their Roles and Role actions assigned in the target Project. Requires a user assigned with the 'Administer the Platform' role.\n\n" + "->Only available for Artifactory 7.90.1 or later.", @@ -98,6 +110,7 @@ func (r *ProjectShareRepositoryWithAllResource) Create(ctx context.Context, req response, err := r.ProviderData.Client.R(). SetPathParam("repo_key", plan.RepoKey.ValueString()). + SetQueryParam("readOnly", fmt.Sprintf("%t", plan.ReadOnly.ValueBool())). SetError(&projectError). Put(shareWithAllProjectsEndpoint) @@ -161,6 +174,8 @@ func (r *ProjectShareRepositoryWithAllResource) Read(ctx context.Context, req re return } + state.ReadOnly = types.BoolValue(status.SharedReadOnly) + // Save updated data into Terraform state resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) } @@ -187,6 +202,7 @@ func (r *ProjectShareRepositoryWithAllResource) Delete(ctx context.Context, req response, err := r.ProviderData.Client.R(). SetPathParam("repo_key", state.RepoKey.ValueString()). + SetQueryParam("readOnly", fmt.Sprintf("%t", state.ReadOnly.ValueBool())). SetError(&projectError). Delete(shareWithAllProjectsEndpoint) diff --git a/pkg/project/resource/resource_project_share_repository_with_all_test.go b/pkg/project/resource/resource_project_share_repository_with_all_test.go index 465017b9..523655e6 100644 --- a/pkg/project/resource/resource_project_share_repository_with_all_test.go +++ b/pkg/project/resource/resource_project_share_repository_with_all_test.go @@ -65,6 +65,7 @@ func TestAccProjectShareWithAllRepository_full(t *testing.T) { resource "project_share_repository_with_all" "{{ .resource_name }}" { repo_key = artifactory_local_generic_repository.{{ .repo_key }}.key + read_only = true depends_on = [ project.{{ .project_name }} @@ -74,6 +75,40 @@ func TestAccProjectShareWithAllRepository_full(t *testing.T) { config := util.ExecuteTemplate("TestAccProjectShareRepository", temp, params) + updatedTemp := ` + resource "artifactory_local_generic_repository" "{{ .repo_key }}" { + key = "{{ .repo_key }}" + + lifecycle { + ignore_changes = ["project_key"] + } + } + + resource "project" "{{ .project_name }}" { + key = "{{ .project_key }}" + display_name = "{{ .project_name }}" + description = "test description" + admin_privileges { + manage_members = true + manage_resources = true + index_resources = true + } + max_storage_in_gibibytes = 1 + block_deployments_on_limit = true + email_notification = false + } + + resource "project_share_repository_with_all" "{{ .resource_name }}" { + repo_key = artifactory_local_generic_repository.{{ .repo_key }}.key + + depends_on = [ + project.{{ .project_name }} + ] + } + ` + + updatedConfig := util.ExecuteTemplate("TestAccProjectShareRepository", updatedTemp, params) + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, @@ -87,6 +122,14 @@ func TestAccProjectShareWithAllRepository_full(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(fqrn, "repo_key", params["repo_key"].(string)), + resource.TestCheckResourceAttr(fqrn, "read_only", "true"), + ), + }, + { + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(fqrn, "repo_key", params["repo_key"].(string)), + resource.TestCheckResourceAttr(fqrn, "read_only", "false"), ), }, { From 5ec719d13c92d346fb9fb6a4ad0e3d868d173b2f Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 7 Aug 2024 10:36:30 -0700 Subject: [PATCH 2/4] Update CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bd618ec..afa175f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.8.0 (July 31, 2024) + +IMPROVEMENTS: + +* resource/project_share_repository, resource/project_share_repository_with_all: Add `read_only` attribute to support sharing repository with project(s) in read-only mode. PR: [#148](https://github.com/jfrog/terraform-provider-project/pull/148) + ## 1.7.2 (August 8, 2024). Tested on Artifactory 7.90.6 with Terraform 1.9.3 and OpenTofu 1.8.1 IMPROVEMENTS: From 50ff8b7f8fd326fad4fae4bda93c540a810c247b Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Mon, 16 Sep 2024 13:10:53 -0700 Subject: [PATCH 3/4] Update `read_only` attribute doc with min Artifactory version --- docs/resources/share_repository.md | 3 +++ docs/resources/share_repository_with_all.md | 3 +++ pkg/project/resource/resource_project_share_repository.go | 3 ++- .../resource/resource_project_share_repository_with_all.go | 3 ++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/resources/share_repository.md b/docs/resources/share_repository.md index 7c2bbc49..5f132cbe 100644 --- a/docs/resources/share_repository.md +++ b/docs/resources/share_repository.md @@ -28,6 +28,9 @@ resource "project_share_repository" "myprojectsharerepo" { - `repo_key` (String) The key of the repository. - `target_project_key` (String) The project key to which the repository should be shared with. +- `read_only` (Boolean) Share repository with a Project in Read-Only mode to avoid any changes or modifications of the shared content. + +->Only available for Artifactory 7.94.0 or later. ## Import diff --git a/docs/resources/share_repository_with_all.md b/docs/resources/share_repository_with_all.md index d85e51b0..1847edc5 100644 --- a/docs/resources/share_repository_with_all.md +++ b/docs/resources/share_repository_with_all.md @@ -26,6 +26,9 @@ resource "project_share_repository_with_all" "myprojectsharerepo" { ### Required - `repo_key` (String) The key of the repository. +- `read_only` (Boolean) Share repository with a Project in Read-Only mode to avoid any changes or modifications of the shared content. + +->Only available for Artifactory 7.94.0 or later. ## Import diff --git a/pkg/project/resource/resource_project_share_repository.go b/pkg/project/resource/resource_project_share_repository.go index aee3eb05..d6029a90 100644 --- a/pkg/project/resource/resource_project_share_repository.go +++ b/pkg/project/resource/resource_project_share_repository.go @@ -74,7 +74,8 @@ func (r *ProjectShareRepositoryResource) Schema(ctx context.Context, req resourc PlanModifiers: []planmodifier.Bool{ boolplanmodifier.RequiresReplace(), }, - Description: "Share repository with a Project in Read-Only mode to avoid any changes or modifications of the shared content.", + Description: "Share repository with a Project in Read-Only mode to avoid any changes or modifications of the shared content.\n\n" + + "->Only available for Artifactory 7.94.0 or later.", }, }, Description: "Share a local or remote repository with a list of projects. Project Members of the target project are granted actions to the shared repository according to their Roles and Role actions assigned in the target Project. Requires a user assigned with the 'Administer the Platform' role.\n\n" + diff --git a/pkg/project/resource/resource_project_share_repository_with_all.go b/pkg/project/resource/resource_project_share_repository_with_all.go index 02f8f9c8..67d2aef9 100644 --- a/pkg/project/resource/resource_project_share_repository_with_all.go +++ b/pkg/project/resource/resource_project_share_repository_with_all.go @@ -61,7 +61,8 @@ func (r *ProjectShareRepositoryWithAllResource) Schema(ctx context.Context, req PlanModifiers: []planmodifier.Bool{ boolplanmodifier.RequiresReplace(), }, - Description: "Share repository with all Projects in Read-Only mode to avoid any changes or modifications of the shared content.", + Description: "Share repository with all Projects in Read-Only mode to avoid any changes or modifications of the shared content.\n\n" + + "->Only available for Artifactory 7.94.0 or later.", }, }, Description: "Share a local or remote repository with all projects. Project Members of the target project are granted actions to the shared repository according to their Roles and Role actions assigned in the target Project. Requires a user assigned with the 'Administer the Platform' role.\n\n" + From 4a7e07d22819371d5085471df527903e7fd30ed1 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Mon, 16 Sep 2024 13:18:03 -0700 Subject: [PATCH 4/4] Update CHANGELOG --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afa175f6..6326cd23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ -## 1.8.0 (July 31, 2024) +## 1.8.0 (September 17, 2024) IMPROVEMENTS: -* resource/project_share_repository, resource/project_share_repository_with_all: Add `read_only` attribute to support sharing repository with project(s) in read-only mode. PR: [#148](https://github.com/jfrog/terraform-provider-project/pull/148) +* resource/project_share_repository, resource/project_share_repository_with_all: Add `read_only` attribute to support sharing repository with project(s) in read-only mode. Issue: [#156](https://github.com/jfrog/terraform-provider-project/issues/156) PR: [#158](https://github.com/jfrog/terraform-provider-project/pull/158) ## 1.7.2 (August 8, 2024). Tested on Artifactory 7.90.6 with Terraform 1.9.3 and OpenTofu 1.8.1