lego/vendor/github.com/exoscale/egoscale/virtual_machines.go

365 lines
8.8 KiB
Go
Raw Normal View History

package egoscale
import (
"bytes"
"compress/gzip"
"context"
"encoding/base64"
"fmt"
"io/ioutil"
"net"
"net/url"
"github.com/jinzhu/copier"
)
// ResourceType returns the type of the resource
func (*VirtualMachine) ResourceType() string {
return "UserVM"
}
// Get fills the VM
func (vm *VirtualMachine) Get(ctx context.Context, client *Client) error {
if vm.ID == "" && vm.Name == "" && vm.DefaultNic() == nil {
return fmt.Errorf("A VirtualMachine may only be searched using ID, Name or IPAddress")
}
vms, err := client.ListWithContext(ctx, vm)
if err != nil {
return err
}
count := len(vms)
if count == 0 {
return &ErrorResponse{
ErrorCode: ParamError,
ErrorText: fmt.Sprintf("VirtualMachine not found. id: %s, name: %s", vm.ID, vm.Name),
}
} else if count > 1 {
return fmt.Errorf("More than one VirtualMachine was found. Query: id: %s, name: %s", vm.ID, vm.Name)
}
return copier.Copy(vm, vms[0])
}
// Delete destroys the VM
func (vm *VirtualMachine) Delete(ctx context.Context, client *Client) error {
_, err := client.RequestWithContext(ctx, &DestroyVirtualMachine{
ID: vm.ID,
})
return err
}
// ListRequest builds the ListVirtualMachines request
func (vm *VirtualMachine) ListRequest() (ListCommand, error) {
// XXX: AffinityGroupID, SecurityGroupID, Tags
req := &ListVirtualMachines{
Account: vm.Account,
DomainID: vm.DomainID,
GroupID: vm.GroupID,
ID: vm.ID,
Name: vm.Name,
State: vm.State,
TemplateID: vm.TemplateID,
ZoneID: vm.ZoneID,
}
nic := vm.DefaultNic()
if nic != nil {
req.IPAddress = nic.IPAddress
}
return req, nil
}
// DefaultNic returns the default nic
func (vm *VirtualMachine) DefaultNic() *Nic {
for _, nic := range vm.Nic {
if nic.IsDefault {
return &nic
}
}
return nil
}
// IP returns the default nic IP address
func (vm *VirtualMachine) IP() *net.IP {
nic := vm.DefaultNic()
if nic != nil {
ip := nic.IPAddress
return &ip
}
return nil
}
// NicsByType returns the corresponding interfaces base on the given type
func (vm *VirtualMachine) NicsByType(nicType string) []Nic {
nics := make([]Nic, 0)
for _, nic := range vm.Nic {
if nic.Type == nicType {
// XXX The CloudStack API forgets to specify it
nic.VirtualMachineID = vm.ID
nics = append(nics, nic)
}
}
return nics
}
// NicByNetworkID returns the corresponding interface based on the given NetworkID
//
// A VM cannot be connected twice to a same network.
func (vm *VirtualMachine) NicByNetworkID(networkID string) *Nic {
for _, nic := range vm.Nic {
if nic.NetworkID == networkID {
nic.VirtualMachineID = vm.ID
return &nic
}
}
return nil
}
// NicByID returns the corresponding interface base on its ID
func (vm *VirtualMachine) NicByID(nicID string) *Nic {
for _, nic := range vm.Nic {
if nic.ID == nicID {
nic.VirtualMachineID = vm.ID
return &nic
}
}
return nil
}
// name returns the CloudStack API command name
func (*DeployVirtualMachine) name() string {
return "deployVirtualMachine"
}
func (req *DeployVirtualMachine) onBeforeSend(params *url.Values) error {
// Either AffinityGroupIDs or AffinityGroupNames must be set
if len(req.AffinityGroupIDs) > 0 && len(req.AffinityGroupNames) > 0 {
return fmt.Errorf("Either AffinityGroupIDs or AffinityGroupNames must be set")
}
// Either SecurityGroupIDs or SecurityGroupNames must be set
if len(req.SecurityGroupIDs) > 0 && len(req.SecurityGroupNames) > 0 {
return fmt.Errorf("Either SecurityGroupIDs or SecurityGroupNames must be set")
}
return nil
}
func (*DeployVirtualMachine) asyncResponse() interface{} {
return new(DeployVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*StartVirtualMachine) name() string {
return "startVirtualMachine"
}
func (*StartVirtualMachine) asyncResponse() interface{} {
return new(StartVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*StopVirtualMachine) name() string {
return "stopVirtualMachine"
}
func (*StopVirtualMachine) asyncResponse() interface{} {
return new(StopVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*RebootVirtualMachine) name() string {
return "rebootVirtualMachine"
}
func (*RebootVirtualMachine) asyncResponse() interface{} {
return new(RebootVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*RestoreVirtualMachine) name() string {
return "restoreVirtualMachine"
}
func (*RestoreVirtualMachine) asyncResponse() interface{} {
return new(RestoreVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*RecoverVirtualMachine) name() string {
return "recoverVirtualMachine"
}
func (*RecoverVirtualMachine) response() interface{} {
return new(RecoverVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*DestroyVirtualMachine) name() string {
return "destroyVirtualMachine"
}
func (*DestroyVirtualMachine) asyncResponse() interface{} {
return new(DestroyVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*UpdateVirtualMachine) name() string {
return "updateVirtualMachine"
}
func (*UpdateVirtualMachine) response() interface{} {
return new(UpdateVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*ExpungeVirtualMachine) name() string {
return "expungeVirtualMachine"
}
func (*ExpungeVirtualMachine) asyncResponse() interface{} {
return new(booleanResponse)
}
// name returns the CloudStack API command name
func (*ScaleVirtualMachine) name() string {
return "scaleVirtualMachine"
}
func (*ScaleVirtualMachine) asyncResponse() interface{} {
return new(booleanResponse)
}
// name returns the CloudStack API command name
func (*ChangeServiceForVirtualMachine) name() string {
return "changeServiceForVirtualMachine"
}
func (*ChangeServiceForVirtualMachine) response() interface{} {
return new(ChangeServiceForVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*ResetPasswordForVirtualMachine) name() string {
return "resetPasswordForVirtualMachine"
}
func (*ResetPasswordForVirtualMachine) asyncResponse() interface{} {
return new(ResetPasswordForVirtualMachineResponse)
}
func (*GetVirtualMachineUserData) name() string {
return "getVirtualMachineUserData"
}
func (*GetVirtualMachineUserData) response() interface{} {
return new(GetVirtualMachineUserDataResponse)
}
func (*MigrateVirtualMachine) name() string {
return "migrateVirtualMachine"
}
func (*MigrateVirtualMachine) asyncResponse() interface{} {
return new(MigrateVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*GetVMPassword) name() string {
return "getVMPassword"
}
func (*GetVMPassword) response() interface{} {
return new(GetVMPasswordResponse)
}
// name returns the CloudStack API command name
func (*ListVirtualMachines) name() string {
return "listVirtualMachines"
}
func (*ListVirtualMachines) response() interface{} {
return new(ListVirtualMachinesResponse)
}
// SetPage sets the current page
func (ls *ListVirtualMachines) SetPage(page int) {
ls.Page = page
}
// SetPageSize sets the page size
func (ls *ListVirtualMachines) SetPageSize(pageSize int) {
ls.PageSize = pageSize
}
func (*ListVirtualMachines) each(resp interface{}, callback IterateItemFunc) {
vms, ok := resp.(*ListVirtualMachinesResponse)
if !ok {
callback(nil, fmt.Errorf("ListVirtualMachinesResponse expected, got %t", resp))
return
}
for i := range vms.VirtualMachine {
if !callback(&vms.VirtualMachine[i], nil) {
break
}
}
}
// name returns the CloudStack API command name
func (*AddNicToVirtualMachine) name() string {
return "addNicToVirtualMachine"
}
func (*AddNicToVirtualMachine) asyncResponse() interface{} {
return new(AddNicToVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*RemoveNicFromVirtualMachine) name() string {
return "removeNicFromVirtualMachine"
}
func (*RemoveNicFromVirtualMachine) asyncResponse() interface{} {
return new(RemoveNicFromVirtualMachineResponse)
}
// name returns the CloudStack API command name
func (*UpdateDefaultNicForVirtualMachine) name() string {
return "updateDefaultNicForVirtualMachine"
}
func (*UpdateDefaultNicForVirtualMachine) asyncResponse() interface{} {
return new(UpdateDefaultNicForVirtualMachineResponse)
}
// Decode decodes the base64 / gzipped encoded user data
func (userdata *VirtualMachineUserData) Decode() (string, error) {
data, err := base64.StdEncoding.DecodeString(userdata.UserData)
if err != nil {
return "", err
}
// 0x1f8b is the magic number for gzip
if len(data) < 2 || data[0] != 0x1f || data[1] != 0x8b {
return string(data), nil
}
gr, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return "", err
}
defer gr.Close() // nolint: errcheck
str, err := ioutil.ReadAll(gr)
if err != nil {
return "", err
}
return string(str), nil
}