Skip to content

Commit

Permalink
AutoGenerate credential name in login (#250)
Browse files Browse the repository at this point in the history
* generate credential name

Signed-off-by: bupd <[email protected]>

* feat: add support for the password-stdin flag in login flow

Signed-off-by: karanngi <[email protected]>

* fix deps

- fixes dependencies

Signed-off-by: bupd <[email protected]>

* return stdout for tests

Signed-off-by: bupd <[email protected]>

* update workflow

Signed-off-by: bupd <[email protected]>

---------

Signed-off-by: bupd <[email protected]>
Signed-off-by: karanngi <[email protected]>
Co-authored-by: karanngi <[email protected]>
  • Loading branch information
bupd and karanngi authored Nov 14, 2024
1 parent cc8d1c8 commit b2fb70f
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 38 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ jobs:
with:
version: ${{ steps.dagger_version.outputs.version }}
verb: call
args: test
args: test export --path=./testResults

- name: Build Binary
uses: dagger/dagger-for-github@v6
with:
version: ${{ steps.dagger_version.outputs.version }}
verb: call
args: build-dev --platform linux/amd64
args: build-dev --platform linux/amd64 export --path=./harbor-dev

push-latest-images:
if: github.event.pull_request == null && !startsWith(github.ref, 'refs/tags/v')
Expand Down
41 changes: 21 additions & 20 deletions cmd/harbor/root/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ package root
import (
"context"
"fmt"
"strings"
"os"

"github.com/goharbor/go-client/pkg/harbor"
"github.com/goharbor/go-client/pkg/sdk/v2.0/client/user"
"github.com/goharbor/harbor-cli/pkg/utils"
"github.com/goharbor/harbor-cli/pkg/views/login"
"github.com/spf13/cobra"
"golang.org/x/term"
)

var (
serverAddress string
Username string
Password string
Name string
passwordStdin bool
)

// LoginCommand creates a new `harbor login` command
Expand All @@ -31,17 +33,31 @@ func LoginCommand() *cobra.Command {
serverAddress = args[0]
}

if passwordStdin {
fmt.Print("Password: ")
passwordBytes, err := term.ReadPassword(int(os.Stdin.Fd()))
if err != nil {
return fmt.Errorf("failed to read password from stdin: %v", err)
}
fmt.Println()
Password = string(passwordBytes)
}

loginView := login.LoginView{
Server: serverAddress,
Username: Username,
Password: Password,
Name: Name,
}

// autogenerate name
if loginView.Name == "" && loginView.Server != "" && loginView.Username != "" {
loginView.Name = fmt.Sprintf("%s@%s", loginView.Username, utils.SanitizeServerAddress(loginView.Server))
}

var err error

if loginView.Server != "" && loginView.Username != "" && loginView.Password != "" &&
loginView.Name != "" {
if loginView.Server != "" && loginView.Username != "" && loginView.Password != "" {
err = runLogin(loginView)
} else {
err = createLoginView(&loginView)
Expand All @@ -58,24 +74,11 @@ func LoginCommand() *cobra.Command {
flags.StringVarP(&Name, "name", "", "", "name for the set of credentials")
flags.StringVarP(&Username, "username", "u", "", "Username")
flags.StringVarP(&Password, "password", "p", "", "Password")
flags.BoolVar(&passwordStdin, "password-stdin", false, "Take the password from stdin")

return cmd
}

// generateCredentialName creates a default credential name based on server and username
func generateCredentialName(server, username string) string {
if strings.HasPrefix(server, "http://") {
server = strings.ReplaceAll(server, "http://", "")
}
if strings.HasPrefix(server, "https://") {
server = strings.ReplaceAll(server, "https://", "")
}
if username != "" {
return fmt.Sprintf("%s@%s", username, server)
}
return server
}

func createLoginView(loginView *login.LoginView) error {
if loginView == nil {
loginView = &login.LoginView{
Expand All @@ -86,6 +89,7 @@ func createLoginView(loginView *login.LoginView) error {
}
}
login.CreateView(loginView)

return runLogin(*loginView)
}

Expand All @@ -104,9 +108,6 @@ func runLogin(opts login.LoginView) error {
if err != nil {
return fmt.Errorf("login failed, please check your credentials: %s", err)
}
if opts.Name == "" {
opts.Name = generateCredentialName(opts.Server, opts.Username)
}

cred := utils.Credential{
Name: opts.Name,
Expand Down
2 changes: 1 addition & 1 deletion dagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
}
],
"source": "dagger",
"engineVersion": "v0.13.6"
"engineVersion": "v0.14.0"
}
24 changes: 12 additions & 12 deletions dagger/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ const (
)

func New(
// Local or remote directory with source code, defaults to "./"
// +optional
// +defaultPath="./"
// Local or remote directory with source code, defaults to "./"
// +optional
// +defaultPath="./"
source *dagger.Directory,
) *HarborCli {
return &HarborCli{Source: source}
Expand Down Expand Up @@ -122,8 +122,8 @@ func (m *HarborCli) lint(ctx context.Context) *dagger.Container {
func (m *HarborCli) PublishImage(
ctx context.Context,
registry, registryUsername string,
// +optional
// +default=["latest"]
// +optional
// +default=["latest"]
imageTags []string,
registryPassword *dagger.Secret) []string {
builders := m.build(ctx)
Expand Down Expand Up @@ -234,7 +234,7 @@ func (m *HarborCli) Test(ctx context.Context) *dagger.Directory {
WithEnvVariable("GOCACHE", "/go/build-cache").
WithMountedDirectory("/src", m.Source).
WithWorkdir("/src").
WithExec([]string{"go", "test", "-v", "./..."}).
WithExec([]string{"go", "test", "./..."}).
Directory("/src")
}

Expand All @@ -254,11 +254,11 @@ func (m *HarborCli) PublishImageAndSign(
registryUsername string,
registryPassword *dagger.Secret,
imageTags []string,
// +optional
// +optional
githubToken *dagger.Secret,
// +optional
// +optional
actionsIdTokenRequestToken *dagger.Secret,
// +optional
// +optional
actionsIdTokenRequestUrl string,
) (string, error) {

Expand All @@ -282,11 +282,11 @@ func (m *HarborCli) PublishImageAndSign(

// Sign signs a container image using Cosign, works also with GitHub Actions
func (m *HarborCli) Sign(ctx context.Context,
// +optional
// +optional
githubToken *dagger.Secret,
// +optional
// +optional
actionsIdTokenRequestUrl string,
// +optional
// +optional
actionsIdTokenRequestToken *dagger.Secret,
registryUsername string,
registryPassword *dagger.Secret,
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/spf13/cobra v1.8.1
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
golang.org/x/term v0.6.0
)

require (
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
9 changes: 9 additions & 0 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package utils
import (
"encoding/json"
"fmt"
"regexp"
"strings"

log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -38,3 +39,11 @@ func ParseProjectRepoReference(projectRepoReference string) (string, string, str
}
return split[0], split[1], split[2]
}

func SanitizeServerAddress(server string) string {
re := regexp.MustCompile(`^https?://`)
server = re.ReplaceAllString(server, "")
re = regexp.MustCompile(`[^a-zA-Z0-9]`)
server = re.ReplaceAllString(server, "-")
return server
}
17 changes: 14 additions & 3 deletions pkg/views/login/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package login

import (
"errors"
"fmt"
"net/url"
"strings"

Expand All @@ -19,10 +20,12 @@ type LoginView struct {

func CreateView(loginView *LoginView) {
theme := huh.ThemeCharm()

err := huh.NewForm(
huh.NewGroup(
huh.NewInput().
Title("Server").
Description("Server address eg. demo.goharbor.io").
Value(&loginView.Server).
Validate(func(str string) error {
if strings.TrimSpace(str) == "" {
Expand Down Expand Up @@ -62,17 +65,25 @@ func CreateView(loginView *LoginView) {
huh.NewInput().
Title("Name of Credential").
Value(&loginView.Name).
Description("Name of credential to be stored in the harbor config file.").
PlaceholderFunc(func() string {
return fmt.Sprintf("%s@%s", loginView.Username, utils.SanitizeServerAddress(loginView.Server))
}, &loginView).
SuggestionsFunc(func() []string {
return []string{
fmt.Sprintf("%s@%s", loginView.Username, utils.SanitizeServerAddress(loginView.Server)),
}
}, &loginView).
Validate(func(str string) error {
if str == "" {
return errors.New("credential name cannot be empty")
loginView.Name = fmt.Sprintf("%s@%s", loginView.Username, utils.SanitizeServerAddress(loginView.Server))
return nil
}
return nil
}),
),
).WithTheme(theme).Run()

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

}

0 comments on commit b2fb70f

Please sign in to comment.