-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathresource_server.go
192 lines (161 loc) · 5.7 KB
/
resource_server.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
package main
import (
"bytes"
"encoding/json"
"fmt"
"github.com/hashicorp/terraform/helper/schema"
"io/ioutil"
"log"
"net/http"
"os"
"time"
)
const api string = "https://app.scaleft.com/v1/teams/"
func resourceServer() *schema.Resource {
return &schema.Resource{
Create: resourceServerCreate,
Read: resourceServerRead,
Update: resourceServerUpdate,
Delete: resourceServerDelete,
Schema: map[string]*schema.Schema{
"hostname": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
},
}
}
func resourceServerCreate(d *schema.ResourceData, m interface{}) error {
hostname := d.Get("hostname").(string)
d.SetId(hostname + "_scaleft")
return nil
}
func resourceServerRead(d *schema.ResourceData, m interface{}) error {
return nil
}
func resourceServerUpdate(d *schema.ResourceData, m interface{}) error {
return nil
}
func resourceServerDelete(d *schema.ResourceData, m interface{}) error {
key_id := os.Getenv("SCALEFT_KEY_ID")
key_secret := os.Getenv("SCALEFT_KEY_SECRET")
key_team := os.Getenv("SCALEFT_TEAM")
project := os.Getenv("SCALEFT_PROJECT")
hostname := d.Get("hostname").(string)
log.Printf("[DEBUG] key_id:%s key_secret:%s key_team:%s project:%s hostname:%s", key_id, key_secret, key_team, project, hostname)
bearer, err := get_token(key_id, key_secret, key_team)
if err != nil {
return fmt.Errorf("Error getting token key_id:%s key_team:%s error:%v", key_id, key_team, err)
}
list, err := get_servers(bearer, key_team, project)
if err != nil {
return fmt.Errorf("Error getting server list. key_team:%s error:%v", key_team, err)
}
ids := get_ids_for_hostname(hostname, list)
if len(ids) == 0 {
// return fmt.Errorf("Error, ScaleFT api returned no servers that matched hostname:%s", hostname)
// This should not happen, but if it does, it's ok?
log.Printf("[WARN] No servers matched for Hostname:%s, Team:%s, Project:%s. We'll keep going though.", hostname, key_team, project)
return nil
}
for _, id := range ids {
err := delete_server(bearer, key_team, project, id)
if err != nil {
log.Printf("[WARN] Failed to delete server with hostname: %s at ScaleFT ID:%s, error:%s", hostname, id, err)
// return fmt.Errorf("Error deleting server at id:%s and key_team:%s project: %s error:%v", id, key_team, project, err)
}
}
return nil
}
type Body struct {
Key_id string `json:"key_id"`
Key_secret string `json:"key_secret"`
}
type Bearer struct {
Bearer_token string `json:"bearer_token"`
}
type Server struct {
Id string `json:"id"`
ProjectName string `json:"project_name"`
Hostname string `json:"hostname"`
AltNames []string `json:"alt_names"`
AccessAddress string `json:"access_address"`
OS string `json:"os"`
RegisteredAt time.Time `json:"registered_at"`
LastSeen time.Time `json:"last_seen"`
CloudProvider string `json:"cloud_provider"`
SSHHostKeys []string `json:"ssh_host_keys"`
BrokerHostCerts []string `json:"broker_host_certs"`
InstanceDetails map[string]interface{} `json:"instance_details"`
State string `json:"state"`
}
type Servers struct {
List []*Server `json:"list"`
}
func get_token(key_id string, key_secret string, key_team string) (string, error) {
p := &Body{key_id, key_secret}
jsonStr, err := json.Marshal(p)
url := api + key_team + "/service_token"
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "error", fmt.Errorf("Error getting token key_id:%s key_team:%s status:%s error:%v", key_id, key_team, string(resp.Status), err)
}
defer resp.Body.Close()
b := Bearer{}
json.NewDecoder(resp.Body).Decode(&b)
return b.Bearer_token, err
}
func get_logs(bearer_token string, key_team string) string {
client := &http.Client{}
url := api + key_team + "/audits"
req, err := http.NewRequest("GET", url, nil)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+bearer_token)
resp, err := client.Do(req)
if err != nil {
panic(err)
}
bodyText, err := ioutil.ReadAll(resp.Body)
s := string(bodyText)
return s
}
func get_servers(bearer_token string, key_team string, project string) (Servers, error) {
client := &http.Client{}
url := api + key_team + "/projects/" + project + "/servers"
req, err := http.NewRequest("GET", url, nil)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+bearer_token)
resp, err := client.Do(req)
if err != nil {
fmt.Errorf("Error listing servers: key_team:%s project: %s status:%s error:%v", key_team, project, string(resp.Status), err)
}
s := struct {
List []*Server `json:"list"`
}{nil}
json.NewDecoder(resp.Body).Decode(&s)
return s, err
}
func delete_server(bearer_token string, key_team string, project string, server_id string) error {
client := &http.Client{}
url := api + key_team + "/projects/" + project + "/servers/" + server_id
req, err := http.NewRequest("DELETE", url, nil)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+bearer_token)
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("Error deleting server:%s status:%s error:%v", server_id, string(resp.Status), err)
}
return nil
}
func get_ids_for_hostname(hostname string, server_list Servers) []string {
filtered := make([]string, len(server_list.List))
for i, l := range server_list.List {
if hostname == l.Hostname {
filtered[i] = l.Id
}
}
return filtered
}