Skip to content

Commit 7392a8e

Browse files
committed
Add proposal for official CLI project for Harbor
Signed-off-by: Akshat <[email protected]>
1 parent b4c27b4 commit 7392a8e

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

proposals/new/cli.md

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Proposal: Add Official CLI for Harbor
2+
3+
Author: Akshat/[akshatdalton](https://github.com/akshatdalton)
4+
5+
## Abstract
6+
7+
This proposal aims to add the official CLI for Harbor. It will have basic features like user login and other CRUD operations like create project, get project, list projects, etc.
8+
9+
## Background
10+
11+
There are some unofficial CLI projects to interact with Harbor API, and now Harbor wants to provide official support for CLI.
12+
13+
## Goals
14+
15+
- Implement official CLI for Harbor.
16+
- Support basic CRUD operations like create project, get project, list projects, etc.
17+
18+
## Implementation
19+
20+
### Directory structure
21+
22+
```
23+
cli/
24+
├── LICENSE
25+
├── README.md
26+
├── cmd
27+
│   ├── login
28+
│   │   └── login.go
29+
│   ├── project
30+
│   │   └── get_project.go
31+
│   ├── root.go
32+
│   └── utils
33+
│   └── utils.go
34+
├── go.mod
35+
├── go.sum
36+
└── main.go
37+
```
38+
39+
I will be using [cobra](https://github.com/spf13/cobra) to make this CLI tool and it will have the directory structure as shown above. Each of the commands will be treated as an individual sub-package.
40+
41+
```
42+
cmd/
43+
├── project
44+
├── create_project.go
45+
├── create_project_test.go
46+
├── delete_project.go
47+
├── delete_project_test.go
48+
├── .
49+
├── .
50+
├── .
51+
```
52+
53+
<br>
54+
55+
User credentials will be stored in `~/.harbor/config` upon sign in and the same will be used to read the credentials to make the API calls.
56+
57+
<br>
58+
59+
[harbor/go-client](https://github.com/goharbor/go-client) will be used to make any API calls for any given server address.
60+
61+
### Example Implementation for `get_project.go`
62+
63+
```go
64+
package project
65+
66+
import (
67+
"context"
68+
69+
"github.com/akshatdalton/harbor-cli/cmd/constants"
70+
"github.com/akshatdalton/harbor-cli/cmd/utils"
71+
"github.com/goharbor/go-client/pkg/sdk/v2.0/client/project"
72+
"github.com/spf13/cobra"
73+
)
74+
75+
type getProjectOptions struct {
76+
projectNameOrID string
77+
}
78+
79+
// NewGetProjectCommand creates a new `harbor get project` command
80+
func NewGetProjectCommand() *cobra.Command {
81+
var opts getProjectOptions
82+
83+
cmd := &cobra.Command{
84+
Use: "project [NAME|ID]",
85+
Short: "get project by name or id",
86+
Args: cobra.ExactArgs(1),
87+
RunE: func(cmd *cobra.Command, args []string) error {
88+
opts.projectNameOrID = args[0]
89+
credentialName, err := cmd.Flags().GetString(constants.CredentialNameOption)
90+
if err != nil {
91+
return err
92+
}
93+
return runGetProject(opts, credentialName)
94+
},
95+
}
96+
97+
return cmd
98+
}
99+
100+
func runGetProject(opts getProjectOptions, credentialName string) error {
101+
client := utils.GetClientByCredentialName(credentialName)
102+
ctx := context.Background()
103+
response, err := client.Project.GetProject(ctx, &project.GetProjectParams{ProjectNameOrID: opts.projectNameOrID})
104+
105+
if err != nil {
106+
return err
107+
}
108+
109+
utils.PrintPayloadInJSONFormat(response)
110+
return nil
111+
}
112+
```
113+
114+
We will follow the verb-noun syntax, for example:
115+
```
116+
harbor get project 1
117+
```
118+
119+
### Login to multiple registries
120+
121+
Users can log in to multiple registries and set the credential name for each set of credentials they log in with. And later can specify the credential to use, for any sub-commands, via the CLI option or by setting the environment variable: `HARBORCREDENTIALNAME`. If nothing is set, the current credential name set in `~/.harbor/config` will be used.
122+
123+
#### Structure of config file
124+
125+
```yaml
126+
current-credential-name: localhost-myusername1
127+
credentials:
128+
- name: localhost-myusername1
129+
username: myusername1
130+
password: mypassword1
131+
serveraddress: http://localhost
132+
- name: server1
133+
username: myusername2
134+
password: myusername2
135+
serveraddress: https://my.goharbor.io
136+
- name: server2
137+
username: myusername3
138+
password: mypassword3
139+
serveraddress: https://my.goharbor.io
140+
```
141+
142+
If the credential name is not specified during login then it will be constructed from the credentials passed in the format: `<DOMAINNAME>-<USERNAME>` where `DOMAINNAME` is the domain name of the server address and `USERNAME` is the username.

0 commit comments

Comments
 (0)