Skip to content

Commit 2a84670

Browse files
authored
feat: add webhook cmd (#391)
1 parent d8d1289 commit 2a84670

24 files changed

Lines changed: 1778 additions & 10 deletions

cmd/harbor/root/cmd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/goharbor/harbor-cli/cmd/harbor/root/schedule"
3030
"github.com/goharbor/harbor-cli/cmd/harbor/root/tag"
3131
"github.com/goharbor/harbor-cli/cmd/harbor/root/user"
32+
"github.com/goharbor/harbor-cli/cmd/harbor/root/webhook"
3233
"github.com/goharbor/harbor-cli/pkg/utils"
3334
"github.com/sirupsen/logrus"
3435
"github.com/spf13/cobra"
@@ -105,6 +106,7 @@ harbor help
105106
schedule.Schedule(),
106107
labels.Labels(),
107108
InfoCommand(),
109+
webhook.Webhook(),
108110
instance.Instance(),
109111
)
110112

cmd/harbor/root/webhook/cmd.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright Project Harbor Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package webhook
15+
16+
import "github.com/spf13/cobra"
17+
18+
func Webhook() *cobra.Command {
19+
cmd := &cobra.Command{
20+
Use: "webhook",
21+
Short: "Manage webhook policies in Harbor",
22+
Long: `Use this command to manage webhook policies in your Harbor projects.
23+
24+
Webhooks enable external systems to be notified of events in Harbor (e.g., pushing an image, deleting an artifact).
25+
This command supports listing, creating, editing, and deleting webhook configurations.`,
26+
Example: ` # List webhook policies in a project
27+
harbor-cli webhook list my-project
28+
29+
# Create a new webhook policy
30+
harbor-cli webhook create --project my-project --name my-webhook
31+
32+
# Edit an existing webhook policy
33+
harbor-cli webhook edit --project my-project --webhook-id 5
34+
35+
# Delete a webhook policy
36+
harbor-cli webhook delete --project my-project --webhook-id 5`,
37+
}
38+
cmd.AddCommand(
39+
CreateWebhookCmd(),
40+
ListWebhookCommand(),
41+
DeleteWebhookCmd(),
42+
EditWebhookCmd(),
43+
)
44+
return cmd
45+
}

cmd/harbor/root/webhook/create.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright Project Harbor Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package webhook
15+
16+
import (
17+
"fmt"
18+
19+
"github.com/goharbor/harbor-cli/pkg/api"
20+
"github.com/goharbor/harbor-cli/pkg/prompt"
21+
"github.com/goharbor/harbor-cli/pkg/utils"
22+
"github.com/goharbor/harbor-cli/pkg/views/webhook/create"
23+
"github.com/spf13/cobra"
24+
)
25+
26+
func CreateWebhookCmd() *cobra.Command {
27+
var opts create.CreateView
28+
29+
cmd := &cobra.Command{
30+
Use: "create [name]",
31+
Short: "Create a new webhook for a Harbor project",
32+
Long: `This command creates a new webhook policy for a specified Harbor project.
33+
34+
You can either provide all required flags (project name, notify type, endpoint, etc.) directly to create the webhook non-interactively,
35+
or leave them out and be guided through an interactive prompt to input each field. The webhook name is required as an argument.`,
36+
Example: ` # Create a webhook using flags
37+
harbor-cli webhook create my-webhook \
38+
--project my-project \
39+
--notify-type http \
40+
--event-type PUSH_ARTIFACT,DELETE_ARTIFACT \
41+
--endpoint-url https://example.com/webhook \
42+
--description "Webhook for artifact events" \
43+
--payload-format Default \
44+
--auth-header "Bearer mytoken"
45+
46+
# Create a webhook using the interactive prompt
47+
harbor-cli webhook create my-webhook`,
48+
Args: cobra.MaximumNArgs(1),
49+
RunE: func(cmd *cobra.Command, args []string) error {
50+
var err error
51+
if len(args) > 0 {
52+
opts.Name = args[0]
53+
}
54+
55+
createView := &create.CreateView{
56+
ProjectName: opts.ProjectName,
57+
Name: opts.Name,
58+
Description: opts.Description,
59+
NotifyType: opts.NotifyType,
60+
PayloadFormat: opts.PayloadFormat,
61+
EventType: opts.EventType,
62+
EndpointURL: opts.EndpointURL,
63+
AuthHeader: opts.AuthHeader,
64+
VerifyRemoteCertificate: opts.VerifyRemoteCertificate,
65+
}
66+
67+
if opts.ProjectName != "" &&
68+
opts.Name != "" &&
69+
opts.NotifyType != "" &&
70+
len(opts.EventType) != 0 &&
71+
opts.EndpointURL != "" {
72+
err = utils.ValidateURL(opts.EndpointURL)
73+
if err != nil {
74+
return err
75+
}
76+
err = api.CreateWebhook(&opts)
77+
} else {
78+
err = createWebhookView(createView)
79+
}
80+
if err != nil {
81+
return fmt.Errorf("failed to create webhook: %v", err)
82+
}
83+
return nil
84+
},
85+
}
86+
87+
flags := cmd.Flags()
88+
89+
flags.StringVarP(&opts.ProjectName, "project", "", "", "Project Name")
90+
flags.StringVarP(&opts.Description, "description", "", "", "Webhook Description")
91+
flags.StringVarP(&opts.NotifyType, "notify-type", "", "", "Notify Type (http, slack)")
92+
flags.StringSliceVarP(&opts.EventType, "event-type", "", []string{}, "Event Types (comma separated)")
93+
flags.StringVarP(&opts.EndpointURL, "endpoint-url", "", "", "Webhook Endpoint URL")
94+
flags.StringVarP(&opts.PayloadFormat, "payload-format", "", "", "Payload Format (Default, CloudEvents)")
95+
flags.StringVarP(&opts.AuthHeader, "auth-header", "", "", "Authentication Header")
96+
flags.BoolVarP(&opts.VerifyRemoteCertificate, "verify-remote-certificate", "", true, "Verify Remote Certificate")
97+
98+
return cmd
99+
}
100+
101+
func createWebhookView(view *create.CreateView) error {
102+
var err error
103+
if view.ProjectName == "" {
104+
view.ProjectName, err = prompt.GetProjectNameFromUser()
105+
if err != nil {
106+
return err
107+
}
108+
}
109+
err = create.WebhookCreateView(view)
110+
if err != nil {
111+
return err
112+
}
113+
return api.CreateWebhook(view)
114+
}

