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

Feat: Add cleanup policies (#226) #481

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions internal/provider/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
nexus "github.com/datadrivers/go-nexus-client/nexus3"
"github.com/datadrivers/go-nexus-client/nexus3/pkg/client"
"github.com/datadrivers/terraform-provider-nexus/internal/services/blobstore"
"github.com/datadrivers/terraform-provider-nexus/internal/services/cleanuppolicies"
"github.com/datadrivers/terraform-provider-nexus/internal/services/other"
"github.com/datadrivers/terraform-provider-nexus/internal/services/repository"
"github.com/datadrivers/terraform-provider-nexus/internal/services/security"
Expand Down Expand Up @@ -79,6 +80,7 @@ func Provider() *schema.Provider {
"nexus_privilege_repository_view": security.DataSourceSecurityPrivilegeRepositoryView(),
"nexus_privilege_repository_admin": security.DataSourceSecurityPrivilegeRepositoryAdmin(),
"nexus_privilege_repository_content_selector": security.DataSourceSecurityPrivilegeRepositoryContentSelector(),
"nexus_cleanup_policy": cleanuppolicies.DataSourceRepositoryCleanupPolicies(),
},
ResourcesMap: map[string]*schema.Resource{
"nexus_blobstore_azure": blobstore.ResourceBlobstoreAzure(),
Expand Down Expand Up @@ -145,6 +147,7 @@ func Provider() *schema.Provider {
"nexus_privilege_repository_admin": security.ResourceSecurityPrivilegeRepositoryAdmin(),
"nexus_privilege_repository_content_selector": security.ResourceSecurityPrivilegeRepositoryContentSelector(),
"nexus_privilege_wildcard": security.ResourceSecurityPrivilegeWildcard(),
"nexus_cleanup_policy": cleanuppolicies.ResourceCleanupPolicies(),
},
Schema: map[string]*schema.Schema{
"insecure": {
Expand Down
60 changes: 60 additions & 0 deletions internal/services/cleanuppolicies/data_source_cleanup_policies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package cleanuppolicies

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

func DataSourceRepositoryCleanupPolicies() *schema.Resource {
return &schema.Resource{
Description: "Manages a cleanup policy in Nexus Repository.",

Read: dataSourceRepositoryCleanupPoliciesRead,

Schema: map[string]*schema.Schema{
"notes": {
Description: "Any details on the specific cleanup policy",
Type: schema.TypeString,
Computed: true,
},
"criteria_last_blob_updated": {
Description: "The age of the component in days",
Type: schema.TypeInt,
Computed: true,
},
"criteria_last_downloaded": {
Description: "the last time the component had been downloaded in days",
Type: schema.TypeInt,
Computed: true,
},
"criteria_release_type": {
Description: "When needed, this is either PRELEASE or RELEASE",
Type: schema.TypeString,
Computed: true,
},
"criteria_asset_regex": {
Description: "A regex string to filter for specific asset paths",
Type: schema.TypeString,
Computed: true,
},
"retain": {
Description: "Number of versions to keep. Only available for Docker and Maven release repositories on PostgreSQL deployments",
Type: schema.TypeInt,
Required: true,
},
"name": {
Description: "The name of the policy needs to be unique and cannot be edited once set. Only letters, digits, underscores(_), hyphens(-), and dots(.) are allowed and may not start with underscore or dot",
Type: schema.TypeString,
Required: true,
},
"format": {
Description: "The target format for the cleanup policy. Some formats have various capabilities and requirements. Note that you cannot currently specify all formats",
Type: schema.TypeString,
Required: true,
},
},
}
}

func dataSourceRepositoryCleanupPoliciesRead(d *schema.ResourceData, m interface{}) error {
return resourceCleanupPoliciesRead(d, m)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cleanuppolicies_test

import (
"github.com/datadrivers/go-nexus-client/nexus3/schema/cleanuppolicies"
"strconv"
"testing"

"github.com/datadrivers/go-nexus-client/nexus3/pkg/tools"
"github.com/datadrivers/terraform-provider-nexus/internal/acceptance"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccDataSourceCleanupPolicy(t *testing.T) {
dataSourceName := "data.nexus_cleanup_policy.acceptance"

cp := cleanuppolicies.CleanupPolicy{
Notes: tools.GetStringPointer(acctest.RandString(25)),
CriteriaLastBlobUpdated: tools.GetIntPointer(acctest.RandInt()),
CriteriaLastDownloaded: tools.GetIntPointer(acctest.RandInt()),
CriteriaReleaseType: tools.GetStringPointer(acctest.RandString(8)),
CriteriaAssetRegex: tools.GetStringPointer(acctest.RandString(15)),
Retain: acctest.RandInt(),
Name: acctest.RandString(10),
Format: acctest.RandString(5),
}

resource.Test(t, resource.TestCase{
PreCheck: func() { acceptance.AccPreCheck(t) },
Providers: acceptance.TestAccProviders,
Steps: []resource.TestStep{
{
Config: testAccResourceCleanupPolicyConfig(cp) + testAccDataSourceCleanupPolicyConfig(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPtr(dataSourceName, "notes", cp.Notes),
resource.TestCheckResourceAttr(dataSourceName, "criteria_last_blob_updated", strconv.Itoa(*cp.CriteriaLastBlobUpdated)),
resource.TestCheckResourceAttr(dataSourceName, "criteria_last_downloaded", strconv.Itoa(*cp.CriteriaLastDownloaded)),
resource.TestCheckResourceAttrPtr(dataSourceName, "criteria_release_type", cp.CriteriaReleaseType),
resource.TestCheckResourceAttrPtr(dataSourceName, "criteria_asset_regex", cp.CriteriaAssetRegex),
resource.TestCheckResourceAttr(dataSourceName, "retain", strconv.Itoa(cp.Retain)),
resource.TestCheckResourceAttr(dataSourceName, "name", cp.Name),
resource.TestCheckResourceAttr(dataSourceName, "format", cp.Format),
),
},
},
})
}

func testAccDataSourceCleanupPolicyConfig() string {
return `
data "nexus_cleanup_policy" "acceptance" {
name = nexus_cleanup_policy.acceptance.name
}
`
}
175 changes: 175 additions & 0 deletions internal/services/cleanuppolicies/resource_cleanup_policies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package cleanuppolicies

import (
nexus "github.com/datadrivers/go-nexus-client/nexus3"
"github.com/datadrivers/go-nexus-client/nexus3/schema/cleanuppolicies"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func ResourceCleanupPolicies() *schema.Resource {
return &schema.Resource{
Description: "Manages a cleanup policy in Nexus Repository.",

Create: resourceCleanupPoliciesCreate,
Read: resourceCleanupPoliciesRead,
Update: resourceCleanupPoliciesUpdate,
Delete: resourceCleanupPoliciesDelete,
Exists: resourceCleanupPoliciesExists,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
"notes": {
Description: "Any details on the specific cleanup policy",
Type: schema.TypeString,
Optional: true,
},
"criteria_last_blob_updated": {
Description: "The age of the component in days",
Type: schema.TypeInt,
Optional: true,
Default: nil,
},
"criteria_last_downloaded": {
Description: "the last time the component had been downloaded in days",
Type: schema.TypeInt,
Optional: true,
Default: nil,
},
"criteria_release_type": {
Description: "When needed, this is either PRELEASE or RELEASE",
Type: schema.TypeString,
Optional: true,
Default: nil,
},
"criteria_asset_regex": {
Description: "A regex string to filter for specific asset paths",
Type: schema.TypeString,
Optional: true,
Default: nil,
},
"retain": {
Description: "Number of versions to keep. Only available for Docker and Maven release repositories on PostgreSQL deployments",
Type: schema.TypeInt,
Optional: true,
Default: 1,
},
"name": {
Description: "The name of the policy needs to be unique and cannot be edited once set. Only letters, digits, underscores(_), hyphens(-), and dots(.) are allowed and may not start with underscore or dot",
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"format": {
Description: "The target format for the cleanup policy. Some formats have various capabilities and requirements. Note that you cannot currently specify all formats",
Type: schema.TypeString,
Required: true,
},
},
}
}

func getCleanupPolicyFromResourceData(d *schema.ResourceData) cleanuppolicies.CleanupPolicy {

notes, _ := d.Get("notes").(string)
criteriaLastBlobUpdated, _ := d.Get("criteria_last_blob_updated").(int)
criteriaLastDownloaded, _ := d.Get("criteria_last_downloaded").(int)
criteriaReleaseType, _ := d.Get("criteria_release_type").(string)
criteriaAssetRegex, _ := d.Get("criteria_asset_regex").(string)
retain, _ := d.Get("retain").(int)
name, _ := d.Get("name").(string)
format, _ := d.Get("format").(string)

policy := cleanuppolicies.CleanupPolicy{
Notes: &notes,
CriteriaLastBlobUpdated: &criteriaLastBlobUpdated,
CriteriaLastDownloaded: &criteriaLastDownloaded,
CriteriaAssetRegex: &criteriaAssetRegex,
Name: name,
Format: format,
}

// Only set CriteriaReleaseType for applicable formats
if format == "maven2" || format == "npm" || format == "yum" {
policy.CriteriaReleaseType = &criteriaReleaseType
}

// Only set CriteriaReleaseType for applicable formats
if format == "maven2" || format == "docker" {
policy.Retain = retain
}

return policy
}

func setCleanupPolicyToResourceData(cleanupPolicy *cleanuppolicies.CleanupPolicy, d *schema.ResourceData) error {
d.SetId(cleanupPolicy.Name)
d.Set("notes", cleanupPolicy.Notes)
d.Set("criteria_last_blob_updated", cleanupPolicy.CriteriaLastBlobUpdated)
d.Set("criteria_last_downloaded", cleanupPolicy.CriteriaLastDownloaded)
d.Set("criteria_release_type", cleanupPolicy.CriteriaReleaseType)
d.Set("criteria_asset_regex", cleanupPolicy.CriteriaAssetRegex)
d.Set("retain", cleanupPolicy.Retain)
d.Set("name", cleanupPolicy.Name)
d.Set("format", cleanupPolicy.Format)
return nil
}

func resourceCleanupPoliciesCreate(d *schema.ResourceData, m interface{}) error {
client := m.(*nexus.NexusClient)

cleanupPolicy := getCleanupPolicyFromResourceData(d)

if err := client.CleanupPolicy.Create(&cleanupPolicy); err != nil {
return err
}

d.SetId(cleanupPolicy.Name)

return resourceCleanupPoliciesRead(d, m)
}

func resourceCleanupPoliciesRead(d *schema.ResourceData, m interface{}) error {
client := m.(*nexus.NexusClient)

cleanupPolicy, err := client.CleanupPolicy.Get(d.Id())
if err != nil {
return err
}

if cleanupPolicy == nil {
d.SetId("")
return nil
}

return setCleanupPolicyToResourceData(cleanupPolicy, d)
}

func resourceCleanupPoliciesUpdate(d *schema.ResourceData, m interface{}) error {
client := m.(*nexus.NexusClient)

cleanupPolicy := getCleanupPolicyFromResourceData(d)
if err := client.CleanupPolicy.Update(&cleanupPolicy); err != nil {
return err
}

return resourceCleanupPoliciesRead(d, m)
}

func resourceCleanupPoliciesDelete(d *schema.ResourceData, m interface{}) error {
client := m.(*nexus.NexusClient)

if err := client.CleanupPolicy.Delete(d.Id()); err != nil {
return err
}

d.SetId("")
return nil
}

func resourceCleanupPoliciesExists(d *schema.ResourceData, m interface{}) (bool, error) {
client := m.(*nexus.NexusClient)

cleanupPolicy, err := client.CleanupPolicy.Get(d.Id())
return cleanupPolicy != nil, err
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package cleanuppolicies_test

import (
"fmt"
"strconv"
"testing"

"github.com/datadrivers/go-nexus-client/nexus3/pkg/tools"
"github.com/datadrivers/go-nexus-client/nexus3/schema/cleanuppolicies"
"github.com/datadrivers/terraform-provider-nexus/internal/acceptance"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccResourceCleanupPolicy(t *testing.T) {
var cleanupPolicy cleanuppolicies.CleanupPolicy

resName := "nexus_security_cleanup_policy.acceptance"
cp := cleanuppolicies.CleanupPolicy{
Notes: tools.GetStringPointer(acctest.RandString(25)),
CriteriaLastBlobUpdated: tools.GetIntPointer(acctest.RandInt()),
CriteriaLastDownloaded: tools.GetIntPointer(acctest.RandInt()),
CriteriaReleaseType: tools.GetStringPointer(acctest.RandString(8)),
CriteriaAssetRegex: tools.GetStringPointer(acctest.RandString(15)),
Retain: acctest.RandInt(),
Name: acctest.RandString(10),
Format: acctest.RandString(5),
}

resource.Test(t, resource.TestCase{
PreCheck: func() { acceptance.AccPreCheck(t) },
Providers: acceptance.TestAccProviders,
Steps: []resource.TestStep{
{
Config: testAccResourceCleanupPolicyConfig(cp) + testAccDataSourceCleanupPolicyConfig(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resName, "notes", *cp.Notes),
resource.TestCheckResourceAttr(resName, "criteria_last_blob_updated", strconv.Itoa(*cp.CriteriaLastBlobUpdated)),
resource.TestCheckResourceAttr(resName, "criteria_last_downloaded", strconv.Itoa(*cp.CriteriaLastDownloaded)),
resource.TestCheckResourceAttr(resName, "criteria_release_type", *cp.CriteriaReleaseType),
resource.TestCheckResourceAttr(resName, "criteria_asset_regex", *cp.CriteriaAssetRegex),
resource.TestCheckResourceAttr(resName, "retain", strconv.Itoa(cp.Retain)),
resource.TestCheckResourceAttr(resName, "name", cp.Name),
resource.TestCheckResourceAttr(resName, "format", cp.Format),
),
},
{
ResourceName: resName,
ImportStateId: cleanupPolicy.Name,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccResourceCleanupPolicyConfig(cp cleanuppolicies.CleanupPolicy) string {
return fmt.Sprintf(`
resource "nexus_security_cleanup_policy" "acceptance" {
notes = "%s"
criteria_last_blob_updated = "%s"
criteria_last_downloaded = "%s"
criteria_release_type = "%s"
criteria_asset_regex = "%s"
retain = "%s"
name = "%s"
format = "%s"
}
`, *cp.Notes, strconv.Itoa(*cp.CriteriaLastBlobUpdated), strconv.Itoa(*cp.CriteriaLastDownloaded),
*cp.CriteriaReleaseType, *cp.CriteriaAssetRegex, strconv.Itoa(cp.Retain), cp.Name, cp.Format)
}