Skip to content

Commit

Permalink
implement keyring support (#18)
Browse files Browse the repository at this point in the history
the--keyring option allow to save and retrieve your password from the system keyring. It supports OS X, Linux/BSD (dbus) and Windows.
  • Loading branch information
tuxtof authored Jul 23, 2022
1 parent 30220f6 commit 11101ee
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 5 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ insecure: true
verbose: false
force: false
kubie: false
keyring: false
#ssh-agent: false
#ssh-file: false
#kubie-path: ~/.kube/.kubie/
Expand All @@ -111,6 +112,7 @@ you can also use the following environement variable
`KARBON_KUBIE_PATH`
`KARBON_SSH_AGENT`
`KARBON_SSH_FILE`
`KARBON_KEYRING`
`KUBECONFIG`

precedence is
Expand All @@ -123,7 +125,10 @@ You can use the `--force` option to overwrite any existing file(s) like kubeconf

## Password

This tools never stored the password. You can use the `KARBON_PASSWORD` env variable otherwise it should be provided in an interactive way.
By default this tools never stored the password.
You can use the `KARBON_PASSWORD` env variable.
You can also use the `--keyring` option to save and retrieve your password from the system keyring. It supports OS X, Linux/BSD (dbus) and Windows.
In all other cases password should be provided in an interactive way.

## SSH option

Expand Down
44 changes: 44 additions & 0 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/ktr0731/go-fuzzyfinder"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/zalando/go-keyring"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"golang.org/x/term"
Expand Down Expand Up @@ -293,21 +294,60 @@ func unmarshalCert(bytes []byte) (*ssh.Certificate, error) {

func getCredentials() (string, string) {
userArg := viper.GetString("user")
keyringFlag := viper.GetBool("keyring")

var password string
var ok bool
var err error
password, ok = os.LookupEnv("KARBON_PASSWORD")

if keyringFlag {
password, err = keyring.Get("kubectl-karbon", userArg)
if err == keyring.ErrNotFound && verbose {
fmt.Printf("No password found in keyring for user %s\n", userArg)
}
if err == nil {
ok = true
}
}

if !ok {
fmt.Printf("Enter %s password:\n", userArg)
bytePassword, err := term.ReadPassword(int(syscall.Stdin))
cobra.CheckErr(err)

password = string(bytePassword)

if keyringFlag {
err = savePasswordKeyring(userArg, password)
cobra.CheckErr(err)
}
}
return userArg, password
}

func savePasswordKeyring(user string, password string) error {
err := keyring.Set("kubectl-karbon", user, password)
if err != nil {
return err
}
if verbose {
fmt.Printf("Password saved in keyring for user %s\n", user)
}
return nil
}

func deletePasswordKeyring(user string) error {
err := keyring.Delete("kubectl-karbon", user)
if err != nil {
return err
}
if verbose {
fmt.Printf("Password deleted from keyring for user %s\n", user)
}
return nil
}

func newNutanixCluster() (*nutanixCluster, error) {
server := viper.GetString("server")
if server == "" {
Expand Down Expand Up @@ -349,6 +389,10 @@ func (c *nutanixCluster) clusterRequest(method string, path string, payload []by

switch res.StatusCode {
case 401:
if viper.GetBool("keyring") {
err = deletePasswordKeyring(c.login)
cobra.CheckErr(err)
}
return nil, fmt.Errorf("invalid client credentials")
case 404:
return nil, fmt.Errorf("karbon cluster not found")
Expand Down
3 changes: 3 additions & 0 deletions cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ If option enabled retrieve SSH key/cert and add them to ssh-agent or in file in
viper.BindPFlag("ssh-agent", cmd.Flags().Lookup("ssh-agent"))
viper.BindPFlag("ssh-file", cmd.Flags().Lookup("ssh-file"))
viper.BindPFlag("force", cmd.Flags().Lookup("force"))
viper.BindPFlag("keyring", cmd.Flags().Lookup("keyring"))
},
Run: func(cmd *cobra.Command, args []string) {

Expand Down Expand Up @@ -169,6 +170,8 @@ func init() {

loginCmd.Flags().Bool("kubie", false, "Store kubeconfig in independent file in kubie-path directory")

loginCmd.Flags().Bool("keyring", false, "Use keyring to store and retrieve credential")

userHomeDir, err := os.UserHomeDir()
cobra.CheckErr(err)
defaultKubiePath := fmt.Sprintf("%s/.kube/kubie/", userHomeDir)
Expand Down
13 changes: 9 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ module github.com/nutanix/kubectl-karbon
go 1.16

require (
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 // indirect
github.com/envoyproxy/protoc-gen-validate v0.6.2 // indirect
github.com/ktr0731/go-fuzzyfinder v0.6.0
github.com/spf13/cobra v1.4.0
github.com/spf13/viper v1.10.1
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
golang.org/x/term v0.0.0-20220411215600-e5f449aeb171
github.com/spf13/cobra v1.5.0
github.com/spf13/viper v1.12.0
github.com/zalando/go-keyring v0.2.1 // indirect
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035
)
Loading

0 comments on commit 11101ee

Please sign in to comment.