feat: support username-password in config update (#447)

This commit is contained in:
Jeffrey Smith II
2022-10-14 07:56:39 -04:00
committed by GitHub
parent 188c393034
commit 6142b7a4a3
4 changed files with 139 additions and 43 deletions

View File

@ -94,6 +94,18 @@ func (c Client) Update(cfg config.Config) error {
return c.printConfigs(configPrintOpts{config: &cfg}) return c.printConfigs(configPrintOpts{config: &cfg})
} }
func (c Client) UpdateWithUserPass(cfg config.Config, userPass string) error {
if userPass != "" && cfg.Token != "" {
return fmt.Errorf("token and username-password cannot be specified together, please choose just one")
}
if cfg.Token == "" && userPass != "" {
cfg.Cookie = base64.StdEncoding.EncodeToString([]byte(userPass))
}
return c.Update(cfg)
}
func (c Client) List() error { func (c Client) List() error {
cfgs, err := c.ConfigService.ListConfigs() cfgs, err := c.ConfigService.ListConfigs()
if err != nil { if err != nil {

View File

@ -2,6 +2,7 @@ package config_test
import ( import (
"bytes" "bytes"
"encoding/base64"
"fmt" "fmt"
"strings" "strings"
"testing" "testing"
@ -72,27 +73,58 @@ func TestClient_PrintActive(t *testing.T) {
func TestClient_Create(t *testing.T) { func TestClient_Create(t *testing.T) {
t.Parallel() t.Parallel()
ctrl := gomock.NewController(t) testCases := []struct {
stdio := mock.NewMockStdIO(ctrl) name string
writtenBytes := bytes.Buffer{} cfg config.Config
stdio.EXPECT().Write(gomock.Any()).DoAndReturn(writtenBytes.Write).AnyTimes() err error
}{
cfg := config.Config{ {
Name: "foo", name: "token",
Active: true, cfg: config.Config{
Host: "http://localhost:8086", Name: "foo",
Token: "supersecret", Active: true,
Org: "me", Host: "http://localhost:8086",
Token: "supersecret",
Org: "me",
},
err: nil,
},
{
name: "userpass",
cfg: config.Config{
Name: "foo",
Active: true,
Host: "http://localhost:8086",
Cookie: base64.StdEncoding.EncodeToString([]byte("user:pass")),
Org: "me",
},
err: nil,
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctrl := gomock.NewController(t)
stdio := mock.NewMockStdIO(ctrl)
writtenBytes := bytes.Buffer{}
stdio.EXPECT().Write(gomock.Any()).DoAndReturn(writtenBytes.Write).AnyTimes()
cfg := tc.cfg
svc := mock.NewMockConfigService(ctrl)
svc.EXPECT().CreateConfig(cfg).Return(cfg, nil)
cli := cmd.Client{CLI: clients.CLI{ConfigService: svc, StdIO: stdio}}
err := cli.Create(cfg)
require.NoError(t, err)
testutils.MatchLines(t, []string{
`Active\s+Name\s+URL\s+Org`,
fmt.Sprintf(`\*\s+%s\s+%s\s+%s`, cfg.Name, cfg.Host, cfg.Org),
}, strings.Split(writtenBytes.String(), "\n"))
})
} }
svc := mock.NewMockConfigService(ctrl)
svc.EXPECT().CreateConfig(cfg).Return(cfg, nil)
cli := cmd.Client{CLI: clients.CLI{ConfigService: svc, StdIO: stdio}}
require.NoError(t, cli.Create(cfg))
testutils.MatchLines(t, []string{
`Active\s+Name\s+URL\s+Org`,
fmt.Sprintf(`\*\s+%s\s+%s\s+%s`, cfg.Name, cfg.Host, cfg.Org),
}, strings.Split(writtenBytes.String(), "\n"))
} }
func TestClient_Delete(t *testing.T) { func TestClient_Delete(t *testing.T) {
@ -165,32 +197,67 @@ func TestClient_Delete(t *testing.T) {
func TestClient_Update(t *testing.T) { func TestClient_Update(t *testing.T) {
t.Parallel() t.Parallel()
ctrl := gomock.NewController(t) testCases := []struct {
stdio := mock.NewMockStdIO(ctrl) name string
writtenBytes := bytes.Buffer{} updates config.Config
stdio.EXPECT().Write(gomock.Any()).DoAndReturn(writtenBytes.Write).AnyTimes() cfg config.Config
err error
updates := config.Config{ }{
Name: "foo", {
Active: true, name: "token",
Token: "doublesecret", updates: config.Config{
Name: "foo",
Active: true,
Token: "doublesecret",
},
cfg: config.Config{
Name: "foo",
Active: true,
Host: "http://localhost:8086",
Token: "doublesecret",
Org: "me",
},
err: nil,
},
{
name: "userpass",
updates: config.Config{
Name: "foo",
Active: true,
Cookie: base64.StdEncoding.EncodeToString([]byte("user:pass")),
},
cfg: config.Config{
Name: "foo",
Active: true,
Host: "http://localhost:8086",
Cookie: base64.StdEncoding.EncodeToString([]byte("user:pass")),
Org: "me",
},
err: nil,
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctrl := gomock.NewController(t)
stdio := mock.NewMockStdIO(ctrl)
writtenBytes := bytes.Buffer{}
stdio.EXPECT().Write(gomock.Any()).DoAndReturn(writtenBytes.Write).AnyTimes()
svc := mock.NewMockConfigService(ctrl)
svc.EXPECT().UpdateConfig(tc.updates).Return(tc.cfg, nil)
cli := cmd.Client{CLI: clients.CLI{ConfigService: svc, StdIO: stdio}}
require.NoError(t, cli.Update(tc.updates))
testutils.MatchLines(t, []string{
`Active\s+Name\s+URL\s+Org`,
fmt.Sprintf(`\*\s+%s\s+%s\s+%s`, tc.cfg.Name, tc.cfg.Host, tc.cfg.Org),
}, strings.Split(writtenBytes.String(), "\n"))
})
} }
cfg := config.Config{
Name: updates.Name,
Active: updates.Active,
Host: "http://localhost:8086",
Token: updates.Token,
Org: "me",
}
svc := mock.NewMockConfigService(ctrl)
svc.EXPECT().UpdateConfig(updates).Return(cfg, nil)
cli := cmd.Client{CLI: clients.CLI{ConfigService: svc, StdIO: stdio}}
require.NoError(t, cli.Update(updates))
testutils.MatchLines(t, []string{
`Active\s+Name\s+URL\s+Org`,
fmt.Sprintf(`\*\s+%s\s+%s\s+%s`, cfg.Name, cfg.Host, cfg.Org),
}, strings.Split(writtenBytes.String(), "\n"))
} }
func TestClient_List(t *testing.T) { func TestClient_List(t *testing.T) {

View File

@ -174,6 +174,7 @@ https://docs.influxdata.com/influxdb/latest/reference/cli/influx/config/rm/
func newConfigUpdateCmd() cli.Command { func newConfigUpdateCmd() cli.Command {
var cfg config.Config var cfg config.Config
var userpass string
return cli.Command{ return cli.Command{
Name: "set", Name: "set",
Aliases: []string{"update"}, Aliases: []string{"update"},
@ -213,6 +214,11 @@ https://docs.influxdata.com/influxdb/latest/reference/cli/influx/config/set/
Usage: "New auth token to set on the config", Usage: "New auth token to set on the config",
Destination: &cfg.Token, Destination: &cfg.Token,
}, },
&cli.StringFlag{
Name: "username-password, p",
Usage: "Username (and optionally password) to use for authentication. Only supported in OSS",
Destination: &userpass,
},
&cli.StringFlag{ &cli.StringFlag{
Name: "org, o", Name: "org, o",
Usage: "New default organization to set on the config", Usage: "New default organization to set on the config",
@ -225,7 +231,13 @@ https://docs.influxdata.com/influxdb/latest/reference/cli/influx/config/set/
}, },
), ),
Action: func(ctx *cli.Context) error { Action: func(ctx *cli.Context) error {
if cfg.Token != "" && userpass != "" {
return fmt.Errorf("cannot specify `--token` and `--username-password` together, please choose one")
}
client := cmd.Client{CLI: getCLI(ctx)} client := cmd.Client{CLI: getCLI(ctx)}
if userpass != "" {
return client.UpdateWithUserPass(cfg, userpass)
}
return client.Update(cfg) return client.Update(cfg)
}, },
} }

View File

@ -124,6 +124,11 @@ func (svc localConfigsSVC) UpdateConfig(up Config) (Config, error) {
} }
if up.Token != "" { if up.Token != "" {
p0.Token = up.Token p0.Token = up.Token
p0.Cookie = ""
}
if up.Cookie != "" {
p0.Token = ""
p0.Cookie = up.Cookie
} }
if up.Host != "" { if up.Host != "" {
p0.Host = up.Host p0.Host = up.Host