cmd/harbor/root/webhook/delete.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright Project Harbor Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package webhook
15+
16+
import (
17+
"fmt"
18+
19+
"github.com/goharbor/harbor-cli/pkg/api"
20+
"github.com/goharbor/harbor-cli/pkg/prompt"
21+
"github.com/spf13/cobra"
22+
)
23+
24+
func DeleteWebhookCmd() *cobra.Command {
25+
var (
26+
projectName string
27+
webhookId int64 = -1
28+
)
29+
30+
cmd := &cobra.Command{
31+
Use: "delete [webhook-name]",
32+
Short: "Delete a webhook from a Harbor project",
33+
Long: `Delete a webhook from a specified Harbor project.
34+
You can either specify the project name and webhook ID using flags,
35+
pass the webhook name as an argument,
36+
or interactively select a project and webhook if not provided.`,
37+
Example: ` # Delete by project and webhook ID
38+
harbor-cli webhook delete --project my-project --webhook 5
39+
40+
# Delete by project and webhook name
41+
harbor-cli webhook delete my-webhook --project my-project
42+
43+
# Fully interactive deletion
44+
harbor-cli webhook delete`,
45+
Args: cobra.MaximumNArgs(1),
46+
RunE: func(cmd *cobra.Command, args []string) error {
47+
var err error
48+
var webhookName string
49+
50+
if len(args) > 0 {
51+
webhookName = args[0]
52+
}
53+
54+
if webhookId != -1 && webhookName != "" {
55+
return fmt.Errorf("webhook ID and name cannot be provided together")
56+
}
57+
58+
if (webhookId != -1 || webhookName != "") && projectName == "" {
59+
return fmt.Errorf("project name must be provided when specifying webhook ID or webhook name")
60+
}
61+
62+
if projectName == "" {
63+
projectName, err = prompt.GetProjectNameFromUser()
64+
if err != nil {
65+
return err
66+
}
67+
}
68+
69+
if webhookName != "" {
70+
webhookId, err = api.GetWebhookID(projectName, webhookName)
71+
if err != nil {
72+
return fmt.Errorf("failed to get webhook ID for '%s': %w", webhookName, err)
73+
}
74+
}
75+
76+
if webhookId == -1 {
77+
selectedWebhook, err := prompt.GetWebhookFromUser(projectName)
78+
if err != nil {
79+
return fmt.Errorf("failed to select webhook: %w", err)
80+
}
81+
webhookId = selectedWebhook.ID
82+
}
83+
84+
if err := api.DeleteWebhook(projectName, webhookId); err != nil {
85+
return fmt.Errorf("failed to delete webhook: %w", err)
86+
}
87+
88+
fmt.Printf("Webhook deleted successfully from project '%s'\n", projectName)
89+
return nil
90+
},
91+
}
92+
93+
flags := cmd.Flags()
94+
flags.StringVarP(&projectName, "project", "", "", "Project name (required when providing webhook ID or name)")
95+
flags.Int64VarP(&webhookId, "webhook-id", "", -1, "Webhook ID (alternative to providing webhook name as argument)")
96+
97+
return cmd
98+
}

0 commit comments

Comments
 (0)