func (c *Client) DetachISOfromServer(id string) error {
	values := url.Values{
		"SUBID": {id},
	}
	if err := c.post(`server/iso_detach`, values, nil); err != nil {
		return err
	}
	return nil
}
DetachISOfromServer detaches the currently mounted ISO image from the virtual machine and reboots it
package lib
import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"net/url"
	"sort"
	"strconv"
	"strings"
)
type Server struct {
	ID               string      `json:"SUBID"`
	Name             string      `json:"label"`
	OS               string      `json:"os"`
	RAM              string      `json:"ram"`
	Disk             string      `json:"disk"`
	MainIP           string      `json:"main_ip"`
	VCpus            int         `json:"vcpu_count,string"`
	Location         string      `json:"location"`
	RegionID         int         `json:"DCID,string"`
	DefaultPassword  string      `json:"default_password"`
	Created          string      `json:"date_created"`
	PendingCharges   float64     `json:"pending_charges"`
	Status           string      `json:"status"`
	Cost             string      `json:"cost_per_month"`
	CurrentBandwidth float64     `json:"current_bandwidth_gb"`
	AllowedBandwidth float64     `json:"allowed_bandwidth_gb,string"`
	NetmaskV4        string      `json:"netmask_v4"`
	GatewayV4        string      `json:"gateway_v4"`
	PowerStatus      string      `json:"power_status"`
	ServerState      string      `json:"server_state"`
	PlanID           int         `json:"VPSPLANID,string"`
	V6Networks       []V6Network `json:"v6_networks"`
	InternalIP       string      `json:"internal_ip"`
	KVMUrl           string      `json:"kvm_url"`
	AutoBackups      string      `json:"auto_backups"`
	Tag              string      `json:"tag"`
	OSID             string      `json:"OSID"`
	AppID            string      `json:"APPID"`
	FirewallGroupID  string      `json:"FIREWALLGROUPID"`
}
type ServerOptions struct {
	IPXEChainURL         string
	ISO                  int
	Script               int
	UserData             string
	Snapshot             string
	SSHKey               string
	ReservedIP           string
	IPV6                 bool
	Networks             []string
	PrivateNetworking    bool
	AutoBackups          bool
	DontNotifyOnActivate bool
	Hostname             string
	Tag                  string
	AppID                string
	FirewallGroupID      string
}
type servers []Server
func (s servers) Len() int      { return len(s) }
func (s servers) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s servers) Less(i, j int) bool {
	if strings.ToLower(s[i].Name) < strings.ToLower(s[j].Name) {
		return true
	} else if strings.ToLower(s[i].Name) > strings.ToLower(s[j].Name) {
		return false
	}
	return s[i].MainIP < s[j].MainIP
}
type AppInfo struct {
	Info string `json:"app_info"`
}
type V6Network struct {
	Network     string `json:"v6_network"`
	MainIP      string `json:"v6_main_ip"`
	NetworkSize string `json:"v6_network_size"`
}
type ISOStatus struct {
	State string `json:"state"`
	ISOID string `json:"ISOID"`
}
func (s *Server) UnmarshalJSON(data []byte) (err error) {
	if s == nil {
		*s = Server{}
	}
	var fields map[string]interface{}
	if err := json.Unmarshal(data, &fields); err != nil {
		return err
	}
	value := fmt.Sprintf("%v", fields["vcpu_count"])
	if len(value) == 0 || value == "<nil>" {
		value = "0"
	}
	vcpu, err := strconv.ParseInt(value, 10, 64)
	if err != nil {
		return err
	}
	s.VCpus = int(vcpu)
	value = fmt.Sprintf("%v", fields["DCID"])
	if len(value) == 0 || value == "<nil>" {
		value = "0"
	}
	region, err := strconv.ParseInt(value, 10, 64)
	if err != nil {
		return err
	}
	s.RegionID = int(region)
	value = fmt.Sprintf("%v", fields["VPSPLANID"])
	if len(value) == 0 || value == "<nil>" {
		value = "0"
	}
	plan, err := strconv.ParseInt(value, 10, 64)
	if err != nil {
		return err
	}
	s.PlanID = int(plan)
	value = fmt.Sprintf("%v", fields["pending_charges"])
	if len(value) == 0 || value == "<nil>" {
		value = "0"
	}
	pc, err := strconv.ParseFloat(value, 64)
	if err != nil {
		return err
	}
	s.PendingCharges = pc
	value = fmt.Sprintf("%v", fields["current_bandwidth_gb"])
	if len(value) == 0 || value == "<nil>" {
		value = "0"
	}
	cb, err := strconv.ParseFloat(value, 64)
	if err != nil {
		return err
	}
	s.CurrentBandwidth = cb
	value = fmt.Sprintf("%v", fields["allowed_bandwidth_gb"])
	if len(value) == 0 || value == "<nil>" {
		value = "0"
	}
	ab, err := strconv.ParseFloat(value, 64)
	if err != nil {
		return err
	}
	s.AllowedBandwidth = ab
	value = fmt.Sprintf("%v", fields["OSID"])
	if value == "<nil>" {
		value = ""
	}
	s.OSID = value
	value = fmt.Sprintf("%v", fields["APPID"])
	if value == "<nil>" || value == "0" {
		value = ""
	}
	s.AppID = value
	value = fmt.Sprintf("%v", fields["FIREWALLGROUPID"])
	if value == "<nil>" || value == "0" {
		value = ""
	}
	s.FirewallGroupID = value
	s.ID = fmt.Sprintf("%v", fields["SUBID"])
	s.Name = fmt.Sprintf("%v", fields["label"])
	s.OS = fmt.Sprintf("%v", fields["os"])
	s.RAM = fmt.Sprintf("%v", fields["ram"])
	s.Disk = fmt.Sprintf("%v", fields["disk"])
	s.MainIP = fmt.Sprintf("%v", fields["main_ip"])
	s.Location = fmt.Sprintf("%v", fields["location"])
	s.DefaultPassword = fmt.Sprintf("%v", fields["default_password"])
	s.Created = fmt.Sprintf("%v", fields["date_created"])
	s.Status = fmt.Sprintf("%v", fields["status"])
	s.Cost = fmt.Sprintf("%v", fields["cost_per_month"])
	s.NetmaskV4 = fmt.Sprintf("%v", fields["netmask_v4"])
	s.GatewayV4 = fmt.Sprintf("%v", fields["gateway_v4"])
	s.PowerStatus = fmt.Sprintf("%v", fields["power_status"])
	s.ServerState = fmt.Sprintf("%v", fields["server_state"])
	v6networks := make([]V6Network, 0)
	if networks, ok := fields["v6_networks"].([]interface{}); ok {
		for _, network := range networks {
			if network, ok := network.(map[string]interface{}); ok {
				v6network := V6Network{
					Network:     fmt.Sprintf("%v", network["v6_network"]),
					MainIP:      fmt.Sprintf("%v", network["v6_main_ip"]),
					NetworkSize: fmt.Sprintf("%v", network["v6_network_size"]),
				}
				v6networks = append(v6networks, v6network)
			}
		}
		s.V6Networks = v6networks
	}
	s.InternalIP = fmt.Sprintf("%v", fields["internal_ip"])
	s.KVMUrl = fmt.Sprintf("%v", fields["kvm_url"])
	s.AutoBackups = fmt.Sprintf("%v", fields["auto_backups"])
	s.Tag = fmt.Sprintf("%v", fields["tag"])
	return
}
func (c *Client) GetServers() (serverList []Server, err error) {
	var serverMap map[string]Server
	if err := c.get(`server/list`, &serverMap); err != nil {
		return nil, err
	}
	for _, server := range serverMap {
		serverList = append(serverList, server)
	}
	sort.Sort(servers(serverList))
	return serverList, nil
}
func (c *Client) GetServersByTag(tag string) (serverList []Server, err error) {
	var serverMap map[string]Server
	if err := c.get(`server/list?tag=`+tag, &serverMap); err != nil {
		return nil, err
	}
	for _, server := range serverMap {
		serverList = append(serverList, server)
	}
	sort.Sort(servers(serverList))
	return serverList, nil
}
func (c *Client) GetServer(id string) (server Server, err error) {
	if err := c.get(`server/list?SUBID=`+id, &server); err != nil {
		return Server{}, err
	}
	return server, nil
}
func (c *Client) CreateServer(name string, regionID, planID, osID int, options *ServerOptions) (Server, error) {
	values := url.Values{
		"label":     {name},
		"DCID":      {fmt.Sprintf("%v", regionID)},
		"VPSPLANID": {fmt.Sprintf("%v", planID)},
		"OSID":      {fmt.Sprintf("%v", osID)},
	}
	if options != nil {
		if options.IPXEChainURL != "" {
			values.Add("ipxe_chain_url", options.IPXEChainURL)
		}
		if options.ISO != 0 {
			values.Add("ISOID", fmt.Sprintf("%v", options.ISO))
		}
		if options.Script != 0 {
			values.Add("SCRIPTID", fmt.Sprintf("%v", options.Script))
		}
		if options.UserData != "" {
			values.Add("userdata", base64.StdEncoding.EncodeToString([]byte(options.UserData)))
		}
		if options.Snapshot != "" {
			values.Add("SNAPSHOTID", options.Snapshot)
		}
		if options.SSHKey != "" {
			values.Add("SSHKEYID", options.SSHKey)
		}
		if options.ReservedIP != "" {
			values.Add("reserved_ip_v4", options.ReservedIP)
		}
		if options.Networks != nil && len(options.Networks) != 0 {
			for _, n := range options.Networks {
				values.Add("NETWORKID[]", n)
			}
		} else {
			values.Add("enable_private_network", "no")
			if options.PrivateNetworking {
				values.Set("enable_private_network", "yes")
			}
		}
		values.Add("enable_ipv6", "no")
		if options.IPV6 {
			values.Set("enable_ipv6", "yes")
		}
		values.Add("auto_backups", "no")
		if options.AutoBackups {
			values.Set("auto_backups", "yes")
		}
		values.Add("notify_activate", "yes")
		if options.DontNotifyOnActivate {
			values.Set("notify_activate", "no")
		}
		if options.Hostname != "" {
			values.Add("hostname", options.Hostname)
		}
		if options.Tag != "" {
			values.Add("tag", options.Tag)
		}
		if options.AppID != "" {
			values.Add("APPID", options.AppID)
		}
		if options.FirewallGroupID != "" {
			values.Add("FIREWALLGROUPID", options.FirewallGroupID)
		}
	}
	var server Server
	if err := c.post(`server/create`, values, &server); err != nil {
		return Server{}, err
	}
	server.Name = name
	server.RegionID = regionID
	server.PlanID = planID
	return server, nil
}
func (c *Client) RenameServer(id, name string) error {
	values := url.Values{
		"SUBID": {id},
		"label": {name},
	}
	if err := c.post(`server/label_set`, values, nil); err != nil {
		return err
	}
	return nil
}
func (c *Client) TagServer(id, tag string) error {
	values := url.Values{
		"SUBID": {id},
		"tag":   {tag},
	}
	if err := c.post(`server/tag_set`, values, nil); err != nil {
		return err
	}
	return nil
}
func (c *Client) StartServer(id string) error {
	values := url.Values{
		"SUBID": {id},
	}
	if err := c.post(`server/start`, values, nil); err != nil {
		return err
	}
	return nil
}
func (c *Client) HaltServer(id string) error {
	values := url.Values{
		"SUBID": {id},
	}
	if err := c.post(`server/halt`, values, nil); err != nil {
		return err
	}
	return nil
}
func (c *Client) RebootServer(id string) error {
	values := url.Values{
		"SUBID": {id},
	}
	if err := c.post(`server/reboot`, values, nil); err != nil {
		return err
	}
	return nil
}
func (c *Client) ReinstallServer(id string) error {
	values := url.Values{
		"SUBID": {id},
	}
	if err := c.post(`server/reinstall`, values, nil); err != nil {
		return err
	}
	return nil
}
func (c *Client) ChangeOSofServer(id string, osID int) error {
	values := url.Values{
		"SUBID": {id},
		"OSID":  {fmt.Sprintf("%v", osID)},
	}
	if err := c.post(`server/os_change`, values, nil); err != nil {
		return err
	}
	return nil
}
func (c *Client) ListOSforServer(id string) (os []OS, err error) {
	var osMap map[string]OS
	if err := c.get(`server/os_change_list?SUBID=`+id, &osMap); err != nil {
		return nil, err
	}
	for _, o := range osMap {
		os = append(os, o)
	}
	sort.Sort(oses(os))
	return os, nil
}
func (c *Client) AttachISOtoServer(id string, isoID int) error {
	values := url.Values{
		"SUBID": {id},
		"ISOID": {fmt.Sprintf("%v", isoID)},
	}
	if err := c.post(`server/iso_attach`, values, nil); err != nil {
		return err
	}
	return nil
}