Skip to content

Commit

Permalink
Add support for Log Rotation configuration (#339)
Browse files Browse the repository at this point in the history
Add support for Log Rotation configuration

#315

---------

Signed-off-by: flbla <[email protected]>
Signed-off-by: Florian Blampey <[email protected]>
  • Loading branch information
flbla authored Jun 12, 2023
1 parent 78fdb0d commit b2e9f76
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 5 deletions.
3 changes: 3 additions & 0 deletions client/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ func GetSchedule(schedule string) (typefmt string, cronfmt string) {
case "weekly", "0 0 0 * * 0":
TypeStr = "Weekly"
CronStr = "0 0 0 * * 0"
case "":
TypeStr = "None"
CronStr = ""
default:
TypeStr = "Custom"
CronStr = schedule
Expand Down
7 changes: 7 additions & 0 deletions client/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ func GetSystemBoby(d *schema.ResourceData, scheduleType string) models.SystemBod
schedule = d.Get("schedule").(string)
} else if scheduleType == "vuln" {
schedule = d.Get("vulnerability_scan_policy").(string)
} else if scheduleType == "purgeaudit" {
schedule = d.Get("schedule").(string)
}

TypeStr, CronStr := GetSchedule(schedule)
Expand All @@ -25,6 +27,9 @@ func GetSystemBoby(d *schema.ResourceData, scheduleType string) models.SystemBod
body.Schedule.Cron = CronStr
if scheduleType == "gc" {
body.Parameters.DeleteUntagged = d.Get("delete_untagged").(bool)
} else if scheduleType == "purgeaudit" {
body.Parameters.AuditRetentionHour = d.Get("audit_retention_hour").(int)
body.Parameters.IncludeOperations = d.Get("include_operations").(string)
}

return body
Expand All @@ -38,6 +43,8 @@ func (client *Client) SetSchedule(d *schema.ResourceData, scheduleType string) (
path = models.PathGC
} else if scheduleType == "vuln" {
path = models.PathVuln
} else if scheduleType == "purgeaudit" {
path = models.PathPurgeAudit
}

body := GetSystemBoby(d, scheduleType)
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The Harbor provider is used to configure an instance of Harbor. The provider nee
* [Resource: harbor_config_system](resources/config_system.md)
* [Resource: harbor_config_email](resources/config_email.md)
* [Resource: harbor_garbage_collection](resources/garbage_collection.md)
* [Resource: harbor_purge_audit_log](resources/purge-audit-log.md)
* [Resource: harbor_immutable_tag_rule](resources/immutable_tag_rule.md)
* [Resource: harbor_interrogation_services](resources/interrogation_services.md)
* [Resource: harbor_label](resources/label.md)
Expand Down
18 changes: 18 additions & 0 deletions docs/resources/purge-audit-log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Resource: harbor_purge_audit_log

## Example Usage
```hcl
resource "harbor_purge_audit_log" "main" {
schedule = "Daily"
audit_retention_hour = 24
include_operations = "create,pull"
}
```

## Argument Reference
The following arguments are supported:
* **schedule** - (Required) Sets the schedule how often the Garbage Collection will run. Can be to `"Hourly"`, `"Daily"`, `"Weekly"` or can be a custom cron string ie, `"5 4 * * *"`

* **audit_retention_hour** - (Required) to configure how long audit logs should be kept. For example, if you set this to 24 Harbor will only purge audit logs that are 24 or more hours old.

* **include_operations** - (Required) valid values are `create` `delete` `pull`, thoses values can be comma separated. When Create, Delete, or Pull is set, Harbor will include audit logs for those operations in the purge.
15 changes: 10 additions & 5 deletions models/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ var PathVuln = "/system/scanAll/schedule"
var PathScanners = "/scanners"

var PathGC = "/system/gc/schedule"
var PathPurgeAudit = "/system/purgeaudit/schedule"

type JobParameters struct {
DeleteUntagged bool `json:"delete_untagged"`
DeleteUntagged bool `json:"delete_untagged,omitempty"`
AuditRetentionHour int `json:"audit_retention_hour,omitempty"`
IncludeOperations string `json:"include_operations,omitempty"`
}

type SystemBody struct {
Expand All @@ -25,10 +28,12 @@ type SystemBody struct {
CreationTime time.Time `json:"creation_time,omitempty"`
UpdateTime time.Time `json:"update_time,omitempty"`
Parameters struct {
DeleteUntagged bool `json:"delete_untagged,omitempty"`
AdditionalProp1 bool `json:"additionalProp1,omitempty"`
AdditionalProp2 bool `json:"additionalProp2,omitempty"`
AdditionalProp3 bool `json:"additionalProp3,omitempty"`
DeleteUntagged bool `json:"delete_untagged,omitempty"`
AuditRetentionHour int `json:"audit_retention_hour,omitempty"`
IncludeOperations string `json:"include_operations,omitempty"`
AdditionalProp1 bool `json:"additionalProp1,omitempty"`
AdditionalProp2 bool `json:"additionalProp2,omitempty"`
AdditionalProp3 bool `json:"additionalProp3,omitempty"`
} `json:"parameters"`
}

Expand Down
1 change: 1 addition & 0 deletions provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func Provider() *schema.Provider {
"harbor_replication": resourceReplication(),
"harbor_retention_policy": resourceRetention(),
"harbor_garbage_collection": resourceGC(),
"harbor_purge_audit_log": resourcePurgeAudit(),
"harbor_label": resourceLabel(),
"harbor_immutable_tag_rule": resourceImmutableTagRule(),
},
Expand Down
120 changes: 120 additions & 0 deletions provider/resource_log_rotation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package provider

import (
"encoding/json"
"fmt"
"strings"

"github.com/goharbor/terraform-provider-harbor/client"
"github.com/goharbor/terraform-provider-harbor/models"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourcePurgeAudit() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"schedule": {
Type: schema.TypeString,
Required: true,
},
"audit_retention_hour": {
Type: schema.TypeInt,
Required: true,
},
"include_operations": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateIncludeOperations,
},
},
Create: resourcePurgeAuditCreate,
Read: resourcePurgeAuditRead,
Update: resourcePurgeAuditUpdate,
Delete: resourcePurgeAuditDelete,
}
}

