From ce70ab3300283f64277fe2e8adaffb3c2e98dbd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Thu, 15 Nov 2018 11:25:19 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E8=A1=A5=E5=85=85Azure=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=BF=AB=E7=85=A7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/compute/guestdrivers/aliyun.go | 23 ---------------------- pkg/compute/guestdrivers/managedvirtual.go | 23 ++++++++++++++++++++++ pkg/util/azure/azure.go | 2 +- pkg/util/azure/snapshot.go | 21 ++++++++++++++++++-- 4 files changed, 43 insertions(+), 26 deletions(-) diff --git a/pkg/compute/guestdrivers/aliyun.go b/pkg/compute/guestdrivers/aliyun.go index 1a91971127..5dfb5ec2d8 100644 --- a/pkg/compute/guestdrivers/aliyun.go +++ b/pkg/compute/guestdrivers/aliyun.go @@ -483,26 +483,3 @@ func (self *SAliyunGuestDriver) OnGuestDeployTaskDataReceived(ctx context.Contex func (self *SAliyunGuestDriver) AllowReconfigGuest() bool { return true } - -func (self *SAliyunGuestDriver) RequestDiskSnapshot(ctx context.Context, guest *models.SGuest, task taskman.ITask, snapshotId, diskId string) error { - iDisk, _ := models.DiskManager.FetchById(diskId) - disk := iDisk.(*models.SDisk) - providerDisk, err := disk.GetIDisk() - if err != nil { - return err - } - iSnapshot, _ := models.SnapshotManager.FetchById(snapshotId) - snapshot := iSnapshot.(*models.SSnapshot) - taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - cloudSnapshot, err := providerDisk.CreateISnapshot(snapshot.Name, "") - if err != nil { - return nil, err - } - res := jsonutils.NewDict() - res.Set("snapshot_id", jsonutils.NewString(cloudSnapshot.GetId())) - res.Set("manager_id", jsonutils.NewString(cloudSnapshot.GetManagerId())) - res.Set("cloudregion_id", jsonutils.NewString(cloudSnapshot.GetRegionId())) - return res, nil - }) - return nil -} diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index 0a8388410f..f3e7458173 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -351,3 +351,26 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncConfigOnHost(ctx context. }) return nil } + +func (self *SManagedVirtualizedGuestDriver) RequestDiskSnapshot(ctx context.Context, guest *models.SGuest, task taskman.ITask, snapshotId, diskId string) error { + iDisk, _ := models.DiskManager.FetchById(diskId) + disk := iDisk.(*models.SDisk) + providerDisk, err := disk.GetIDisk() + if err != nil { + return err + } + iSnapshot, _ := models.SnapshotManager.FetchById(snapshotId) + snapshot := iSnapshot.(*models.SSnapshot) + taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + cloudSnapshot, err := providerDisk.CreateISnapshot(snapshot.Name, "") + if err != nil { + return nil, err + } + res := jsonutils.NewDict() + res.Set("snapshot_id", jsonutils.NewString(cloudSnapshot.GetId())) + res.Set("manager_id", jsonutils.NewString(cloudSnapshot.GetManagerId())) + res.Set("cloudregion_id", jsonutils.NewString(cloudSnapshot.GetRegionId())) + return res, nil + }) + return nil +} diff --git a/pkg/util/azure/azure.go b/pkg/util/azure/azure.go index 651a848e3f..791e6d3fa1 100644 --- a/pkg/util/azure/azure.go +++ b/pkg/util/azure/azure.go @@ -274,7 +274,7 @@ func (self *SAzureClient) checkParams(body jsonutils.JSONObject, params []string for i := 0; i < len(params); i++ { data, err := body.GetString(params[i]) if err != nil { - return nil, fmt.Errorf("Missing %s params") + return nil, fmt.Errorf("Missing %s params", params[i]) } result[params[i]] = data } diff --git a/pkg/util/azure/snapshot.go b/pkg/util/azure/snapshot.go index 5db8d6da4c..429b1451c8 100644 --- a/pkg/util/azure/snapshot.go +++ b/pkg/util/azure/snapshot.go @@ -22,8 +22,9 @@ type SSnapshot struct { Name string Location string ManagedBy string - Sku SnapshotSku + Sku *SnapshotSku Properties DiskProperties + Type string } func (self *SSnapshot) GetId() string { @@ -57,7 +58,23 @@ func (self *SSnapshot) IsEmulated() bool { } func (self *SRegion) CreateSnapshot(diskId, snapName, desc string) (*SSnapshot, error) { - snapshot := SSnapshot{} + disk, err := self.GetDisk(diskId) + if err != nil { + return nil, err + } + snapshot := SSnapshot{ + region: self, + Name: snapName, + Location: self.Name, + Properties: DiskProperties{ + CreationData: CreationData{ + CreateOption: "Copy", + SourceResourceID: diskId, + }, + DiskSizeGB: disk.Properties.DiskSizeGB, + }, + Type: "Microsoft.Compute/snapshots", + } return &snapshot, self.client.Create(jsonutils.Marshal(snapshot), &snapshot) } From 7c15b8d2fb7268165f3c69a3c8d2fae17552a081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Thu, 15 Nov 2018 20:10:59 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E4=BD=BF=E7=94=A8xterm?= =?UTF-8?q?-256color?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/webconsole/server/tty_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/webconsole/server/tty_server.go b/pkg/webconsole/server/tty_server.go index bde779afa8..09955dcc2e 100644 --- a/pkg/webconsole/server/tty_server.go +++ b/pkg/webconsole/server/tty_server.go @@ -99,7 +99,7 @@ func initSocketHandler(so socketio.Socket, p *session.Pty) { log.Infof("exec: %s", p.Command) args := strings.Split(p.Command, " ") cmd := exec.Command(args[0], args[1:]...) - cmd.Env = append(cmd.Env, "TERM=screen-256color") + cmd.Env = append(cmd.Env, "TERM=xterm-256color") if _pty, err := pty.Start(cmd); err != nil { so.Emit(OUTPUT_EVENT, err.Error()+"\r\n") log.Errorf("exec error: %v", err) From 4035cbe3630f185402944f2f211d20bf578a91dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Thu, 15 Nov 2018 21:13:16 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=B0=83=E5=BA=A6?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E9=99=90=E5=88=B6=E8=B0=83=E5=BA=A6=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E7=BB=8F=E5=85=B8=E5=AE=9E=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/util/azure/classic_host.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/util/azure/classic_host.go b/pkg/util/azure/classic_host.go index e756d8788d..e932ec8d35 100644 --- a/pkg/util/azure/classic_host.go +++ b/pkg/util/azure/classic_host.go @@ -73,7 +73,7 @@ func (self *SClassicHost) GetMemSizeMB() int { return 0 } func (self *SClassicHost) GetEnabled() bool { - return false + return true } func (self *SClassicHost) GetHostStatus() string { From 2e868ed7c118cce8b18f387e19580288b5429ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Fri, 16 Nov 2018 15:28:32 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E9=81=BF=E5=85=8D=E5=85=AC=E6=9C=89?= =?UTF-8?q?=E4=BA=91=E6=89=BE=E4=B8=8D=E5=88=B0=E5=AF=B9=E5=BA=94=E7=9A=84?= =?UTF-8?q?cloudregion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/compute/guestdrivers/managedvirtual.go | 7 ++++++- pkg/compute/models/snapshots.go | 8 ++++++++ pkg/util/aliyun/snapshot.go | 2 +- pkg/util/azure/snapshot.go | 4 +++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index f3e7458173..36d1f7f73d 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -369,7 +369,12 @@ func (self *SManagedVirtualizedGuestDriver) RequestDiskSnapshot(ctx context.Cont res := jsonutils.NewDict() res.Set("snapshot_id", jsonutils.NewString(cloudSnapshot.GetId())) res.Set("manager_id", jsonutils.NewString(cloudSnapshot.GetManagerId())) - res.Set("cloudregion_id", jsonutils.NewString(cloudSnapshot.GetRegionId())) + extId := cloudSnapshot.GetRegionId() + cloudregion, err := models.CloudregionManager.FetchByExternalId(extId) + if err != nil { + return nil, err + } + res.Set("cloudregion_id", jsonutils.NewString(cloudregion.GetId())) return res, nil }) return nil diff --git a/pkg/compute/models/snapshots.go b/pkg/compute/models/snapshots.go index 491381fe77..bc0e70fef6 100644 --- a/pkg/compute/models/snapshots.go +++ b/pkg/compute/models/snapshots.go @@ -439,8 +439,16 @@ func totalSnapshotCount(projectId string) int { func (self *SSnapshot) SyncWithCloudSnapshot(userCred mcclient.TokenCredential, ext cloudprovider.ICloudSnapshot) error { _, err := self.GetModelManager().TableSpec().Update(self, func() error { + self.Name = ext.GetName() self.Status = ext.GetStatus() self.DiskType = ext.GetDiskType() + + cloudregionId := ext.GetRegionId() + region, err := CloudregionManager.FetchByExternalId(cloudregionId) + if err != nil { + return err + } + self.CloudregionId = region.GetId() return nil }) if err != nil { diff --git a/pkg/util/aliyun/snapshot.go b/pkg/util/aliyun/snapshot.go index e0cada0372..515115e8fb 100644 --- a/pkg/util/aliyun/snapshot.go +++ b/pkg/util/aliyun/snapshot.go @@ -56,7 +56,7 @@ func (self *SSnapshot) GetManagerId() string { } func (self *SSnapshot) GetRegionId() string { - return self.region.GetId() + return self.region.GetGlobalId() } func (self *SSnapshot) GetSize() int32 { diff --git a/pkg/util/azure/snapshot.go b/pkg/util/azure/snapshot.go index 429b1451c8..8804fb7832 100644 --- a/pkg/util/azure/snapshot.go +++ b/pkg/util/azure/snapshot.go @@ -154,9 +154,11 @@ func (self *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) { classicSnapshots = append(classicSnapshots, _classicSnapshots...) isnapshots := make([]cloudprovider.ICloudSnapshot, len(snapshots)+len(classicSnapshots)) for i := 0; i < len(snapshots); i++ { + snapshots[i].region = self isnapshots[i] = &snapshots[i] } for i := 0; i < len(classicSnapshots); i++ { + classicSnapshots[i].region = self isnapshots[len(snapshots)+i] = &classicSnapshots[i] } return isnapshots, nil @@ -171,7 +173,7 @@ func (self *SSnapshot) GetManagerId() string { } func (self *SSnapshot) GetRegionId() string { - return self.region.GetId() + return self.region.GetGlobalId() } func (self *SSnapshot) GetDiskType() string { From de45f88830a3d549ca45167876c2a7c75b186acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Fri, 16 Nov 2018 17:16:58 +0800 Subject: [PATCH 05/10] =?UTF-8?q?Azure=E4=B8=BB=E6=9C=BA=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E5=B8=A6=E4=B8=8Aregion=E4=BF=A1=E6=81=AF,=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E9=87=8D=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/util/azure/classic_host.go | 2 +- pkg/util/azure/host.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/util/azure/classic_host.go b/pkg/util/azure/classic_host.go index e932ec8d35..89ddfc3373 100644 --- a/pkg/util/azure/classic_host.go +++ b/pkg/util/azure/classic_host.go @@ -26,7 +26,7 @@ func (self *SClassicHost) GetId() string { } func (self *SClassicHost) GetName() string { - return fmt.Sprintf("%s-classic", self.zone.region.client.subscriptionId) + return fmt.Sprintf("%s/%s-classic", self.zone.region.GetName(), self.zone.region.client.subscriptionId) } func (self *SClassicHost) GetGlobalId() string { diff --git a/pkg/util/azure/host.go b/pkg/util/azure/host.go index 2fe2f279cc..147d5a8dd0 100644 --- a/pkg/util/azure/host.go +++ b/pkg/util/azure/host.go @@ -23,7 +23,7 @@ func (self *SHost) GetId() string { } func (self *SHost) GetName() string { - return fmt.Sprintf("%s", self.zone.region.client.subscriptionId) + return fmt.Sprintf("%s/%s", self.zone.region.GetName(), self.zone.region.client.subscriptionId) } func (self *SHost) GetGlobalId() string { From 110fdc1d24cc0816bcc4b406340751ea70b4c0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Fri, 16 Nov 2018 17:23:03 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E4=B8=BB=E6=9C=BA?= =?UTF-8?q?=E5=90=8D=E4=B8=AD=E6=96=87=E5=AD=97=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/util/azure/classic_host.go | 2 +- pkg/util/azure/host.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/util/azure/classic_host.go b/pkg/util/azure/classic_host.go index 89ddfc3373..d20ed16f4e 100644 --- a/pkg/util/azure/classic_host.go +++ b/pkg/util/azure/classic_host.go @@ -26,7 +26,7 @@ func (self *SClassicHost) GetId() string { } func (self *SClassicHost) GetName() string { - return fmt.Sprintf("%s/%s-classic", self.zone.region.GetName(), self.zone.region.client.subscriptionId) + return fmt.Sprintf("%s/%s-classic", self.zone.region.GetGlobalId(), self.zone.region.client.subscriptionId) } func (self *SClassicHost) GetGlobalId() string { diff --git a/pkg/util/azure/host.go b/pkg/util/azure/host.go index 147d5a8dd0..089e714fd3 100644 --- a/pkg/util/azure/host.go +++ b/pkg/util/azure/host.go @@ -23,7 +23,7 @@ func (self *SHost) GetId() string { } func (self *SHost) GetName() string { - return fmt.Sprintf("%s/%s", self.zone.region.GetName(), self.zone.region.client.subscriptionId) + return fmt.Sprintf("%s/%s", self.zone.region.GetGlobalId(), self.zone.region.client.subscriptionId) } func (self *SHost) GetGlobalId() string { From 503bec34c86f2b00ed54736ec988ab5a4f11bc9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Fri, 16 Nov 2018 16:55:17 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/cloudprovider/resources.go | 2 -- pkg/compute/guestdrivers/managedvirtual.go | 7 ------- pkg/compute/models/snapshots.go | 21 ++++++++----------- pkg/compute/tasks/guest_disk_snapshot_task.go | 13 +++--------- pkg/util/aliyun/snapshot.go | 8 ------- pkg/util/azure/snapshot.go | 8 ------- 6 files changed, 12 insertions(+), 47 deletions(-) diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 0935ffb38f..2a9df62487 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -249,12 +249,10 @@ type ICloudDisk interface { type ICloudSnapshot interface { ICloudResource - GetManagerId() string GetSize() int32 GetDiskId() string GetDiskType() string Delete() error - GetRegionId() string } type ICloudVpc interface { diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index 36d1f7f73d..30dbc10618 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -368,13 +368,6 @@ func (self *SManagedVirtualizedGuestDriver) RequestDiskSnapshot(ctx context.Cont } res := jsonutils.NewDict() res.Set("snapshot_id", jsonutils.NewString(cloudSnapshot.GetId())) - res.Set("manager_id", jsonutils.NewString(cloudSnapshot.GetManagerId())) - extId := cloudSnapshot.GetRegionId() - cloudregion, err := models.CloudregionManager.FetchByExternalId(extId) - if err != nil { - return nil, err - } - res.Set("cloudregion_id", jsonutils.NewString(cloudregion.GetId())) return res, nil }) return nil diff --git a/pkg/compute/models/snapshots.go b/pkg/compute/models/snapshots.go index bc0e70fef6..367f05bb71 100644 --- a/pkg/compute/models/snapshots.go +++ b/pkg/compute/models/snapshots.go @@ -273,6 +273,7 @@ func (self *SSnapshotManager) CreateSnapshot(ctx context.Context, userCred mccli return nil, err } disk := iDisk.(*SDisk) + storage := disk.GetStorage() snapshot := &SSnapshot{} snapshot.SetModelManager(self) snapshot.ProjectId = userCred.GetProjectId() @@ -282,6 +283,8 @@ func (self *SSnapshotManager) CreateSnapshot(ctx context.Context, userCred mccli snapshot.DiskType = disk.DiskType snapshot.Location = location snapshot.CreatedBy = createdBy + snapshot.ManagerId = storage.ManagerId + snapshot.CloudregionId = storage.getZone().GetRegion().GetId() snapshot.Name = name snapshot.Status = SNAPSHOT_CREATING err = SnapshotManager.TableSpec().Insert(snapshot) @@ -437,18 +440,12 @@ func totalSnapshotCount(projectId string) int { return count } -func (self *SSnapshot) SyncWithCloudSnapshot(userCred mcclient.TokenCredential, ext cloudprovider.ICloudSnapshot) error { +func (self *SSnapshot) SyncWithCloudSnapshot(userCred mcclient.TokenCredential, ext cloudprovider.ICloudSnapshot, region *SCloudregion) error { _, err := self.GetModelManager().TableSpec().Update(self, func() error { self.Name = ext.GetName() self.Status = ext.GetStatus() self.DiskType = ext.GetDiskType() - - cloudregionId := ext.GetRegionId() - region, err := CloudregionManager.FetchByExternalId(cloudregionId) - if err != nil { - return err - } - self.CloudregionId = region.GetId() + self.CloudregionId = region.Id return nil }) if err != nil { @@ -457,7 +454,7 @@ func (self *SSnapshot) SyncWithCloudSnapshot(userCred mcclient.TokenCredential, return err } -func (manager *SSnapshotManager) newFromCloudSnapshot(userCred mcclient.TokenCredential, extSnapshot cloudprovider.ICloudSnapshot, region *SCloudregion) (*SSnapshot, error) { +func (manager *SSnapshotManager) newFromCloudSnapshot(userCred mcclient.TokenCredential, extSnapshot cloudprovider.ICloudSnapshot, region *SCloudregion, provider *SCloudprovider) (*SSnapshot, error) { snapshot := SSnapshot{} snapshot.SetModelManager(manager) @@ -475,7 +472,7 @@ func (manager *SSnapshotManager) newFromCloudSnapshot(userCred mcclient.TokenCre snapshot.DiskType = extSnapshot.GetDiskType() snapshot.Size = int(extSnapshot.GetSize()) * 1024 - snapshot.ManagerId = extSnapshot.GetManagerId() + snapshot.ManagerId = provider.Id snapshot.CloudregionId = region.Id snapshot.ProjectId = userCred.GetProjectId() @@ -526,7 +523,7 @@ func (manager *SSnapshotManager) SyncSnapshots(ctx context.Context, userCred mcc } } for i := 0; i < len(commondb); i += 1 { - err = commondb[i].SyncWithCloudSnapshot(userCred, commonext[i]) + err = commondb[i].SyncWithCloudSnapshot(userCred, commonext[i], region) if err != nil { syncResult.UpdateError(err) } else { @@ -534,7 +531,7 @@ func (manager *SSnapshotManager) SyncSnapshots(ctx context.Context, userCred mcc } } for i := 0; i < len(added); i += 1 { - _, err := manager.newFromCloudSnapshot(userCred, added[i], region) + _, err := manager.newFromCloudSnapshot(userCred, added[i], region, provider) if err != nil { syncResult.AddError(err) } else { diff --git a/pkg/compute/tasks/guest_disk_snapshot_task.go b/pkg/compute/tasks/guest_disk_snapshot_task.go index 9c9e7aa7ea..4f5f230ef2 100644 --- a/pkg/compute/tasks/guest_disk_snapshot_task.go +++ b/pkg/compute/tasks/guest_disk_snapshot_task.go @@ -52,32 +52,25 @@ func (self *GuestDiskSnapshotTask) DoDiskSnapshot(ctx context.Context, guest *mo func (self *GuestDiskSnapshotTask) OnDiskSnapshotComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { res := data.(*jsonutils.JSONDict) + snapshotId, _ := self.Params.GetString("snapshot_id") + iSnapshot, _ := models.SnapshotManager.FetchById(snapshotId) + snapshot := iSnapshot.(*models.SSnapshot) if guest.Hypervisor == models.HYPERVISOR_KVM { location, err := res.GetString("location") if err != nil { log.Infof("OnDiskSnapshotComplete called with data no location") return } - snapshotId, _ := self.Params.GetString("snapshot_id") - iSnapshot, _ := models.SnapshotManager.FetchById(snapshotId) - snapshot := iSnapshot.(*models.SSnapshot) models.SnapshotManager.TableSpec().Update(snapshot, func() error { snapshot.Location = location snapshot.Status = models.SNAPSHOT_READY return nil }) } else { - snapshotId, _ := self.Params.GetString("snapshot_id") - iSnapshot, _ := models.SnapshotManager.FetchById(snapshotId) - snapshot := iSnapshot.(*models.SSnapshot) extSnapshotId, _ := data.GetString("snapshot_id") - cloudregionId, _ := data.GetString("cloudregion_id") - managerId, _ := data.GetString("manager_id") models.SnapshotManager.TableSpec().Update(snapshot, func() error { - snapshot.CloudregionId = cloudregionId snapshot.ExternalId = extSnapshotId snapshot.Status = models.SNAPSHOT_READY - snapshot.ManagerId = managerId return nil }) } diff --git a/pkg/util/aliyun/snapshot.go b/pkg/util/aliyun/snapshot.go index 515115e8fb..87d9523970 100644 --- a/pkg/util/aliyun/snapshot.go +++ b/pkg/util/aliyun/snapshot.go @@ -51,14 +51,6 @@ func (self *SSnapshot) GetStatus() string { } } -func (self *SSnapshot) GetManagerId() string { - return self.region.client.providerId -} - -func (self *SSnapshot) GetRegionId() string { - return self.region.GetGlobalId() -} - func (self *SSnapshot) GetSize() int32 { return self.SourceDiskSize } diff --git a/pkg/util/azure/snapshot.go b/pkg/util/azure/snapshot.go index 8804fb7832..ccc78658bd 100644 --- a/pkg/util/azure/snapshot.go +++ b/pkg/util/azure/snapshot.go @@ -168,14 +168,6 @@ func (self *SSnapshot) GetDiskId() string { return self.Properties.CreationData.SourceResourceID } -func (self *SSnapshot) GetManagerId() string { - return self.region.client.providerId -} - -func (self *SSnapshot) GetRegionId() string { - return self.region.GetGlobalId() -} - func (self *SSnapshot) GetDiskType() string { return "" } From 54dda9496ffdefc5f331d1b0d8bd3c203542583b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Fri, 16 Nov 2018 20:42:30 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E9=87=8D=E5=A4=8D=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=B7=B2=E5=88=86=E9=85=8D=E7=9A=84=E6=9C=AA=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E7=BD=91=E5=8D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/util/azure/host.go | 52 +++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/pkg/util/azure/host.go b/pkg/util/azure/host.go index 089e714fd3..a32a5ca6df 100644 --- a/pkg/util/azure/host.go +++ b/pkg/util/azure/host.go @@ -42,18 +42,48 @@ func (self *SHost) Refresh() error { return nil } -func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, networkId string, ipAddr string, desc string, passwd string, storageType string, diskSizes []int, publicKey string, secgroupId string) (cloudprovider.ICloudVM, error) { - nicId := "" - if net := self.zone.getNetworkById(networkId); net == nil { - return nil, fmt.Errorf("invalid network ID %s", networkId) - } else if nic, err := self.zone.region.CreateNetworkInterface(fmt.Sprintf("%s-ipconfig", name), ipAddr, net.GetId(), secgroupId); err != nil { - return nil, err - } else { - nicId = nic.ID - } - vmId, err := self._createVM(name, imgId, int32(sysDiskSize), cpu, memMB, nicId, ipAddr, desc, passwd, storageType, diskSizes, publicKey) +func (self *SHost) searchNetorkInterface(IPAddr string, networkId string, secgroupId string) (*SInstanceNic, error) { + interfaces, err := self.zone.region.GetNetworkInterfaces() if err != nil { - self.zone.region.DeleteNetworkInterface(nicId) + return nil, err + } + for i, nic := range interfaces { + for _, ipConf := range nic.Properties.IPConfigurations { + if ipConf.Properties.PrivateIPAddress == IPAddr && networkId == ipConf.Properties.Subnet.ID && ipConf.Properties.PrivateIPAllocationMethod == "Static" { + if nic.Properties.NetworkSecurityGroup == nil || nic.Properties.NetworkSecurityGroup.ID != secgroupId { + nic.Properties.NetworkSecurityGroup = &SSecurityGroup{ID: secgroupId} + if err := self.zone.region.client.Update(jsonutils.Marshal(nic), nil); err != nil { + log.Errorf("assign secgroup %s for nic %s failed %d") + return nil, err + } + } + return &interfaces[i], nil + } + } + } + return nil, cloudprovider.ErrNotFound +} + +func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, networkId string, ipAddr string, desc string, passwd string, storageType string, diskSizes []int, publicKey string, secgroupId string) (cloudprovider.ICloudVM, error) { + net := self.zone.getNetworkById(networkId) + if net == nil { + return nil, fmt.Errorf("invalid network ID %s", networkId) + } + nic, err := self.searchNetorkInterface(ipAddr, net.GetId(), secgroupId) + if err != nil { + if err == cloudprovider.ErrNotFound { + nic, err = self.zone.region.CreateNetworkInterface(fmt.Sprintf("%s-ipconfig", name), ipAddr, net.GetId(), secgroupId) + if err != nil { + return nil, err + } + } else { + return nil, err + } + } + + vmId, err := self._createVM(name, imgId, int32(sysDiskSize), cpu, memMB, nic.ID, ipAddr, desc, passwd, storageType, diskSizes, publicKey) + if err != nil { + self.zone.region.DeleteNetworkInterface(nic.ID) return nil, err } if vm, err := self.zone.region.GetInstance(vmId); err != nil { From c6c1b17c3edba2104ceaf646c60e2964c358aaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Sat, 17 Nov 2018 15:53:11 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E5=8F=96=E6=B6=88=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=85=AC=E6=9C=89=E4=BA=91vpc=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/compute/models/vpcs.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/compute/models/vpcs.go b/pkg/compute/models/vpcs.go index 2ec8e1bd24..639cbd6f10 100644 --- a/pkg/compute/models/vpcs.go +++ b/pkg/compute/models/vpcs.go @@ -344,10 +344,6 @@ func (manager *SVpcManager) ValidateCreateData(ctx context.Context, userCred mcc return nil, httperrors.NewInputParameterError("Invalid cloudregion_id") } if region.isManaged() { - if region.GetVpcCount() >= MAX_VPC_PER_REGION { - return nil, httperrors.NewNotAcceptableError("Too many vpcs per region") - } - managerStr, _ := data.GetString("manager_id") if len(managerStr) == 0 { managerStr, _ = data.GetString("manager") From db0f7656aa8735f8c2341a3dae8ccd877eaae149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Sat, 17 Nov 2018 20:29:45 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E6=9C=AA=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E6=97=B6=EF=BC=8C=E5=B0=9D=E8=AF=95=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/util/azure/azure.go | 143 +++++++++++++++++++++++++------- pkg/util/azure/debug.go | 4 + pkg/util/azure/service.go | 55 ++++++++++++ pkg/util/azure/shell/service.go | 41 +++++++++ pkg/util/azure/shell/vpc.go | 19 +++++ pkg/util/azure/vpc.go | 6 +- 6 files changed, 239 insertions(+), 29 deletions(-) create mode 100644 pkg/util/azure/service.go create mode 100644 pkg/util/azure/shell/service.go diff --git a/pkg/util/azure/azure.go b/pkg/util/azure/azure.go index 791e6d3fa1..85120b53c1 100644 --- a/pkg/util/azure/azure.go +++ b/pkg/util/azure/azure.go @@ -100,8 +100,10 @@ func (self *SAzureClient) getDefaultClient() (*autorest.Client, error) { return nil, err } client.Authorizer = authorizer - // client.RequestInspector = LogRequest() - // client.ResponseInspector = LogResponse() + if DEBUG { + client.RequestInspector = LogRequest() + client.ResponseInspector = LogResponse() + } return &client, nil } @@ -110,7 +112,7 @@ func (self *SAzureClient) jsonRequest(method, url string, body string) (jsonutil if err != nil { return nil, err } - return jsonRequest(cli, method, self.domain, url, body) + return jsonRequest(cli, method, self.domain, url, self.subscriptionId, body) } func (self *SAzureClient) Get(resourceId string, params []string, retVal interface{}) error { @@ -125,7 +127,7 @@ func (self *SAzureClient) Get(resourceId string, params []string, retVal interfa if err != nil { return err } - body, err := jsonRequest(cli, "GET", self.domain, path, "") + body, err := jsonRequest(cli, "GET", self.domain, path, self.subscriptionId, "") if err != nil { return err } @@ -145,7 +147,7 @@ func (self *SAzureClient) ListVmSizes(location string) (jsonutils.JSONObject, er return nil, fmt.Errorf("need subscription id") } url := fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/locations/%s/vmSizes", self.subscriptionId, location) - return jsonRequest(cli, "GET", self.domain, url, "") + return jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "") } func (self *SAzureClient) ListClassicDisks() (jsonutils.JSONObject, error) { @@ -157,7 +159,7 @@ func (self *SAzureClient) ListClassicDisks() (jsonutils.JSONObject, error) { return nil, fmt.Errorf("need subscription id") } url := fmt.Sprintf("/subscriptions/%s/services/disks", self.subscriptionId) - return jsonRequest(cli, "GET", self.domain, url, "") + return jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "") } func (self *SAzureClient) ListAll(resourceType string, retVal interface{}) error { @@ -172,7 +174,7 @@ func (self *SAzureClient) ListAll(resourceType string, retVal interface{}) error if len(resourceType) > 0 { url += fmt.Sprintf("/providers/%s", resourceType) } - body, err := jsonRequest(cli, "GET", self.domain, url, "") + body, err := jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "") if err != nil { return err } @@ -187,7 +189,7 @@ func (self *SAzureClient) ListSubscriptions() (jsonutils.JSONObject, error) { if err != nil { return nil, err } - return jsonRequest(cli, "GET", self.domain, "/subscriptions", "") + return jsonRequest(cli, "GET", self.domain, "/subscriptions", self.subscriptionId, "") } func (self *SAzureClient) List(golbalResource string, retVal interface{}) error { @@ -202,7 +204,7 @@ func (self *SAzureClient) List(golbalResource string, retVal interface{}) error if len(self.subscriptionId) > 0 && len(golbalResource) > 0 { url += fmt.Sprintf("/%s", golbalResource) } - body, err := jsonRequest(cli, "GET", self.domain, url, "") + body, err := jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "") if err != nil { return err } @@ -218,7 +220,7 @@ func (self *SAzureClient) ListByTypeWithResourceGroup(resourceGroupName string, return fmt.Errorf("Missing subscription Info") } url := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/%s", self.subscriptionId, resourceGroupName, Type) - body, err := jsonRequest(cli, "GET", self.domain, url, "") + body, err := jsonRequest(cli, "GET", self.domain, url, self.subscriptionId, "") if err != nil { return err } @@ -230,7 +232,7 @@ func (self *SAzureClient) Delete(resourceId string) error { if err != nil { return err } - _, err = jsonRequest(cli, "DELETE", self.domain, resourceId, "") + _, err = jsonRequest(cli, "DELETE", self.domain, resourceId, self.subscriptionId, "") return err } @@ -240,7 +242,7 @@ func (self *SAzureClient) PerformAction(resourceId string, action string, body s return nil, err } url := fmt.Sprintf("%s/%s", resourceId, action) - return jsonRequest(cli, "POST", self.domain, url, body) + return jsonRequest(cli, "POST", self.domain, url, self.subscriptionId, body) } func (self *SAzureClient) fetchResourceGroup(cli *autorest.Client, location string) error { @@ -255,7 +257,7 @@ func (self *SAzureClient) fetchResourceGroup(cli *autorest.Client, location stri if len(self.ressourceGroups) == 0 { //Create Default resourceGroup _url := fmt.Sprintf("/subscriptions/%s/resourcegroups/Default", self.subscriptionId) - body, err := jsonRequest(cli, "PUT", self.domain, _url, fmt.Sprintf(`{"name": "Default", "location": "%s"}`, location)) + body, err := jsonRequest(cli, "PUT", self.domain, _url, self.subscriptionId, fmt.Sprintf(`{"name": "Default", "location": "%s"}`, location)) if err != nil { return err } @@ -281,6 +283,18 @@ func (self *SAzureClient) checkParams(body jsonutils.JSONObject, params []string return result, nil } +type AzureErrorDetail struct { + Code string `json:"code,omitempty"` + Message string `json:"message,omitempty"` + Target string `json:"target,omitempty"` +} + +type AzureError struct { + Code string `json:"code,omitempty"` + Details []AzureErrorDetail `json:"details,omitempty"` + Message string `json:"message,omitempty"` +} + func (self *SAzureClient) Create(body jsonutils.JSONObject, retVal interface{}) error { cli, err := self.getDefaultClient() if err != nil { @@ -301,11 +315,14 @@ func (self *SAzureClient) Create(body jsonutils.JSONObject, retVal interface{}) return fmt.Errorf("Create Default resourceGroup error?") } url := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/%s/%s", self.subscriptionId, self.ressourceGroups[0].Name, params["type"], params["name"]) - result, err := jsonRequest(cli, "PUT", self.domain, url, body.String()) + result, err := jsonRequest(cli, "PUT", self.domain, url, self.subscriptionId, body.String()) if err != nil { return err } - return result.Unmarshal(retVal) + if retVal != nil { + return result.Unmarshal(retVal) + } + return nil } func (self *SAzureClient) CheckNameAvailability(Type string, body string) (jsonutils.JSONObject, error) { @@ -317,7 +334,7 @@ func (self *SAzureClient) CheckNameAvailability(Type string, body string) (jsonu return nil, fmt.Errorf("Missing subscription ID") } url := fmt.Sprintf("/subscriptions/%s/providers/%s/checkNameAvailability", self.subscriptionId, Type) - return jsonRequest(cli, "POST", self.domain, url, body) + return jsonRequest(cli, "POST", self.domain, url, self.subscriptionId, body) } func (self *SAzureClient) Update(body jsonutils.JSONObject, retVal interface{}) error { @@ -326,7 +343,7 @@ func (self *SAzureClient) Update(body jsonutils.JSONObject, retVal interface{}) return err } url, err := body.GetString("id") - result, err := jsonRequest(cli, "PUT", self.domain, url, body.String()) + result, err := jsonRequest(cli, "PUT", self.domain, url, self.subscriptionId, body.String()) if err != nil { return err } @@ -336,8 +353,86 @@ func (self *SAzureClient) Update(body jsonutils.JSONObject, retVal interface{}) return nil } -func jsonRequest(client *autorest.Client, method, domain, baseUrl string, body string) (jsonutils.JSONObject, error) { - return _jsonRequest(client, method, domain, baseUrl, body) +func waitRegisterComplete(client *autorest.Client, domain, subscriptionId string, serviceType string) error { + for i := 1; i < 10; i++ { + result, err := _jsonRequest(client, "GET", domain, fmt.Sprintf("/subscriptions/%s/providers", subscriptionId), "") + if err != nil { + return err + } + value, err := result.GetArray("value") + if err != nil { + return err + } + for _, v := range value { + namespace, _ := v.GetString("namespace") + if namespace == serviceType { + state, _ := v.GetString("registrationState") + if state == "Registered" { + return nil + } + log.Debugf("service %s state %s waite %d second ...", serviceType, state, i*10) + } + } + time.Sleep(time.Second * time.Duration(i*10)) + } + return fmt.Errorf("wait service %s register timeout", serviceType) +} + +func registerService(client *autorest.Client, domain, subscriptionId string, serviceType string) error { + registryUrl := fmt.Sprintf("/subscriptions/%s/providers/%s/register", subscriptionId, serviceType) + result, err := _jsonRequest(client, "POST", domain, registryUrl, "") + if err != nil || result.Contains("error") { + return fmt.Errorf("failed to register %s service", serviceType) + } + if state, _ := result.GetString("registrationState"); state == "Registered" { + return nil + } + return waitRegisterComplete(client, domain, subscriptionId, serviceType) +} + +func recoverFromError(client *autorest.Client, domain, subscriptionId string, azureErr AzureError) bool { + switch azureErr.Code { + case "SubscriptionNotRegistered": + services := []string{"Microsoft.Network"} + for _, service := range services { + if err := registerService(client, domain, subscriptionId, service); err != nil { + log.Errorf("register %s error: %v", service, err) + return false + } + } + return true + case "MissingSubscriptionRegistration": + for _, detail := range azureErr.Details { + log.Errorf("The subscription is not registered to use namespace '%s', try register it", detail.Target) + if err := registerService(client, domain, subscriptionId, detail.Target); err != nil { + log.Errorf("register %s error: %v", detail.Target, err) + return false + } + } + return true + default: + return false + } + return false +} + +func jsonRequest(client *autorest.Client, method, domain, baseUrl string, subscriptionId string, body string) (jsonutils.JSONObject, error) { + result, err := _jsonRequest(client, method, domain, baseUrl, body) + if err != nil { + return nil, err + } + if result.Contains("error") { + azureError := AzureError{} + if err := result.Unmarshal(&azureError, "error"); err != nil { + return nil, fmt.Errorf(result.String()) + } + if recoverFromError(client, domain, subscriptionId, azureError) { + return _jsonRequest(client, method, domain, baseUrl, body) + } + log.Errorf("Azure %s request: %s \nbody: %s error: %v", method, baseUrl, body, result.String()) + return nil, fmt.Errorf(result.String()) + } + return result, nil } func waitForComplatetion(client *autorest.Client, req *http.Request, resp *http.Response, timeout time.Duration) (jsonutils.JSONObject, error) { @@ -464,15 +559,7 @@ func _jsonRequest(client *autorest.Client, method, domain, baseURL, body string) return nil, err } _data := strings.Replace(string(data), "\r", "", -1) - result, err = jsonutils.Parse([]byte(_data)) - if err != nil { - return nil, err - } - if result.Contains("error") { - log.Errorf("Azure %s request: %s \nbody: %s error: %v", req.Method, req.URL.String(), body, result.String()) - return nil, fmt.Errorf(result.String()) - } - return result, nil + return jsonutils.Parse([]byte(_data)) } func (self *SAzureClient) UpdateAccount(tenantId, secret, envName string) error { diff --git a/pkg/util/azure/debug.go b/pkg/util/azure/debug.go index 8da73e4983..57beb087d0 100644 --- a/pkg/util/azure/debug.go +++ b/pkg/util/azure/debug.go @@ -9,6 +9,10 @@ import ( "github.com/Azure/go-autorest/autorest" ) +const ( + DEBUG = false +) + func LogRequest() autorest.PrepareDecorator { return func(p autorest.Preparer) autorest.Preparer { return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { diff --git a/pkg/util/azure/service.go b/pkg/util/azure/service.go new file mode 100644 index 0000000000..c5fa17abe7 --- /dev/null +++ b/pkg/util/azure/service.go @@ -0,0 +1,55 @@ +package azure + +import ( + "fmt" +) + +type SServices struct { + Value []SService `json:"value,omitempty"` +} + +type SService struct { + ID string `json:"id,omitempty"` + Namespace string `json:"namespace,omitempty"` + RegistrationState string `json:"registrationState,omitempty"` + ResourceTypes []ResourceType `json:"resourceTypes,omitempty"` +} + +type ResourceType struct { + ApiVersions []string `json:"apiVersions,omitempty"` + Capabilities string `json:"capabilities,omitempty"` + Locations []string `json:"locations,omitempty"` + ResourceType string `json:"locations,omitempty"` +} + +func (self *SRegion) ListServices() ([]SService, error) { + services := []SService{} + return services, self.client.List("providers", &services) +} + +func (self *SRegion) SerciceShow(serviceType string) (*SService, error) { + service := SService{} + return &service, self.client.Get("providers/"+serviceType, []string{}, &service) +} + +func (self *SRegion) serviceOperation(resourceType, operation string) error { + services, err := self.ListServices() + if err != nil { + return err + } + for _, service := range services { + if service.Namespace == resourceType { + _, err := self.client.jsonRequest("POST", fmt.Sprintf("%s/%s", service.ID, operation), "") + return err + } + } + return fmt.Errorf("failed to find namespace: %s", resourceType) +} + +func (self *SRegion) ServiceRegister(resourceType string) error { + return self.serviceOperation(resourceType, "register") +} + +func (self *SRegion) ServiceUnRegister(resourceType string) error { + return self.serviceOperation(resourceType, "unregister") +} diff --git a/pkg/util/azure/shell/service.go b/pkg/util/azure/shell/service.go new file mode 100644 index 0000000000..2f1c26bb5f --- /dev/null +++ b/pkg/util/azure/shell/service.go @@ -0,0 +1,41 @@ +package shell + +import ( + "yunion.io/x/onecloud/pkg/util/azure" + "yunion.io/x/onecloud/pkg/util/shellutils" +) + +func init() { + type ServiceListOptions struct { + } + shellutils.R(&ServiceListOptions{}, "service-list", "List providers", func(cli *azure.SRegion, args *ServiceListOptions) error { + services, err := cli.ListServices() + if err != nil { + return err + } + printList(services, len(services), 0, 0, []string{}) + return nil + }) + + type ServiceOptions struct { + NAME string `help:"Name for service register"` + } + + shellutils.R(&ServiceOptions{}, "service-register", "Register service", func(cli *azure.SRegion, args *ServiceOptions) error { + return cli.ServiceRegister(args.NAME) + }) + + shellutils.R(&ServiceOptions{}, "service-unregister", "Unregister service", func(cli *azure.SRegion, args *ServiceOptions) error { + return cli.ServiceUnRegister(args.NAME) + }) + + shellutils.R(&ServiceOptions{}, "service-show", "Show service detail", func(cli *azure.SRegion, args *ServiceOptions) error { + service, err := cli.SerciceShow(args.NAME) + if err != nil { + return err + } + printObject(service) + return nil + }) + +} diff --git a/pkg/util/azure/shell/vpc.go b/pkg/util/azure/shell/vpc.go index 6c068fdc0b..552a22c654 100644 --- a/pkg/util/azure/shell/vpc.go +++ b/pkg/util/azure/shell/vpc.go @@ -32,4 +32,23 @@ func init() { printObject(vpc) return nil }) + + shellutils.R(&VpcOptions{}, "vpc-delete", "Delete vpc", func(cli *azure.SRegion, args *VpcOptions) error { + return cli.DeleteVpc(args.ID) + }) + + type VpcCreateOptions struct { + NAME string `help:"vpc Name"` + CIDR string `help:"vpc cidr"` + Desc string `help:"vpc description"` + } + + shellutils.R(&VpcCreateOptions{}, "vpc-create", "Create vpc", func(cli *azure.SRegion, args *VpcCreateOptions) error { + vpc, err := cli.CreateIVpc(args.NAME, args.Desc, args.CIDR) + if err != nil { + return err + } + printObject(vpc) + return nil + }) } diff --git a/pkg/util/azure/vpc.go b/pkg/util/azure/vpc.go index b75d14bbde..07060c4a4c 100644 --- a/pkg/util/azure/vpc.go +++ b/pkg/util/azure/vpc.go @@ -77,7 +77,11 @@ func (self *SVpc) GetCidrBlock() string { } func (self *SVpc) Delete() error { - return self.region.client.Delete(self.ID) + return self.region.DeleteVpc(self.ID) +} + +func (self *SRegion) DeleteVpc(vpcId string) error { + return self.client.Delete(vpcId) } func (self *SVpc) getSecurityGroups() ([]SSecurityGroup, error) {