Skip to content

Commit 0dd15d5

Browse files
authored
feat : instance remaining subcommands (#812)
1 parent 8338315 commit 0dd15d5

24 files changed

Lines changed: 1168 additions & 85 deletions

cmd/harbor/root/instance/cmd.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ These instances represent external services such as Dragonfly or Kraken that hel
2626
CreateInstanceCommand(),
2727
DeleteInstanceCommand(),
2828
ListInstanceCommand(),
29+
PingInstanceCommand(),
30+
UpdateInstanceCommand(),
31+
ViewInstanceCommand(),
2932
)
3033
return cmd
3134
}

cmd/harbor/root/instance/create.go

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package instance
1515

1616
import (
1717
"fmt"
18+
"strings"
1819

1920
"github.com/goharbor/harbor-cli/pkg/api"
2021
"github.com/goharbor/harbor-cli/pkg/utils"
@@ -24,54 +25,87 @@ import (
2425

2526
func CreateInstanceCommand() *cobra.Command {
2627
var opts create.CreateView
28+
var authUsername, authPassword, authToken string
2729

2830
cmd := &cobra.Command{
2931
Use: "create",
3032
Short: "Create a new preheat provider instance in Harbor",
3133
Long: `Create a new preheat provider instance within Harbor for distributing container images.
3234
The instance can be an external service such as Dragonfly, Kraken, or any custom provider.
3335
You will need to provide the instance's name, vendor, endpoint, and optionally other details such as authentication and security options.`,
34-
Example: ` harbor-cli instance create --name my-instance --provider Dragonfly --url http://dragonfly.local --description "My preheat provider instance" --enable=true`,
36+
Example: ` harbor-cli instance create --name my-instance --provider dragonfly --url http://dragonfly.local --description "My preheat provider instance" --enable=true`,
3537
Args: cobra.NoArgs,
3638
RunE: func(cmd *cobra.Command, args []string) error {
3739
var err error
38-
createView := &create.CreateView{
39-
Name: opts.Name,
40-
Vendor: opts.Vendor,
41-
Description: opts.Description,
42-
Endpoint: opts.Endpoint,
43-
Insecure: opts.Insecure,
44-
Enabled: opts.Enabled,
45-
AuthMode: opts.AuthMode,
46-
AuthInfo: opts.AuthInfo,
47-
}
40+
var instanceName string
4841

4942
if opts.Name != "" && opts.Vendor != "" && opts.Endpoint != "" {
5043
formattedEndpoint := utils.FormatUrl(opts.Endpoint)
5144
if err := utils.ValidateURL(formattedEndpoint); err != nil {
5245
return err
5346
}
5447
opts.Endpoint = formattedEndpoint
48+
49+
opts.AuthMode = strings.ToUpper(strings.TrimSpace(opts.AuthMode))
50+
51+
switch opts.AuthMode {
52+
case "BASIC":
53+
if authUsername == "" || authPassword == "" {
54+
return fmt.Errorf("username and password are required when authmode is BASIC. Use --auth-username and --auth-password flags")
55+
}
56+
opts.AuthInfo = map[string]string{
57+
"username": authUsername,
58+
"password": authPassword,
59+
}
60+
case "OAUTH":
61+
if authToken == "" {
62+
return fmt.Errorf("token is required when authmode is OAUTH. Use --auth-token flag")
63+
}
64+
opts.AuthInfo = map[string]string{
65+
"token": authToken,
66+
}
67+
case "NONE":
68+
// Auth credentials are ignored when authmode is NONE
69+
default:
70+
return fmt.Errorf("invalid authmode '%s'. Valid options: NONE, BASIC, OAUTH", opts.AuthMode)
71+
}
72+
5573
err = api.CreateInstance(opts)
74+
instanceName = opts.Name
5675
} else {
76+
createView := &create.CreateView{
77+
Name: opts.Name,
78+
Vendor: opts.Vendor,
79+
Description: opts.Description,
80+
Endpoint: opts.Endpoint,
81+
Insecure: opts.Insecure,
82+
Enabled: opts.Enabled,
83+
AuthMode: opts.AuthMode,
84+
}
5785
err = createInstanceView(createView)
86+
instanceName = createView.Name
5887
}
5988

6089
if err != nil {
61-
return fmt.Errorf("failed to create instance: %v", err)
90+
return fmt.Errorf("failed to create instance: %v", utils.ParseHarborErrorMsg(err))
6291
}
92+
93+
fmt.Printf("Instance '%s' created successfully\n", instanceName)
6394
return nil
6495
},
6596
}
6697

6798
flags := cmd.Flags()
6899
flags.StringVarP(&opts.Name, "name", "n", "", "Name of the instance")
69-
flags.StringVarP(&opts.Vendor, "provider", "p", "", "Provider for the instance")
70-
flags.StringVarP(&opts.Endpoint, "url", "u", "", "URL for the instance")
71-
flags.StringVarP(&opts.Description, "description", "", "", "Description of the instance")
72-
flags.BoolVarP(&opts.Insecure, "insecure", "i", true, "Whether or not the certificate will be verified when Harbor tries to access the server")
73-
flags.BoolVarP(&opts.Enabled, "enable", "", true, "Whether it is enabled or not")
74-
flags.StringVarP(&opts.AuthMode, "authmode", "a", "NONE", "Choosing different types of authentication method")
100+
flags.StringVarP(&opts.Vendor, "provider", "p", "", "Provider for the instance (e.g. dragonfly, kraken)")
101+
flags.StringVarP(&opts.Endpoint, "url", "u", "", "Endpoint URL for the instance")
102+
flags.StringVarP(&opts.Description, "description", "d", "", "Description of the instance")
103+
flags.BoolVarP(&opts.Insecure, "insecure", "i", false, "Whether or not the certificate will be verified when Harbor tries to access the server")
104+
flags.BoolVarP(&opts.Enabled, "enable", "", true, "Whether the instance is enabled or not")
105+
flags.StringVarP(&opts.AuthMode, "authmode", "a", "NONE", "Authentication mode (NONE, BASIC, OAUTH)")
106+
flags.StringVar(&authUsername, "auth-username", "", "Username for BASIC authentication")
107+
flags.StringVar(&authPassword, "auth-password", "", "Password for BASIC authentication")
108+
flags.StringVar(&authToken, "auth-token", "", "Token for OAUTH authentication")
75109

76110
return cmd
77111
}
@@ -81,6 +115,8 @@ func createInstanceView(createView *create.CreateView) error {
81115
createView = &create.CreateView{}
82116
}
83117

84-
create.CreateInstanceView(createView)
118+
if err := create.CreateInstanceView(createView); err != nil {
119+
return err
120+
}
85121
return api.CreateInstance(*createView)
86122
}

cmd/harbor/root/instance/delete.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ If no argument is provided, you will be prompted to select an instance from a li
4343
} else if len(args) > 0 {
4444
instanceName = args[0]
4545
} else {
46-
instanceName = prompt.GetInstanceFromUser()
46+
instanceName, err = prompt.GetInstanceNameFromUser()
47+
if err != nil {
48+
return fmt.Errorf("%v", err)
49+
}
4750
}
4851
err = api.DeleteInstance(instanceName)
4952
if err != nil {

cmd/harbor/root/instance/list.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ This command provides an easy way to view all instances along with their details
4545
return fmt.Errorf("page size should be less than or equal to 100")
4646
}
4747

