terraform/vendor/github.com/1and1/oneandone-cloudserver-sdk-go/servers.go

809 lines
23 KiB
Go

package oneandone
import (
"encoding/json"
"errors"
"math/big"
"net/http"
)
type Server struct {
ApiPtr
Identity
descField
CloudPanelId string `json:"cloudpanel_id,omitempty"`
CreationDate string `json:"creation_date,omitempty"`
FirstPassword string `json:"first_password,omitempty"`
Datacenter *Datacenter `json:"datacenter,omitempty"`
Status *Status `json:"status,omitempty"`
Hardware *Hardware `json:"hardware,omitempty"`
Image *Identity `json:"image,omitempty"`
Dvd *Identity `json:"dvd,omitempty"`
MonPolicy *Identity `json:"monitoring_policy,omitempty"`
Snapshot *ServerSnapshot `json:"snapshot,omitempty"`
Ips []ServerIp `json:"ips,omitempty"`
PrivateNets []Identity `json:"private_networks,omitempty"`
Alerts *ServerAlerts `json:"-"`
AlertsRaw *json.RawMessage `json:"alerts,omitempty"`
}
type Hardware struct {
Vcores int `json:"vcore,omitempty"`
CoresPerProcessor int `json:"cores_per_processor"`
Ram float32 `json:"ram"`
Hdds []Hdd `json:"hdds,omitempty"`
FixedInsSizeId string `json:"fixed_instance_size_id,omitempty"`
ApiPtr
}
type ServerHdds struct {
Hdds []Hdd `json:"hdds,omitempty"`
}
type Hdd struct {
idField
Size int `json:"size,omitempty"`
IsMain bool `json:"is_main,omitempty"`
ApiPtr
}
type serverDeployImage struct {
idField
Password string `json:"password,omitempty"`
Firewall *Identity `json:"firewall_policy,omitempty"`
}
type ServerIp struct {
idField
typeField
Ip string `json:"ip,omitempty"`
ReverseDns string `json:"reverse_dns,omitempty"`
Firewall *Identity `json:"firewall_policy,omitempty"`
LoadBalancers []Identity `json:"load_balancers,omitempty"`
ApiPtr
}
type ServerIpInfo struct {
idField // IP id
Ip string `json:"ip,omitempty"`
ServerName string `json:"server_name,omitempty"`
}
type ServerSnapshot struct {
idField
CreationDate string `json:"creation_date,omitempty"`
DeletionDate string `json:"deletion_date,omitempty"`
}
type ServerAlerts struct {
AlertSummary []serverAlertSummary
AlertDetails *serverAlertDetails
}
type serverAlertSummary struct {
countField
typeField
}
type serverAlertDetails struct {
Criticals []ServerAlert `json:"critical,omitempty"`
Warnings []ServerAlert `json:"warning,omitempty"`
}
type ServerAlert struct {
typeField
descField
Date string `json:"date"`
}
type ServerRequest struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Hardware Hardware `json:"hardware"`
ApplianceId string `json:"appliance_id,omitempty"`
Password string `json:"password,omitempty"`
PowerOn bool `json:"power_on"`
FirewallPolicyId string `json:"firewall_policy_id,omitempty"`
IpId string `json:"ip_id,omitempty"`
LoadBalancerId string `json:"load_balancer_id,omitempty"`
MonitoringPolicyId string `json:"monitoring_policy_id,omitempty"`
DatacenterId string `json:"datacenter_id,omitempty"`
SSHKey string `json:"rsa_key,omitempty"`
}
type ServerAction struct {
Action string `json:"action,omitempty"`
Method string `json:"method,omitempty"`
}
type FixedInstanceInfo struct {
Identity
Hardware *Hardware `json:"hardware,omitempty"`
ApiPtr
}
// GET /servers
func (api *API) ListServers(args ...interface{}) ([]Server, error) {
url, err := processQueryParams(createUrl(api, serverPathSegment), args...)
if err != nil {
return nil, err
}
result := []Server{}
err = api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
for _, s := range result {
s.api = api
s.decodeRaws()
}
return result, nil
}
// POST /servers
func (api *API) CreateServer(request *ServerRequest) (string, *Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment)
insert2map := func(hasht map[string]interface{}, key string, value string) {
if key != "" && value != "" {
hasht[key] = value
}
}
req := make(map[string]interface{})
hw := make(map[string]interface{})
req["name"] = request.Name
req["description"] = request.Description
req["appliance_id"] = request.ApplianceId
req["power_on"] = request.PowerOn
insert2map(req, "password", request.Password)
insert2map(req, "firewall_policy_id", request.FirewallPolicyId)
insert2map(req, "ip_id", request.IpId)
insert2map(req, "load_balancer_id", request.LoadBalancerId)
insert2map(req, "monitoring_policy_id", request.MonitoringPolicyId)
insert2map(req, "datacenter_id", request.DatacenterId)
insert2map(req, "rsa_key", request.SSHKey)
req["hardware"] = hw
if request.Hardware.FixedInsSizeId != "" {
hw["fixed_instance_size_id"] = request.Hardware.FixedInsSizeId
} else {
hw["vcore"] = request.Hardware.Vcores
hw["cores_per_processor"] = request.Hardware.CoresPerProcessor
hw["ram"] = request.Hardware.Ram
hw["hdds"] = request.Hardware.Hdds
}
err := api.Client.Post(url, &req, &result, http.StatusAccepted)
if err != nil {
return "", nil, err
}
result.api = api
result.decodeRaws()
return result.Id, result, nil
}
// This is a wraper function for `CreateServer` that returns the server's IP address and first password.
// The function waits at most `timeout` seconds for the server to be created.
// The initial `POST /servers` response does not contain the IP address, so we need to wait
// until the server is created.
func (api *API) CreateServerEx(request *ServerRequest, timeout int) (string, string, error) {
id, server, err := api.CreateServer(request)
if server != nil && err == nil {
count := timeout / 5
if request.PowerOn {
err = api.WaitForState(server, "POWERED_ON", 5, count)
} else {
err = api.WaitForState(server, "POWERED_OFF", 5, count)
}
if err != nil {
return "", "", err
}
server, err := api.GetServer(id)
if server != nil && err == nil && server.Ips[0].Ip != "" {
if server.FirstPassword != "" {
return server.Ips[0].Ip, server.FirstPassword, nil
}
if request.Password != "" {
return server.Ips[0].Ip, request.Password, nil
}
// should never reach here
return "", "", errors.New("No server's password was found.")
}
}
return "", "", err
}
// GET /servers/{id}
func (api *API) GetServer(server_id string) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id)
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/fixed_instance_sizes
func (api *API) ListFixedInstanceSizes() ([]FixedInstanceInfo, error) {
result := []FixedInstanceInfo{}
url := createUrl(api, serverPathSegment, "fixed_instance_sizes")
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
for index, _ := range result {
result[index].api = api
}
return result, nil
}
// GET /servers/fixed_instance_sizes/{fixed_instance_size_id}
func (api *API) GetFixedInstanceSize(fis_id string) (*FixedInstanceInfo, error) {
result := new(FixedInstanceInfo)
url := createUrl(api, serverPathSegment, "fixed_instance_sizes", fis_id)
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
result.api = api
return result, nil
}
// DELETE /servers/{id}
func (api *API) DeleteServer(server_id string, keep_ips bool) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id)
pm := make(map[string]interface{}, 1)
pm["keep_ips"] = keep_ips
url = appendQueryParams(url, pm)
err := api.Client.Delete(url, nil, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// PUT /servers/{id}
func (api *API) RenameServer(server_id string, new_name string, new_desc string) (*Server, error) {
data := struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
}{Name: new_name, Description: new_desc}
result := new(Server)
url := createUrl(api, serverPathSegment, server_id)
err := api.Client.Put(url, &data, &result, http.StatusOK)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{server_id}/hardware
func (api *API) GetServerHardware(server_id string) (*Hardware, error) {
result := new(Hardware)
url := createUrl(api, serverPathSegment, server_id, "hardware")
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
result.api = api
return result, nil
}
// PUT /servers/{server_id}/hardware
func (api *API) UpdateServerHardware(server_id string, hardware *Hardware) (*Server, error) {
var vc, cpp *int
var ram *float32
if hardware.Vcores > 0 {
vc = new(int)
*vc = hardware.Vcores
}
if hardware.CoresPerProcessor > 0 {
cpp = new(int)
*cpp = hardware.CoresPerProcessor
}
if big.NewFloat(float64(hardware.Ram)).Cmp(big.NewFloat(0)) != 0 {
ram = new(float32)
*ram = hardware.Ram
}
req := struct {
VCores *int `json:"vcore,omitempty"`
Cpp *int `json:"cores_per_processor,omitempty"`
Ram *float32 `json:"ram,omitempty"`
Flavor string `json:"fixed_instance_size_id,omitempty"`
}{VCores: vc, Cpp: cpp, Ram: ram, Flavor: hardware.FixedInsSizeId}
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "hardware")
err := api.Client.Put(url, &req, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{id}/hardware/hdds
func (api *API) ListServerHdds(server_id string) ([]Hdd, error) {
result := []Hdd{}
url := createUrl(api, serverPathSegment, server_id, "hardware/hdds")
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
for index, _ := range result {
result[index].api = api
}
return result, nil
}
// POST /servers/{id}/hardware/hdds
func (api *API) AddServerHdds(server_id string, hdds *ServerHdds) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "hardware/hdds")
err := api.Client.Post(url, &hdds, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{id}/hardware/hdds/{id}
func (api *API) GetServerHdd(server_id string, hdd_id string) (*Hdd, error) {
result := new(Hdd)
url := createUrl(api, serverPathSegment, server_id, "hardware/hdds", hdd_id)
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
result.api = api
return result, nil
}
// DELETE /servers/{id}/hardware/hdds/{id}
func (api *API) DeleteServerHdd(server_id string, hdd_id string) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "hardware/hdds", hdd_id)
err := api.Client.Delete(url, nil, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// PUT /servers/{id}/hardware/hdds/{id}
func (api *API) ResizeServerHdd(server_id string, hdd_id string, new_size int) (*Server, error) {
data := Hdd{Size: new_size}
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "hardware/hdds", hdd_id)
err := api.Client.Put(url, &data, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{id}/image
func (api *API) GetServerImage(server_id string) (*Identity, error) {
result := new(Identity)
url := createUrl(api, serverPathSegment, server_id, "image")
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
return result, nil
}
// PUT /servers/{id}/image
func (api *API) ReinstallServerImage(server_id string, image_id string, password string, fp_id string) (*Server, error) {
data := new(serverDeployImage)
data.Id = image_id
data.Password = password
if fp_id != "" {
fp := new(Identity)
fp.Id = fp_id
data.Firewall = fp
}
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "image")
err := api.Client.Put(url, &data, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{id}/ips
func (api *API) ListServerIps(server_id string) ([]ServerIp, error) {
result := []ServerIp{}
url := createUrl(api, serverPathSegment, server_id, "ips")
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
for index, _ := range result {
result[index].api = api
}
return result, nil
}
// POST /servers/{id}/ips
func (api *API) AssignServerIp(server_id string, ip_type string) (*Server, error) {
data := typeField{Type: ip_type}
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "ips")
err := api.Client.Post(url, &data, &result, http.StatusCreated)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{id}/ips/{id}
func (api *API) GetServerIp(server_id string, ip_id string) (*ServerIp, error) {
result := new(ServerIp)
url := createUrl(api, serverPathSegment, server_id, "ips", ip_id)
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
result.api = api
return result, nil
}
// DELETE /servers/{id}/ips/{id}
func (api *API) DeleteServerIp(server_id string, ip_id string, keep_ip bool) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "ips", ip_id)
qm := make(map[string]interface{}, 1)
qm["keep_ip"] = keep_ip
url = appendQueryParams(url, qm)
err := api.Client.Delete(url, nil, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
return result, nil
}
// GET /servers/{id}/status
func (api *API) GetServerStatus(server_id string) (*Status, error) {
result := new(Status)
url := createUrl(api, serverPathSegment, server_id, "status")
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
return result, nil
}
// PUT /servers/{id}/status/action (action = REBOOT)
func (api *API) RebootServer(server_id string, is_hardware bool) (*Server, error) {
result := new(Server)
request := ServerAction{}
request.Action = "REBOOT"
if is_hardware {
request.Method = "HARDWARE"
} else {
request.Method = "SOFTWARE"
}
url := createUrl(api, serverPathSegment, server_id, "status", "action")
err := api.Client.Put(url, &request, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// PUT /servers/{id}/status/action (action = POWER_OFF)
func (api *API) ShutdownServer(server_id string, is_hardware bool) (*Server, error) {
result := new(Server)
request := ServerAction{}
request.Action = "POWER_OFF"
if is_hardware {
request.Method = "HARDWARE"
} else {
request.Method = "SOFTWARE"
}
url := createUrl(api, serverPathSegment, server_id, "status", "action")
err := api.Client.Put(url, &request, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// PUT /servers/{id}/status/action (action = POWER_ON)
func (api *API) StartServer(server_id string) (*Server, error) {
result := new(Server)
request := ServerAction{}
request.Action = "POWER_ON"
url := createUrl(api, serverPathSegment, server_id, "status", "action")
err := api.Client.Put(url, &request, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{id}/dvd
func (api *API) GetServerDvd(server_id string) (*Identity, error) {
result := new(Identity)
url := createUrl(api, serverPathSegment, server_id, "dvd")
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
return result, nil
}
// DELETE /servers/{id}/dvd
func (api *API) EjectServerDvd(server_id string) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "dvd")
err := api.Client.Delete(url, nil, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// PUT /servers/{id}/dvd
func (api *API) LoadServerDvd(server_id string, dvd_id string) (*Server, error) {
request := Identity{}
request.Id = dvd_id
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "dvd")
err := api.Client.Put(url, &request, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{id}/private_networks
func (api *API) ListServerPrivateNetworks(server_id string) ([]Identity, error) {
result := []Identity{}
url := createUrl(api, serverPathSegment, server_id, "private_networks")
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
return result, nil
}
// POST /servers/{id}/private_networks
func (api *API) AssignServerPrivateNetwork(server_id string, pn_id string) (*Server, error) {
req := new(Identity)
req.Id = pn_id
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "private_networks")
err := api.Client.Post(url, &req, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{id}/private_networks/{id}
func (api *API) GetServerPrivateNetwork(server_id string, pn_id string) (*PrivateNetwork, error) {
result := new(PrivateNetwork)
url := createUrl(api, serverPathSegment, server_id, "private_networks", pn_id)
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
result.api = api
return result, nil
}
// DELETE /servers/{id}/private_networks/{id}
func (api *API) RemoveServerPrivateNetwork(server_id string, pn_id string) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "private_networks", pn_id)
err := api.Client.Delete(url, nil, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{server_id}/ips/{ip_id}/load_balancers
func (api *API) ListServerIpLoadBalancers(server_id string, ip_id string) ([]Identity, error) {
result := []Identity{}
url := createUrl(api, serverPathSegment, server_id, "ips", ip_id, "load_balancers")
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
return result, nil
}
// POST /servers/{server_id}/ips/{ip_id}/load_balancers
func (api *API) AssignServerIpLoadBalancer(server_id string, ip_id string, lb_id string) (*Server, error) {
req := struct {
LbId string `json:"load_balancer_id"`
}{lb_id}
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "ips", ip_id, "load_balancers")
err := api.Client.Post(url, &req, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// DELETE /servers/{server_id}/ips/{ip_id}/load_balancers
func (api *API) UnassignServerIpLoadBalancer(server_id string, ip_id string, lb_id string) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "ips", ip_id, "load_balancers", lb_id)
err := api.Client.Delete(url, nil, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{server_id}/ips/{ip_id}/firewall_policy
func (api *API) GetServerIpFirewallPolicy(server_id string, ip_id string) (*Identity, error) {
result := new(Identity)
url := createUrl(api, serverPathSegment, server_id, "ips", ip_id, "firewall_policy")
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
return result, nil
}
// PUT /servers/{server_id}/ips/{ip_id}/firewall_policy
func (api *API) AssignServerIpFirewallPolicy(server_id string, ip_id string, fp_id string) (*Server, error) {
req := idField{fp_id}
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "ips", ip_id, "firewall_policy")
err := api.Client.Put(url, &req, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// DELETE /servers/{server_id}/ips/{ip_id}/firewall_policy
func (api *API) UnassignServerIpFirewallPolicy(server_id string, ip_id string) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "ips", ip_id, "firewall_policy")
err := api.Client.Delete(url, nil, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// GET /servers/{id}/snapshots
func (api *API) GetServerSnapshot(server_id string) (*ServerSnapshot, error) {
result := new(ServerSnapshot)
url := createUrl(api, serverPathSegment, server_id, "snapshots")
err := api.Client.Get(url, &result, http.StatusOK)
if err != nil {
return nil, err
}
return result, nil
}
// POST /servers/{id}/snapshots
func (api *API) CreateServerSnapshot(server_id string) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "snapshots")
err := api.Client.Post(url, nil, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// PUT /servers/{server_id}/snapshots/{snapshot_id}
func (api *API) RestoreServerSnapshot(server_id string, snapshot_id string) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "snapshots", snapshot_id)
err := api.Client.Put(url, nil, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// DELETE /servers/{server_id}/snapshots/{snapshot_id}
func (api *API) DeleteServerSnapshot(server_id string, snapshot_id string) (*Server, error) {
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "snapshots", snapshot_id)
err := api.Client.Delete(url, nil, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
// POST /servers/{server_id}/clone
func (api *API) CloneServer(server_id string, new_name string, datacenter_id string) (*Server, error) {
data := struct {
Name string `json:"name"`
DatacenterId string `json:"datacenter_id,omitempty"`
}{Name: new_name, DatacenterId: datacenter_id}
result := new(Server)
url := createUrl(api, serverPathSegment, server_id, "clone")
err := api.Client.Post(url, &data, &result, http.StatusAccepted)
if err != nil {
return nil, err
}
result.api = api
result.decodeRaws()
return result, nil
}
func (s *Server) GetState() (string, error) {
st, err := s.api.GetServerStatus(s.Id)
if st == nil {
return "", err
}
return st.State, err
}
func (server *Server) decodeRaws() {
if server.AlertsRaw != nil {
server.Alerts = new(ServerAlerts)
var sad serverAlertDetails
if err := json.Unmarshal(*server.AlertsRaw, &sad); err == nil {
server.Alerts.AlertDetails = &sad
return
}
var sams []serverAlertSummary
if err := json.Unmarshal(*server.AlertsRaw, &sams); err == nil {
server.Alerts.AlertSummary = sams
}
}
}