openstack创建

This commit is contained in:
屈轩
2019-02-16 17:37:33 +08:00
parent a2a28c05a5
commit d85e2f8162
30 changed files with 923 additions and 83 deletions
+1 -1
View File
@@ -211,7 +211,7 @@ type ICloudVM interface {
GetInstanceType() string
AssignSecurityGroup(secgroupId string) error
AssignSecurityGroups(secgroupIds []string) error
SetSecurityGroups(secgroupIds []string) error
GetHypervisor() string
+1 -1
View File
@@ -461,7 +461,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncConfigOnHost(ctx context.
}
externalIds = append(externalIds, extID)
}
return nil, iVM.AssignSecurityGroups(externalIds)
return nil, iVM.SetSecurityGroups(externalIds)
}
iDisks, err := iVM.GetIDisks()
+62
View File
@@ -1,8 +1,14 @@
package guestdrivers
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/billing"
)
type SOpenStackGuestDriver struct {
@@ -29,3 +35,59 @@ func (self *SOpenStackGuestDriver) GetDefaultSysDiskBackend() string {
func (self *SOpenStackGuestDriver) GetMinimalSysDiskSizeGb() int {
return options.Options.DefaultDiskSizeMB / 1024
}
func (self *SOpenStackGuestDriver) ChooseHostStorage(host *models.SHost, backend string) *models.SStorage {
storages := host.GetAttachedStorages("")
for i := 0; i < len(storages); i++ {
if storages[i].StorageType == backend {
return &storages[i]
}
}
for _, stype := range []string{models.STORAGE_OPENSTACK_ISCSI} {
for i := 0; i < len(storages); i++ {
if storages[i].StorageType == stype {
return &storages[i]
}
}
}
return nil
}
func (self *SOpenStackGuestDriver) GetDetachDiskStatus() ([]string, error) {
return []string{models.VM_READY}, nil
}
func (self *SOpenStackGuestDriver) GetAttachDiskStatus() ([]string, error) {
return []string{models.VM_READY}, nil
}
func (self *SOpenStackGuestDriver) GetRebuildRootStatus() ([]string, error) {
return []string{models.VM_READY, models.VM_RUNNING, models.VM_REBUILD_ROOT_FAIL}, nil
}
func (self *SOpenStackGuestDriver) GetChangeConfigStatus() ([]string, error) {
return []string{models.VM_READY, models.VM_RUNNING}, nil
}
func (self *SOpenStackGuestDriver) GetDeployStatus() ([]string, error) {
return []string{models.VM_READY, models.VM_RUNNING}, nil
}
func (self *SOpenStackGuestDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
data, err := self.SManagedVirtualizedGuestDriver.ValidateCreateData(ctx, userCred, data)
if err != nil {
return nil, err
}
if data.Contains("net.0") && data.Contains("net.1") {
return nil, httperrors.NewInputParameterError("cannot support more than 1 nic")
}
return data, nil
}
func (self *SOpenStackGuestDriver) AllowReconfigGuest() bool {
return true
}
func (self *SOpenStackGuestDriver) IsSupportedBillingCycle(bc billing.SBillingCycle) bool {
return false
}
+1 -1
View File
@@ -350,7 +350,7 @@ func (self *SQcloudGuestDriver) RequestSyncConfigOnHost(ctx context.Context, gue
}
externalIds = append(externalIds, extID)
}
return nil, iVM.AssignSecurityGroups(externalIds)
return nil, iVM.SetSecurityGroups(externalIds)
}
iDisks, err := iVM.GetIDisks()
+4
View File
@@ -16,3 +16,7 @@ func init() {
func (self *SOpenStackHostDriver) GetHostType() string {
return models.HOST_TYPE_OPENSTACK
}
func (self *SOpenStackHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb int) error {
return nil
}
+2 -2
View File
@@ -896,8 +896,8 @@ func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
return self.host.zone.region.AssignSecurityGroup(secgroupId, self.InstanceId)
}
func (self *SInstance) AssignSecurityGroups(secgroupIds []string) error {
return self.host.zone.region.AssignSecurityGroups(secgroupIds, self.InstanceId)
func (self *SInstance) SetSecurityGroups(secgroupIds []string) error {
return self.host.zone.region.SetSecurityGroups(secgroupIds, self.InstanceId)
}
func (self *SInstance) GetBillingType() string {
+2 -2
View File
@@ -501,10 +501,10 @@ func (self *SRegion) syncSecgroupRules(secgroupId string, rules []secrules.Secur
}
func (self *SRegion) AssignSecurityGroup(secgroupId, instanceId string) error {
return self.AssignSecurityGroups([]string{secgroupId}, instanceId)
return self.SetSecurityGroups([]string{secgroupId}, instanceId)
}
func (self *SRegion) AssignSecurityGroups(secgroupIds []string, instanceId string) error {
func (self *SRegion) SetSecurityGroups(secgroupIds []string, instanceId string) error {
params := map[string]string{"InstanceId": instanceId}
for _, secgroupId := range secgroupIds {
params["SecurityGroupId"] = secgroupId
+2 -2
View File
@@ -283,10 +283,10 @@ func (self *SInstance) GetMachine() string {
}
func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
return self.AssignSecurityGroups([]string{secgroupId})
return self.SetSecurityGroups([]string{secgroupId})
}
func (self *SInstance) AssignSecurityGroups(secgroupIds []string) error {
func (self *SInstance) SetSecurityGroups(secgroupIds []string) error {
ids := []*string{}
for i := 0; i < len(secgroupIds); i++ {
ids = append(ids, &secgroupIds[i])
+1 -1
View File
@@ -487,7 +487,7 @@ type assignProperties struct {
NetworkSecurityGroup SubResource `json:"networkSecurityGroup,omitempty"`
}
func (self *SClassicInstance) AssignSecurityGroups(secgroupIds []string) error {
func (self *SClassicInstance) SetSecurityGroups(secgroupIds []string) error {
return cloudprovider.ErrNotSupported
}
+1 -1
View File
@@ -1020,7 +1020,7 @@ func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
return self.host.zone.region.AssiginSecurityGroup(self.ID, secgroupId)
}
func (self *SInstance) AssignSecurityGroups(secgroupIds []string) error {
func (self *SInstance) SetSecurityGroups(secgroupIds []string) error {
return cloudprovider.ErrNotSupported
}
+1 -1
View File
@@ -528,7 +528,7 @@ func (dc *SVirtualMachine) ChangeConfig2(ctx context.Context, instanceType strin
return cloudprovider.ErrNotImplemented
}
func (self *SVirtualMachine) AssignSecurityGroups(secgroupIds []string) error {
func (self *SVirtualMachine) SetSecurityGroups(secgroupIds []string) error {
return cloudprovider.ErrNotImplemented
}
+3 -2
View File
@@ -9,6 +9,7 @@ import (
"strconv"
"sort"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudprovider"
@@ -363,10 +364,10 @@ func (self *SInstance) GetMachine() string {
}
func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
return self.AssignSecurityGroups([]string{secgroupId})
return self.SetSecurityGroups([]string{secgroupId})
}
func (self *SInstance) AssignSecurityGroups(secgroupIds []string) error {
func (self *SInstance) SetSecurityGroups(secgroupIds []string) error {
currentSecgroups, err := self.host.zone.region.GetInstanceSecrityGroupIds(self.GetId())
if err != nil {
return err
+41 -18
View File
@@ -2,9 +2,11 @@ package openstack
import (
"context"
"fmt"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
)
@@ -104,7 +106,7 @@ func (disk *SDisk) GetMetadata() *jsonutils.JSONDict {
}
func (region *SRegion) GetDisks(category string) ([]SDisk, error) {
_, resp, err := region.CinderGet("/volumes/detail", "", nil)
_, resp, err := region.CinderList("/volumes/detail", "", nil)
if err != nil {
return nil, err
}
@@ -126,11 +128,11 @@ func (disk *SDisk) GetId() string {
}
func (disk *SDisk) Delete(ctx context.Context) error {
return cloudprovider.ErrNotImplemented
return disk.storage.zone.region.DeleteDisk(disk.ID)
}
func (disk *SDisk) Resize(ctx context.Context, sizeMb int64) error {
return cloudprovider.ErrNotImplemented
return disk.storage.zone.region.ResizeDisk(disk.ID, sizeMb)
}
func (disk *SDisk) GetName() string {
@@ -179,8 +181,8 @@ func (disk *SDisk) Refresh() error {
return jsonutils.Update(disk, new)
}
func (disk *SDisk) ResizeDisk(newSize int64) error {
return disk.storage.zone.region.ResizeDisk(disk.ID, newSize)
func (disk *SDisk) ResizeDisk(sizeMb int64) error {
return disk.storage.zone.region.ResizeDisk(disk.ID, sizeMb)
}
func (disk *SDisk) GetDiskFormat() string {
@@ -226,8 +228,21 @@ func (disk *SDisk) GetMountpoint() string {
return ""
}
func (disk *SRegion) CreateDisk(zoneId string, category string, name string, sizeGb int, desc string) (string, error) {
return "", cloudprovider.ErrNotImplemented
func (region *SRegion) CreateDisk(zoneName string, category string, name string, sizeGb int, desc string) (string, error) {
params := map[string]map[string]interface{}{
"volume": {
"size": sizeGb,
"volume_type": category,
"name": name,
"description": desc,
"availability_zone": zoneName,
},
}
_, resp, err := region.CinderCreate("/volumes", "", jsonutils.Marshal(params))
if err != nil {
return "", err
}
return resp.GetString("volume", "id")
}
func (region *SRegion) GetDisk(diskId string) (*SDisk, error) {
@@ -239,12 +254,19 @@ func (region *SRegion) GetDisk(diskId string) (*SDisk, error) {
return disk, resp.Unmarshal(disk, "volume")
}
func (disk *SRegion) DeleteDisk(diskId string) error {
return cloudprovider.ErrNotImplemented
func (region *SRegion) DeleteDisk(diskId string) error {
_, err := region.CinderDelete("/volumes/"+diskId, "")
return err
}
func (disk *SRegion) ResizeDisk(diskId string, sizeMb int64) error {
return cloudprovider.ErrNotImplemented
func (region *SRegion) ResizeDisk(diskId string, sizeMb int64) error {
params := map[string]map[string]interface{}{
"os-extend": {
"new_size": sizeMb / 1024,
},
}
_, _, err := region.CinderAction(fmt.Sprintf("/volumes/%s/action", diskId), "", jsonutils.Marshal(params))
return err
}
func (disk *SRegion) ResetDisk(diskId, snapshotId string) error {
@@ -252,7 +274,12 @@ func (disk *SRegion) ResetDisk(diskId, snapshotId string) error {
}
func (disk *SDisk) CreateISnapshot(ctx context.Context, name, desc string) (cloudprovider.ICloudSnapshot, error) {
return nil, cloudprovider.ErrNotImplemented
snapshotId, err := disk.storage.zone.region.CreateSnapshot(disk.ID, name, desc)
if err != nil {
log.Errorf("createSnapshot fail %v", err)
return nil, err
}
return disk.storage.zone.region.GetISnapshotById(snapshotId)
}
func (disk *SDisk) GetISnapshot(snapshotId string) (cloudprovider.ICloudSnapshot, error) {
@@ -264,7 +291,7 @@ func (disk *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
}
func (disk *SDisk) Reset(ctx context.Context, snapshotId string) (string, error) {
return "", disk.storage.zone.region.ResetDisk(disk.ID, snapshotId)
return "", cloudprovider.ErrNotSupported
}
func (disk *SDisk) GetBillingType() string {
@@ -280,9 +307,5 @@ func (disk *SDisk) GetAccessPath() string {
}
func (disk *SDisk) Rebuild(ctx context.Context) error {
return disk.storage.zone.region.RebuildDisk(disk.ID)
}
func (region *SRegion) RebuildDisk(diskId string) error {
return cloudprovider.ErrNotImplemented
return cloudprovider.ErrNotSupported
}
+231
View File
@@ -0,0 +1,231 @@
package openstack
import (
"context"
"net/url"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/pkg/utils"
)
const (
QUEUED = "queued" // The Image service reserved an image ID for the image in the catalog but did not yet upload any image data.
SAVING = "saving" // The Image service is in the process of saving the raw data for the image into the backing store.
ACTIVE = "active" // The image is active and ready for consumption in the Image service.
KILLED = "killed" // An image data upload error occurred.
DELETED = "deleted" // The Image service retains information about the image but the image is no longer available for use.
PENDING_DELETE = "pending_delete" // Similar to the deleted status. An image in this state is not recoverable.
DEACTIVATED = "deactivated" // The image data is not available for use.
UPLOADING = "uploading" // Data has been staged as part of the interoperable image import process. It is not yet available for use. (Since Image API 2.6)
IMPORTING = "importing" // The image data is being processed as part of the interoperable image import process, but is not yet available for use. (Since Image API 2.6)
)
type SImage struct {
storageCache *SStoragecache
Status string
Name string
Tags []string
ContainerFormat string
CreatedAt time.Time
DiskFormat string
UpdatedAt time.Time
Visibility string
Self string
MinDisk int
Protected bool
ID string
File string
Checksum string
OsHashAlgo string
OsHashValue string
OsHidden bool
Owner string
Size int
MinRAM int
Schema string
VirtualSize int
visibility string
}
func (region *SRegion) GetImages(name string, status string, imageIds []string) ([]SImage, error) {
params := url.Values{}
if utils.IsInStringArray(status, []string{QUEUED, SAVING, ACTIVE, KILLED, DELETED, PENDING_DELETE, DEACTIVATED, UPLOADING, IMPORTING}) {
params.Add("status", status)
}
if len(name) > 0 {
params.Add("name", name)
}
if len(imageIds) > 0 {
params.Add("id", "in:"+strings.Join(imageIds, ","))
}
_, resp, err := region.List("image", "/v2/images?"+params.Encode(), "", nil)
if err != nil {
return nil, err
}
images := []SImage{}
return images, resp.Unmarshal(&images, "images")
}
func (image *SImage) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (image *SImage) GetId() string {
return image.ID
}
func (image *SImage) GetName() string {
return image.Name
}
func (image *SImage) IsEmulated() bool {
return false
}
func (image *SImage) GetGlobalId() string {
return image.ID
}
func (image *SImage) Delete(ctx context.Context) error {
return image.storageCache.region.DeleteImage(image.ID)
}
func (image *SImage) GetStatus() string {
switch image.Status {
case QUEUED, SAVING, UPLOADING, IMPORTING:
return models.CACHED_IMAGE_STATUS_CACHING
case ACTIVE:
return models.CACHED_IMAGE_STATUS_READY
case DELETED, DEACTIVATED, PENDING_DELETE, KILLED:
return models.CACHED_IMAGE_STATUS_CACHE_FAILED
default:
return models.CACHED_IMAGE_STATUS_CACHE_FAILED
}
}
func (image *SImage) GetImageStatus() string {
switch image.Status {
case QUEUED, SAVING, UPLOADING, IMPORTING:
return models.CACHED_IMAGE_STATUS_CACHING
case ACTIVE:
return models.CACHED_IMAGE_STATUS_READY
case DELETED, DEACTIVATED, PENDING_DELETE, KILLED:
return models.CACHED_IMAGE_STATUS_CACHE_FAILED
default:
return models.CACHED_IMAGE_STATUS_CACHE_FAILED
}
}
func (image *SImage) Refresh() error {
new, err := image.storageCache.region.GetImage(image.ID)
if err != nil {
return err
}
return jsonutils.Update(image, new)
}
func (image *SImage) GetImageType() string {
switch image.Visibility {
case "public":
return cloudprovider.CachedImageTypeSystem
default:
return cloudprovider.CachedImageTypeCustomized
}
}
func (image *SImage) GetSize() int64 {
return int64(image.Size)
}
func (image *SImage) GetOsType() string {
return "Linux"
}
func (image *SImage) GetOsDist() string {
return "Linux"
}
func (image *SImage) GetOsVersion() string {
return ""
}
func (image *SImage) GetOsArch() string {
return "x86_64"
}
func (image *SImage) GetMinOsDiskSizeGb() int {
return 50
}
func (image *SImage) GetImageFormat() string {
return image.DiskFormat
}
func (image *SImage) GetCreateTime() time.Time {
return image.CreatedAt
}
func (region *SRegion) GetImage(imageId string) (*SImage, error) {
images, err := region.GetImages("", "", []string{imageId})
if err != nil {
return nil, err
}
if len(images) == 0 {
return nil, cloudprovider.ErrNotFound
}
return &images[0], nil
}
func (image *SImage) GetIStoragecache() cloudprovider.ICloudStoragecache {
return image.storageCache
}
func (region *SRegion) DeleteImage(imageId string) error {
_, err := region.Delete("image", "/v2/images/"+imageId, "")
return err
}
func (region *SRegion) GetImageStatus(imageId string) (string, error) {
image, err := region.GetImage(imageId)
if err != nil {
return "", err
}
return image.Status, nil
}
func (region *SRegion) GetImageByName(name string) (*SImage, error) {
images, err := region.GetImages(name, "", []string{})
if err != nil {
return nil, err
}
if len(images) == 0 {
return nil, cloudprovider.ErrNotFound
}
return &images[0], nil
}
// func (region *SRegion) ImportImage(name string, osArch, osDist, osVersion string, imageUrl string) (*SImage, error) {
// params, err := region.GetImportImageParams(name, osArch, osDist, osVersion, imageUrl)
// if err != nil {
// return nil, err
// }
// log.Debugf("Upload image with params %#v", params)
// if _, err := region.cvmRequest("ImportImage", params); err != nil {
// return nil, err
// }
// for i := 0; i < 8; i++ {
// image, err := region.GetImageByName(name)
// if err == nil {
// return image, nil
// }
// time.Sleep(time.Minute * time.Duration(i))
// }
// return nil, cloudprovider.ErrNotFound
// }
+80 -13
View File
@@ -10,6 +10,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/pkg/utils"
)
const (
@@ -137,7 +138,7 @@ func (region *SRegion) GetSecurityGroupsByInstance(instanceId string) ([]Securit
func (region *SRegion) GetInstances(zoneName string, hostName string) ([]SInstance, error) {
_, maxVersion, _ := region.GetVersion("compute")
_, resp, err := region.Get("compute", "/servers/detail", maxVersion, nil)
_, resp, err := region.List("compute", "/servers/detail", maxVersion, nil)
if err != nil {
return nil, err
}
@@ -337,11 +338,17 @@ func (instance *SInstance) GetHypervisor() string {
}
func (instance *SInstance) StartVM(ctx context.Context) error {
return cloudprovider.ErrNotImplemented
if err := instance.host.zone.region.StartVM(instance.ID); err != nil {
return err
}
return cloudprovider.WaitStatus(instance, models.VM_RUNNING, 10*time.Second, 8*time.Minute)
}
func (instance *SInstance) StopVM(ctx context.Context, isForce bool) error {
return cloudprovider.ErrNotImplemented
if err := instance.host.zone.region.StopVM(instance.ID, isForce); err != nil {
return err
}
return cloudprovider.WaitStatus(instance, models.VM_RUNNING, 10*time.Second, 8*time.Minute)
}
func (region *SRegion) GetInstanceVNCUrl(instanceId string) (string, error) {
@@ -401,20 +408,23 @@ func (region *SRegion) CreateInstance(name string, imageId string, instanceType
return "", cloudprovider.ErrNotImplemented
}
func (region *SRegion) doStartVM(instanceId string) error {
return cloudprovider.ErrNotImplemented
func (region *SRegion) instanceOperation(instanceId, operate string) error {
params := jsonutils.Marshal(map[string]string{operate: ""})
_, maxVersion, _ := region.GetVersion("compute")
_, _, err := region.Post("compute", fmt.Sprintf("/servers/%s/action", instanceId), maxVersion, params)
return err
}
func (region *SRegion) doStopVM(instanceId string, isForce bool) error {
return cloudprovider.ErrNotImplemented
return region.instanceOperation(instanceId, "os-stop")
}
func (region *SRegion) doDeleteVM(instanceId string) error {
return cloudprovider.ErrNotImplemented
return region.instanceOperation(instanceId, "forceDelete")
}
func (region *SRegion) StartVM(instanceId string) error {
return cloudprovider.ErrNotImplemented
return region.instanceOperation(instanceId, "os-start")
}
func (region *SRegion) StopVM(instanceId string, isForce bool) error {
@@ -422,7 +432,20 @@ func (region *SRegion) StopVM(instanceId string, isForce bool) error {
}
func (region *SRegion) DeleteVM(instanceId string) error {
return cloudprovider.ErrNotImplemented
instance, err := region.GetInstance(instanceId)
if err != nil {
if err == cloudprovider.ErrNotFound {
return nil
}
log.Errorf("failed to get instance %s %v", instanceId, err)
return err
}
status := instance.GetStatus()
log.Debugf("Instance status on delete is %s", status)
if status != models.VM_READY {
log.Warningf("DeleteVM: vm status is %s expect %s", status, models.VM_READY)
}
return region.doDeleteVM(instanceId)
}
func (region *SRegion) DeployVM(instanceId string, name string, password string, keypairName string, deleteKeypair bool, description string) error {
@@ -430,7 +453,7 @@ func (region *SRegion) DeployVM(instanceId string, name string, password string,
}
func (instance *SInstance) DeleteVM(ctx context.Context) error {
return cloudprovider.ErrNotImplemented
return instance.host.zone.region.DeleteVM(instance.ID)
}
func (region *SRegion) ReplaceSystemDisk(instanceId string, imageId string, passwd string, keypairName string, sysDiskSizeGB int) error {
@@ -454,11 +477,55 @@ func (region *SRegion) AttachDisk(instanceId string, diskId string) error {
}
func (instance *SInstance) AssignSecurityGroup(secgroupId string) error {
return cloudprovider.ErrNotImplemented
secgroup, err := instance.host.zone.region.GetSecurityGroup(secgroupId)
if err != nil {
return err
}
params := map[string]map[string]string{
"addSecurityGroup": {
"name": secgroup.Name,
},
}
_, _, err = instance.host.zone.region.Post("compute", fmt.Sprintf("/servers/%s/action", instance.ID), "", jsonutils.Marshal(params))
return err
}
func (instance *SInstance) AssignSecurityGroups(secgroupIds []string) error {
return cloudprovider.ErrNotImplemented
func (instance *SInstance) RevokeSecurityGroup(secgroupId string) error {
secgroup, err := instance.host.zone.region.GetSecurityGroup(secgroupId)
if err != nil {
return err
}
params := map[string]map[string]string{
"removeSecurityGroup": {
"name": secgroup.Name,
},
}
_, _, err = instance.host.zone.region.Post("compute", fmt.Sprintf("/servers/%s/action", instance.ID), "", jsonutils.Marshal(params))
return err
}
func (instance *SInstance) SetSecurityGroups(secgroupIds []string) error {
secgroups, err := instance.host.zone.region.GetSecurityGroupsByInstance(instance.ID)
if err != nil {
return err
}
originIds := []string{}
for _, secgroup := range secgroups {
if !utils.IsInStringArray(secgroup.ID, secgroupIds) {
if err := instance.RevokeSecurityGroup(secgroup.ID); err != nil {
return err
}
}
originIds = append(originIds, secgroup.ID)
}
for _, secgroupId := range secgroupIds {
if !utils.IsInStringArray(secgroupId, originIds) {
if err := instance.AssignSecurityGroup(secgroupId); err != nil {
return err
}
}
}
return nil
}
func (instance *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) {
+19 -5
View File
@@ -73,8 +73,9 @@ func (network *SNetwork) Delete() error {
return network.wire.zone.region.DeleteNetwork(network.ID)
}
func (network *SRegion) DeleteNetwork(networkId string) error {
return cloudprovider.ErrNotImplemented
func (region *SRegion) DeleteNetwork(networkId string) error {
_, err := region.Delete("network", "/v2.0/subnets/"+networkId, "")
return err
}
func (network *SNetwork) GetIWire() cloudprovider.ICloudWire {
@@ -126,7 +127,7 @@ func (region *SRegion) GetNetwork(networkId string) (*SNetwork, error) {
}
func (region *SRegion) GetNetworks(vpcId string) ([]SNetwork, error) {
_, resp, err := region.Get("network", "/v2.0/subnets", "", nil)
_, resp, err := region.List("network", "/v2.0/subnets", "", nil)
if err != nil {
return nil, err
}
@@ -152,6 +153,19 @@ func (network *SNetwork) Refresh() error {
return jsonutils.Update(network, new)
}
func (network *SRegion) CreateNetwork(zoneId string, vpcId string, name string, cidr string, desc string) (string, error) {
return "", cloudprovider.ErrNotImplemented
func (region *SRegion) CreateNetwork(vpcId string, name string, cidr string, desc string) (string, error) {
params := map[string]map[string]interface{}{
"subnet": {
"name": name,
"network_id": vpcId,
"cidr": cidr,
"description": desc,
"ip_version": 4,
},
}
_, resp, err := region.Post("network", "/v2.0/subnets", "", jsonutils.Marshal(params))
if err != nil {
return "", err
}
return resp.GetString("subnet", "id")
}
+26
View File
@@ -3,6 +3,7 @@ package openstack
import (
"context"
"fmt"
"io"
"net/http"
"strings"
@@ -71,6 +72,31 @@ func (cli *SOpenStackClient) Request(region, service, method string, url string,
return session.JSONRequest(service, "", httputils.THttpMethod(method), url, header, body)
}
func (cli *SOpenStackClient) RawRequest(region, service, method string, url string, microversion string, body jsonutils.JSONObject) (*http.Response, error) {
header := http.Header{}
if len(microversion) > 0 {
header.Set("X-Openstack-Nova-API-Version", microversion)
}
ctx := context.Background()
session := cli.client.NewSession(ctx, region, "", "internal", cli.tokenCredential, "")
data := strings.NewReader("")
if body != nil {
data = strings.NewReader(body.String())
}
return session.RawRequest(service, "", httputils.THttpMethod(method), url, header, data)
}
func (cli *SOpenStackClient) StreamRequest(region, service, method string, url string, microversion string, body io.Reader) (*http.Response, error) {
header := http.Header{}
if len(microversion) > 0 {
header.Set("X-Openstack-Nova-API-Version", microversion)
}
header.Set("Content-Type", "application/octet-stream")
ctx := context.Background()
session := cli.client.NewSession(ctx, region, "", "internal", cli.tokenCredential, "")
return session.RawRequest(service, "", httputils.THttpMethod(method), url, header, body)
}
func (cli *SOpenStackClient) getVersion(region string, service string) (string, string, error) {
ctx := context.Background()
session := cli.client.NewSession(ctx, region, "", "internal", cli.tokenCredential, "")
+1 -1
View File
@@ -60,7 +60,7 @@ func (region *SRegion) GetPorts(macAddress string) ([]SPort, error) {
params.Set("mac_address", macAddress)
}
url := fmt.Sprintf("%s?%s", base, params.Encode())
_, resp, err := region.Get("network", url, "", nil)
_, resp, err := region.List("network", url, "", nil)
if err != nil {
return nil, err
}
+97 -3
View File
@@ -3,6 +3,7 @@ package openstack
import (
"fmt"
"net/http"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -63,7 +64,25 @@ func (region *SRegion) Refresh() error {
}
func (region *SRegion) CreateIVpc(name string, desc string, cidr string) (cloudprovider.ICloudVpc, error) {
return nil, cloudprovider.ErrNotImplemented
params := map[string]map[string]string{
"network": {
"name": name,
"description": desc,
},
}
_, resp, err := region.Post("network", "/v2.0/networks", "", jsonutils.Marshal(params))
if err != nil {
return nil, err
}
err = region.fetchInfrastructure()
if err != nil {
return nil, err
}
vpcId, err := resp.GetString("network", "id")
if err != nil {
return nil, err
}
return region.GetIVpcById(vpcId)
}
func (region *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
@@ -173,7 +192,7 @@ func (region *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error)
}
func (region *SRegion) fetchZones() error {
_, resp, err := region.Get("compute", "/os-availability-zone", "", jsonutils.NewDict())
_, resp, err := region.List("compute", "/os-availability-zone", "", jsonutils.NewDict())
if err != nil {
return err
}
@@ -227,14 +246,53 @@ func (region *SRegion) fetchInfrastructure() error {
}
func (region *SRegion) Get(service, url string, microversion string, body jsonutils.JSONObject) (http.Header, jsonutils.JSONObject, error) {
return region.client.Request(region.Name, service, "GET", url, microversion, body)
if strings.HasSuffix(url, "/") {
return nil, nil, cloudprovider.ErrNotFound
}
header, resp, err := region.client.Request(region.Name, service, "GET", url, microversion, body)
if err != nil {
if strings.Contains(err.Error(), "404") {
return nil, nil, cloudprovider.ErrNotFound
}
return nil, nil, err
}
return header, resp, nil
}
func (region *SRegion) List(service, url string, microversion string, body jsonutils.JSONObject) (http.Header, jsonutils.JSONObject, error) {
header, resp, err := region.client.Request(region.Name, service, "GET", url, microversion, body)
if err != nil {
if strings.Contains(err.Error(), "404") {
return nil, nil, cloudprovider.ErrNotFound
}
return nil, nil, err
}
return header, resp, nil
}
func (region *SRegion) Post(service, url string, microversion string, body jsonutils.JSONObject) (http.Header, jsonutils.JSONObject, error) {
return region.client.Request(region.Name, service, "POST", url, microversion, body)
}
func (region *SRegion) Delete(service, url string, microversion string) (*http.Response, error) {
return region.client.RawRequest(region.Name, service, "DELETE", url, microversion, nil)
}
func (region *SRegion) CinderList(url string, microversion string, body jsonutils.JSONObject) (http.Header, jsonutils.JSONObject, error) {
for _, service := range []string{"volumev3", "volumev2", "volume"} {
header, resp, err := region.Get(service, url, microversion, body)
if err == nil {
return header, resp, nil
}
log.Debugf("failed to list %s by service %s error: %v, try another", url, service, err)
}
return nil, nil, fmt.Errorf("failed to get %s by cinder service", url)
}
func (region *SRegion) CinderGet(url string, microversion string, body jsonutils.JSONObject) (http.Header, jsonutils.JSONObject, error) {
if strings.HasSuffix(url, "/") {
return nil, nil, cloudprovider.ErrNotFound
}
for _, service := range []string{"volumev3", "volumev2", "volume"} {
header, resp, err := region.Get(service, url, microversion, body)
if err == nil {
@@ -245,6 +303,42 @@ func (region *SRegion) CinderGet(url string, microversion string, body jsonutils
return nil, nil, fmt.Errorf("failed to get %s by cinder service", url)
}
func (region *SRegion) CinderCreate(url string, microversion string, body jsonutils.JSONObject) (http.Header, jsonutils.JSONObject, error) {
for _, service := range []string{"volumev3", "volumev2", "volume"} {
header, resp, err := region.Post(service, url, microversion, body)
if err == nil {
return header, resp, nil
}
log.Debugf("failed to create %s by service %s error: %v, try another", url, service, err)
}
return nil, nil, fmt.Errorf("failed to create %s by cinder service", url)
}
func (region *SRegion) CinderDelete(url string, microversion string) (*http.Response, error) {
if strings.HasSuffix(url, "/") {
return nil, cloudprovider.ErrNotFound
}
for _, service := range []string{"volumev3", "volumev2", "volume"} {
resp, err := region.Delete(service, url, microversion)
if err == nil {
return resp, nil
}
log.Debugf("failed to delete %s by service %s error: %v, try another", url, service, err)
}
return nil, fmt.Errorf("failed to delete %s by cinder service", url)
}
func (region *SRegion) CinderAction(url string, microversion string, body jsonutils.JSONObject) (http.Header, jsonutils.JSONObject, error) {
for _, service := range []string{"volumev3", "volumev2", "volume"} {
header, resp, err := region.Post(service, url, microversion, body)
if err == nil {
return header, resp, nil
}
log.Debugf("failed to operate %s by service %s error: %v, try another", url, service, err)
}
return nil, nil, fmt.Errorf("failed to operate %s by cinder service", url)
}
func (region *SRegion) ProjectId() string {
return region.client.tokenCredential.GetProjectId()
}
+135 -6
View File
@@ -2,10 +2,12 @@ package openstack
import (
"net"
"sort"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
@@ -45,6 +47,20 @@ type SSecurityGroup struct {
TenantID string
}
type SecurigyGroupRuleSet []SSecurityGroupRule
func (v SecurigyGroupRuleSet) Len() int {
return len(v)
}
func (v SecurigyGroupRuleSet) Swap(i, j int) {
v[i], v[j] = v[j], v[i]
}
func (v SecurigyGroupRuleSet) Less(i, j int) bool {
return strings.Compare(v[i].String(), v[j].String()) <= 0
}
func (region *SRegion) GetSecurityGroup(secgroupId string) (*SSecurityGroup, error) {
_, resp, err := region.Get("network", "/v2.0/security-groups/"+secgroupId, "", nil)
if err != nil {
@@ -55,7 +71,7 @@ func (region *SRegion) GetSecurityGroup(secgroupId string) (*SSecurityGroup, err
}
func (region *SRegion) GetSecurityGroups() ([]SSecurityGroup, error) {
_, resp, err := region.Get("network", "/v2.0/security-groups", "", nil)
_, resp, err := region.List("network", "/v2.0/security-groups", "", nil)
if err != nil {
return nil, err
}
@@ -172,14 +188,127 @@ func (secgroup *SSecurityGroup) Refresh() error {
return jsonutils.Update(secgroup, new)
}
func (secgroup *SRegion) SyncSecurityGroup(secgroupId string, vpcId string, name string, desc string, rules []secrules.SecurityRule) (string, error) {
return "", cloudprovider.ErrNotImplemented
func (region *SRegion) SyncSecurityGroup(secgroupId string, vpcId string, name string, desc string, rules []secrules.SecurityRule) (string, error) {
if len(secgroupId) > 0 {
_, err := region.GetSecurityGroup(secgroupId)
if err != nil {
if err != cloudprovider.ErrNotFound {
return "", err
}
secgroupId = ""
}
}
if len(secgroupId) == 0 {
secgroupId, err := region.CreateSecurityGroup(name, desc)
if err != nil {
return "", err
}
secgroupId = secgroupId
}
return region.syncSecgroupRules(secgroupId, rules)
}
func (region *SRegion) syncSecgroupRules(secgroupId string, rules []secrules.SecurityRule) (string, error) {
secgroup, err := region.GetSecurityGroup(secgroupId)
if err != nil {
return "", err
}
sort.Sort(secrules.SecurityRuleSet(rules))
sort.Sort(SecurigyGroupRuleSet(secgroup.SecurityGroupRules))
i, j := 0, 0
for i < len(rules) || j < len(secgroup.SecurityGroupRules) {
if i < len(rules) && j < len(secgroup.SecurityGroupRules) {
secruleStr := secgroup.SecurityGroupRules[j].String()
ruleStr := rules[i].String()
cmp := strings.Compare(secruleStr, ruleStr)
if cmp == 0 {
i++
j++
} else if cmp > 0 {
if err := region.delSecurityGroupRule(secgroup.SecurityGroupRules[j].ID); err != nil {
log.Errorf("delSecurityGroupRule error %v", err)
return "", err
}
j++
} else {
if err := region.addSecurityGroupRules(secgroupId, &rules[i]); err != nil {
log.Errorf("addSecurityGroupRule error %v", rules[i])
return "", err
}
i++
}
} else if i >= len(rules) {
if err := region.delSecurityGroupRule(secgroup.SecurityGroupRules[j].ID); err != nil {
log.Errorf("delSecurityGroupRule error %v", err)
return "", err
}
j++
} else if j >= len(secgroup.SecurityGroupRules) {
if err := region.addSecurityGroupRules(secgroupId, &rules[i]); err != nil {
log.Errorf("addSecurityGroupRule error %v", rules[i])
return "", err
}
i++
}
}
return secgroupId, nil
}
func (region *SRegion) delSecurityGroupRule(ruleId string) error {
_, err := region.Delete("network", "/v2.0/security-group-rules/"+ruleId, "")
return err
}
func (region *SRegion) addSecurityGroupRules(secgroupId string, rule *secrules.SecurityRule) error {
direction := "ingress"
if rule.Direction == secrules.SecurityRuleEgress {
direction = "egress"
}
params := map[string]map[string]interface{}{
"security_group_rule": {
"direction": direction,
"protocol": rule.Protocol,
"security_group_id": secgroupId,
"remote_ip_prefix": rule.IPNet.String(),
},
}
if len(rule.Ports) > 0 {
for _, port := range rule.Ports {
params["security_group_rule"]["port_range_max"] = port
params["security_group_rule"]["port_range_max"] = port
_, _, err := region.Post("network", "/v2.0/security-group-rules", "", jsonutils.Marshal(params))
if err != nil {
return err
}
}
return nil
}
if rule.PortEnd > 0 && rule.PortStart > 0 {
params["security_group_rule"]["port_range_max"] = rule.PortStart
params["security_group_rule"]["port_range_max"] = rule.PortEnd
}
_, _, err := region.Post("network", "/v2.0/security-group-rules", "", jsonutils.Marshal(params))
return err
}
func (region *SRegion) DeleteSecurityGroup(vpcId, secGroupId string) error {
return cloudprovider.ErrNotImplemented
_, err := region.Delete("network", "/v2.0/security-groups/"+secGroupId, "")
return err
}
func (region *SRegion) CreateSecurityGroup(name, description string) (*SSecurityGroup, error) {
return nil, cloudprovider.ErrNotImplemented
func (region *SRegion) CreateSecurityGroup(name, description string) (string, error) {
params := map[string]map[string]interface{}{
"security_group": {
"name": name,
"description": description,
},
}
_, resp, err := region.Post("network", "/v2.0/security-groups", "", jsonutils.Marshal(params))
if err != nil {
return "", err
}
return resp.GetString("security_group", "id")
}
+24 -3
View File
@@ -1,6 +1,8 @@
package shell
import (
"fmt"
"yunion.io/x/onecloud/pkg/util/openstack"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
@@ -18,11 +20,11 @@ func init() {
return nil
})
type DiskShowOptions struct {
ID string `help:"Storage type for disk"`
type DiskOptions struct {
ID string `help:"ID of disk"`
}
shellutils.R(&DiskShowOptions{}, "disk-show", "Show disk", func(cli *openstack.SRegion, args *DiskShowOptions) error {
shellutils.R(&DiskOptions{}, "disk-show", "Show disk", func(cli *openstack.SRegion, args *DiskOptions) error {
disk, err := cli.GetDisk(args.ID)
if err != nil {
return err
@@ -30,4 +32,23 @@ func init() {
printObject(disk)
return nil
})
shellutils.R(&DiskOptions{}, "disk-delete", "Delete disk", func(cli *openstack.SRegion, args *DiskOptions) error {
return cli.DeleteDisk(args.ID)
})
type DiskCreateOptions struct {
ZONE string `help:"Zone name"`
CATEGORY string `help:"Disk category"`
NAME string `help:"Disk Name"`
SIZE int `help:"Disk Size GB"`
}
shellutils.R(&DiskCreateOptions{}, "disk-create", "Create disk", func(cli *openstack.SRegion, args *DiskCreateOptions) error {
diskId, err := cli.CreateDisk(args.ZONE, args.CATEGORY, args.NAME, args.SIZE, "")
if err != nil {
return err
}
fmt.Println(diskId)
return nil
})
}
+36
View File
@@ -0,0 +1,36 @@
package shell
import (
"yunion.io/x/onecloud/pkg/util/openstack"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type ImageListOptions struct {
Name string
Ids []string
Status string
}
shellutils.R(&ImageListOptions{}, "image-list", "List images", func(cli *openstack.SRegion, args *ImageListOptions) error {
images, err := cli.GetImages(args.Name, args.Status, args.Ids)
if err != nil {
return err
}
printList(images, 0, 0, 0, []string{})
return nil
})
type ImageOptions struct {
ID string
}
shellutils.R(&ImageOptions{}, "image-show", "Show image", func(cli *openstack.SRegion, args *ImageOptions) error {
image, err := cli.GetImages("", "", []string{args.ID})
if err != nil {
return err
}
printObject(image[0])
return nil
})
}
+23 -2
View File
@@ -1,6 +1,8 @@
package shell
import (
"fmt"
"yunion.io/x/onecloud/pkg/util/openstack"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
@@ -18,11 +20,11 @@ func init() {
return nil
})
type SnapshotShowOptions struct {
type SnapshotOptions struct {
ID string `help:"ID of snapshot"`
}
shellutils.R(&SnapshotShowOptions{}, "snapshot-show", "Show snapshot", func(cli *openstack.SRegion, args *SnapshotShowOptions) error {
shellutils.R(&SnapshotOptions{}, "snapshot-show", "Show snapshot", func(cli *openstack.SRegion, args *SnapshotOptions) error {
snapshot, err := cli.GetISnapshotById(args.ID)
if err != nil {
return err
@@ -31,4 +33,23 @@ func init() {
return nil
})
shellutils.R(&SnapshotOptions{}, "snapshot-delete", "Delete snapshot", func(cli *openstack.SRegion, args *SnapshotOptions) error {
return cli.DeleteSnapshot(args.ID)
})
type SnapshotCreateOptions struct {
DISKID string `help:"Disk ID"`
Name string `help:"Disk Name"`
Desc string `help:"Disk description"`
}
shellutils.R(&SnapshotCreateOptions{}, "snapshot-create", "Create snapshot", func(cli *openstack.SRegion, args *SnapshotCreateOptions) error {
snapshotId, err := cli.CreateSnapshot(args.DISKID, args.Name, args.Desc)
if err != nil {
return err
}
fmt.Println(snapshotId)
return nil
})
}
+21 -5
View File
@@ -78,7 +78,7 @@ func (snapshot *SSnapshot) Refresh() error {
}
func (region *SRegion) GetSnapshots(diskId string) ([]cloudprovider.ICloudSnapshot, error) {
_, resp, err := region.CinderGet("/snapshots/detail", "", nil)
_, resp, err := region.CinderList("/snapshots/detail", "", nil)
if err != nil {
return nil, err
}
@@ -121,6 +121,9 @@ func (snapshot *SSnapshot) GetGlobalId() string {
}
func (snapshot *SSnapshot) GetName() string {
if len(snapshot.Name) == 0 {
return snapshot.ID
}
return snapshot.Name
}
@@ -139,10 +142,23 @@ func (snapshot *SSnapshot) GetDiskType() string {
return models.DISK_TYPE_DATA
}
func (snapshot *SRegion) DeleteSnapshot(snapshotId string) error {
return cloudprovider.ErrNotImplemented
func (region *SRegion) DeleteSnapshot(snapshotId string) error {
_, err := region.CinderDelete("/snapshots/"+snapshotId, "")
return err
}
func (snapshot *SRegion) CreateSnapshot(diskId, name, desc string) (string, error) {
return "", cloudprovider.ErrNotImplemented
func (region *SRegion) CreateSnapshot(diskId, name, desc string) (string, error) {
params := map[string]map[string]interface{}{
"snapshot": {
"volume_id": diskId,
"name": name,
"description": desc,
"force": true,
},
}
_, resp, err := region.CinderCreate("/snapshots", "", jsonutils.Marshal(params))
if err != nil {
return "", err
}
return resp.GetString("snapshot", "id")
}
+7 -1
View File
@@ -4,6 +4,7 @@ import (
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
@@ -94,7 +95,12 @@ func (storage *SStorage) GetIStoragecache() cloudprovider.ICloudStoragecache {
}
func (storage *SStorage) CreateIDisk(name string, sizeGb int, desc string) (cloudprovider.ICloudDisk, error) {
return nil, cloudprovider.ErrNotImplemented
diskId, err := storage.zone.region.CreateDisk(storage.zone.ZoneName, storage.Name, name, sizeGb, desc)
if err != nil {
log.Errorf("createDisk fail %v", err)
return nil, err
}
return storage.GetIDiskById(diskId)
}
func (storage *SStorage) GetIDiskById(idStr string) (cloudprovider.ICloudDisk, error) {
+86 -5
View File
@@ -3,11 +3,18 @@ package openstack
import (
"context"
"fmt"
"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/onecloud/pkg/image/options"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/util/qemuimg"
)
type SStoragecache struct {
@@ -49,7 +56,16 @@ func (cache *SStoragecache) GetManagerId() string {
}
func (cache *SStoragecache) fetchImages() error {
return cloudprovider.ErrNotImplemented
images, err := cache.region.GetImages("", ACTIVE, []string{})
if err != nil {
return err
}
cache.iimages = make([]cloudprovider.ICloudImage, len(images))
for i := 0; i < len(images); i++ {
images[i].storageCache = cache
cache.iimages[i] = &images[i]
}
return nil
}
func (cache *SStoragecache) GetIImages() ([]cloudprovider.ICloudImage, error) {
@@ -62,7 +78,12 @@ func (cache *SStoragecache) GetIImages() ([]cloudprovider.ICloudImage, error) {
}
func (cache *SStoragecache) GetIImageById(extId string) (cloudprovider.ICloudImage, error) {
return nil, cloudprovider.ErrNotImplemented
image, err := cache.region.GetImage(extId)
if err != nil {
return nil, err
}
image.storageCache = cache
return image, nil
}
func (cache *SStoragecache) GetPath() string {
@@ -70,11 +91,71 @@ func (cache *SStoragecache) GetPath() string {
}
func (cache *SStoragecache) UploadImage(ctx context.Context, userCred mcclient.TokenCredential, imageId string, osArch, osType, osDist, osVersion string, extId string, isForce bool) (string, error) {
return "", cloudprovider.ErrNotImplemented
if len(extId) > 0 {
log.Debugf("UploadImage: Image external ID exists %s", extId)
statsu, err := cache.region.GetImageStatus(extId)
if err != nil {
log.Errorf("GetImageStatus error %s", err)
}
if statsu == ACTIVE && !isForce {
return extId, nil
}
}
log.Debugf("UploadImage: no external ID")
return cache.uploadImage(ctx, userCred, imageId, osArch, osType, osDist, osVersion, isForce)
}
func (cache *SStoragecache) uploadImage(userCred mcclient.TokenCredential, imageId string, osArch, osType, osDist string, isForce bool) (string, error) {
return "", cloudprovider.ErrNotImplemented
func (cache *SStoragecache) uploadImage(ctx context.Context, userCred mcclient.TokenCredential, imageId string, osArch, osType, osDist, osVersion string, isForce bool) (string, error) {
s := auth.GetAdminSession(ctx, options.Options.Region, "")
meta, reader, err := modules.Images.Download(s, imageId, string(qemuimg.VMDK), false)
if err != nil {
return "", err
}
log.Infof("meta data %s", meta)
imageBaseName := imageId
if imageBaseName[0] >= '0' && imageBaseName[0] <= '9' {
imageBaseName = fmt.Sprintf("img%s", imageId)
}
imageName := imageBaseName
nameIdx := 1
for {
_, err = cache.region.GetImageByName(imageName)
if err != nil {
if err == cloudprovider.ErrNotFound {
break
} else {
return "", err
}
}
imageName = fmt.Sprintf("%s-%d", imageBaseName, nameIdx)
nameIdx++
}
params := map[string]string{
"container_format": "bare",
"disk_format": "vmdk",
"name": imageName,
"id": imageId,
}
_, resp, err := cache.region.Post("images", "/v2/images", "", jsonutils.Marshal(params))
if err != nil {
return "", err
}
image := &SImage{storageCache: cache}
if err := resp.Unmarshal(image); err != nil {
return "", err
}
_, err = cache.region.client.StreamRequest(cache.region.Name, "image", "PUT", fmt.Sprintf("/v2/images/%s/file", image.ID), "", reader)
if err != nil {
return "", err
}
return image.ID, cloudprovider.WaitStatus(image, models.CACHED_IMAGE_STATUS_READY, 15*time.Second, 3600*time.Second)
}
func (cache *SStoragecache) CreateIImage(snapshoutId, imageName, osType, imageDesc string) (cloudprovider.ICloudImage, error) {
+3 -2
View File
@@ -96,7 +96,8 @@ func (vpc *SVpc) Delete() error {
}
func (region *SRegion) DeleteVpc(vpcId string) error {
return cloudprovider.ErrNotImplemented
_, err := region.Delete("network", "/v2.0/networks/"+vpcId, "")
return err
}
func (vpc *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
@@ -191,7 +192,7 @@ func (region *SRegion) GetVpc(vpcId string) (*SVpc, error) {
}
func (region *SRegion) GetVpcs() ([]SVpc, error) {
_, resp, err := region.Get("network", "/v2.0/networks", "", nil)
_, resp, err := region.List("network", "/v2.0/networks", "", nil)
if err != nil {
return nil, err
}
+8 -1
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
@@ -56,7 +57,13 @@ func (wire *SWire) GetBandwidth() int {
}
func (wire *SWire) CreateINetwork(name string, cidr string, desc string) (cloudprovider.ICloudNetwork, error) {
return nil, cloudprovider.ErrNotImplemented
networkId, err := wire.zone.region.CreateNetwork(wire.vpc.ID, name, cidr, desc)
if err != nil {
log.Errorf("CreateNetwork error %s", err)
return nil, err
}
wire.inetworks = nil
return wire.GetINetworkById(networkId)
}
func (wire *SWire) GetINetworkById(netid string) (cloudprovider.ICloudNetwork, error) {
+3 -3
View File
@@ -94,7 +94,7 @@ func (zone *SZone) fetchStorages() error {
zone.istorages = []cloudprovider.ICloudStorage{}
for _, service := range []string{"volumev3", "volumev2", "volume"} {
_, resp, err := zone.region.Get(service, "/types", "", nil)
_, resp, err := zone.region.List(service, "/types", "", nil)
if err == nil {
storages := []SStorage{}
if err := resp.Unmarshal(&storages, "volume_types"); err != nil {
@@ -142,7 +142,7 @@ func (zone *SZone) GetIHosts() ([]cloudprovider.ICloudHost, error) {
hosts := []SHost{}
_, maxVersion, err := zone.region.GetVersion("compute")
if err == nil && version.GE(maxVersion, HYPERVISORS_VERSION) {
_, resp, err := zone.region.Get("compute", "/os-hypervisors/detail", maxVersion, nil)
_, resp, err := zone.region.List("compute", "/os-hypervisors/detail", maxVersion, nil)
if err != nil {
return nil, err
}
@@ -156,7 +156,7 @@ func (zone *SZone) GetIHosts() ([]cloudprovider.ICloudHost, error) {
return ihosts, nil
}
_, resp, err := zone.region.Get("compute", "/os-hosts", "", nil)
_, resp, err := zone.region.List("compute", "/os-hosts", "", nil)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -749,7 +749,7 @@ func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
return self.host.zone.region.instanceOperation(self.InstanceId, "ModifyInstancesAttribute", params)
}
func (self *SInstance) AssignSecurityGroups(secgroupIds []string) error {
func (self *SInstance) SetSecurityGroups(secgroupIds []string) error {
params := map[string]string{}
for i := 0; i < len(secgroupIds); i++ {
params[fmt.Sprintf("SecurityGroups.%d", i)] = secgroupIds[i]