From 2bc4e77989238213c82067313dcd326b052e33c8 Mon Sep 17 00:00:00 2001 From: Qu Xuan Date: Tue, 12 Jan 2021 17:37:03 +0800 Subject: [PATCH] fix(region): optimized azure reset linux pasword --- pkg/multicloud/azure/instance.go | 81 +++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/pkg/multicloud/azure/instance.go b/pkg/multicloud/azure/instance.go index 28855d1b05..afd7ab2995 100644 --- a/pkg/multicloud/azure/instance.go +++ b/pkg/multicloud/azure/instance.go @@ -31,6 +31,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/multicloud" "yunion.io/x/onecloud/pkg/util/billing" + "yunion.io/x/onecloud/pkg/util/version" ) const ( @@ -155,6 +156,23 @@ type VirtualMachineProperties struct { VmId string `json:"vmId,omitempty"` } +type SExtensionResourceProperties struct { + AutoUpgradeMinorVersion bool + ProvisioningState string + Publisher string + Type string + TypeHandlerVersion string +} + +type SExtensionResource struct { + Id string + Name string + Type string + Location string + + Properties SExtensionResourceProperties +} + type SInstance struct { multicloud.SInstanceBase host *SHost @@ -166,6 +184,8 @@ type SInstance struct { Location string vmSize *SVMSize Tags map[string]string + + Resources []SExtensionResource } func (self *SRegion) GetInstance(instanceId string) (*SInstance, error) { @@ -521,15 +541,22 @@ func (region *SRegion) resetOvsEnv(instanceId string) error { func (region *SRegion) deleteExtension(instanceId, extensionName string) error { return region.del(fmt.Sprintf("%s/extensions/%s", instanceId, extensionName)) } -func (region *SRegion) resetLoginInfo(osType, instanceId string, setting map[string]string) error { +func (region *SRegion) resetLoginInfo(osType, instanceId string, setting map[string]interface{}) error { + // https://github.com/Azure/azure-linux-extensions/blob/master/VMAccess/README.md + handlerVersion := "1.5" properties := map[string]interface{}{ "Publisher": "Microsoft.OSTCExtensions", "Type": "VMAccessForLinux", - "TypeHandlerVersion": "1.4", - "Settings": setting, + "TypeHandlerVersion": handlerVersion, + "Settings": map[string]string{}, + "protectedSettings": setting, + + "autoUpgradeMinorVersion": true, } if osType == osprofile.OS_TYPE_WINDOWS { - properties["TypeHandlerVersion"] = "2.0" + // https://github.com/Azure/azure-cli/blob/dev/src/azure-cli/azure/cli/command_modules/vm/custom.py + handlerVersion = "2.4" + properties["TypeHandlerVersion"] = handlerVersion properties["Publisher"] = "Microsoft.Compute" properties["Type"] = "VMAccessAgent" } @@ -537,8 +564,20 @@ func (region *SRegion) resetLoginInfo(osType, instanceId string, setting map[str "Location": region.Name, "Properties": properties, } + instance, err := region.GetInstance(instanceId) + if err != nil { + return errors.Wrapf(err, "GetInstance(%s)", instanceId) + } + for _, extension := range instance.Resources { + if extension.Name == "enablevmaccess" { + if version.GT(extension.Properties.TypeHandlerVersion, handlerVersion) { + properties["TypeHandlerVersion"] = extension.Properties.TypeHandlerVersion + break + } + } + } resource := fmt.Sprintf("%s/extensions/enablevmaccess", instanceId) - _, err := region.put(resource, jsonutils.Marshal(params)) + _, err = region.put(resource, jsonutils.Marshal(params)) if err != nil { switch osType { case osprofile.OS_TYPE_WINDOWS: @@ -557,11 +596,39 @@ func (region *SRegion) resetLoginInfo(osType, instanceId string, setting map[str return err } } + err = cloudprovider.Wait(time.Second*5, time.Minute*5, func() (bool, error) { + instance, err := region.GetInstance(instanceId) + if err != nil { + return false, errors.Wrapf(err, "GetInstance(%s)", instanceId) + } + for _, extension := range instance.Resources { + if extension.Name == "enablevmaccess" { + if extension.Properties.ProvisioningState == "Succeeded" { + return true, nil + } + log.Debugf("enablevmaccess status %s expect Succeeded", extension.Properties.ProvisioningState) + if extension.Properties.ProvisioningState == "Failed" { + if instance.Properties.InstanceView != nil { + for _, info := range instance.Properties.InstanceView.Extensions { + if info.Name == "enablevmaccess" && len(info.Statuses) > 0 { + return false, fmt.Errorf("details: %s", jsonutils.Marshal(info.Statuses)) + } + } + } + return false, fmt.Errorf("reset passwod failed") + } + } + } + return false, nil + }) + if err != nil { + return errors.Wrapf(err, "wait for enablevmaccess error: %v", err) + } return nil } func (region *SRegion) resetPublicKey(osType, instanceId string, username, publicKey string) error { - setting := map[string]string{ + setting := map[string]interface{}{ "username": username, "ssh_key": publicKey, } @@ -569,7 +636,7 @@ func (region *SRegion) resetPublicKey(osType, instanceId string, username, publi } func (region *SRegion) resetPassword(osType, instanceId, username, password string) error { - setting := map[string]string{ + setting := map[string]interface{}{ "username": username, "password": password, }