From 1ba5db64cd0e1fd609cb65c3d79812d9fbcc96f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Thu, 30 Aug 2018 14:01:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0azure=E4=BA=91=E7=9B=98?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/climc/shell/servers.go | 4 +- pkg/compute/models/guests.go | 5 +- pkg/compute/models/hosts.go | 2 +- pkg/compute/models/wires.go | 1 + pkg/util/azure/azure.go | 1 + pkg/util/azure/disk.go | 15 ++- pkg/util/azure/host.go | 8 +- pkg/util/azure/instance.go | 121 +++++++++++++----- pkg/util/azure/network.go | 27 ++++ pkg/util/azure/region.go | 53 ++++++-- pkg/util/azure/securitygroup.go | 4 +- pkg/util/azure/storage.go | 8 +- pkg/util/azure/vpc.go | 33 ++++- pkg/util/azure/wire.go | 81 ++++++++---- pkg/util/azure/zone.go | 6 +- .../x/pkg/util/sysutils/storagetypes.go | 10 +- 16 files changed, 286 insertions(+), 93 deletions(-) diff --git a/cmd/climc/shell/servers.go b/cmd/climc/shell/servers.go index 6e963049b0..0f030f7519 100644 --- a/cmd/climc/shell/servers.go +++ b/cmd/climc/shell/servers.go @@ -63,7 +63,7 @@ func init() { Gpu bool `help:"Show gpu servers"` Secgroup string `help:"Secgroup ID or Name"` AdminSecgroup string `help:"AdminSecgroup ID or Name"` - Hypervisor string `help:"Show server of hypervisor" choices:"kvm|esxi|container|baremetal|aliyun"` + Hypervisor string `help:"Show server of hypervisor" choices:"kvm|esxi|container|baremetal|aliyun|azure"` Manager string `help:"Show servers imported from manager"` BaseListOptions } @@ -163,7 +163,7 @@ func init() { Project string `help:"'Owner project ID or Name"` User string `help:"Owner user ID or Name"` System bool `help:"Create a system VM, sysadmin ONLY option"` - Hypervisor string `help:"Hypervisor type" choices:"kvm|esxi|baremetal|container|aliyun"` + Hypervisor string `help:"Hypervisor type" choices:"kvm|esxi|baremetal|container|aliyun|azure"` TaskNotify bool `help:"Setup task notify"` Count int `help:"Create multiple simultaneously" default:"1"` DryRun bool `help:"Dry run to test scheduler"` diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index 30d56e78b0..27fd46d58b 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -119,7 +119,7 @@ const ( var VM_RUNNING_STATUS = []string{VM_START_START, VM_STARTING, VM_RUNNING, VM_SNAPSHOT_STREAM} var VM_CREATING_STATUS = []string{VM_CREATE_NETWORK, VM_CREATE_DISK, VM_START_DEPLOY, VM_DEPLOYING} -var HYPERVISORS = []string{HYPERVISOR_KVM, HYPERVISOR_BAREMETAL, HYPERVISOR_ESXI, HYPERVISOR_CONTAINER, HYPERVISOR_ALIYUN} +var HYPERVISORS = []string{HYPERVISOR_KVM, HYPERVISOR_BAREMETAL, HYPERVISOR_ESXI, HYPERVISOR_CONTAINER, HYPERVISOR_ALIYUN, HYPERVISOR_AZURE} // var HYPERVISORS = []string{HYPERVISOR_ALIYUN} @@ -985,6 +985,9 @@ func (self *SGuest) GetExtraDetails(ctx context.Context, userCred mcclient.Token if len(osName) > 0 { extra.Add(jsonutils.NewString(osName), "os_name") } + if metaData, err := self.GetAllMetadata(userCred); err == nil { + extra.Add(jsonutils.Marshal(metaData), "metadata") + } if userCred.IsSystemAdmin() { host := self.GetHost() if host != nil { diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index 869a45c5df..0da1a44f6d 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -67,7 +67,7 @@ const ( HOST_STATUS_CONVERTING = "converting" ) -var HOST_TYPES = []string{HOST_TYPE_BAREMETAL, HOST_TYPE_HYPERVISOR, HOST_TYPE_ESXI, HOST_TYPE_KUBELET, HOST_TYPE_XEN, HOST_TYPE_ALIYUN} +var HOST_TYPES = []string{HOST_TYPE_BAREMETAL, HOST_TYPE_HYPERVISOR, HOST_TYPE_ESXI, HOST_TYPE_KUBELET, HOST_TYPE_XEN, HOST_TYPE_ALIYUN, HOST_TYPE_AZURE} var NIC_TYPES = []string{NIC_TYPE_IPMI, NIC_TYPE_ADMIN} type SHostManager struct { diff --git a/pkg/compute/models/wires.go b/pkg/compute/models/wires.go index d522c53e58..1f97cfc544 100644 --- a/pkg/compute/models/wires.go +++ b/pkg/compute/models/wires.go @@ -511,6 +511,7 @@ func (self *SWire) GetIWire() (cloudprovider.ICloudWire, error) { } ivpc, err := vpc.GetIVpc() if err != nil { + log.Errorf("can not find ivpc") return nil, err } return ivpc.GetIWireById(self.GetExternalId()) diff --git a/pkg/util/azure/azure.go b/pkg/util/azure/azure.go index be2649b143..c8a2a91938 100644 --- a/pkg/util/azure/azure.go +++ b/pkg/util/azure/azure.go @@ -36,6 +36,7 @@ var DefaultResourceGroup = map[string]string{ "disk": "YunionDiskResource", "instance": "YunionInstanceResource", "vpc": "YunionVpcResource", + "network": "YunionNetworkResource", } type SAzureClient struct { diff --git a/pkg/util/azure/disk.go b/pkg/util/azure/disk.go index 15a2d71ed5..4a8187bfdb 100644 --- a/pkg/util/azure/disk.go +++ b/pkg/util/azure/disk.go @@ -92,15 +92,16 @@ func (self *SRegion) DeleteDisk(diskId string) error { } func (self *SRegion) deleteDisk(diskId string) error { - computeClient := compute.NewDisksClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId) - computeClient.Authorizer = self.client.authorizer + diskClient := compute.NewDisksClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId) + diskClient.Authorizer = self.client.authorizer if resourceGroup, name, err := PareResourceGroupWithName(diskId); err != nil { return err - } else if _, err := computeClient.Delete(context.Background(), resourceGroup, name); err != nil { + } else if result, err := diskClient.Delete(context.Background(), resourceGroup, name); err != nil { + return err + } else if err := result.WaitForCompletion(context.Background(), diskClient.Client); err != nil { return err - } else { - return nil } + return nil } func (self *SRegion) GetDisk(resourceGroup string, diskName string) (*SDisk, error) { @@ -161,7 +162,7 @@ func (self *SRegion) getDisk(resourceGroup string, diskName string) (*SDisk, err func (self *SDisk) Refresh() error { if disk, err := self.storage.zone.region.GetDisk(self.ResourceGroup, self.Name); err != nil { - return err + return cloudprovider.ErrNotFound } else { return jsonutils.Update(self, disk) } @@ -185,7 +186,7 @@ func (self *SDisk) GetName() string { func (self *SDisk) GetGlobalId() string { resourceGroup, _, _ := PareResourceGroupWithName(self.ID) - return fmt.Sprintf("resourceGroups/%s/providers/%s/%s", resourceGroup, self.storage.zone.region.SubscriptionID, self.Name) + return fmt.Sprintf("resourceGroups/%s/providers/disk/%s", resourceGroup, self.Name) } func (self *SDisk) IsEmulated() bool { diff --git a/pkg/util/azure/host.go b/pkg/util/azure/host.go index 83a624dbc6..7cd9136f5c 100644 --- a/pkg/util/azure/host.go +++ b/pkg/util/azure/host.go @@ -98,7 +98,13 @@ func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) { } func (self *SHost) GetIVMById(gid string) (cloudprovider.ICloudVM, error) { - return nil, nil + resourceGroup, name, _ := PareResourceGroupWithName(gid) + if instance, err := self.zone.region.GetInstance(resourceGroup, name); err != nil { + return nil, err + } else { + instance.host = self + return instance, nil + } } func (self *SHost) GetStorageSizeMB() int { diff --git a/pkg/util/azure/instance.go b/pkg/util/azure/instance.go index 39ad80a504..5cf389450e 100644 --- a/pkg/util/azure/instance.go +++ b/pkg/util/azure/instance.go @@ -18,13 +18,7 @@ import ( ) type HardwareProfile struct { - VMSize string - MaxDataDiskCount int32 - MemoryInMB int32 - NumberOfCores int32 - Name string - OsDiskSizeInMB int32 - ResourceDiskSizeInMB int32 + VMSize string } type ImageReference struct { @@ -168,6 +162,7 @@ type SInstance struct { Name string Type string Location string + vmSize *SVMSize Tags map[string]string } @@ -176,7 +171,8 @@ func PareResourceGroupWithName(s string) (string, string, error) { if resourceGroups := valid.FindStringSubmatch(s); len(resourceGroups) == 3 { return resourceGroups[1], resourceGroups[2], nil } - return s, "", cloudprovider.ErrNotFound + log.Errorf("PareResourceGroupWithName[%s] error", s) + return "", "", cloudprovider.ErrNotFound } func (self *SRegion) GetInstance(resourceGroup string, VMName string) (*SInstance, error) { @@ -206,11 +202,6 @@ func (self *SRegion) GetInstances() ([]SInstance, error) { if err := jsonutils.Update(&instance, _instance); err != nil { return instances, err } - if vmSize, err := self.getVMSize(instance.Properties.HardwareProfile.VMSize); err != nil { - return instances, err - } else if err := jsonutils.Update(&instance.Properties.HardwareProfile, vmSize); err != nil { - return instances, err - } instance.ResourceGroup, _, _ = PareResourceGroupWithName(instance.ID) instances = append(instances, instance) } @@ -225,7 +216,17 @@ func (self *SRegion) doDeleteVM(instanceId string) error { } func (self *SInstance) GetMetadata() *jsonutils.JSONDict { - return nil + 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") + } + return data } func (self *SInstance) GetHypervisor() string { @@ -239,7 +240,7 @@ func (self *SInstance) IsEmulated() bool { func (self *SInstance) Refresh() error { if instance, err := self.host.zone.region.GetInstance(self.ResourceGroup, self.Name); err != nil { log.Errorf("Refresh Instance error: %v", err) - return err + return cloudprovider.ErrNotFound } else if err := jsonutils.Update(self, instance); err != nil { log.Errorf("Refresh Instance error: %v", err) return err @@ -254,7 +255,17 @@ 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" { - return code[1] + switch code[1] { + case "stopped": + return models.VM_READY + case "running": + return models.VM_RUNNING + case "stopping": + return models.VM_START_STOP + default: + return models.VM_UNKNOWN + } + } } } @@ -298,7 +309,8 @@ func (self *SInstance) GetName() string { } func (self *SInstance) GetGlobalId() string { - return fmt.Sprintf("%s/%s", self.host.zone.region.GetGlobalId(), self.Properties.VmId) + resourceGroup, _, _ := PareResourceGroupWithName(self.ID) + return fmt.Sprintf("resourceGroups/%s/providers/server/%s", resourceGroup, self.Name) } func (self *SRegion) DeleteVM(instanceId string) error { @@ -326,7 +338,7 @@ func (self *SInstance) DeleteVM() error { func (self *SInstance) getDiskWithStore(resourceGroup string, diskName string) (*SDisk, error) { if disk, err := self.host.zone.region.GetDisk(resourceGroup, diskName); err != nil { return nil, err - } else if store, err := self.host.zone.getStorageByType(strings.ToLower(string(disk.Sku.Name))); err != nil { + } 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 { @@ -366,7 +378,7 @@ func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) { } func (self *SInstance) GetOSType() string { - return osprofile.NormalizeOSType(self.Properties.InstanceView.OsName) + return osprofile.NormalizeOSType(string(self.Properties.StorageProfile.OsDisk.OsType)) } func (self *SInstance) GetINics() ([]cloudprovider.ICloudNic, error) { @@ -411,12 +423,33 @@ 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 { - return int8(self.Properties.HardwareProfile.NumberOfCores) + if self.vmSize == nil { + if err := self.fetchVMSize(); err != nil { + log.Errorf("fail to fetch vmSize: %v", err) + return 0 + } + } + return int8(self.vmSize.NumberOfCores) } func (self *SInstance) GetVmemSizeMB() int { - return int(self.Properties.HardwareProfile.MemoryInMB) + if self.vmSize == nil { + if err := self.fetchVMSize(); err != nil { + log.Errorf("fail to fetch vmSize: %v", err) + return 0 + } + } + return int(self.vmSize.MemoryInMB) } func (self *SInstance) GetCreateTime() time.Time { @@ -434,27 +467,45 @@ func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) { } func (self *SRegion) StartVM(instanceId string) error { - // status, _ := self.GetInstanceStatus(instanceId) - // if status != InstanceStatusStopped { - // return cloudprovider.ErrInvalidStatus - // } + resourceGroup, name, _ := PareResourceGroupWithName(instanceId) + computeClient := compute.NewVirtualMachinesClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId) + computeClient.Authorizer = self.client.authorizer + if result, err := computeClient.Start(context.Background(), resourceGroup, name); err != nil { + return err + } else if err := result.WaitForCompletion(context.Background(), computeClient.Client); err != nil { + return err + } return nil } func (self *SInstance) StartVM() error { - // err := self.host.zone.region.StartVM(self.InstanceId) - // if err != nil { - // return err - // } - return cloudprovider.WaitStatus(self, models.VM_RUNNING, 5*time.Second, 180*time.Second) // 3minutes + if err := self.host.zone.region.StartVM(self.ID); err != nil { + return err + } + return nil } func (self *SInstance) StopVM(isForce bool) error { - // err := self.host.zone.region.StopVM(self.InstanceId, isForce) - // if err != nil { - // return err - // } - return cloudprovider.WaitStatus(self, models.VM_READY, 10*time.Second, 300*time.Second) // 5mintues + if err := self.host.zone.region.StopVM(self.ID, isForce); err != nil { + return err + } + return nil +} + +func (self *SRegion) StopVM(instanceId string, isForce bool) error { + return self.doStopVM(instanceId, isForce) +} + +func (self *SRegion) doStopVM(instanceId string, isForce bool) error { + resourceGroup, name, _ := PareResourceGroupWithName(instanceId) + computeClient := compute.NewVirtualMachinesClientWithBaseURI(self.client.baseUrl, self.client.subscriptionId) + computeClient.Authorizer = self.client.authorizer + if result, err := computeClient.PowerOff(context.Background(), resourceGroup, name); 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 { diff --git a/pkg/util/azure/network.go b/pkg/util/azure/network.go index 8577d5e6b0..8b0f008628 100644 --- a/pkg/util/azure/network.go +++ b/pkg/util/azure/network.go @@ -1,9 +1,11 @@ package azure import ( + "context" "fmt" "strings" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-06-01/network" "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" @@ -50,6 +52,31 @@ func (self *SNetwork) GetStatus() string { } func (self *SNetwork) Delete() error { + vpc := self.wire.vpc + addressSpace := network.AddressSpace{AddressPrefixes: &vpc.Properties.AddressSpace.AddressPrefixes} + subnets := []network.Subnet{} + for i := 0; i < len(vpc.Properties.Subnets); i++ { + subnet := vpc.Properties.Subnets[i] + if subnet.Name == self.Name { + continue + } + subnetPropertiesFormat := network.SubnetPropertiesFormat{AddressPrefix: &subnet.Properties.AddressPrefix} + subNet := network.Subnet{Name: &subnet.Name, SubnetPropertiesFormat: &subnetPropertiesFormat} + subnets = append(subnets, subNet) + } + + properties := network.VirtualNetworkPropertiesFormat{AddressSpace: &addressSpace, Subnets: &subnets} + params := network.VirtualNetwork{VirtualNetworkPropertiesFormat: &properties, Location: &vpc.Location} + + region := self.wire.vpc.region + networkClient := network.NewVirtualNetworksClientWithBaseURI(region.client.baseUrl, region.SubscriptionID) + networkClient.Authorizer = region.client.authorizer + resourceGroup, _, _ := PareResourceGroupWithName(vpc.ID) + if result, err := networkClient.CreateOrUpdate(context.Background(), resourceGroup, vpc.Name, params); err != nil { + return err + } else if err := result.WaitForCompletion(context.Background(), networkClient.Client); err != nil { + return err + } return nil } diff --git a/pkg/util/azure/region.go b/pkg/util/azure/region.go index 9727cbcabc..2e8acba71a 100644 --- a/pkg/util/azure/region.go +++ b/pkg/util/azure/region.go @@ -14,7 +14,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage" ) -type VMSize struct { +type SVMSize struct { MaxDataDiskCount int32 MemoryInMB int32 NumberOfCores int32 @@ -31,7 +31,7 @@ type SRegion struct { storageCache *SStoragecache - vmSize map[string]VMSize + vmSize map[string]SVMSize ID string SubscriptionID string Name string @@ -56,9 +56,9 @@ func (self *SRegion) fetchVMSize() error { if vmSizeList, err := computeClient.List(context.Background(), self.Name); err != nil { return err } else { - self.vmSize = make(map[string]VMSize, len(*vmSizeList.Value)) + self.vmSize = make(map[string]SVMSize, len(*vmSizeList.Value)) for _, _vmSize := range *vmSizeList.Value { - vmSize := VMSize{} + vmSize := SVMSize{} jsonutils.Update(&vmSize, _vmSize) self.vmSize[*_vmSize.Name] = vmSize } @@ -66,7 +66,7 @@ func (self *SRegion) fetchVMSize() error { return nil } -func (self *SRegion) getVMSize(size string) (*VMSize, error) { +func (self *SRegion) getVMSize(size string) (*SVMSize, error) { if self.vmSize == nil || len(self.vmSize) == 0 { if err := self.fetchVMSize(); err != nil { return nil, err @@ -153,11 +153,27 @@ func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) { } func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { - return nil, nil + izones, err := self.GetIZones() + if err != nil { + return nil, err + } + for i := 0; i < len(izones); i += 1 { + istore, err := izones[i].GetIStorageById(id) + if err == nil { + return istore, nil + } else if err != cloudprovider.ErrNotFound { + return nil, err + } + } + return nil, cloudprovider.ErrNotFound } func (self *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) { - return nil, nil + storageCache := self.getStoragecache() + if storageCache.GetGlobalId() == id { + return self.storageCache, nil + } + return nil, cloudprovider.ErrNotFound } func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) { @@ -180,11 +196,30 @@ func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) { } func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) { - return nil, nil + if izones, err := self.GetIZones(); err != nil { + return nil, err + } else { + for i := 0; i < len(izones); i += 1 { + if izones[i].GetGlobalId() == id { + return izones[i], nil + } + } + } + return nil, cloudprovider.ErrNotFound } func (self *SRegion) getZoneById(id string) (*SZone, error) { - return nil, nil + if izones, err := self.GetIZones(); err != nil { + return nil, err + } else { + for i := 0; i < len(izones); i += 1 { + zone := izones[i].(*SZone) + if zone.GetId() == id { + return zone, nil + } + } + } + return nil, fmt.Errorf("no such zone %s", id) } func (self *SRegion) fetchZones() error { diff --git a/pkg/util/azure/securitygroup.go b/pkg/util/azure/securitygroup.go index f282a64c0f..b93e5a2529 100644 --- a/pkg/util/azure/securitygroup.go +++ b/pkg/util/azure/securitygroup.go @@ -70,7 +70,7 @@ type SSecurityGroup struct { } func (self *SecurityRulePropertiesFormat) String() string { - log.Debugf("serize rule: %s", jsonutils.Marshal(self).PrettyString()) + //log.Debugf("serize rule: %s", jsonutils.Marshal(self).PrettyString()) action := secrules.SecurityRuleDeny if self.Access == SecurityRuleAccessAllow { action = secrules.SecurityRuleAllow @@ -118,7 +118,7 @@ func (self *SecurityRulePropertiesFormat) String() string { result += fmt.Sprintf(" %s", port) } } - log.Debugf("result: %s", result) + //log.Debugf("result: %s", result) return result } diff --git a/pkg/util/azure/storage.go b/pkg/util/azure/storage.go index b641b2646a..311efcaaf2 100644 --- a/pkg/util/azure/storage.go +++ b/pkg/util/azure/storage.go @@ -21,15 +21,15 @@ func (self *SStorage) GetMetadata() *jsonutils.JSONDict { } func (self *SStorage) GetId() string { - return fmt.Sprintf("%s/%s", self.zone.GetGlobalId(), self.storageType) + return fmt.Sprintf("%s/%s", self.zone.GetGlobalId(), strings.ToLower(self.storageType)) } func (self *SStorage) GetName() string { - return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, self.storageType) + return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, strings.ToLower(self.storageType)) } func (self *SStorage) GetGlobalId() string { - return fmt.Sprintf("%s/%s/%s", self.zone.region.GetGlobalId(), self.zone.region.client.subscriptionId, self.storageType) + return fmt.Sprintf("%s/%s/%s", self.zone.region.GetGlobalId(), self.zone.region.client.subscriptionId, strings.ToLower(self.storageType)) } func (self *SStorage) IsEmulated() bool { @@ -115,7 +115,7 @@ func (self *SStorage) GetStatus() string { } func (self *SStorage) GetStorageType() string { - return self.storageType + return strings.ToLower(self.storageType) } func (self *SStorage) Refresh() error { diff --git a/pkg/util/azure/vpc.go b/pkg/util/azure/vpc.go index be6a2a78c6..e7b712909b 100644 --- a/pkg/util/azure/vpc.go +++ b/pkg/util/azure/vpc.go @@ -65,7 +65,7 @@ func (self *SVpc) GetName() string { func (self *SVpc) GetGlobalId() string { resourceGroup, _, _ := PareResourceGroupWithName(self.ID) - return fmt.Sprintf("%s/resourceGroups/%s/%s/%s", self.region.GetGlobalId(), resourceGroup, self.region.SubscriptionID, self.Name) + return fmt.Sprintf("resourceGroups/%s/providers/vpc/%s", resourceGroup, self.Name) } func (self *SVpc) IsEmulated() bool { @@ -113,6 +113,27 @@ func (self *SVpc) fetchSecurityGroups() error { return nil } +func (self *SVpc) getWire() *SWire { + if self.iwires == nil { + self.fetchWires() + } + return self.iwires[0].(*SWire) +} + +func (self *SVpc) fetchNetworks() error { + self.Refresh() + for i := 0; i < len(self.Properties.Subnets); i++ { + _network := self.Properties.Subnets[i] + wire := self.getWire() + network := SNetwork{wire: wire, Name: _network.Name, ID: _network.ID} + if err := jsonutils.Update(&network, _network); err != nil { + return err + } + wire.addNetwork(&network) + } + return nil +} + func (self *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { if self.secgroups == nil { err := self.fetchSecurityGroups() @@ -139,7 +160,7 @@ func (self *SVpc) fetchWires() error { func (self *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) { if self.iwires == nil { - if err := self.fetchWires(); err != nil { + if err := self.fetchNetworks(); err != nil { return nil, err } } @@ -176,6 +197,14 @@ func (self *SVpc) GetStatus() string { } func (self *SVpc) Refresh() error { + resourceGroup, _, _ := PareResourceGroupWithName(self.ID) + vpcClient := network.NewVirtualNetworksClientWithBaseURI(self.region.client.baseUrl, self.region.SubscriptionID) + vpcClient.Authorizer = self.region.client.authorizer + if result, err := vpcClient.Get(context.Background(), resourceGroup, self.Name, ""); err != nil { + return cloudprovider.ErrNotFound + } else if err := jsonutils.Update(self, result); err != nil { + return err + } return nil } diff --git a/pkg/util/azure/wire.go b/pkg/util/azure/wire.go index 3c9fc7a399..1e347e946d 100644 --- a/pkg/util/azure/wire.go +++ b/pkg/util/azure/wire.go @@ -1,8 +1,10 @@ package azure import ( + "context" "fmt" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-06-01/network" "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/onecloud/pkg/cloudprovider" @@ -11,8 +13,6 @@ import ( type SWire struct { zone *SZone vpc *SVpc - name string - id string inetworks []cloudprovider.ICloudNetwork } @@ -44,20 +44,62 @@ func (self *SWire) Refresh() error { return nil } +func (self *SWire) addNetwork(network *SNetwork) { + if self.inetworks == nil { + self.inetworks = make([]cloudprovider.ICloudNetwork, 0) + } + find := false + for i := 0; i < len(self.inetworks); i += 1 { + if self.inetworks[i].GetId() == network.ID { + find = true + break + } + } + if !find { + self.inetworks = append(self.inetworks, network) + } +} + +func (self *SRegion) createNetwork(vpc *SVpc, subnetName string, cidr string, desc string) (string, error) { + addressSpace := network.AddressSpace{AddressPrefixes: &vpc.Properties.AddressSpace.AddressPrefixes} + subnets := []network.Subnet{} + for i := 0; i < len(vpc.Properties.Subnets); i++ { + subnet := vpc.Properties.Subnets[i] + subnetPropertiesFormat := network.SubnetPropertiesFormat{AddressPrefix: &subnet.Properties.AddressPrefix} + subNet := network.Subnet{Name: &subnet.Name, SubnetPropertiesFormat: &subnetPropertiesFormat} + subnets = append(subnets, subNet) + } + subnetPropertiesFormat := network.SubnetPropertiesFormat{AddressPrefix: &cidr} + subNet := network.Subnet{Name: &subnetName, SubnetPropertiesFormat: &subnetPropertiesFormat} + subnets = append(subnets, subNet) + + properties := network.VirtualNetworkPropertiesFormat{AddressSpace: &addressSpace, Subnets: &subnets} + params := network.VirtualNetwork{VirtualNetworkPropertiesFormat: &properties, Location: &vpc.Location} + + networkClient := network.NewVirtualNetworksClientWithBaseURI(self.client.baseUrl, self.SubscriptionID) + networkClient.Authorizer = self.client.authorizer + resourceGroup, _, _ := PareResourceGroupWithName(vpc.ID) + if result, err := networkClient.CreateOrUpdate(context.Background(), resourceGroup, vpc.Name, params); err != nil { + return "", err + } else if err := result.WaitForCompletion(context.Background(), networkClient.Client); err != nil { + return "", err + } + return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s", self.SubscriptionID, resourceGroup, vpc.Name, subnetName), nil +} + func (self *SWire) CreateINetwork(name string, cidr string, desc string) (cloudprovider.ICloudNetwork, error) { - // vswitchId, err := self.zone.region.createVSwitch(self.zone.ZoneId, self.vpc.VpcId, name, cidr, desc) - // if err != nil { - // log.Errorf("createVSwitch error %s", err) - // return nil, err - // } - // self.inetworks = nil - // vswitch := self.getNetworkById(vswitchId) - // if vswitch == nil { - // log.Errorf("cannot find vswitch after create????") - // return nil, cloudprovider.ErrNotFound - // } - // return vswitch, nil - return nil, nil + if networkId, err := self.zone.region.createNetwork(self.vpc, name, cidr, desc); err != nil { + log.Errorf("createNetwork error %s", err) + return nil, err + } else { + self.inetworks = nil + if network := self.getNetworkById(networkId); network == nil { + log.Errorf("cannot find network after create????") + return nil, cloudprovider.ErrNotFound + } else { + return network, nil + } + } } func (self *SWire) GetBandwidth() int { @@ -79,13 +121,8 @@ func (self *SWire) GetINetworkById(netid string) (cloudprovider.ICloudNetwork, e func (self *SWire) GetINetworks() ([]cloudprovider.ICloudNetwork, error) { if self.inetworks == nil { - self.inetworks = make([]cloudprovider.ICloudNetwork, len(self.vpc.Properties.Subnets)) - for i, _netwrok := range self.vpc.Properties.Subnets { - network := SNetwork{wire: self, Name: _netwrok.Name, ID: _netwrok.ID} - if err := jsonutils.Update(&network, _netwrok); err != nil { - return nil, err - } - self.inetworks[i] = &network + if err := self.vpc.fetchNetworks(); err != nil { + return nil, err } } return self.inetworks, nil diff --git a/pkg/util/azure/zone.go b/pkg/util/azure/zone.go index fbcc1f31e3..accc2e834b 100644 --- a/pkg/util/azure/zone.go +++ b/pkg/util/azure/zone.go @@ -3,7 +3,6 @@ package azure import ( "context" "fmt" - "strings" "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" @@ -68,9 +67,8 @@ func (self *SZone) getStorageTypes() error { } else { for _, sku := range *skuList.Value { if len(*sku.Locations) > 0 && (*sku.Locations)[0] == self.region.Name { - storageType := strings.ToLower(string(sku.Name)) - if !utils.IsInStringArray(storageType, self.storageTypes) { - self.storageTypes = append(self.storageTypes, storageType) + if !utils.IsInStringArray(string(sku.Name), self.storageTypes) { + self.storageTypes = append(self.storageTypes, string(sku.Name)) } } } diff --git a/vendor/yunion.io/x/pkg/util/sysutils/storagetypes.go b/vendor/yunion.io/x/pkg/util/sysutils/storagetypes.go index 16baa403d2..2ecc08ec40 100644 --- a/vendor/yunion.io/x/pkg/util/sysutils/storagetypes.go +++ b/vendor/yunion.io/x/pkg/util/sysutils/storagetypes.go @@ -13,14 +13,18 @@ const ( STORAGE_CLOUD_SSD = "cloud_ssd" STORAGE_CLOUD_EFFICIENCY = "cloud_efficiency" - STORAGE_STANDARD = "standard" //Azure hdd storage type - STORAGE_PREMIUM = "premium" //Azure ssd storage type + //Azure hdd storage type + STORAGE_STANDARD_GRS = "standard_grs" + STORAGE_STANDARD_LRS = "standard_lrs" + STORAGE_STANDARD_RAGRS = "standard_ragrs" + STORAGE_STANDARD_ZRS = "standard_zrs" + STORAGE_PREMIUM_LRS = "premium_lrs" ) var STORAGE_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_SHEEPDOG, STORAGE_RBD, STORAGE_DOCKER, STORAGE_NAS, STORAGE_VSAN, STORAGE_CLOUD, STORAGE_CLOUD_SSD, STORAGE_CLOUD_EFFICIENCY, - STORAGE_STANDARD, STORAGE_PREMIUM} + STORAGE_STANDARD_GRS, STORAGE_STANDARD_LRS, STORAGE_STANDARD_RAGRS, STORAGE_STANDARD_ZRS, STORAGE_PREMIUM_LRS} var LOCAL_STORAGE_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL}