feat: implement capsul create
This commit is contained in:
parent
3e91174ce0
commit
5294e84d5e
|
@ -1,5 +1,3 @@
|
||||||
# The path to our pass credentials store
|
|
||||||
export PASSWORD_STORE_DIR=$(pwd)/../../autonomic/passwords/passwords/
|
export PASSWORD_STORE_DIR=$(pwd)/../../autonomic/passwords/passwords/
|
||||||
|
|
||||||
# The Hetzner Cloud API token for managing our instances
|
|
||||||
export HCLOUD_TOKEN=$(pass show logins/hetzner/cicd/api_key)
|
export HCLOUD_TOKEN=$(pass show logins/hetzner/cicd/api_key)
|
||||||
|
# export CAPSUL_TOKEN=...
|
||||||
|
|
4
TODO.md
4
TODO.md
|
@ -5,11 +5,11 @@
|
||||||
## Feature parity
|
## Feature parity
|
||||||
|
|
||||||
- [ ] Commands
|
- [ ] Commands
|
||||||
- [ ] `abra server`
|
- [x] `abra server`
|
||||||
- [x] `ls`
|
- [x] `ls`
|
||||||
- [x] `add`
|
- [x] `add`
|
||||||
- [ ] `new`
|
- [ ] `new`
|
||||||
- [ ] `capsul`
|
- [x] `capsul`
|
||||||
- [x] `hetzner`
|
- [x] `hetzner`
|
||||||
- [x] `rm`
|
- [x] `rm`
|
||||||
- [x] `init`
|
- [x] `init`
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/formatter"
|
"coopcloud.tech/abra/cli/formatter"
|
||||||
"github.com/hetznercloud/hcloud-go/hcloud"
|
"github.com/hetznercloud/hcloud-go/hcloud"
|
||||||
|
@ -71,7 +77,7 @@ environment variable or otherwise passing the "--env/-e" flag.
|
||||||
}
|
}
|
||||||
|
|
||||||
if hetznerCloudAPIToken == "" {
|
if hetznerCloudAPIToken == "" {
|
||||||
logrus.Fatal("API token is missing, cannot continue")
|
logrus.Fatal("Hetznew Cloud API token is missing, cannot continue")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
@ -111,6 +117,127 @@ environment variable or otherwise passing the "--env/-e" flag.
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var capsulInstance string
|
||||||
|
var capsulType string
|
||||||
|
var capsulImage string
|
||||||
|
var capsulSSHKey string
|
||||||
|
var capsulAPIToken string
|
||||||
|
var serverNewCapsulCommand = &cli.Command{
|
||||||
|
Name: "capsul",
|
||||||
|
Usage: "Create a new Capsul virtual server",
|
||||||
|
ArgsUsage: "<name>",
|
||||||
|
Description: `
|
||||||
|
Create a new Capsul virtual server.
|
||||||
|
|
||||||
|
This command uses the uses the Capsul API bindings of your chosen instance to
|
||||||
|
send a server creation request. You must already have an account on your chosen
|
||||||
|
Capsul instance before using this command.
|
||||||
|
|
||||||
|
Your token can be loaded from the environment using the CAPSUL_TOKEN
|
||||||
|
environment variable or otherwise passing the "--env/-e" flag.
|
||||||
|
`,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "instance",
|
||||||
|
Aliases: []string{"I"},
|
||||||
|
Usage: "Capsul instance",
|
||||||
|
Destination: &capsulInstance,
|
||||||
|
Value: "yolo.servers.coop",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "type",
|
||||||
|
Aliases: []string{"t"},
|
||||||
|
Usage: "Server type",
|
||||||
|
Value: "f1-xs",
|
||||||
|
Destination: &capsulType,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "image",
|
||||||
|
Aliases: []string{"i"},
|
||||||
|
Usage: "Image type",
|
||||||
|
Value: "debian10",
|
||||||
|
Destination: &capsulImage,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "ssh-key",
|
||||||
|
Aliases: []string{"s"},
|
||||||
|
Usage: "SSH key",
|
||||||
|
Value: "",
|
||||||
|
Destination: &capsulSSHKey,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "token",
|
||||||
|
Aliases: []string{"T"},
|
||||||
|
Usage: "Capsul instance API token",
|
||||||
|
EnvVars: []string{"CAPSUL_TOKEN"},
|
||||||
|
Destination: &capsulAPIToken,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(c *cli.Context) error {
|
||||||
|
name := c.Args().First()
|
||||||
|
if name == "" {
|
||||||
|
return cli.ShowSubcommandHelp(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
if capsulAPIToken == "" {
|
||||||
|
logrus.Fatal("Capsul API token is missing, cannot continue")
|
||||||
|
}
|
||||||
|
|
||||||
|
// yep, the response time is quite slow, something to fix Capsul side
|
||||||
|
client := &http.Client{Timeout: 20 * time.Second}
|
||||||
|
|
||||||
|
capsulCreateURL := fmt.Sprintf("https://%s/api/capsul/create", capsulInstance)
|
||||||
|
values := map[string]string{
|
||||||
|
"name": name,
|
||||||
|
"size": capsulType,
|
||||||
|
"os": capsulImage,
|
||||||
|
"ssh_key_0": capsulSSHKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
payload, err := json.Marshal(values)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", capsulCreateURL, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header = http.Header{
|
||||||
|
"Content-Type": []string{"application/json"},
|
||||||
|
"Authorization": []string{capsulAPIToken},
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
logrus.Fatal(string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
type capsulCreateResponse struct{ ID string }
|
||||||
|
var resp capsulCreateResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&resp); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tableColumns := []string{"Name", "ID"}
|
||||||
|
table := formatter.CreateTable(tableColumns)
|
||||||
|
table.Append([]string{name, resp.ID})
|
||||||
|
table.Render()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
var serverNewCommand = &cli.Command{
|
var serverNewCommand = &cli.Command{
|
||||||
Name: "new",
|
Name: "new",
|
||||||
Usage: "Create a new server using a 3rd party provider",
|
Usage: "Create a new server using a 3rd party provider",
|
||||||
|
@ -118,5 +245,6 @@ var serverNewCommand = &cli.Command{
|
||||||
ArgsUsage: "<provider>",
|
ArgsUsage: "<provider>",
|
||||||
Subcommands: []*cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
serverNewHetznerCloudCommand,
|
serverNewHetznerCloudCommand,
|
||||||
|
serverNewCapsulCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue