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

Add: created immutable command #129

Open
wants to merge 4 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
2 changes: 2 additions & 0 deletions cmd/harbor/root/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"

"github.com/goharbor/harbor-cli/cmd/harbor/root/artifact"
"github.com/goharbor/harbor-cli/cmd/harbor/root/immutable"
"github.com/goharbor/harbor-cli/cmd/harbor/root/project"
"github.com/goharbor/harbor-cli/cmd/harbor/root/registry"
repositry "github.com/goharbor/harbor-cli/cmd/harbor/root/repository"
Expand Down Expand Up @@ -109,6 +110,7 @@ harbor help
repositry.Repository(),
user.User(),
artifact.Artifact(),
immutable.Immutable(),
)

return root
Expand Down
21 changes: 21 additions & 0 deletions cmd/harbor/root/immutable/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package immutable

import (
"github.com/spf13/cobra"
)

func Immutable() *cobra.Command {
cmd := &cobra.Command{
Use: "immutable",
Short: "Manage Immutability rules in the project",
Long: `Manage Immutability rules in the project in Harbor`,
Example: `harbor immutable create`,
}
cmd.AddCommand(
CreateImmutableCommand(),
ListImmutableCommand(),
DeleteImmutableCommand(),
)

return cmd
}
62 changes: 62 additions & 0 deletions cmd/harbor/root/immutable/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package immutable

import (
"github.com/goharbor/harbor-cli/pkg/api"
"github.com/goharbor/harbor-cli/pkg/prompt"
"github.com/goharbor/harbor-cli/pkg/views/immutable/create"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

func CreateImmutableCommand() *cobra.Command {
var opts create.CreateView

cmd := &cobra.Command{
Use: "create",
Short: "create immutable tag rule",
Long: "create immutable tag rule to the project in harbor",
Args: cobra.MaximumNArgs(1),
Example: "harbor immutable create",
Run: func(cmd *cobra.Command, args []string) {
var err error
createView := &create.CreateView{
ScopeSelectors: create.ImmutableSelector{
Decoration: opts.ScopeSelectors.Decoration,
Pattern: opts.ScopeSelectors.Pattern,
},
TagSelectors: create.ImmutableSelector{
Decoration: opts.TagSelectors.Decoration,
Pattern: opts.TagSelectors.Pattern,
},
}
if len(args) > 0 {
err = createImmutableView(createView,args[0])
} else {
projectName := prompt.GetProjectNameFromUser()
err = createImmutableView(createView,projectName)
}

if err != nil {
log.Errorf("failed to create immutable tag rule: %v", err)
}

},
}

flags := cmd.Flags()
flags.StringVarP(&opts.ScopeSelectors.Decoration, "repo-decoration", "", "", "repository which either apply or exclude from the rule")
flags.StringVarP(&opts.ScopeSelectors.Pattern, "repo-list", "", "", "list of repository to which to either apply or exclude from the rule")
flags.StringVarP(&opts.TagSelectors.Decoration, "tag-decoration", "", "", "tags which either apply or exclude from the rule")
flags.StringVarP(&opts.TagSelectors.Pattern, "tag-list", "", "", "list of tags to which to either apply or exclude from the rule")

return cmd
}

func createImmutableView(createView *create.CreateView,projectName string) error {
if createView == nil {
createView = &create.CreateView{}
}

create.CreateImmutableView(createView)
return api.CreateImmutable(*createView,projectName)
}
33 changes: 33 additions & 0 deletions cmd/harbor/root/immutable/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package immutable

import (
"github.com/goharbor/harbor-cli/pkg/api"
"github.com/spf13/cobra"
log "github.com/sirupsen/logrus"
"github.com/goharbor/harbor-cli/pkg/prompt"
)

func DeleteImmutableCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "delete",
Short: "delete immutable rule",
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
var err error
var immutableId int64
if len(args) > 0 {
immutableId = prompt.GetImmutableTagRule(args[0])
err = api.DeleteImmutable(args[0],immutableId)
} else {
projectName := prompt.GetProjectNameFromUser()
immutableId = prompt.GetImmutableTagRule(projectName)
err = api.DeleteImmutable(projectName,immutableId)
}
if err != nil {
log.Errorf("failed to delete immutable rule: %v", err)
}
},
}

return cmd
}
46 changes: 46 additions & 0 deletions cmd/harbor/root/immutable/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package immutable

import (
"github.com/goharbor/go-client/pkg/sdk/v2.0/client/immutable"
"github.com/goharbor/harbor-cli/pkg/api"
"github.com/goharbor/harbor-cli/pkg/prompt"
"github.com/goharbor/harbor-cli/pkg/utils"
"github.com/goharbor/harbor-cli/pkg/views/immutable/list"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

func ListImmutableCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "list all immutable tag rule of project",
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
var err error
var resp immutable.ListImmuRulesOK

if len(args) > 0 {
projectName := args[0]
resp, err = api.ListImmutable(projectName)
} else {
projectName := prompt.GetProjectNameFromUser()
resp, err = api.ListImmutable(projectName)
}

if err != nil {
log.Errorf("failed to list immutablility rule: %v", err)
}
FormatFlag := viper.GetString("output-format")
if FormatFlag != "" {
utils.PrintPayloadInJSONFormat(resp)
return
}

list.ListImmuRules(resp.Payload)

},
}

