/
add.go
143 lines (136 loc) · 4.66 KB
/
add.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main
import (
"strings"
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app"
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app/args"
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app/flags"
"github.com/BytemarkHosting/bytemark-client/cmd/bytemark/app/with"
"github.com/BytemarkHosting/bytemark-client/lib/brain"
brainRequests "github.com/BytemarkHosting/bytemark-client/lib/requests/brain"
"github.com/BytemarkHosting/bytemark-client/util/log"
"github.com/urfave/cli"
)
func init() {
commands = append(commands, cli.Command{
Name: "add",
Usage: "add SSH keys to a user / IPs to a server",
UsageText: "add key|ip",
Description: "add SSH keys to a user or IPs to a server",
Action: cli.ShowSubcommandHelp,
Subcommands: []cli.Command{{
Name: "key",
Usage: "add public SSH keys to a Bytemark user",
UsageText: "add key [--user <user>] [--public-key-file <filename>] <key>",
Description: `Add the given public key to the given user (or the default user). This will allow them to use that key to access management IPs they have access to using that key. To remove a key, use the remove key command. --public-key-file will be ignored if a public key is specified in the arguments`,
Flags: []cli.Flag{
cli.StringFlag{
Name: "user",
Usage: "Which user to add the key to. Defaults to the username you log in as.",
},
cli.StringFlag{
Name: "public-key",
Usage: "the text of a public key to add. If set, is used in preference to --public-key-file",
},
cli.GenericFlag{
Name: "public-key-file",
Usage: "The public key file to add to the account",
Value: &flags.FileFlag{},
},
},
Action: app.Action(args.Join("public-key"), with.Auth, func(ctx *app.Context) (err error) {
user := ctx.String("user")
if user == "" {
user = ctx.Config().GetIgnoreErr("user")
}
publicKeyFileContents := flags.FileContents(ctx, "public-key-file")
key := strings.TrimSpace(ctx.String("public-key"))
if key == "" {
if publicKeyFileContents == "" {
return ctx.Help("Please specify a key")
}
key = publicKeyFileContents
} else {
// if public-key is not blank, try to use it as a filename
// FileFlag does some nice ~-substitution which is why we use it rather than the infinitely more normal-looking ioutil.ReadFile
publicKeyFile := flags.FileFlag{FileName: key}
if err = publicKeyFile.Set(key); err == nil {
key = publicKeyFile.Value
}
}
if strings.Contains(key, "PRIVATE KEY") {
return ctx.Help("The key needs to be a public key, not a private key")
}
err = brainRequests.AddUserAuthorizedKey(ctx.Client(), user, key)
if err == nil {
log.Log("Key added successfully")
}
return
}),
}, {
Name: "ips",
Aliases: []string{"ip"},
Usage: "add extra IP addresses to a server",
UsageText: "add ips [--ipv4 | --ipv6] [--ips <number>] <server name>",
Description: `Add an extra IP to the given server. The IP will be chosen by the brain and output to standard out.`,
Flags: []cli.Flag{
cli.BoolFlag{
Name: "ipv4",
Usage: "If set, requests IPv4 addresses. This is the default",
},
cli.BoolFlag{
Name: "ipv6",
Usage: "If set, requests IPv6 addresses.",
},
cli.IntFlag{
Name: "ips",
Usage: "How many IPs to add (1 to 4)",
Value: 1,
},
cli.StringFlag{
Name: "reason",
Usage: "Reason for adding the IP. If not set, will prompt.",
},
cli.GenericFlag{
Name: "server",
Usage: "The server to add IPs to",
Value: new(flags.VirtualMachineNameFlag),
},
},
Action: app.Action(args.Optional("server"), with.RequiredFlags("server"), with.Auth, func(c *app.Context) error {
addrs := c.Int("ips")
if addrs < 1 {
addrs = 1
}
family := "ipv4"
if c.Bool("ipv6") {
if c.Bool("ipv4") {
return c.Help("--ipv4 cannot be specified at the same time as --ipv6")
}
family = "ipv6"
}
reason := c.String("reason")
if reason == "" {
if addrs == 1 {
reason = c.Prompter().Prompt("Enter the purpose for this extra IP: ")
} else {
reason = c.Prompter().Prompt("Enter the purpose for these extra IPs: ")
}
}
ipcr := brain.IPCreateRequest{
Addresses: addrs,
Family: family,
Reason: reason,
Contiguous: c.Bool("contiguous"),
}
vmName := flags.VirtualMachineName(c, "server")
ips, err := c.Client().AddIP(vmName, ipcr)
if err != nil {
return err
}
log.Log("IPs added:")
log.Output(ips.String(), "\r\n")
return nil
}),
}},
})
}