Skip to content

Commit

Permalink
feat: enable retention policies
Browse files Browse the repository at this point in the history
  • Loading branch information
shreddedbacon committed Dec 17, 2023
1 parent 90c31db commit 1a6cb7e
Show file tree
Hide file tree
Showing 8 changed files with 736 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.20
require (
github.com/cheshir/go-mq/v2 v2.0.1
github.com/coreos/go-semver v0.3.1
github.com/cxmcc/unixsums v0.0.0-20131125091133-89564297d82f
github.com/go-logr/logr v1.2.4
github.com/google/go-cmp v0.5.9
github.com/hashicorp/go-version v1.6.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cxmcc/unixsums v0.0.0-20131125091133-89564297d82f h1:PkAFGgVtJnasAxOaiEY1RYPx8W+7X7l66vi8T2apKCM=
github.com/cxmcc/unixsums v0.0.0-20131125091133-89564297d82f/go.mod h1:XJq7OckzkOtlgeEKFwkH2gFbc1+1WRFUBf7QnvfyrzQ=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
Expand Down
8 changes: 8 additions & 0 deletions internal/harbor/harbor.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ type Harbor struct {
WebhookEventTypes []string
LagoonTargetName string
Config *config.Options
TagRetention TagRetention
}

type TagRetention struct {
Enabled bool
PullRequestRetention int
BranchRetention int
Schedule string
}

// New create a new harbor connection.
Expand Down
61 changes: 61 additions & 0 deletions internal/harbor/harbor22x.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,43 @@ func (h *Harbor) CreateProjectV2(ctx context.Context, projectName string) (*harb
// fmt.Println(x)
// }

// handle the creation and updating of retention policies as required
if h.TagRetention.Enabled {
// generate a somewhat random schedule from the retention schedule template, using the harbor projectname as the seed
schedule, err := helpers.ConvertCrontab(projectName, h.TagRetention.Schedule)
if err != nil {
h.Log.Info(fmt.Sprintf("Error generating retention schedule %s: %v", project.Name, err))
}
schedule = fmt.Sprintf("0 %s", schedule) // harbor needs seconds :\
// create the retention policy as required
retention := h.generateRetentionPolicy(int64(project.ProjectID), schedule, h.TagRetention.BranchRetention, h.TagRetention.PullRequestRetention)
// get the existing one if one exists
policy, err := h.ClientV5.GetRetentionPolicyByProject(ctx, projectName)
if err != nil {
h.Log.Info(fmt.Sprintf("Error getting retention policy %s: %v", project.Name, err))
}
if policy != nil {
r1, _ := json.Marshal(policy.Rules)
r2, _ := json.Marshal(retention.Rules)
t1, _ := json.Marshal(policy.Trigger)
t2, _ := json.Marshal(retention.Trigger)
// if the policy differs, then we need to update it with our new policy
if string(r1) != string(r2) || string(t1) != string(t2) {
retention.ID = policy.ID
err := h.ClientV5.UpdateRetentionPolicy(ctx, retention)
if err != nil {
f, _ := json.Marshal(err)
h.Log.Info(fmt.Sprintf("Error updating retention policy %s: %v", project.Name, string(f)))
}
}
} else {
// create it if it doesn't
if err := h.ClientV5.NewRetentionPolicy(ctx, retention); err != nil {
h.Log.Info(fmt.Sprintf("Error creating retention policy %s: %v", project.Name, err))
}
}
}

if h.WebhookAddition {
wps, err := h.ClientV5.ListProjectWebhookPolicies(ctx, int(project.ProjectID))
if err != nil {
Expand Down Expand Up @@ -278,6 +315,14 @@ func (h *Harbor) DeleteRepository(ctx context.Context, projectName, branch strin
if err != nil {
h.Log.Info(fmt.Sprintf("Error deleting harbor repository %s", repo.Name))
}
h.Log.Info(
fmt.Sprintf(
"Deleted harbor repository %s in project %s, environment %s",
repo.Name,
projectName,
environmentName,
),
)
}
}
if len(listRepositories) > 100 {
Expand All @@ -293,6 +338,14 @@ func (h *Harbor) DeleteRepository(ctx context.Context, projectName, branch strin
if err != nil {
h.Log.Info(fmt.Sprintf("Error deleting harbor repository %s", repo.Name))
}
h.Log.Info(
fmt.Sprintf(
"Deleted harbor repository %s in project %s, environment %s",
repo.Name,
projectName,
environmentName,
),
)
}
}
}
Expand Down Expand Up @@ -321,6 +374,14 @@ func (h *Harbor) DeleteRobotAccount(ctx context.Context, projectName, branch str
h.Log.Info(fmt.Sprintf("Error deleting project %s robot account %s", projectName, robot.Name))
return
}
h.Log.Info(
fmt.Sprintf(
"Deleted harbor robot account %s in project %s, environment %s",
robot.Name,
projectName,
environmentName,
),
)
}
}
}
Expand Down
67 changes: 67 additions & 0 deletions internal/harbor/harbor_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"encoding/json"
"time"

harborclientv5model "github.com/mittwald/goharbor-client/v5/apiv2/model"
"github.com/uselagoon/remote-controller/internal/helpers"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -204,3 +205,69 @@ func (h *Harbor) UpsertHarborSecret(ctx context.Context, cl client.Client, ns, n
}
return false, nil
}

func (h *Harbor) generateRetentionPolicy(projectID int64, schedule string, branchRetention, prRetention int) *harborclientv5model.RetentionPolicy {
return &harborclientv5model.RetentionPolicy{
Algorithm: "or",
Rules: []*harborclientv5model.RetentionRule{
{ // create a retention policy for all images
Action: "retain",
Params: map[string]interface{}{
"latestPulledN": branchRetention,
},
ScopeSelectors: map[string][]harborclientv5model.RetentionSelector{
"repository": {
{
Decoration: "repoMatches",
Kind: "doublestar",
Pattern: "[^pr\\-]*/*", // exclude pullrequest repository images https://github.com/bmatcuk/doublestar#patterns
},
},
},
TagSelectors: []*harborclientv5model.RetentionSelector{
{
Decoration: "matches",
Extras: "{\"untagged\":true}",
Kind: "doublestar",
Pattern: "**",
},
},
Template: "latestPulledN",
},
{ // create a retention policy specifically for pullrequests
Action: "retain",
Params: map[string]interface{}{
"latestPulledN": prRetention,
},
ScopeSelectors: map[string][]harborclientv5model.RetentionSelector{
"repository": {
{
Decoration: "repoMatches",
Kind: "doublestar",
Pattern: "pr-*",
},
},
},
TagSelectors: []*harborclientv5model.RetentionSelector{
{
Decoration: "matches",
Extras: "{\"untagged\":true}",
Kind: "doublestar",
Pattern: "**",
},
},
Template: "latestPulledN",
},
},
Scope: &harborclientv5model.RetentionPolicyScope{
Level: "project",
Ref: projectID,
},
Trigger: &harborclientv5model.RetentionRuleTrigger{
Kind: "Schedule",
Settings: map[string]string{
"cron": schedule,
},
},
}
}
Loading

0 comments on commit 1a6cb7e

Please sign in to comment.