func resourcePurgeAuditCreate(d *schema.ResourceData, m interface{}) error {
apiClient := m.(*client.Client)
err := apiClient.SetSchedule(d, "purgeaudit")
if err != nil {
return err
}
d.SetId(models.PathPurgeAudit)
return resourcePurgeAuditRead(d, m)
}

func resourcePurgeAuditRead(d *schema.ResourceData, m interface{}) error {
apiClient := m.(*client.Client)

resp, _, respCode, err := apiClient.SendRequest("GET", models.PathPurgeAudit, nil, 200)
if respCode == 404 && err != nil {
d.SetId("")
return fmt.Errorf("resource not found %s", d.Id())
}
if len(resp) == 0 {
d.SetId("")
return nil
}

var jsonData models.SystemBody
err = json.Unmarshal([]byte(resp), &jsonData)
if err != nil {
return err
}
jobParameters := jsonData.JobParameters

var jsonJobParameters models.JobParameters
err = json.Unmarshal([]byte(jobParameters), &jsonJobParameters)
if err != nil {
fmt.Println(err)
}

if jsonData.Schedule.Type == "Custom" {
d.Set("schedule", jsonData.Schedule.Cron)
} else {
d.Set("schedule", jsonData.Schedule.Type)
}
d.Set("audit_retention_hour", jsonJobParameters.AuditRetentionHour)
d.Set("include_operations", jsonJobParameters.IncludeOperations)
return nil
}

func resourcePurgeAuditUpdate(d *schema.ResourceData, m interface{}) error {
return resourcePurgeAuditCreate(d, m)
}

func resourcePurgeAuditDelete(d *schema.ResourceData, m interface{}) error {
apiClient := m.(*client.Client)
d.Set("schedule", "")
err := apiClient.SetSchedule(d, "purgeaudit")
if err != nil {
return err
}
d.SetId("")
return nil
}

func validateIncludeOperations(v interface{}, k string) (warns []string, errs []error) {
includeOperations := v.(string)
validValues := []string{"create", "pull", "delete"}

ops := strings.Split(includeOperations, ",")
for _, op := range ops {
op = strings.TrimSpace(op)
if !containsString(validValues, op) {
errs = append(errs, fmt.Errorf("Invalid value %q in %q. Valid values are: create, pull, delete", op, k))
}
}

return warns, errs
}

func containsString(arr []string, value string) bool {
for _, v := range arr {
if v == value {
return true
}
}
return false
}
42 changes: 42 additions & 0 deletions provider/resource_log_rotation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package provider

import (
"fmt"
"testing"

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

const resourcePurgeAuditMain = "harbor_purge_audit_log.main"

func TestAccPurgeAuditUpdate(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
// CheckDestroy: testAccCheckLabelDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckPurgeAuditBasic(),
Check: resource.ComposeTestCheckFunc(
testAccCheckResourceExists(resourcePurgeAuditMain),
resource.TestCheckResourceAttr(
resourcePurgeAuditMain, "schedule", "Daily"),
resource.TestCheckResourceAttr(
resourcePurgeAuditMain, "audit_retention_hour", "24"),
resource.TestCheckResourceAttr(
resourcePurgeAuditMain, "include_operations", "create,pull"),
),
},
},
})
}

func testAccCheckPurgeAuditBasic() string {
return fmt.Sprintf(`
resource "harbor_purge_audit_log" "main" {
schedule = "Daily"
audit_retention_hour = 24
include_operations = "create,pull"
}
`)
}

0 comments on commit b2e9f76

Please sign in to comment.