Files
cloudpods/pkg/util/azure/instance.go
T
邱剑 a0237e1d0c Automatic merge from release/2.2.0 -> release/2.3.0
* commit 'bd44d611bdb2c7a1c0bad453ae66b270c2bebdc5':
  Azure stop默认使用deallocate
2018-10-18 17:56:25 +08:00

877 lines
25 KiB
Go

package azure
import (
"context"
"fmt"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/pkg/util/osprofile"
"yunion.io/x/pkg/util/secrules"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute"
)
const (
DEFAULT_EXTENSION_NAME = "enablevmaccess"
)
type HardwareProfile struct {
VMSize string
}
type ImageReference struct {
Publisher string
Offer string
Sku string
Version string
ID string
}
type OperatingSystemTypes string
const (
// Linux ...
Linux OperatingSystemTypes = "Linux"
// Windows ...
Windows OperatingSystemTypes = "Windows"
)
type OSDisk struct {
OsType OperatingSystemTypes
Name string
DiskSizeGB int32
ManagedDisk ManagedDiskParameters
}
type VirtualHardDisk struct {
URI string
}
type CachingTypes string
const (
// CachingTypesNone ...
CachingTypesNone CachingTypes = "None"
// CachingTypesReadOnly ...
CachingTypesReadOnly CachingTypes = "ReadOnly"
// CachingTypesReadWrite ...
CachingTypesReadWrite CachingTypes = "ReadWrite"
)
type ManagedDiskParameters struct {
StorageAccountType string
ID string
}
type DataDisk struct {
Lun int32
Name string
Vhd VirtualHardDisk
Caching CachingTypes
DiskSizeGB int32
CreateOption string
ManagedDisk ManagedDiskParameters
}
type StorageProfile struct {
ImageReference ImageReference
OsDisk OSDisk
DataDisks []DataDisk
}
type SSHPublicKey struct {
Path string
KeyData string
}
type SSHConfiguration struct {
PublicKeys []SSHPublicKey
}
type LinuxConfiguration struct {
DisablePasswordAuthentication bool
SSH SSHConfiguration
}
type SubResource struct {
ID string
}
type VaultCertificate struct {
CertificateURL string
CertificateStore string
}
type VaultSecretGroup struct {
SourceVault SubResource
VaultCertificates []VaultCertificate
}
type OsProfile struct {
ComputerName string
AdminUsername string
AdminPassword string
CustomData string
LinuxConfiguration LinuxConfiguration
Secrets []VaultSecretGroup
}
type NetworkInterfaceReference struct {
ID string
}
type NetworkProfile struct {
NetworkInterfaces []NetworkInterfaceReference
}
type InstanceViewStatus struct {
Code string
Level string
DisplayStatus string
Message string
Time time.Time
}
type VirtualMachineInstanceView struct {
ComputerName string
OsName string
OsVersion string
Statuses []InstanceViewStatus
}
type VirtualMachineProperties struct {
HardwareProfile HardwareProfile
StorageProfile StorageProfile
OsProfile OsProfile
NetworkProfile NetworkProfile
InstanceView VirtualMachineInstanceView
VmId string
}
type SInstance struct {
host *SHost
idisks []cloudprovider.ICloudDisk
CreationTime time.Time
Properties VirtualMachineProperties
ID string
Name string
Type string
Location string
vmSize *SVMSize
Tags map[string]string
}
func (self *SRegion) GetInstance(instanceId string) (*SInstance, error) {
instance := SInstance{}
computeClient := compute.NewVirtualMachinesClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
computeClient.Authorizer = self.client.authorizer
_, resourceGroup, instanceName := pareResourceGroupWithName(instanceId, INSTANCE_RESOURCE)
if len(instanceName) == 0 {
return nil, cloudprovider.ErrNotFound
}
if _instance, err := computeClient.Get(context.Background(), resourceGroup, instanceName, "instanceView"); err != nil {
if _instance.Response.StatusCode == 404 {
return nil, cloudprovider.ErrNotFound
}
return nil, err
} else if err := jsonutils.Update(&instance, _instance); err != nil {
return nil, err
} else {
return &instance, nil
}
}
func (self *SRegion) GetInstances() ([]SInstance, error) {
instances := make([]SInstance, 0)
computeClient := compute.NewVirtualMachinesClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
computeClient.Authorizer = self.client.authorizer
if instanceList, err := computeClient.ListAll(context.Background()); err != nil {
return instances, err
} else {
for _, _instance := range instanceList.Values() {
if *_instance.Location == self.Name {
if instance, err := self.GetInstance(*_instance.ID); err != nil {
return nil, err
} else {
instances = append(instances, *instance)
}
}
}
}
return instances, nil
}
func (self *SRegion) doDeleteVM(instanceId string) error {
_, resourceGroup, instanceName := pareResourceGroupWithName(instanceId, INSTANCE_RESOURCE)
computeClient := compute.NewVirtualMachinesClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
computeClient.Authorizer = self.client.authorizer
if resulte, err := computeClient.Delete(context.Background(), resourceGroup, instanceName); err != nil {
return err
} else if err := resulte.WaitForCompletion(context.Background(), computeClient.Client); err != nil {
return err
}
return nil
}
func (self *SInstance) GetMetadata() *jsonutils.JSONDict {
data := jsonutils.NewDict()
if osDistribution := self.Properties.StorageProfile.ImageReference.Publisher; len(osDistribution) > 0 {
data.Add(jsonutils.NewString(osDistribution), "os_distribution")
}
if loginAccount := self.Properties.OsProfile.AdminUsername; len(loginAccount) > 0 {
data.Add(jsonutils.NewString(loginAccount), "login_account")
}
if loginKey := self.Properties.OsProfile.AdminPassword; len(loginKey) > 0 {
data.Add(jsonutils.NewString(loginKey), "login_key")
}
data.Add(jsonutils.NewString(self.Properties.HardwareProfile.VMSize), "price_key")
if nics, err := self.getNics(); err == nil {
for _, nic := range nics {
if len(nic.Properties.NetworkSecurityGroup.ID) > 0 {
data.Add(jsonutils.NewString(nic.Properties.NetworkSecurityGroup.ID), "secgroupId")
break
}
}
}
return data
}
func (self *SInstance) GetHypervisor() string {
return models.HYPERVISOR_AZURE
}
func (self *SInstance) IsEmulated() bool {
return false
}
func (self *SInstance) getOsDisk() (*SDisk, error) {
diskId := self.Properties.StorageProfile.OsDisk.ManagedDisk.ID
if osDisk, err := self.getDiskWithStore(diskId); err != nil {
log.Errorf("Failed to find instance %s os disk: %s", self.Name, diskId)
return nil, err
} else {
return osDisk, nil
}
}
func (self *SInstance) getDisks() ([]SDisk, error) {
disks := make([]SDisk, 0)
diskId := self.Properties.StorageProfile.OsDisk.ManagedDisk.ID
if osdisk, err := self.getDiskWithStore(diskId); err != nil {
log.Errorf("Failed to find instance %s os disk: %s", self.Name, diskId)
return nil, err
} else {
disks = append(disks, *osdisk)
}
for _, _disk := range self.Properties.StorageProfile.DataDisks {
if disk, err := self.getDiskWithStore(_disk.ManagedDisk.ID); err != nil {
log.Errorf("Failed to find instance %s data disk: %s", self.Name, _disk.ManagedDisk.ID)
return nil, err
} else {
disks = append(disks, *disk)
}
}
return disks, nil
}
func (self *SInstance) getNics() ([]SInstanceNic, error) {
nics := make([]SInstanceNic, 0)
for _, _nic := range self.Properties.NetworkProfile.NetworkInterfaces {
if nic, err := self.host.zone.region.GetNetworkInterfaceDetail(_nic.ID); err != nil {
log.Errorf("Failed to find instance %s nic: %s", self.Name, _nic.ID)
return nil, err
} else {
nic.instance = self
nics = append(nics, *nic)
}
}
return nics, nil
}
func (self *SInstance) Refresh() error {
if instance, err := self.host.zone.region.GetInstance(self.ID); err != nil {
return err
} else {
return jsonutils.Update(self, instance)
}
}
func (self *SInstance) GetStatus() string {
for _, statuses := range self.Properties.InstanceView.Statuses {
if code := strings.Split(statuses.Code, "/"); len(code) == 2 {
if code[0] == "PowerState" {
switch code[1] {
case "stopped":
return models.VM_READY
case "deallocated":
return models.VM_DEALLOCATED
case "running":
return models.VM_RUNNING
case "stopping":
return models.VM_START_STOP
case "starting":
return models.VM_STARTING
case "deleting":
return models.VM_DELETING
default:
log.Errorf("Unknow instance status %s", code[1])
return models.VM_UNKNOWN
}
}
}
if statuses.Level == "Error" {
log.Errorf("Find error code: [%s] message: %s", statuses.Code, statuses.Message)
}
}
return models.VM_UNKNOWN
}
func (self *SInstance) GetIHost() cloudprovider.ICloudHost {
return self.host
}
func (self *SInstance) AttachDisk(diskId string) error {
if err := self.host.zone.region.AttachDisk(self.ID, diskId); err != nil {
return err
}
return cloudprovider.WaitStatus(self, self.GetStatus(), 10*time.Second, 300*time.Second)
}
func (region *SRegion) UpdateInstance(instanceId string, params compute.VirtualMachineUpdate) error {
computeClient := compute.NewVirtualMachinesClientWithBaseURI(region.client.baseUrl, region.client.subscriptionId)
computeClient.Authorizer = region.client.authorizer
_, resourceGroup, instanceName := pareResourceGroupWithName(instanceId, INSTANCE_RESOURCE)
log.Debugf("update VM: %s", jsonutils.Marshal(params).String())
if _, err := computeClient.Update(context.Background(), resourceGroup, instanceName, params); err != nil {
return err
}
return nil
}
func (region *SRegion) AttachDisk(instanceId, diskId string) error {
if instance, err := region.GetInstance(instanceId); err != nil {
return err
} else if disk, err := region.GetDisk(diskId); err != nil {
return err
} else {
dataDisks := []compute.DataDisk{}
maxLun := int32(0)
for i := 0; i < len(instance.Properties.StorageProfile.DataDisks); i++ {
_disk := instance.Properties.StorageProfile.DataDisks[i]
if disk.ID == _disk.ManagedDisk.ID {
return nil
} else {
if maxLun < _disk.Lun {
maxLun = _disk.Lun
}
dataDisks = append(dataDisks, compute.DataDisk{
Lun: &_disk.Lun,
CreateOption: compute.DiskCreateOptionTypes(_disk.CreateOption),
ManagedDisk: &compute.ManagedDiskParameters{
ID: &_disk.ManagedDisk.ID,
},
})
}
}
maxLun++
dataDisks = append(dataDisks, compute.DataDisk{
Lun: &maxLun,
CreateOption: compute.DiskCreateOptionTypesAttach,
ManagedDisk: &compute.ManagedDiskParameters{
ID: &disk.ID,
},
})
params := compute.VirtualMachineUpdate{
VirtualMachineProperties: &compute.VirtualMachineProperties{
StorageProfile: &compute.StorageProfile{
DataDisks: &dataDisks,
},
},
}
return region.UpdateInstance(instanceId, params)
}
}
func (self *SInstance) DetachDisk(diskId string) error {
if err := self.host.zone.region.DetachDisk(self.ID, diskId); err != nil {
return err
}
return cloudprovider.WaitStatus(self, self.GetStatus(), 10*time.Second, 300*time.Second)
}
func (region *SRegion) DetachDisk(instanceId, diskId string) error {
if instance, err := region.GetInstance(instanceId); err != nil {
return err
} else if disk, err := region.GetDisk(diskId); err != nil {
return err
} else {
dataDisks := []compute.DataDisk{}
for i := 0; i < len(instance.Properties.StorageProfile.DataDisks); i++ {
if instance.Properties.StorageProfile.DataDisks[i].ManagedDisk.ID == disk.ID {
continue
}
dataDisks = append(dataDisks, compute.DataDisk{
Lun: &instance.Properties.StorageProfile.DataDisks[i].Lun,
ManagedDisk: &compute.ManagedDiskParameters{
ID: &instance.Properties.StorageProfile.DataDisks[i].ManagedDisk.ID,
},
})
}
params := compute.VirtualMachineUpdate{
VirtualMachineProperties: &compute.VirtualMachineProperties{
StorageProfile: &compute.StorageProfile{
DataDisks: &dataDisks,
},
},
}
return region.UpdateInstance(instanceId, params)
}
}
func (self *SInstance) ChangeConfig(instanceId string, ncpu int, vmem int) error {
if err := self.host.zone.region.ChangeVMConfig(instanceId, ncpu, vmem); err != nil {
return err
}
return cloudprovider.WaitStatus(self, self.GetStatus(), 10*time.Second, 300*time.Second)
}
func (region *SRegion) ChangeVMConfig(instanceId string, ncpu int, vmem int) error {
for _, vmSize := range region.getHardwareProfile(ncpu, vmem) {
params := compute.VirtualMachineUpdate{
VirtualMachineProperties: &compute.VirtualMachineProperties{
HardwareProfile: &compute.HardwareProfile{
VMSize: compute.VirtualMachineSizeTypes(vmSize),
},
},
}
log.Debugf("Try HardwareProfile : %s", vmSize)
if err := region.UpdateInstance(instanceId, params); err == nil {
return nil
}
}
return fmt.Errorf("Failed to change vm config, specification not supported")
}
func (self *SInstance) DeployVM(name string, password string, publicKey string, deleteKeypair bool, description string) error {
return self.host.zone.region.DeployVM(self.ID, name, password, publicKey, deleteKeypair, description)
}
type VirtualMachineExtensionProperties struct {
Publisher string
Type string
TypeHandlerVersion string
}
type SVirtualMachineExtension struct {
Location string
Properties VirtualMachineExtensionProperties
}
func (region *SRegion) resetLoginInfo(instanceId string, setting map[string]string) error {
_, resourceGroup, instanceName := pareResourceGroupWithName(instanceId, INSTANCE_RESOURCE)
extensionClient := compute.NewVirtualMachineExtensionsClientWithBaseURI(region.client.baseUrl, region.SubscriptionID)
extensionClient.Authorizer = region.client.authorizer
publisher := "Microsoft.OSTCExtensions"
Type := "VMAccessForLinux"
typeHandlerVersion := "1.4"
params := compute.VirtualMachineExtension{
Location: &region.Name,
VirtualMachineExtensionProperties: &compute.VirtualMachineExtensionProperties{
Publisher: &publisher,
Type: &Type,
TypeHandlerVersion: &typeHandlerVersion,
ProtectedSettings: setting,
},
}
region.CreateResourceGroup(resourceGroup)
if result, err := extensionClient.CreateOrUpdate(context.Background(), resourceGroup, instanceName, DEFAULT_EXTENSION_NAME, params); err != nil {
return err
} else if err := result.WaitForCompletion(context.Background(), extensionClient.Client); err != nil {
return err
}
return nil
}
func (region *SRegion) resetPublicKey(instanceId string, username, publicKey string) error {
setting := map[string]string{
"username": username,
"ssh_key": publicKey,
}
return region.resetLoginInfo(instanceId, setting)
}
func (region *SRegion) resetPassword(instanceId, username, password string) error {
setting := map[string]string{
"username": username,
"password": password,
}
return region.resetLoginInfo(instanceId, setting)
}
func (region *SRegion) DeployVM(instanceId, name, password, publicKey string, deleteKeypair bool, description string) error {
if instance, err := region.GetInstance(instanceId); err != nil {
return err
} else {
if deleteKeypair {
return nil
}
if len(publicKey) > 0 {
return region.resetPublicKey(instanceId, instance.Properties.OsProfile.AdminUsername, publicKey)
} else {
return region.resetPassword(instanceId, instance.Properties.OsProfile.AdminUsername, password)
}
return nil
}
}
func (self *SInstance) RebuildRoot(imageId string, passwd string, publicKey string, sysSizeGB int) (string, error) {
return self.host.zone.region.ReplaceSystemDisk(self.ID, imageId, passwd, publicKey, int32(sysSizeGB))
}
func (region *SRegion) ReplaceSystemDisk(instanceId, imageId, passwd, publicKey string, sysSizeGB int32) (string, error) {
log.Debugf("ReplaceSystemDisk %s image: %s", instanceId, imageId)
if err := region.deallocateVM(instanceId); err != nil {
return "", err
}
if instance, err := region.GetInstance(instanceId); err != nil {
return "", err
} else {
image, err := region.GetImage(imageId)
if err != nil {
return "", err
}
orgOsType := instance.GetOSType()
destOsType := image.GetOsType()
if orgOsType != destOsType {
return "", fmt.Errorf("Cannot replease osType %s => %s", orgOsType, destOsType)
}
diskName := fmt.Sprintf("vdisk_%s_%d", instance.Name, time.Now().UnixNano())
storageType := string(instance.Properties.StorageProfile.OsDisk.ManagedDisk.StorageAccountType)
oldDiskId := instance.Properties.StorageProfile.OsDisk.ManagedDisk.ID
if diskId, err := region.createDisk(storageType, diskName, sysSizeGB, "", imageId); err != nil {
return "", err
} else {
osType := compute.OperatingSystemTypes(image.GetOsType())
disk, _ := region.GetDisk(diskId)
sshKeys := []compute.SSHPublicKey{{KeyData: &publicKey}}
params := compute.VirtualMachineUpdate{
VirtualMachineProperties: &compute.VirtualMachineProperties{
StorageProfile: &compute.StorageProfile{
//ImageReference: &compute.ImageReference{ID: &image.ID},
OsDisk: &compute.OSDisk{
Name: &disk.Name,
ManagedDisk: &compute.ManagedDiskParameters{
ID: &disk.ID,
StorageAccountType: compute.StorageAccountTypes(storageType),
},
CreateOption: compute.DiskCreateOptionTypesFromImage,
OsType: osType,
//DiskSizeGB: &sysSizeGB,
},
},
OsProfile: &compute.OSProfile{
AdminUsername: &instance.Properties.OsProfile.AdminUsername,
AdminPassword: &passwd,
LinuxConfiguration: &compute.LinuxConfiguration{},
},
},
}
if len(publicKey) > 0 {
params.OsProfile.LinuxConfiguration.SSH = &compute.SSHConfiguration{PublicKeys: &sshKeys}
}
if err := region.UpdateInstance(instanceId, params); err != nil {
region.deleteDisk(diskId)
return "", err
}
for i := 0; i < 3; i++ {
log.Debugf("try delete old disk: %s", oldDiskId)
if err := region.deleteDisk(oldDiskId); err == nil {
break
}
time.Sleep(time.Second * time.Duration(i*10))
}
return disk.ID, nil
}
}
}
func (region *SRegion) RebuildRoot(instanceId string) error {
_, resourceGroup, instanceName := pareResourceGroupWithName(instanceId, INSTANCE_RESOURCE)
computeClient := compute.NewVirtualMachinesClientWithBaseURI(region.client.baseUrl, region.client.subscriptionId)
computeClient.Authorizer = region.client.authorizer
if _, err := computeClient.Redeploy(context.Background(), resourceGroup, instanceName); err != nil {
return err
}
return nil
}
func (self *SInstance) UpdateVM(name string) error {
return cloudprovider.ErrNotSupported
}
func (self *SInstance) GetId() string {
return self.ID
}
func (self *SInstance) GetName() string {
return self.Name
}
func (self *SInstance) GetGlobalId() string {
return strings.ToLower(self.ID)
}
func (self *SRegion) GetInstanceStatus(instanceId string) (string, error) {
instance, err := self.GetInstance(instanceId)
if err != nil {
return "", err
}
return instance.GetStatus(), nil
}
func (self *SRegion) DeleteVM(instanceId string) error {
return self.doDeleteVM(instanceId)
}
func (self *SInstance) DeleteVM() error {
if err := self.host.zone.region.DeleteVM(self.ID); err != nil {
return err
}
if nics, err := self.getNics(); err != nil {
return err
} else {
for _, nic := range nics {
if err := nic.Delete(); err != nil {
if err != cloudprovider.ErrNotFound {
return err
}
}
}
}
return nil
}
func (self *SInstance) getDiskWithStore(diskId string) (*SDisk, error) {
if disk, err := self.host.zone.region.GetDisk(diskId); err != nil {
return nil, err
} else if store, err := self.host.zone.getStorageByType(string(disk.Sku.Name)); err != nil {
log.Errorf("fail to find storage for disk(%s) : %v", disk.Name, err)
return nil, err
} else {
disk.storage = store
return disk, nil
}
}
func (self *SInstance) fetchDisks() error {
self.idisks = make([]cloudprovider.ICloudDisk, len(self.Properties.StorageProfile.DataDisks)+1)
if disks, err := self.getDisks(); err != nil {
return err
} else {
for i := 0; i < len(disks); i++ {
self.idisks[i] = &disks[i]
}
}
return nil
}
func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
if self.idisks == nil {
if err := self.fetchDisks(); err != nil {
return nil, err
}
}
return self.idisks, nil
}
func (self *SInstance) GetOSType() string {
return osprofile.NormalizeOSType(string(self.Properties.StorageProfile.OsDisk.OsType))
}
func (self *SInstance) GetINics() ([]cloudprovider.ICloudNic, error) {
nics := make([]cloudprovider.ICloudNic, 0)
if _nics, err := self.getNics(); err != nil {
return nil, err
} else {
for i := 0; i < len(_nics); i++ {
_nics[i].instance = self
nics = append(nics, &_nics[i])
}
}
return nics, nil
}
func (self *SInstance) GetOSName() string {
return self.Properties.StorageProfile.ImageReference.Offer
}
func (self *SInstance) GetBios() string {
return "BIOS"
}
func (self *SInstance) GetMachine() string {
return "pc"
}
func (self *SInstance) GetBootOrder() string {
return "dcn"
}
func (self *SInstance) GetVga() string {
return "std"
}
func (self *SInstance) GetVdi() string {
return "vnc"
}
func (self *SInstance) fetchVMSize() error {
if vmSize, err := self.host.zone.region.getVMSize(self.Properties.HardwareProfile.VMSize); err != nil {
return err
} else {
self.vmSize = vmSize
}
return nil
}
func (self *SInstance) GetVcpuCount() int8 {
self.fetchVMSize()
return int8(self.vmSize.NumberOfCores)
}
func (self *SInstance) GetVmemSizeMB() int {
self.fetchVMSize()
return int(self.vmSize.MemoryInMB)
}
func (self *SInstance) GetCreateTime() time.Time {
return self.CreationTime
}
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
ret := jsonutils.NewDict()
return ret, nil
}
func (self *SRegion) StartVM(instanceId string) error {
_, resourceGroup, instanceName := pareResourceGroupWithName(instanceId, INSTANCE_RESOURCE)
computeClient := compute.NewVirtualMachinesClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
computeClient.Authorizer = self.client.authorizer
if _, err := computeClient.Start(context.Background(), resourceGroup, instanceName); err != nil {
return err
}
return nil
}
func (self *SInstance) StartVM() error {
if err := self.host.zone.region.StartVM(self.ID); err != nil {
return err
}
return cloudprovider.WaitStatus(self, models.VM_RUNNING, 10*time.Second, 300*time.Second)
}
func (self *SInstance) StopVM(isForce bool) error {
if err := self.host.zone.region.StopVM(self.ID, isForce); err != nil {
return err
}
return cloudprovider.WaitStatus(self, models.VM_READY, 10*time.Second, 300*time.Second)
}
func (self *SRegion) StopVM(instanceId string, isForce bool) error {
return self.deallocateVM(instanceId)
}
func (self *SRegion) deallocateVM(instanceId string) error {
_, resourceGroup, instanceName := pareResourceGroupWithName(instanceId, INSTANCE_RESOURCE)
computeClient := compute.NewVirtualMachinesClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
computeClient.Authorizer = self.client.authorizer
result, err := computeClient.Deallocate(context.Background(), resourceGroup, instanceName)
if err != nil {
return err
}
if err := result.WaitForCompletion(context.Background(), computeClient.Client); err != nil {
return err
}
return nil
}
func (self *SRegion) doStopVM(instanceId string, isForce bool) error {
_, resourceGroup, instanceName := pareResourceGroupWithName(instanceId, INSTANCE_RESOURCE)
computeClient := compute.NewVirtualMachinesClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId)
computeClient.Authorizer = self.client.authorizer
if result, err := computeClient.PowerOff(context.Background(), resourceGroup, instanceName); err != nil {
return err
} else if err := result.WaitForCompletion(context.Background(), computeClient.Client); err != nil {
return err
}
return nil
}
func (self *SInstance) SyncSecurityGroup(secgroupId string, name string, rules []secrules.SecurityRule) error {
nics, err := self.getNics()
if err != nil {
return err
}
if len(secgroupId) == 0 {
for _, nic := range nics {
if err := nic.revokeSecurityGroup(); err != nil {
return err
}
}
} else if extId, err := self.host.zone.region.syncSecurityGroup(secgroupId, name, rules); err != nil {
return err
} else {
for _, nic := range nics {
if err := nic.assignSecurityGroup(extId); err != nil {
return err
}
}
}
return nil
}
func (self *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) {
if nics, err := self.getNics(); err != nil {
return nil, err
} else {
for _, nic := range nics {
for _, ip := range nic.Properties.IPConfigurations {
if len(ip.Properties.PublicIPAddress.ID) > 0 {
return self.host.zone.region.GetEip(ip.Properties.PublicIPAddress.ID)
}
}
}
}
return nil, nil
}
func (self *SInstance) GetBillingType() string {
return models.BILLING_TYPE_POSTPAID
}
func (self *SInstance) GetExpiredAt() time.Time {
return time.Now()
}
func (self *SInstance) UpdateUserData(userData string) error {
params := compute.VirtualMachineUpdate{}
params.OsProfile = &compute.OSProfile{
CustomData: &userData,
}
return self.host.zone.region.UpdateInstance(self.ID, params)
}