return cmd
}
66 changes: 66 additions & 0 deletions pkg/api/immutable_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package api

import (
"github.com/goharbor/go-client/pkg/sdk/v2.0/client/immutable"
"github.com/goharbor/go-client/pkg/sdk/v2.0/models"
"github.com/goharbor/harbor-cli/pkg/utils"
"github.com/goharbor/harbor-cli/pkg/views/immutable/create"
log "github.com/sirupsen/logrus"
)

func CreateImmutable(opts create.CreateView, projectName string) error {
ctx, client, err := utils.ContextWithClient()
if err != nil {
return err
}
tagSelector := &models.ImmutableSelector{
Decoration: opts.TagSelectors.Decoration,
Pattern: opts.TagSelectors.Pattern,
}
scope := models.ImmutableSelector{
Decoration: opts.ScopeSelectors.Decoration,
Pattern: opts.ScopeSelectors.Pattern,
}
scopeSelector := map[string][]models.ImmutableSelector{
"repository": {
scope,
},
}

_, err = client.Immutable.CreateImmuRule(ctx, &immutable.CreateImmuRuleParams{ProjectNameOrID: projectName,ImmutableRule: &models.ImmutableRule{TagSelectors: []*models.ImmutableSelector{tagSelector},ScopeSelectors: scopeSelector}})

if err != nil {
return err
}

log.Info("Added Tag Immutability Rule")
return nil
}

func ListImmutable(projectName string)(immutable.ListImmuRulesOK,error){
ctx, client, err := utils.ContextWithClient()
if err != nil {
return immutable.ListImmuRulesOK{}, err
}
response,err := client.Immutable.ListImmuRules(ctx,&immutable.ListImmuRulesParams{ProjectNameOrID: projectName})
if err != nil {
return immutable.ListImmuRulesOK{}, err
}

return *response, nil
}

func DeleteImmutable(projectName string,ImmutableID int64) error{
ctx, client, err := utils.ContextWithClient()
if err != nil {
return err
}
_, err = client.Immutable.DeleteImmuRule(ctx,&immutable.DeleteImmuRuleParams{ProjectNameOrID: projectName,ImmutableRuleID: ImmutableID})
if err != nil {
return err
}

log.Info("immutable rule deleted successfully")

return nil
}
10 changes: 10 additions & 0 deletions pkg/prompt/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
rview "github.com/goharbor/harbor-cli/pkg/views/registry/select"
repoView "github.com/goharbor/harbor-cli/pkg/views/repository/select"
uview "github.com/goharbor/harbor-cli/pkg/views/user/select"
iview "github.com/goharbor/harbor-cli/pkg/views/immutable/select"
log "github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -71,6 +72,15 @@ func GetUserIdFromUser() int64 {

}

func GetImmutableTagRule(projectName string) int64 {
immutableid := make(chan int64)
go func() {
response, _ := api.ListImmutable(projectName)
iview.ImmutableList(response.Payload, immutableid)
}()
return <-immutableid
}

func GetTagFromUser(repoName, projectName, reference string) string {
tag := make(chan string)
go func() {
Expand Down
74 changes: 74 additions & 0 deletions pkg/views/immutable/create/view.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package create

import (
"errors"

"github.com/charmbracelet/huh"
log "github.com/sirupsen/logrus"
)

type CreateView struct {
ScopeSelectors ImmutableSelector `json:"scope_selectors,omitempty"`
TagSelectors ImmutableSelector `json:"tag_selectors"`
}

type ImmutableSelector struct {
Decoration string `json:"decoration,omitempty"`
Pattern string `json:"pattern,omitempty"`
}

func CreateImmutableView(createView *CreateView) {
theme := huh.ThemeCharm()
err := huh.NewForm(
huh.NewGroup(
huh.NewSelect[string]().
Title("\nFor the repositories\n").
Options(
huh.NewOption("matching", "repoMatches"),
huh.NewOption("excluding", "repoExcludes"),
).Value(&createView.ScopeSelectors.Decoration).
Validate(func(str string) error {
if str == "" {
return errors.New("decoration cannot be empty")
}
return nil
}),
huh.NewInput().
Title("List of repositories").
Value(&createView.ScopeSelectors.Pattern).
Description("Enter multiple comma separated repos,repo*,or **").
Validate(func(str string) error {
if str == "" {
return errors.New("pattern cannot be empty")
}
return nil
}),
huh.NewSelect[string]().
Title("Tags\n").
Options(
huh.NewOption("matching", "matches"),
huh.NewOption("excluding", "excludes"),
).Value(&createView.TagSelectors.Decoration).
Validate(func(str string) error {
if str == "" {
return errors.New("decoration cannot be empty")
}
return nil
}),
huh.NewInput().
Title("List of Tags").
Value(&createView.TagSelectors.Pattern).
Description("Enter multiple comma separated repos,repo*,or **").
Validate(func(str string) error {
if str == "" {
return errors.New("pattern cannot be empty")
}
return nil
}),
),
).WithTheme(theme).Run()

if err != nil {
log.Fatal(err)
}
}
Loading
Loading