48-
instance, err := api.ListInstance(opts)
48+
instance, err := api.ListAllInstance(opts)
4949

5050
if err != nil {
5151
return fmt.Errorf("failed to get instance list: %v", err)

cmd/harbor/root/instance/ping.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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 instance
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+
log "github.com/sirupsen/logrus"
23+
"github.com/spf13/cobra"
24+
"github.com/spf13/viper"
25+
)
26+
27+
func PingInstanceCommand() *cobra.Command {
28+
var useInstanceID bool
29+
30+
cmd := &cobra.Command{
31+
Use: "ping [NAME|ID]",
32+
Short: "Ping preheat provider instance by name or id",
33+
Long: `Ping a preheat provider instance to test its connectivity in Harbor. You can specify the instance
34+
by name or ID directly as an argument. If no argument is provided, you will be prompted to select
35+
an instance from a list of available instances.`,
36+
Example: ` harbor-cli instance ping my-instance
37+
harbor-cli instance ping 1 --id`,
38+
Args: cobra.MaximumNArgs(1),
39+
RunE: func(cmd *cobra.Command, args []string) error {
40+
var err error
41+
var instanceName string
42+
43+
if useInstanceID && len(args) == 0 {
44+
return fmt.Errorf("instance ID must be provided when using --id")
45+
}
46+
47+
if len(args) > 0 {
48+
log.Debugf("Instance name provided: %s", args[0])
49+
instanceName = args[0]
50+
} else {
51+
log.Debug("No instance name provided, prompting user")
52+
instanceName, err = prompt.GetInstanceNameFromUser()
53+
if err != nil {
54+
return fmt.Errorf("failed to get instance name: %v", utils.ParseHarborErrorMsg(err))
55+
}
56+
}
57+
58+
log.Debugf("Pinging instance: %s", instanceName)
59+
response, err := api.PingInstance(instanceName, useInstanceID)
60+
if err != nil {
61+
if utils.ParseHarborErrorCode(err) == "404" {
62+
return fmt.Errorf("instance %s does not exist", instanceName)
63+
}
64+
return fmt.Errorf("failed to ping instance: %v", utils.ParseHarborErrorMsg(err))
65+
}
66+
67+
outputFormat := viper.GetString("output-format")
68+
if outputFormat != "" {
69+
if err := utils.PrintFormat(response, outputFormat); err != nil {
70+
return err
71+
}
72+
} else {
73+
fmt.Printf("Instance '%s' pinged successfully\n", instanceName)
74+
}
75+
return nil
76+
},
77+
}
78+
79+
flags := cmd.Flags()
80+
flags.BoolVar(&useInstanceID, "id", false, "Get instance by id")
81+
82+
return cmd
83+
}

0 commit comments

Comments
 (0)