Skip to content

Commit

Permalink
feat: Add latest_policy to storage block of docker hosted repository
Browse files Browse the repository at this point in the history
related to #341
  • Loading branch information
anmoel committed Aug 9, 2024
1 parent fcc6686 commit b8d9dd4
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 17 deletions.
3 changes: 2 additions & 1 deletion docs/data-sources/repository_docker_hosted.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ data "nexus_repository_docker_hosted" "example" {
- `docker` (List of Object) docker contains the configuration of the docker repository (see [below for nested schema](#nestedatt--docker))
- `id` (String) Used to identify data source at nexus
- `online` (Boolean) Whether this repository accepts incoming requests
- `storage` (List of Object) The storage configuration of the repository (see [below for nested schema](#nestedatt--storage))
- `storage` (List of Object) The storage configuration of the repository docker hosted (see [below for nested schema](#nestedatt--storage))

<a id="nestedatt--cleanup"></a>
### Nested Schema for `cleanup`
Expand Down Expand Up @@ -62,5 +62,6 @@ Read-Only:
Read-Only:

- `blob_store_name` (String)
- `latest_policy` (Boolean)
- `strict_content_type_validation` (Boolean)
- `write_policy` (String)
3 changes: 2 additions & 1 deletion docs/resources/repository_docker_hosted.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ resource "nexus_repository_docker_hosted" "example" {

- `docker` (Block List, Min: 1, Max: 1) docker contains the configuration of the docker repository (see [below for nested schema](#nestedblock--docker))
- `name` (String) A unique identifier for this repository
- `storage` (Block List, Min: 1, Max: 1) The storage configuration of the repository (see [below for nested schema](#nestedblock--storage))
- `storage` (Block List, Min: 1, Max: 1) The storage configuration of the repository docker hosted (see [below for nested schema](#nestedblock--storage))

### Optional

Expand Down Expand Up @@ -69,6 +69,7 @@ Required:

Optional:

- `latest_policy` (Boolean) Whether to allow redeploying the 'latest' tag but defer to the Deployment Policy for all other tags. Only usable with write_policy "ALLOW_ONCE"
- `write_policy` (String) Controls if deployments of and updates to assets are allowed


Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ toolchain go1.21.1

require (
github.com/client9/misspell v0.3.4
github.com/datadrivers/go-nexus-client v1.11.0
github.com/datadrivers/go-nexus-client v1.12.0
github.com/golangci/golangci-lint v1.59.1
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
github.com/hashicorp/terraform-plugin-docs v0.19.4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53E
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/daixiang0/gci v0.13.4 h1:61UGkmpoAcxHM2hhNkZEf5SzwQtWJXTSws7jaPyqwlw=
github.com/daixiang0/gci v0.13.4/go.mod h1:12etP2OniiIdP4q+kjUGrC/rUagga7ODbqsom5Eo5Yk=
github.com/datadrivers/go-nexus-client v1.11.0 h1:fTmBYPzPBLL8v1LQOc8Fyzz40lHDl3Bm3ofvpNdHRro=
github.com/datadrivers/go-nexus-client v1.11.0/go.mod h1:sPjBOxF7idUoiJoa730L3JyKZodjT0LDAvVF8u4kOLU=
github.com/datadrivers/go-nexus-client v1.12.0 h1:ZBoTNAxdWbPs5gYZemJ+HLfk/8xt7aZyPtI1/R7ahag=
github.com/datadrivers/go-nexus-client v1.12.0/go.mod h1:sPjBOxF7idUoiJoa730L3JyKZodjT0LDAvVF8u4kOLU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
19 changes: 18 additions & 1 deletion internal/acceptance/template-strings-repository-docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ resource "nexus_repository_docker_hosted" "acceptance" {
{{- end }}
v1_enabled = "{{ .Docker.V1Enabled }}"
}
` + TemplateStringHostedRepository
` + TemplateStringNameOnline +
TemplateStringCleanup +
TemplateStringComponent +
TemplateStringDockerStorageHosted +
TemplateStringEnd

TemplateStringRepositoryDockerGroup = `
resource "nexus_repository_docker_group" "acceptance" {
Expand Down Expand Up @@ -61,4 +65,17 @@ resource "nexus_repository_docker_proxy" "acceptance" {
{{- end }}
}
` + TemplateStringProxyRepository

TemplateStringDockerStorageHosted = `
storage {
blob_store_name = "{{ .Storage.BlobStoreName }}"
strict_content_type_validation = {{ .Storage.StrictContentTypeValidation }}
{{- if .Storage.WritePolicy }}
write_policy = "{{ .Storage.WritePolicy }}"
{{- end }}
{{- if .Storage.LatestPolicy }}
latest_policy = "{{ .Storage.LatestPolicy }}"
{{- end }}
}
`
)
72 changes: 72 additions & 0 deletions internal/schema/repository/schema_docker.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package repository

import (
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

var (
Expand Down Expand Up @@ -74,4 +77,73 @@ var (
},
},
}

ResourceDockerHostedStorage = &schema.Schema{
Description: "The storage configuration of the repository docker hosted",
Type: schema.TypeList,
Required: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"blob_store_name": {
Description: "Blob store used to store repository contents",
Required: true,
Set: func(v interface{}) int {
return schema.HashString(strings.ToLower(v.(string)))
},
Type: schema.TypeString,
},
"strict_content_type_validation": {
Description: "Whether to validate uploaded content's MIME type appropriate for the repository format",
Required: true,
Type: schema.TypeBool,
},
"write_policy": {
Description: "Controls if deployments of and updates to assets are allowed",
Default: "ALLOW",
Optional: true,
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice([]string{
"ALLOW",
"ALLOW_ONCE",
"DENY",
}, false),
},
"latest_policy": {
Description: "Whether to allow redeploying the 'latest' tag but defer to the Deployment Policy for all other tags. Only usable with write_policy \"ALLOW_ONCE\"",
Optional: true,
Type: schema.TypeBool,
},
},
},
}
DataSourceDockerHostedStorage = &schema.Schema{
Description: "The storage configuration of the repository docker hosted",
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"blob_store_name": {
Description: "Blob store used to store repository contents",
Computed: true,
Type: schema.TypeString,
},
"strict_content_type_validation": {
Description: "Whether to validate uploaded content's MIME type appropriate for the repository format",
Computed: true,
Type: schema.TypeBool,
},
"write_policy": {
Description: "Controls if deployments of and updates to assets are allowed",
Computed: true,
Type: schema.TypeString,
},
"latest_policy": {
Description: "Whether to allow redeploying the 'latest' tag but defer to the Deployment Policy for all other tags. Only usable with write_policy \"ALLOW_ONCE\"",
Computed: true,
Type: schema.TypeBool,
},
},
},
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func DataSourceRepositoryDockerHosted() *schema.Resource {
// Hosted schemas
"cleanup": repository.DataSourceCleanup,
"component": repository.DataSourceComponent,
"storage": repository.DataSourceHostedStorage,
"storage": repository.DataSourceDockerHostedStorage,
// Docker hosted schemas
"docker": repository.DataSourceDocker,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ func TestAccDataSourceRepositoryDockerHosted(t *testing.T) {
repo := repository.DockerHostedRepository{
Name: name,
Online: true,
Storage: repository.HostedStorage{
Storage: repository.DockerHostedStorage{
BlobStoreName: "default",
StrictContentTypeValidation: false,
WritePolicy: "ALLOW",
},
Docker: repository.Docker{
ForceBasicAuth: true,
Expand All @@ -56,6 +57,7 @@ func TestAccDataSourceRepositoryDockerHosted(t *testing.T) {
resource.TestCheckResourceAttr(dataSourceName, "docker.0.v1_enabled", strconv.FormatBool(repo.Docker.V1Enabled)),
resource.TestCheckResourceAttr(dataSourceName, "storage.0.blob_store_name", repo.Storage.BlobStoreName),
resource.TestCheckResourceAttr(dataSourceName, "storage.0.strict_content_type_validation", strconv.FormatBool(repo.Storage.StrictContentTypeValidation)),
resource.TestCheckResourceAttr(dataSourceName, "storage.0.write_policy", string(repo.Storage.WritePolicy)),
),
),
},
Expand Down
15 changes: 15 additions & 0 deletions internal/services/repository/flatten.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,21 @@ func flattenHostedStorage(storage *repository.HostedStorage) []map[string]interf
return []map[string]interface{}{data}
}

func flattenDockerHostedStorage(dockerStorage *repository.DockerHostedStorage) []map[string]interface{} {
if dockerStorage == nil {
return nil
}
data := map[string]interface{}{
"blob_store_name": dockerStorage.BlobStoreName,
"strict_content_type_validation": dockerStorage.StrictContentTypeValidation,
"write_policy": dockerStorage.WritePolicy,
}
if dockerStorage.LatestPolicy != nil {
data["latest_policy"] = dockerStorage.LatestPolicy
}
return []map[string]interface{}{data}
}

func flattenMaven(maven *repository.Maven) []map[string]interface{} {
data := map[string]interface{}{
"version_policy": maven.VersionPolicy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func ResourceRepositoryDockerHosted() *schema.Resource {
// Hosted schemas
"cleanup": repositorySchema.ResourceCleanup,
"component": repositorySchema.ResourceComponent,
"storage": repositorySchema.ResourceHostedStorage,
"storage": repositorySchema.ResourceDockerHostedStorage,
// Docker hosted schemas
"docker": repositorySchema.ResourceDocker,
},
Expand All @@ -39,23 +39,26 @@ func ResourceRepositoryDockerHosted() *schema.Resource {

func getDockerHostedRepositoryFromResourceData(resourceData *schema.ResourceData) repository.DockerHostedRepository {
storageConfig := resourceData.Get("storage").([]interface{})[0].(map[string]interface{})
writePolicy := repository.StorageWritePolicy(storageConfig["write_policy"].(string))
dockerConfig := resourceData.Get("docker").([]interface{})[0].(map[string]interface{})

repo := repository.DockerHostedRepository{
Name: resourceData.Get("name").(string),
Online: resourceData.Get("online").(bool),
Storage: repository.HostedStorage{
Storage: repository.DockerHostedStorage{
BlobStoreName: storageConfig["blob_store_name"].(string),
StrictContentTypeValidation: storageConfig["strict_content_type_validation"].(bool),
WritePolicy: &writePolicy,
WritePolicy: repository.StorageWritePolicy(storageConfig["write_policy"].(string)),
},
Docker: repository.Docker{
ForceBasicAuth: dockerConfig["force_basic_auth"].(bool),
V1Enabled: dockerConfig["v1_enabled"].(bool),
},
}

if latestPolicy, ok := storageConfig["latest_policy"]; ok {
repo.Storage.LatestPolicy = tools.GetBoolPointer(latestPolicy.(bool))
}

if httpPort, ok := dockerConfig["http_port"]; ok {
if httpPort.(int) > 0 {
repo.Docker.HTTPPort = tools.GetIntPointer(httpPort.(int))
Expand Down Expand Up @@ -109,7 +112,7 @@ func setDockerHostedRepositoryToResourceData(repo *repository.DockerHostedReposi
return err
}

if err := resourceData.Set("storage", flattenHostedStorage(&repo.Storage)); err != nil {
if err := resourceData.Set("storage", flattenDockerHostedStorage(&repo.Storage)); err != nil {
return err
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
)

func testAccResourceRepositoryDockerHosted(name string) repository.DockerHostedRepository {
writePolicy := repository.StorageWritePolicyAllow
latestPolicy := true

return repository.DockerHostedRepository{
Name: name,
Expand All @@ -27,10 +27,11 @@ func testAccResourceRepositoryDockerHosted(name string) repository.DockerHostedR
HTTPSPort: tools.GetIntPointer(rand.Intn(999) + 33000),
V1Enabled: false,
},
Storage: repository.HostedStorage{
Storage: repository.DockerHostedStorage{
BlobStoreName: "default",
StrictContentTypeValidation: true,
WritePolicy: &writePolicy,
WritePolicy: repository.StorageWritePolicyAllowOnce,
LatestPolicy: &latestPolicy,
},
Cleanup: &repository.Cleanup{
PolicyNames: []string{"cleanup-weekly"},
Expand Down Expand Up @@ -77,7 +78,8 @@ func TestAccResourceRepositoryDockerHosted(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "storage.#", "1"),
resource.TestCheckResourceAttr(resourceName, "storage.0.blob_store_name", repo.Storage.BlobStoreName),
resource.TestCheckResourceAttr(resourceName, "storage.0.strict_content_type_validation", strconv.FormatBool(repo.Storage.StrictContentTypeValidation)),
resource.TestCheckResourceAttr(resourceName, "storage.0.write_policy", string(*repo.Storage.WritePolicy)),
resource.TestCheckResourceAttr(resourceName, "storage.0.write_policy", string(repo.Storage.WritePolicy)),
resource.TestCheckResourceAttr(resourceName, "storage.0.latest_policy", strconv.FormatBool(*repo.Storage.LatestPolicy)),
resource.TestCheckResourceAttr(resourceName, "cleanup.#", "1"),
resource.TestCheckResourceAttr(resourceName, "cleanup.0.policy_names.#", "1"),
resource.TestCheckResourceAttr(resourceName, "cleanup.0.policy_names.0", repo.Cleanup.PolicyNames[0]),
Expand Down

0 comments on commit b8d9dd4

Please sign in to comment.