-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathhetzner.go
152 lines (129 loc) · 3.53 KB
/
hetzner.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
144
145
146
147
148
149
150
151
152
package provision
import (
"context"
"fmt"
"github.com/hetznercloud/hcloud-go/hcloud"
"strconv"
)
var Status = "running"
type HetznerProvisioner struct {
client *hcloud.Client
}
// Creates a new Hetzner provisioner using an auth token.
func NewHetznerProvisioner(authToken string) (*HetznerProvisioner, error) {
client := hcloud.NewClient(hcloud.WithToken(authToken))
return &HetznerProvisioner{
client: client,
}, nil
}
// Get status of a specific server by id.
func (p *HetznerProvisioner) Status(id string) (*ProvisionedHost, error) {
intId, err := strconv.Atoi(id)
if err != nil {
return nil, err
}
server, _, err := p.client.Server.GetByID(context.Background(), intId)
if err != nil {
return nil, err
}
if server == nil {
return nil, fmt.Errorf("failed to find server with id %s", id)
}
status := ""
ip := ""
if server.Status == hcloud.ServerStatusRunning {
status = ActiveStatus
ip = server.PublicNet.IPv4.IP.String()
} else {
status = string(server.Status)
}
return &ProvisionedHost{
IP: ip,
ID: id,
Status: status,
}, nil
}
// Provision a new server on Hetzner cloud to use as an inlet node.
func (p *HetznerProvisioner) Provision(host BasicHost) (*ProvisionedHost, error) {
img, _, err := p.client.Image.GetByName(context.Background(), host.OS)
loc, _, err := p.client.Location.GetByName(context.Background(), host.Region)
pln, _, err := p.client.ServerType.GetByName(context.Background(), host.Plan)
if err != nil {
return nil, err
}
server, _, err := p.client.Server.Create(context.Background(), hcloud.ServerCreateOpts{
Name: host.Name,
ServerType: pln,
Image: img,
Location: loc,
UserData: host.UserData,
StartAfterCreate: hcloud.Bool(true),
Labels: map[string]string{
"managed-by": "inlets",
},
})
if err != nil {
return nil, err
}
return &ProvisionedHost{
IP: server.Server.PublicNet.IPv4.IP.String(),
ID: strconv.Itoa(server.Server.ID),
Status: "creating",
}, nil
}
// List all nodes that are managed by inlets.
func (p *HetznerProvisioner) List(filter ListFilter) ([]*ProvisionedHost, error) {
var hosts []*ProvisionedHost
hostList, err := p.client.Server.AllWithOpts(context.Background(), hcloud.ServerListOpts{
// Adding a label to the VPS so that it is easier to select inlets managed servers and also
// to tell the user that the server in question is managed by inlets.
ListOpts: hcloud.ListOpts{
LabelSelector: "managed-by=inlets",
},
})
if err != nil {
return nil, err
}
for _, instance := range hostList {
hosts = append(hosts, &ProvisionedHost{
IP: instance.PublicNet.IPv4.IP.String(),
ID: strconv.Itoa(instance.ID),
Status: string(instance.Status),
})
}
return hosts, nil
}
// Delete a specific server from the Hetzner cloud.
func (p *HetznerProvisioner) Delete(request HostDeleteRequest) error {
id := request.ID
if len(id) <= 0 {
hosts, err := p.List(ListFilter{})
if err != nil {
return err
}
for _, instance := range hosts {
if instance.IP == request.IP {
id = instance.ID
}
}
if len(id) <= 0 {
return fmt.Errorf("failed to find server with id with IP %s", request.IP)
}
}
idAsInt, err := strconv.Atoi(id)
if err != nil {
return err
}
server, _, err := p.client.Server.GetByID(context.Background(), idAsInt)
if err != nil {
return err
}
if server == nil {
return fmt.Errorf("failed to find server with id %s", id)
}
_, err = p.client.Server.Delete(context.Background(), server)
if err != nil {
return err
}
return nil
}