Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Commit ad0f9c9

Browse files
committed
WIP mirgation to urfave/cli
1 parent 6316e07 commit ad0f9c9

File tree

10 files changed

+253
-271
lines changed

10 files changed

+253
-271
lines changed

cmd/coder/configssh.go

Lines changed: 106 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -11,162 +11,165 @@ import (
1111
"strings"
1212
"time"
1313

14-
"github.com/spf13/pflag"
15-
"go.coder.com/cli"
16-
"go.coder.com/flog"
17-
1814
"cdr.dev/coder-cli/internal/config"
1915
"cdr.dev/coder-cli/internal/entclient"
20-
)
16+
"github.com/urfave/cli"
2117

22-
var (
23-
privateKeyFilepath = filepath.Join(os.Getenv("HOME"), ".ssh", "coder_enterprise")
18+
"go.coder.com/flog"
2419
)
2520

26-
type configSSHCmd struct {
27-
filepath string
28-
remove bool
29-
30-
startToken, startMessage, endToken string
31-
}
32-
33-
func (cmd *configSSHCmd) Spec() cli.CommandSpec {
34-
return cli.CommandSpec{
35-
Name: "config-ssh",
36-
Usage: "",
37-
Desc: "add your Coder Enterprise environments to ~/.ssh/config",
21+
func makeConfigSSHCmd() cli.Command {
22+
var (
23+
configpath string
24+
remove = false
25+
)
26+
27+
return cli.Command{
28+
Name: "config-ssh",
29+
UsageText: "",
30+
Description: "add your Coder Enterprise environments to ~/.ssh/config",
31+
Action: configSSH(&configpath, &remove),
32+
Flags: []cli.Flag{
33+
cli.StringFlag{
34+
Name: "filepath",
35+
Usage: "overide the default path of your ssh config file",
36+
Value: filepath.Join(os.Getenv("HOME"), ".ssh", "config"),
37+
TakesFile: true,
38+
Destination: &configpath,
39+
},
40+
cli.BoolFlag{
41+
Name: "remove",
42+
Usage: "remove the auto-generated Coder Enterprise ssh config",
43+
Destination: &remove,
44+
},
45+
},
3846
}
3947
}
4048

41-
func (cmd *configSSHCmd) RegisterFlags(fl *pflag.FlagSet) {
42-
fl.BoolVar(&cmd.remove, "remove", false, "remove the auto-generated Coder Enterprise ssh config")
43-
home := os.Getenv("HOME")
44-
defaultPath := filepath.Join(home, ".ssh", "config")
45-
fl.StringVar(&cmd.filepath, "config-path", defaultPath, "overide the default path of your ssh config file")
46-
47-
cmd.startToken = "# ------------START-CODER-ENTERPRISE-----------"
48-
cmd.startMessage = `# The following has been auto-generated by "coder config-ssh"
49+
func configSSH(filepath *string, remove *bool) func(c *cli.Context) {
50+
startToken := "# ------------START-CODER-ENTERPRISE-----------"
51+
startMessage := `# The following has been auto-generated by "coder config-ssh"
4952
# to make accessing your Coder Enterprise environments easier.
5053
#
5154
# To remove this blob, run:
5255
#
5356
# coder config-ssh --remove
5457
#
5558
# You should not hand-edit this section, unless you are deleting it.`
56-
cmd.endToken = "# ------------END-CODER-ENTERPRISE------------"
57-
}
58-
59-
func (cmd *configSSHCmd) Run(fl *pflag.FlagSet) {
60-
ctx, cancel := context.WithCancel(context.Background())
61-
defer cancel()
59+
endToken := "# ------------END-CODER-ENTERPRISE------------"
60+
61+
return func(c *cli.Context) {
62+
ctx, cancel := context.WithCancel(context.Background())
63+
defer cancel()
64+
65+
currentConfig, err := readStr(*filepath)
66+
if os.IsNotExist(err) {
67+
// SSH configs are not always already there.
68+
currentConfig = ""
69+
} else if err != nil {
70+
flog.Fatal("failed to read ssh config file %q: %v", filepath, err)
71+
}
6272

63-
currentConfig, err := readStr(cmd.filepath)
64-
if os.IsNotExist(err) {
65-
// SSH configs are not always already there.
66-
currentConfig = ""
67-
} else if err != nil {
68-
flog.Fatal("failed to read ssh config file %q: %v", cmd.filepath, err)
69-
}
73+
startIndex := strings.Index(currentConfig, startToken)
74+
endIndex := strings.Index(currentConfig, endToken)
7075

71-
startIndex := strings.Index(currentConfig, cmd.startToken)
72-
endIndex := strings.Index(currentConfig, cmd.endToken)
76+
if *remove {
77+
if startIndex == -1 || endIndex == -1 {
78+
flog.Fatal("the Coder Enterprise ssh configuration section could not be safely deleted or does not exist")
79+
}
80+
currentConfig = currentConfig[:startIndex-1] + currentConfig[endIndex+len(endToken)+1:]
7381

74-
if cmd.remove {
75-
if startIndex == -1 || endIndex == -1 {
76-
flog.Fatal("the Coder Enterprise ssh configuration section could not be safely deleted or does not exist")
77-
}
78-
currentConfig = currentConfig[:startIndex-1] + currentConfig[endIndex+len(cmd.endToken)+1:]
82+
err = writeStr(*filepath, currentConfig)
83+
if err != nil {
84+
flog.Fatal("failed to write to ssh config file %q: %v", *filepath, err)
85+
}
7986

80-
err = writeStr(cmd.filepath, currentConfig)
81-
if err != nil {
82-
flog.Fatal("failed to write to ssh config file %q: %v", cmd.filepath, err)
87+
return
8388
}
8489

85-
return
86-
}
90+
entClient := requireAuth()
8791

88-
entClient := requireAuth()
92+
sshAvailable := isSSHAvailable(ctx)
93+
if !sshAvailable {
94+
flog.Fatal("SSH is disabled or not available for your Coder Enterprise deployment.")
95+
}
8996

90-
sshAvailable := cmd.ensureSSHAvailable(ctx)
91-
if !sshAvailable {
92-
flog.Fatal("SSH is disabled or not available for your Coder Enterprise deployment.")
93-
}
97+
me, err := entClient.Me()
98+
if err != nil {
99+
flog.Fatal("failed to fetch username: %v", err)
100+
}
94101

95-
me, err := entClient.Me()
96-
if err != nil {
97-
flog.Fatal("failed to fetch username: %v", err)
98-
}
102+
envs := getEnvs(entClient)
103+
if len(envs) < 1 {
104+
flog.Fatal("no environments found")
105+
}
106+
newConfig, err := makeNewConfigs(me.Username, envs, startToken, startMessage, endToken)
107+
if err != nil {
108+
flog.Fatal("failed to make new ssh configurations: %v", err)
109+
}
99110

100-
envs := getEnvs(entClient)
101-
if len(envs) < 1 {
102-
flog.Fatal("no environments found")
103-
}
104-
newConfig, err := cmd.makeNewConfigs(me.Username, envs)
105-
if err != nil {
106-
flog.Fatal("failed to make new ssh configurations: %v", err)
107-
}
111+
// if we find the old config, remove those chars from the string
112+
if startIndex != -1 && endIndex != -1 {
113+
currentConfig = currentConfig[:startIndex-1] + currentConfig[endIndex+len(endToken)+1:]
114+
}
108115

109-
// if we find the old config, remove those chars from the string
110-
if startIndex != -1 && endIndex != -1 {
111-
currentConfig = currentConfig[:startIndex-1] + currentConfig[endIndex+len(cmd.endToken)+1:]
112-
}
116+
err = writeStr(*filepath, currentConfig+newConfig)
117+
if err != nil {
118+
flog.Fatal("failed to write new configurations to ssh config file %q: %v", filepath, err)
119+
}
120+
err = writeSSHKey(ctx, entClient)
121+
if err != nil {
122+
flog.Fatal("failed to fetch and write ssh key: %v", err)
123+
}
113124

114-
err = writeStr(cmd.filepath, currentConfig+newConfig)
115-
if err != nil {
116-
flog.Fatal("failed to write new configurations to ssh config file %q: %v", cmd.filepath, err)
117-
}
118-
err = writeSSHKey(ctx, entClient)
119-
if err != nil {
120-
flog.Fatal("failed to fetch and write ssh key: %v", err)
125+
fmt.Printf("An auto-generated ssh config was written to %q\n", filepath)
126+
fmt.Printf("Your private ssh key was written to %q\n", privateKeyFilepath)
127+
fmt.Println("You should now be able to ssh into your environment")
128+
fmt.Printf("For example, try running\n\n\t$ ssh coder.%s\n\n", envs[0].Name)
121129
}
122-
123-
fmt.Printf("An auto-generated ssh config was written to %q\n", cmd.filepath)
124-
fmt.Printf("Your private ssh key was written to %q\n", privateKeyFilepath)
125-
fmt.Println("You should now be able to ssh into your environment")
126-
fmt.Printf("For example, try running\n\n\t$ ssh coder.%s\n\n", envs[0].Name)
127130
}
128131

132+
var (
133+
privateKeyFilepath = filepath.Join(os.Getenv("HOME"), ".ssh", "coder_enterprise")
134+
)
135+
129136
func writeSSHKey(ctx context.Context, client *entclient.Client) error {
130137
key, err := client.SSHKey()
131138
if err != nil {
132139
return err
133140
}
134-
err = ioutil.WriteFile(privateKeyFilepath, []byte(key.PrivateKey), 0400)
135-
if err != nil {
136-
return err
137-
}
138-
return nil
141+
return ioutil.WriteFile(privateKeyFilepath, []byte(key.PrivateKey), 0400)
139142
}
140143

141-
func (cmd *configSSHCmd) makeNewConfigs(userName string, envs []entclient.Environment) (string, error) {
144+
func makeNewConfigs(userName string, envs []entclient.Environment, startToken, startMsg, endToken string) (string, error) {
142145
hostname, err := configuredHostname()
143146
if err != nil {
144147
return "", nil
145148
}
146149

147-
newConfig := fmt.Sprintf("\n%s\n%s\n\n", cmd.startToken, cmd.startMessage)
150+
newConfig := fmt.Sprintf("\n%s\n%s\n\n", startToken, startMsg)
148151
for _, env := range envs {
149-
newConfig += cmd.makeConfig(hostname, userName, env.Name)
152+
newConfig += makeSSHConfig(hostname, userName, env.Name)
150153
}
151-
newConfig += fmt.Sprintf("\n%s\n", cmd.endToken)
154+
newConfig += fmt.Sprintf("\n%s\n", endToken)
152155

153156
return newConfig, nil
154157
}
155158

156-
func (cmd *configSSHCmd) makeConfig(host, userName, envName string) string {
159+
func makeSSHConfig(host, userName, envName string) string {
157160
return fmt.Sprintf(
158161
`Host coder.%s
159-
HostName %s
160-
User %s-%s
161-
StrictHostKeyChecking no
162-
ConnectTimeout=0
163-
IdentityFile=%s
164-
ServerAliveInterval 60
165-
ServerAliveCountMax 3
162+
HostName %s
163+
User %s-%s
164+
StrictHostKeyChecking no
165+
ConnectTimeout=0
166+
IdentityFile=%s
167+
ServerAliveInterval 60
168+
ServerAliveCountMax 3
166169
`, envName, host, userName, envName, privateKeyFilepath)
167170
}
168171

169-
func (cmd *configSSHCmd) ensureSSHAvailable(ctx context.Context) bool {
172+
func isSSHAvailable(ctx context.Context) bool {
170173
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
171174
defer cancel()
172175

cmd/coder/login.go

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,28 @@ import (
77
"strings"
88
"sync"
99

10+
"cdr.dev/coder-cli/internal/config"
11+
"cdr.dev/coder-cli/internal/loginsrv"
1012
"github.com/pkg/browser"
11-
"github.com/spf13/pflag"
13+
"github.com/urfave/cli"
1214

13-
"go.coder.com/cli"
1415
"go.coder.com/flog"
15-
16-
"cdr.dev/coder-cli/internal/config"
17-
"cdr.dev/coder-cli/internal/loginsrv"
1816
)
1917

20-
type loginCmd struct {
21-
}
22-
23-
func (cmd loginCmd) Spec() cli.CommandSpec {
24-
return cli.CommandSpec{
25-
Name: "login",
26-
Usage: "[Coder Enterprise URL eg. http://my.coder.domain/ ]",
27-
Desc: "authenticate this client for future operations",
18+
func makeLoginCmd() cli.Command {
19+
cmd := cli.Command{
20+
Name: "login",
21+
Usage: "[Coder Enterprise URL eg. http://my.coder.domain/ ]",
22+
Description: "authenticate this client for future operations",
23+
Action: login,
2824
}
25+
return cmd
2926
}
30-
func (cmd loginCmd) Run(fl *pflag.FlagSet) {
31-
rawURL := fl.Arg(0)
27+
28+
func login(c *cli.Context) {
29+
rawURL := c.Args().First()
3230
if rawURL == "" || !strings.HasPrefix(rawURL, "http") {
33-
exitUsage(fl)
31+
flog.Fatal("invalid URL")
3432
}
3533

3634
u, err := url.Parse(rawURL)

cmd/coder/logout.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,22 @@ package main
33
import (
44
"os"
55

6-
"github.com/spf13/pflag"
6+
"cdr.dev/coder-cli/internal/config"
7+
"github.com/urfave/cli"
78

8-
"go.coder.com/cli"
99
"go.coder.com/flog"
10-
11-
"cdr.dev/coder-cli/internal/config"
1210
)
1311

14-
type logoutCmd struct {
15-
}
16-
17-
func (cmd logoutCmd) Spec() cli.CommandSpec {
18-
return cli.CommandSpec{
12+
func makeLogoutCmd() cli.Command {
13+
return cli.Command{
1914
Name: "logout",
20-
Desc: "remove local authentication credentials (if any)",
15+
//Usage: "",
16+
Description: "remove local authentication credentials (if any)",
17+
Action: logout,
2118
}
2219
}
2320

24-
func (cmd logoutCmd) Run(_ *pflag.FlagSet) {
21+
func logout(c *cli.Context) {
2522
err := config.Session.Delete()
2623
if err != nil {
2724
if os.IsNotExist(err) {

0 commit comments

Comments
 (0)