diff --git a/CHANGELOG.md b/CHANGELOG.md index 442eee605..0933a49f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ IMPROVEMENTS: * **New Resource:** artifactory_virtual_cocoapods_repository, which was missing from the provider. Issue: [#1079](https://github.com/jfrog/terraform-provider-artifactory/issues/1079) PR: [#1084](https://github.com/jfrog/terraform-provider-artifactory/pull/1084) +* resource/artifactory_remote_generic_repository: Add `retrieve_sha256_from_server` attribute. Issue: [#1080](https://github.com/jfrog/terraform-provider-artifactory/issues/1080) PR: [#1085](https://github.com/jfrog/terraform-provider-artifactory/pull/1085) ## 12.0.0 (September 16, 2024). Tested on Artifactory 7.90.10 with Terraform 1.9.6 and OpenTofu 1.8.2 diff --git a/docs/resources/remote_generic_repository.md b/docs/resources/remote_generic_repository.md index 83e7f5dda..954b81ac8 100644 --- a/docs/resources/remote_generic_repository.md +++ b/docs/resources/remote_generic_repository.md @@ -9,8 +9,8 @@ Creates a remote Generic repository. ```hcl resource "artifactory_remote_generic_repository" "my-remote-generic" { - key = "my-remote-generic" - url = "http://testartifactory.io/artifactory/example-generic/" + key = "my-remote-generic" + url = "http://testartifactory.io/artifactory/example-generic/" } ``` @@ -26,6 +26,7 @@ All generic repo arguments are supported, in addition to: * `notes` - (Optional) Internal description. * `url` - (Required) The remote repo URL. * `propagate_query_params` - (Optional, Default: `false`) When set, if query params are included in the request to Artifactory, they will be passed on to the remote repository. +* `retrieve_sha256_from_server` - (Optional, Default: `false`) When set to `true`, Artifactory retrieves the SHA256 from the remote server if it is not cached in the remote repo. ## Import diff --git a/pkg/artifactory/resource/repository/remote/remote.go b/pkg/artifactory/resource/repository/remote/remote.go index f8334eb87..a0b8f0be2 100644 --- a/pkg/artifactory/resource/repository/remote/remote.go +++ b/pkg/artifactory/resource/repository/remote/remote.go @@ -507,7 +507,7 @@ func UnpackBaseRemoteRepo(s *schema.ResourceData, packageType string) Repository d := &utilsdk.ResourceData{ResourceData: s} repo := RepositoryRemoteBaseParams{ - Rclass: "remote", + Rclass: Rclass, Key: d.GetString("key", false), ProjectKey: d.GetString("project_key", false), ProjectEnvironments: d.GetSet("project_environments"), @@ -600,6 +600,7 @@ func UnpackJavaRemoteRepo(s *schema.ResourceData, repoType string) JavaRemoteRep func mkResourceSchema(skeemas map[int16]map[string]*schema.Schema, packer packer.PackFunc, unpack unpacker.UnpackFunc, constructor repository.Constructor) *schema.Resource { var reader = repository.MkRepoRead(packer, constructor) + return &schema.Resource{ CreateContext: repository.MkRepoCreate(unpack, reader), ReadContext: reader, diff --git a/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_generic_repository.go b/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_generic_repository.go index bec9c0078..eeaa4e1ec 100644 --- a/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_generic_repository.go +++ b/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_generic_repository.go @@ -1,6 +1,8 @@ package remote import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/jfrog/terraform-provider-artifactory/v12/pkg/artifactory/resource/repository" "github.com/jfrog/terraform-provider-shared/packer" @@ -10,10 +12,11 @@ import ( type GenericRemoteRepo struct { RepositoryRemoteBaseParams - PropagateQueryParams bool `json:"propagateQueryParams"` + PropagateQueryParams bool `json:"propagateQueryParams"` + RetrieveSha256FromServer bool `hcl:"retrieve_sha256_from_server" json:"retrieveSha256FromServer"` } -var genericSchema = lo.Assign( +var genericSchemaV3 = lo.Assign( baseSchema, map[string]*schema.Schema{ "propagate_query_params": { @@ -26,15 +29,54 @@ var genericSchema = lo.Assign( repository.RepoLayoutRefSchema(Rclass, repository.GenericPackageType), ) -var GenericSchemas = GetSchemas(genericSchema) +var genericSchemaV4 = lo.Assign( + genericSchemaV3, + map[string]*schema.Schema{ + "retrieve_sha256_from_server": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "When set to `true`, Artifactory retrieves the SHA256 from the remote server if it is not cached in the remote repo.", + }, + }, +) + +const currentGenericSchemaVersion = 4 -func ResourceArtifactoryRemoteGenericRepository() *schema.Resource { +var getSchemas = func(s map[string]*schema.Schema) map[int16]map[string]*schema.Schema { + return map[int16]map[string]*schema.Schema{ + 0: lo.Assign( + baseSchemaV1, + s, + ), + 1: lo.Assign( + baseSchemaV1, + s, + ), + 2: lo.Assign( + baseSchemaV2, + s, + ), + 3: lo.Assign( + baseSchemaV3, + s, + ), + 4: lo.Assign( + baseSchemaV3, + genericSchemaV4, + ), + } +} +var GenericSchemas = getSchemas(genericSchemaV4) + +func ResourceArtifactoryRemoteGenericRepository() *schema.Resource { var unpackGenericRemoteRepo = func(s *schema.ResourceData) (interface{}, string, error) { d := &utilsdk.ResourceData{ResourceData: s} repo := GenericRemoteRepo{ RepositoryRemoteBaseParams: UnpackBaseRemoteRepo(s, repository.GenericPackageType), PropagateQueryParams: d.GetBool("propagate_query_params", false), + RetrieveSha256FromServer: d.GetBool("retrieve_sha256_from_server", false), } return repo, repo.Id(), nil } @@ -54,12 +96,34 @@ func ResourceArtifactoryRemoteGenericRepository() *schema.Resource { }, nil } - return mkResourceSchema( + resourceSchema := mkResourceSchema( GenericSchemas, - packer.Default(GenericSchemas[CurrentSchemaVersion]), + packer.Default(GenericSchemas[currentGenericSchemaVersion]), unpackGenericRemoteRepo, constructor, ) + + resourceSchema.Schema = GenericSchemas[currentGenericSchemaVersion] + resourceSchema.SchemaVersion = currentGenericSchemaVersion + resourceSchema.StateUpgraders = append( + resourceSchema.StateUpgraders, + schema.StateUpgrader{ + Type: repository.Resource(GenericSchemas[3]).CoreConfigSchema().ImpliedType(), + Upgrade: genericResourceStateUpgradeV3, + Version: 3, + }, + ) + + return resourceSchema +} + +func genericResourceStateUpgradeV3(_ context.Context, rawState map[string]interface{}, _ interface{}) (map[string]interface{}, error) { + rawState["retrieve_sha256_from_server"] = false + if v, ok := rawState["property_sets"]; !ok || v == nil { + rawState["property_sets"] = []string{} + } + + return rawState, nil } var BasicSchema = func(packageType string) map[string]*schema.Schema { diff --git a/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_repository_test.go b/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_repository_test.go index ea2d83307..e5f426ab2 100644 --- a/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_repository_test.go +++ b/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_repository_test.go @@ -1143,6 +1143,93 @@ func TestAccRemoteRepository_generic_with_propagate(t *testing.T) { }) } +func TestAccRemoteRepository_generic_with_retrieve_sha256_from_server(t *testing.T) { + + const temp = ` + resource "artifactory_remote_generic_repository" "%s" { + key = "%s" + description = "This is a test" + url = "https://registry.npmjs.org/" + repo_layout_ref = "simple-default" + retrieve_sha256_from_server = true + retrieval_cache_period_seconds = 70 + } + ` + id := testutil.RandomInt() + name := fmt.Sprintf("remote-test-repo-basic%d", id) + fqrn := fmt.Sprintf("artifactory_remote_generic_repository.%s", name) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: acctest.VerifyDeleted(fqrn, "", acctest.CheckRepo), + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(temp, name, name), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(fqrn, "key", name), + resource.TestCheckResourceAttr(fqrn, "package_type", "generic"), + resource.TestCheckResourceAttr(fqrn, "retrieve_sha256_from_server", "true"), + ), + }, + { + ResourceName: fqrn, + ImportState: true, + ImportStateVerify: true, + ImportStateCheck: validator.CheckImportState(name, "key"), + }, + }, + }) +} + +func TestAccRemoteRepository_generic_migrate_to_schema_v4(t *testing.T) { + _, fqrn, name := testutil.MkNames("test-generic-remote", "artifactory_remote_generic_repository") + + const temp = ` + resource "artifactory_remote_generic_repository" "{{ .name }}" { + key = "{{ .name }}" + description = "This is a test" + url = "https://registry.npmjs.org/" + repo_layout_ref = "simple-default" + propagate_query_params = true + retrieval_cache_period_seconds = 70 + } + ` + + params := map[string]interface{}{ + "name": name, + } + + config := util.ExecuteTemplate("TestAccRemoteRepository_generic_migrate_to_schema_v4", temp, params) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + CheckDestroy: acctest.VerifyDeleted(fqrn, "", acctest.CheckRepo), + Steps: []resource.TestStep{ + { + Config: config, + ExternalProviders: map[string]resource.ExternalProvider{ + "artifactory": { + Source: "jfrog/artifactory", + VersionConstraint: "12.0.0", + }, + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(fqrn, "key", name), + resource.TestCheckResourceAttr(fqrn, "package_type", "generic"), + resource.TestCheckNoResourceAttr(fqrn, "retrieve_sha256_from_server"), + ), + }, + { + ProviderFactories: acctest.ProviderFactories, + Config: config, + PlanOnly: true, + ConfigPlanChecks: testutil.ConfigPlanChecks(""), + }, + }, + }) +} + func TestAccRemoteRepository_gems_with_propagate_fails(t *testing.T) { for _, repoType := range remote.PackageTypesLikeBasic { const remoteGemsRepoBasicWithPropagate = ` diff --git a/pkg/artifactory/resource/repository/virtual/resource_artifactory_virtual_repository_test.go b/pkg/artifactory/resource/repository/virtual/resource_artifactory_virtual_repository_test.go index 1219deef6..3466bd3f4 100644 --- a/pkg/artifactory/resource/repository/virtual/resource_artifactory_virtual_repository_test.go +++ b/pkg/artifactory/resource/repository/virtual/resource_artifactory_virtual_repository_test.go @@ -557,7 +557,7 @@ func TestAccVirtualRepository_update(t *testing.T) { }) } -func TestNugetPackageCreationFull(t *testing.T) { +func TestAccVirtualNugetRepository_PackageCreationFull(t *testing.T) { id := testutil.RandomInt() name := fmt.Sprintf("foo%d", id) fqrn := fmt.Sprintf("artifactory_virtual_nuget_repository.%s", name) @@ -598,7 +598,6 @@ func TestNugetPackageCreationFull(t *testing.T) { }, }, }) - } func TestAccVirtualRepository_full(t *testing.T) {