From a07ab4c121c319c6f10ad650952b053951a9e6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Thu, 15 Nov 2018 12:28:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96model?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/cloudprovider/resources.go | 8 +- pkg/compute/guestdrivers/aliyun.go | 19 ++- pkg/compute/guestdrivers/azure.go | 43 +++--- pkg/compute/guestdrivers/managedvirtual.go | 95 ++++++++----- pkg/compute/handlers.go | 1 + pkg/compute/models/hosts.go | 17 +++ pkg/compute/models/secgroupcache.go | 127 ++++++++++++++++++ pkg/compute/models/secgroups.go | 17 ++- .../tasks/cloud_provider_sync_info_task.go | 2 +- pkg/util/aliyun/instance.go | 35 ++--- pkg/util/aliyun/region.go | 12 ++ pkg/util/aliyun/securitygroup.go | 4 +- pkg/util/aliyun/shell/secgroup.go | 18 +++ pkg/util/aliyun/shell/vpc.go | 9 ++ pkg/util/aliyun/vpc.go | 30 ----- pkg/util/azure/classic_instance.go | 13 +- pkg/util/azure/classic_vpc.go | 5 - pkg/util/azure/instance.go | 43 +++--- pkg/util/azure/region.go | 12 ++ pkg/util/azure/securitygroup.go | 79 +---------- pkg/util/azure/vpc.go | 9 -- pkg/util/esxi/virtualmachine.go | 15 ++- 22 files changed, 370 insertions(+), 243 deletions(-) create mode 100644 pkg/compute/models/secgroupcache.go diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index 0935ffb38f..2f524841d3 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -43,6 +43,7 @@ type ICloudRegion interface { GetIHostById(id string) (ICloudHost, error) GetIStorageById(id string) (ICloudStorage, error) GetIStoragecacheById(id string) (ICloudStoragecache, error) + SyncSecurityGroup(secgroupId string, vpcId string, name string, desc string, rules []secrules.SecurityRule) (string, error) CreateIVpc(name string, desc string, cidr string) (ICloudVpc, error) @@ -163,7 +164,10 @@ type ICloudVM interface { GetBios() string GetMachine() string - SyncSecurityGroup(secgroupId string, name string, rules []secrules.SecurityRule) error + RevokeSecurityGroup() error + AssignSecurityGroup(secgroupId string) error + + //SyncSecurityGroup(secgroupId string, name string, rules []secrules.SecurityRule) error GetHypervisor() string // GetSecurityGroup() ICloudSecurityGroup @@ -273,7 +277,7 @@ type ICloudVpc interface { GetIWireById(wireId string) (ICloudWire, error) - SyncSecurityGroup(secgroupId string, name string, rules []secrules.SecurityRule) (string, error) + //SyncSecurityGroup(secgroupId string, name string, rules []secrules.SecurityRule) (string, error) } type ICloudWire interface { diff --git a/pkg/compute/guestdrivers/aliyun.go b/pkg/compute/guestdrivers/aliyun.go index 1a91971127..190891966e 100644 --- a/pkg/compute/guestdrivers/aliyun.go +++ b/pkg/compute/guestdrivers/aliyun.go @@ -202,25 +202,32 @@ func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu if action == "create" { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + iregion, err := host.GetIRegion() + if err != nil { + log.Errorf("GetIRegion fail %s", err) + return nil, err + } nets := guest.GetNetworks() net := nets[0].GetNetwork() vpc := net.GetVpc() - ivpc, err := vpc.GetIVpc() - if err != nil { - log.Errorf("getIVPC fail %s", err) - return nil, err + secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), desc.SecGroupId, host.GetRegion().GetId(), host.ManagerId) + if secgroupCache == nil { + return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s, regionId: %s, provider: %s", desc.SecGroupId, host.GetRegion().GetId(), host.ManagerId) } - secgrpId, err := ivpc.SyncSecurityGroup(desc.SecGroupId, desc.SecGroupName, desc.SecRules) + secgroupExtId, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpc.ExternalId, desc.SecGroupName, "", desc.SecRules) if err != nil { log.Errorf("SyncSecurityGroup fail %s", err) return nil, err } + if err := secgroupCache.SetExternalId(secgroupExtId); err != nil { + return nil, fmt.Errorf("failed to set externalId for secgroup %s externalId %s: error: %v", desc.SecGroupId, secgroupExtId, err) + } iVM, err := ihost.CreateVM(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.Cpu, desc.Memory, desc.ExternalNetworkId, - desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgrpId) + desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId) if err != nil { return nil, err } diff --git a/pkg/compute/guestdrivers/azure.go b/pkg/compute/guestdrivers/azure.go index 3526e0d30e..0fb4555cc7 100644 --- a/pkg/compute/guestdrivers/azure.go +++ b/pkg/compute/guestdrivers/azure.go @@ -123,34 +123,47 @@ func (self *SAzureGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gue if err := config.Unmarshal(&desc, "desc"); err != nil { return err } - if action, err := config.GetString("action"); err != nil { + action, err := config.GetString("action") + if err != nil { return err - } else if ihost, err := host.GetIHost(); err != nil { + } + ihost, err := host.GetIHost() + if err != nil { return err - } else if action == "create" { + } + if action == "create" { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { + if len(passwd) == 0 { + //Azure创建必须要设置密码 + passwd = seclib2.RandomPassword2(12) + } + + iregion, err := host.GetIRegion() + if err != nil { + log.Errorf("GetIRegion fail %s", err) + return nil, err + } + + secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), desc.SecGroupId, host.GetRegion().GetId(), host.ManagerId) + if secgroupCache == nil { + return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s, regionId: %s, provider: %s", desc.SecGroupId, host.GetRegion().GetId(), host.ManagerId) + } + nets := guest.GetNetworks() net := nets[0].GetNetwork() vpc := net.GetVpc() - ivpc, err := vpc.GetIVpc() - if err != nil { - log.Errorf("getIVPC fail %s", err) - return nil, err - } - - if len(passwd) == 0 { - passwd = seclib2.RandomPassword2(12) - } - - secgrpId, err := ivpc.SyncSecurityGroup(desc.SecGroupId, desc.SecGroupName, desc.SecRules) + secgroupExtId, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpc.ExternalId, desc.SecGroupName, "", desc.SecRules) if err != nil { log.Errorf("SyncSecurityGroup fail %s", err) return nil, err } + if err := secgroupCache.SetExternalId(secgroupExtId); err != nil { + return nil, fmt.Errorf("failed to set externalId for secgroup %s externalId %s: error: %v", desc.SecGroupId, secgroupExtId, err) + } if iVM, err := ihost.CreateVM(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.Cpu, desc.Memory, desc.ExternalNetworkId, - desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgrpId); err != nil { + desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, publicKey, secgroupExtId); err != nil { return nil, err } else { log.Debugf("VMcreated %s, wait status running ...", iVM.GetGlobalId()) diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index 0a8388410f..0b0d13c151 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -307,45 +307,72 @@ func (self *SManagedVirtualizedGuestDriver) RequestChangeVmConfig(ctx context.Co func (self *SManagedVirtualizedGuestDriver) RequestSyncConfigOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { - if ihost, err := host.GetIHost(); err != nil { + ihost, err := host.GetIHost() + if err != nil { return nil, err - } else if iVM, err := ihost.GetIVMById(guest.ExternalId); err != nil { + } + iVM, err := ihost.GetIVMById(guest.ExternalId) + if err != nil { return nil, err - } else { - if fw_only, _ := task.GetParams().Bool("fw_only"); fw_only { - if err := iVM.SyncSecurityGroup(guest.SecgrpId, guest.GetSecgroupName(), guest.GetSecRules()); err != nil { - return nil, err - } - } else { - if iDisks, err := iVM.GetIDisks(); err != nil { - return nil, err - } else { - disks := make([]models.SDisk, 0) - for _, guestdisk := range guest.GetDisks() { - disk := guestdisk.GetDisk() - disks = append(disks, *disk) - } + } + if fw_only, _ := task.GetParams().Bool("fw_only"); fw_only { + if len(guest.SecgrpId) == 0 { + return nil, iVM.RevokeSecurityGroup() + } + iregion, err := host.GetIRegion() + if err != nil { + return nil, err + } + region := host.GetRegion() + secgroupCache := models.SecurityGroupCacheManager.Register(ctx, task.GetUserCred(), guest.SecgrpId, region.GetId(), host.ManagerId) + if secgroupCache == nil { + return nil, fmt.Errorf("failed to registor secgroupCache for secgroup: %s region: %s, provider: %s", guest.SecgrpId, region.GetId(), host.ManagerId) + } - added := make([]models.SDisk, 0) - commondb := make([]models.SDisk, 0) - commonext := make([]cloudprovider.ICloudDisk, 0) - removed := make([]cloudprovider.ICloudDisk, 0) - - if err := compare.CompareSets(disks, iDisks, &added, &commondb, &commonext, &removed); err != nil { - return nil, err - } - for _, disk := range removed { - if err := iVM.DetachDisk(disk.GetId()); err != nil { - return nil, err - } - } - for _, disk := range added { - if err := iVM.AttachDisk(disk.ExternalId); err != nil { - return nil, err - } - } + vpcId := "" + for _, network := range guest.GetNetworks() { + if vpc := network.GetNetwork().GetVpc(); vpc != nil { + vpcId = vpc.ExternalId + break } } + + extId, err := iregion.SyncSecurityGroup(secgroupCache.ExternalId, vpcId, guest.GetSecgroupName(), "", guest.GetSecRules()) + if err != nil { + return nil, err + } + if err = secgroupCache.SetExternalId(extId); err != nil { + return nil, err + } + return nil, iVM.AssignSecurityGroup(extId) + } + iDisks, err := iVM.GetIDisks() + if err != nil { + return nil, err + } + disks := make([]models.SDisk, 0) + for _, guestdisk := range guest.GetDisks() { + disk := guestdisk.GetDisk() + disks = append(disks, *disk) + } + + added := make([]models.SDisk, 0) + commondb := make([]models.SDisk, 0) + commonext := make([]cloudprovider.ICloudDisk, 0) + removed := make([]cloudprovider.ICloudDisk, 0) + + if err := compare.CompareSets(disks, iDisks, &added, &commondb, &commonext, &removed); err != nil { + return nil, err + } + for _, disk := range removed { + if err := iVM.DetachDisk(disk.GetId()); err != nil { + return nil, err + } + } + for _, disk := range added { + if err := iVM.AttachDisk(disk.ExternalId); err != nil { + return nil, err + } } return nil, nil }) diff --git a/pkg/compute/handlers.go b/pkg/compute/handlers.go index 311109892f..70db6f2315 100644 --- a/pkg/compute/handlers.go +++ b/pkg/compute/handlers.go @@ -57,6 +57,7 @@ func InitHandlers(app *appsrv.Application) { models.KeypairManager, models.IsolatedDeviceManager, models.SecurityGroupManager, + models.SecurityGroupCacheManager, models.SecurityGroupRuleManager, models.VCenterManager, models.DnsRecordManager, diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index 1508b7d8dc..d551a5872b 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -1505,6 +1505,23 @@ func (self *SHost) GetIHost() (cloudprovider.ICloudHost, error) { return ihost, nil } +func (self *SHost) GetIRegion() (cloudprovider.ICloudRegion, error) { + provider, err := self.GetDriver() + if err != nil { + return nil, fmt.Errorf("No cloudprovide for host %s: %s", self.Name, err) + } + region := self.GetRegion() + if region == nil { + return nil, fmt.Errorf("failed to find host %s region info", self.Name) + } + iregion, err := provider.GetIRegionById(region.ExternalId) + if err != nil { + msg := fmt.Sprintf("fail to find iregion by id %s: %v", region.ExternalId, err) + return nil, fmt.Errorf(msg) + } + return iregion, nil +} + func (self *SHost) getDiskConfig() jsonutils.JSONObject { bs := self.GetBaremetalstorage() if bs != nil { diff --git a/pkg/compute/models/secgroupcache.go b/pkg/compute/models/secgroupcache.go new file mode 100644 index 0000000000..953f9b255f --- /dev/null +++ b/pkg/compute/models/secgroupcache.go @@ -0,0 +1,127 @@ +package models + +import ( + "context" + "fmt" + + "yunion.io/x/jsonutils" + "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/pkg/util/stringutils" + "yunion.io/x/sqlchemy" +) + +type SSecurityGroupCacheManager struct { + db.SResourceBaseManager +} + +type SSecurityGroupCache struct { + db.SResourceBase + SManagedResourceBase + + Id string `width:"128" charset:"ascii" primary:"true" list:"user"` + SecgroupId string `width:"128" charset:"ascii" create:"required"` + ExternalId string `width:"256" charset:"utf8" index:"true" list:"admin" create:"admin_optional"` + CloudregionId string `width:"36" charset:"ascii" nullable:"true" list:"user"` +} + +var SecurityGroupCacheManager *SSecurityGroupCacheManager + +func init() { + SecurityGroupCacheManager = &SSecurityGroupCacheManager{SResourceBaseManager: db.NewResourceBaseManager(SSecurityGroupCache{}, "secgroupcache_tbl", "secgroupcache", "secgroupcaches")} +} + +func (self *SSecurityGroupCache) BeforeInsert() { + if len(self.Id) == 0 { + self.Id = stringutils.UUID4() + } +} + +func (manager *SSecurityGroupCacheManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return false +} + +func (manager *SSecurityGroupCacheManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool { + return true +} + +func (self *SSecurityGroupCache) AllowUpdateItem(ctx context.Context, userCred mcclient.TokenCredential) bool { + return false +} + +func (self *SSecurityGroupCache) AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { + return false +} + +func (manager *SSecurityGroupCacheManager) FilterById(q *sqlchemy.SQuery, idStr string) *sqlchemy.SQuery { + return q.Equals("id", idStr) +} + +func (manager *SSecurityGroupCacheManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (sql *sqlchemy.SQuery, err error) { + sql, err = manager.SResourceBaseManager.ListItemFilter(ctx, q, userCred, query) + if err != nil { + return nil, err + } + if defsecgroup, _ := query.GetString("secgroup"); len(defsecgroup) > 0 { + if secgroup, _ := SecurityGroupManager.FetchByIdOrName(userCred.GetProjectId(), defsecgroup); secgroup != nil { + sql = sql.Equals("secgroup_id", secgroup.GetId()) + } else { + return nil, httperrors.NewNotFoundError(fmt.Sprintf("Security Group %s not found", defsecgroup)) + } + } + return sql, nil +} + +func (self *SSecurityGroupCache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { + return db.DeleteModel(ctx, userCred, self) +} + +func (manager *SSecurityGroupCacheManager) GetSecgroupCache(ctx context.Context, userCred mcclient.TokenCredential, secgroupId, regionId, providerId string) *SSecurityGroupCache { + secgroupCache := SSecurityGroupCache{} + query := manager.Query() + cond := sqlchemy.AND(sqlchemy.Equals(query.Field("secgroup_id"), secgroupId), sqlchemy.Equals(query.Field("cloudregion_id"), regionId), sqlchemy.Equals(query.Field("manager_id"), providerId)) + query = query.Filter(cond) + + count := query.Count() + if count > 1 { + log.Errorf("duplicate secgroupcache for secgroup: %s regionId: %s providerId: %s", secgroupId, regionId, providerId) + } else if count == 0 { + return nil + } + query.First(&secgroupCache) + secgroupCache.SetModelManager(manager) + return &secgroupCache +} + +func (manager *SSecurityGroupCacheManager) Register(ctx context.Context, userCred mcclient.TokenCredential, secgroupId, regionId, providerId string) *SSecurityGroupCache { + lockman.LockClass(ctx, manager, userCred.GetProjectId()) + defer lockman.ReleaseClass(ctx, manager, userCred.GetProjectId()) + + secgroupCache := manager.GetSecgroupCache(ctx, userCred, secgroupId, regionId, providerId) + if secgroupCache != nil { + return secgroupCache + } + + secgroupCache = &SSecurityGroupCache{ + SecgroupId: secgroupId, + CloudregionId: regionId, + } + secgroupCache.SetModelManager(manager) + secgroupCache.ManagerId = providerId + if err := manager.TableSpec().Insert(secgroupCache); err != nil { + log.Errorf("insert secgroupcache error: %v", err) + return nil + } + return secgroupCache +} + +func (self *SSecurityGroupCache) SetExternalId(externalId string) error { + _, err := self.GetModelManager().TableSpec().Update(self, func() error { + self.ExternalId = externalId + return nil + }) + return err +} diff --git a/pkg/compute/models/secgroups.go b/pkg/compute/models/secgroups.go index 40b2965999..f570af9de5 100644 --- a/pkg/compute/models/secgroups.go +++ b/pkg/compute/models/secgroups.go @@ -194,7 +194,7 @@ func (manager *SSecurityGroupManager) getSecurityGroups() ([]SSecurityGroup, err } } -func (manager *SSecurityGroupManager) SyncSecgroups(ctx context.Context, userCred mcclient.TokenCredential, secgroups []cloudprovider.ICloudSecurityGroup) ([]SSecurityGroup, []cloudprovider.ICloudSecurityGroup, compare.SyncResult) { +func (manager *SSecurityGroupManager) SyncSecgroups(ctx context.Context, userCred mcclient.TokenCredential, secgroups []cloudprovider.ICloudSecurityGroup, regionId, providerId string) ([]SSecurityGroup, []cloudprovider.ICloudSecurityGroup, compare.SyncResult) { localSecgroups := make([]SSecurityGroup, 0) remoteSecgroups := make([]cloudprovider.ICloudSecurityGroup, 0) syncResult := compare.SyncResult{} @@ -237,7 +237,7 @@ func (manager *SSecurityGroupManager) SyncSecgroups(ctx context.Context, userCre if rules, err := added[i].GetRules(); err != nil { syncResult.AddError(err) } else if len(rules) > 0 { - if new, err := manager.newFromCloudVpc(userCred, added[i]); err != nil { + if new, err := manager.newFromCloudVpc(userCred, added[i], regionId, providerId); err != nil { syncResult.AddError(err) } else if len(rules) > 0 { localSecgroups = append(localSecgroups, *new) @@ -265,7 +265,7 @@ func (self *SSecurityGroup) SyncWithCloudSecurityGroup(userCred mcclient.TokenCr return nil } -func (manager *SSecurityGroupManager) newFromCloudVpc(userCred mcclient.TokenCredential, extSec cloudprovider.ICloudSecurityGroup) (*SSecurityGroup, error) { +func (manager *SSecurityGroupManager) newFromCloudVpc(userCred mcclient.TokenCredential, extSec cloudprovider.ICloudSecurityGroup, regionId, providerId string) (*SSecurityGroup, error) { secgroup := SSecurityGroup{} secgroup.SetModelManager(manager) secgroup.Name = extSec.GetName() @@ -276,6 +276,17 @@ func (manager *SSecurityGroupManager) newFromCloudVpc(userCred mcclient.TokenCre if err := manager.TableSpec().Insert(&secgroup); err != nil { return nil, err } + + secgroupcache := SSecurityGroupCache{} + secgroupcache.ExternalId = secgroup.ExternalId + secgroupcache.SecgroupId = secgroup.Id + secgroupcache.CloudregionId = regionId + secgroupcache.ManagerId = providerId + + if err := SecurityGroupCacheManager.TableSpec().Insert(&secgroupcache); err != nil { + return nil, err + } + return &secgroup, nil } diff --git a/pkg/compute/tasks/cloud_provider_sync_info_task.go b/pkg/compute/tasks/cloud_provider_sync_info_task.go index e3093c1df6..89850eb49a 100644 --- a/pkg/compute/tasks/cloud_provider_sync_info_task.go +++ b/pkg/compute/tasks/cloud_provider_sync_info_task.go @@ -219,7 +219,7 @@ func syncVpcSecGroup(ctx context.Context, provider *models.SCloudprovider, task logSyncFailed(provider, task, msg) return } else { - _, _, result := models.SecurityGroupManager.SyncSecgroups(ctx, task.UserCred, secgroups) + _, _, result := models.SecurityGroupManager.SyncSecgroups(ctx, task.UserCred, secgroups, localVpc.CloudregionId, provider.Id) msg := result.Result() notes := fmt.Sprintf("SyncSecurityGroup for VPC %s result: %s", localVpc.Name, msg) log.Infof(notes) diff --git a/pkg/util/aliyun/instance.go b/pkg/util/aliyun/instance.go index eec17d7c88..ce83715db8 100644 --- a/pkg/util/aliyun/instance.go +++ b/pkg/util/aliyun/instance.go @@ -8,7 +8,6 @@ import ( "yunion.io/x/log" "yunion.io/x/pkg/util/osprofile" "yunion.io/x/pkg/util/seclib" - "yunion.io/x/pkg/util/secrules" "yunion.io/x/pkg/utils" "yunion.io/x/onecloud/pkg/cloudprovider" @@ -733,32 +732,6 @@ func (self *SRegion) AttachDisk(instanceId string, diskId string) error { return nil } -func (self *SInstance) SyncSecurityGroup(secgroupId string, name string, rules []secrules.SecurityRule) error { - if vpc, err := self.getVpc(); err != nil { - return err - } else if len(secgroupId) == 0 { - for index, secgrpId := range self.SecurityGroupIds.SecurityGroupId { - if err := vpc.revokeSecurityGroup(secgrpId, self.InstanceId, index == 0); err != nil { - return err - } - } - } else if secgrpId, err := vpc.SyncSecurityGroup(secgroupId, name, rules); err != nil { - return err - } else if err := vpc.assignSecurityGroup(secgrpId, self.InstanceId); err != nil { - return err - } else { - for _, secgroupId := range self.SecurityGroupIds.SecurityGroupId { - if secgroupId != secgrpId { - if err := vpc.revokeSecurityGroup(secgroupId, self.InstanceId, false); err != nil { - return err - } - } - } - self.SecurityGroupIds.SecurityGroupId = []string{secgrpId} - } - return nil -} - func (self *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) { if len(self.PublicIpAddress.IpAddress) > 0 { eip := SEipAddress{} @@ -793,3 +766,11 @@ func (self *SInstance) GetBillingType() string { func (self *SInstance) GetExpiredAt() time.Time { return self.ExpiredTime } + +func (self *SInstance) AssignSecurityGroup(secgroupId string) error { + return cloudprovider.ErrNotImplemented +} + +func (self *SInstance) RevokeSecurityGroup() error { + return cloudprovider.ErrNotImplemented +} diff --git a/pkg/util/aliyun/region.go b/pkg/util/aliyun/region.go index 9744393607..b15757b9c6 100644 --- a/pkg/util/aliyun/region.go +++ b/pkg/util/aliyun/region.go @@ -9,6 +9,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/util/secrules" "yunion.io/x/pkg/utils" "yunion.io/x/onecloud/pkg/cloudprovider" @@ -634,3 +635,14 @@ func (self *SRegion) GetIEipById(eipId string) (cloudprovider.ICloudEIP, error) } return &eips[0], nil } + +func (region *SRegion) SyncSecurityGroup(secgroupId string, vpcId string, name string, desc string, rules []secrules.SecurityRule) (string, error) { + if len(secgroupId) == 0 { + extId, err := region.CreateSecurityGroup(vpcId, name, desc) + if err != nil { + return "", err + } + secgroupId = extId + } + return secgroupId, cloudprovider.ErrNotImplemented +} diff --git a/pkg/util/aliyun/securitygroup.go b/pkg/util/aliyun/securitygroup.go index f873f2adac..b24f976640 100644 --- a/pkg/util/aliyun/securitygroup.go +++ b/pkg/util/aliyun/securitygroup.go @@ -204,7 +204,7 @@ func (self *SRegion) GetSecurityGroupDetails(secGroupId string) (*SSecurityGroup return &secgrp, nil } -func (self *SRegion) createSecurityGroup(vpcId string, name string, desc string) (string, error) { +func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc string) (string, error) { params := make(map[string]string) if len(vpcId) > 0 { params["VpcId"] = vpcId @@ -384,7 +384,7 @@ func (self *SRegion) delSecurityGroupRule(secGrpId string, rule *secrules.Securi } func (self *SRegion) createDefaultSecurityGroup(vpcId string) (string, error) { - secId, err := self.createSecurityGroup(vpcId, "", "") + secId, err := self.CreateSecurityGroup(vpcId, "", "") if err != nil { return "", err } diff --git a/pkg/util/aliyun/shell/secgroup.go b/pkg/util/aliyun/shell/secgroup.go index 89c71ac038..5ccab97b8c 100644 --- a/pkg/util/aliyun/shell/secgroup.go +++ b/pkg/util/aliyun/shell/secgroup.go @@ -1,6 +1,8 @@ package shell import ( + "fmt" + "yunion.io/x/onecloud/pkg/util/aliyun" "yunion.io/x/onecloud/pkg/util/shellutils" ) @@ -31,4 +33,20 @@ func init() { printObject(secgrp) return nil }) + + type SecurityGroupCreateOptions struct { + NAME string `help:"SecurityGroup name"` + VpcId string `help:"VPC ID"` + Desc string `help:"SecurityGroup description"` + } + + shellutils.R(&SecurityGroupCreateOptions{}, "security-group-create", "Create details of a security group", func(cli *aliyun.SRegion, args *SecurityGroupCreateOptions) error { + secgroupId, err := cli.CreateSecurityGroup(args.VpcId, args.NAME, args.Desc) + if err != nil { + return err + } + fmt.Println("secgroupId: %s", secgroupId) + return nil + }) + } diff --git a/pkg/util/aliyun/shell/vpc.go b/pkg/util/aliyun/shell/vpc.go index 045793ba5f..e6f3014b6b 100644 --- a/pkg/util/aliyun/shell/vpc.go +++ b/pkg/util/aliyun/shell/vpc.go @@ -18,4 +18,13 @@ func init() { printList(vpcs, total, args.Offset, args.Limit, []string{}) return nil }) + + type VpcOptions struct { + ID string `help:"VPC id"` + } + + shellutils.R(&VpcOptions{}, "vpc-delete", "Delete vpc", func(cli *aliyun.SRegion, args *VpcOptions) error { + return cli.DeleteVpc(args.ID) + }) + } diff --git a/pkg/util/aliyun/vpc.go b/pkg/util/aliyun/vpc.go index 91951cf029..9e36cc5d97 100644 --- a/pkg/util/aliyun/vpc.go +++ b/pkg/util/aliyun/vpc.go @@ -7,7 +7,6 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/onecloud/pkg/cloudprovider" - "yunion.io/x/pkg/util/secrules" ) const ( @@ -204,35 +203,6 @@ func (self *SVpc) Delete() error { return self.region.DeleteVpc(self.VpcId) } -func (self *SVpc) SyncSecurityGroup(secgroupId string, name string, rules []secrules.SecurityRule) (string, error) { - secgrpId := "" - if secgroup, err := self.region.getSecurityGroupByTag(self.VpcId, secgroupId); err != nil { - if secgrpId, err = self.region.createSecurityGroup(self.VpcId, name, ""); err != nil { - return "", err - } else if err := self.region.addTagToSecurityGroup(secgrpId, "id", secgroupId, 1); err != nil { - return "", err - } - //addRules - log.Debugf("Add Rules for %s", secgrpId) - for _, rule := range rules { - if err := self.region.addSecurityGroupRule(secgrpId, &rule); err != nil { - return "", err - } - } - } else { - //syncRules - secgrpId = secgroup.SecurityGroupId - log.Debugf("Sync Rules for %s", secgroup.GetName()) - if secgroup.GetName() != name { - if err := self.region.modifySecurityGroup(secgrpId, name, ""); err != nil { - log.Errorf("Change SecurityGroup name to %s failed: %v", name, err) - } - } - self.region.syncSecgroupRules(secgrpId, rules) - } - return secgrpId, nil -} - func (self *SVpc) assignSecurityGroup(secgroupId string, instanceId string) error { return self.region.assignSecurityGroup(secgroupId, instanceId) } diff --git a/pkg/util/azure/classic_instance.go b/pkg/util/azure/classic_instance.go index 388e9f3620..47ff97c309 100644 --- a/pkg/util/azure/classic_instance.go +++ b/pkg/util/azure/classic_instance.go @@ -10,7 +10,6 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/pkg/util/osprofile" - "yunion.io/x/pkg/util/secrules" ) type ClassicVirtualMachineInstanceView struct { @@ -415,10 +414,6 @@ func (self *SRegion) StopClassicVM(instanceId string, isForce bool) error { return err } -func (self *SClassicInstance) SyncSecurityGroup(secgroupId string, name string, rules []secrules.SecurityRule) error { - return cloudprovider.ErrNotSupported -} - func (self *SClassicInstance) GetIEIP() (cloudprovider.ICloudEIP, error) { if self.Properties.NetworkProfile.ReservedIps != nil && len(*self.Properties.NetworkProfile.ReservedIps) > 0 { for _, reserveIp := range *self.Properties.NetworkProfile.ReservedIps { @@ -456,3 +451,11 @@ func (self *SClassicInstance) GetBillingType() string { func (self *SClassicInstance) GetExpiredAt() time.Time { return time.Now() } + +func (self *SClassicInstance) AssignSecurityGroup(secgroupId string) error { + return cloudprovider.ErrNotImplemented +} + +func (self *SClassicInstance) RevokeSecurityGroup() error { + return cloudprovider.ErrNotImplemented +} diff --git a/pkg/util/azure/classic_vpc.go b/pkg/util/azure/classic_vpc.go index 6e369a6617..28478ac967 100644 --- a/pkg/util/azure/classic_vpc.go +++ b/pkg/util/azure/classic_vpc.go @@ -6,7 +6,6 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" - "yunion.io/x/pkg/util/secrules" ) type ClassicAddressSpace struct { @@ -76,10 +75,6 @@ func (self *SClassicVpc) Delete() error { return self.region.client.Delete(self.ID) } -func (self *SClassicVpc) SyncSecurityGroup(tag string, name string, rules []secrules.SecurityRule) (string, error) { - return "", cloudprovider.ErrNotImplemented -} - func (self *SClassicVpc) getWire() *SClassicWire { if self.iwires == nil { self.fetchWires() diff --git a/pkg/util/azure/instance.go b/pkg/util/azure/instance.go index aff99f53ee..bcc5b093fc 100644 --- a/pkg/util/azure/instance.go +++ b/pkg/util/azure/instance.go @@ -10,7 +10,6 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/pkg/util/osprofile" - "yunion.io/x/pkg/util/secrules" ) const ( @@ -977,31 +976,6 @@ func (self *SRegion) StopVM(instanceId string, isForce bool) error { return err } -func (self *SInstance) SyncSecurityGroup(dbSecgroupId string, name string, rules []secrules.SecurityRule) error { - nics, err := self.getNics() - if err != nil { - return err - } - if len(dbSecgroupId) == 0 { - for _, nic := range nics { - if err := nic.revokeSecurityGroup(); err != nil { - return err - } - } - return nil - } - extId, err := self.host.zone.region.syncSecurityGroup(dbSecgroupId, name, rules) - if err != nil { - return err - } - for _, nic := range nics { - if err := nic.assignSecurityGroup(extId); err != nil { - return err - } - } - return nil -} - func (self *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) { nics, err := self.getNics() if err != nil { @@ -1030,3 +1004,20 @@ func (self *SInstance) GetBillingType() string { func (self *SInstance) GetExpiredAt() time.Time { return time.Now() } + +func (self *SInstance) AssignSecurityGroup(secgroupId string) error { + return self.host.zone.region.AssiginSecurityGroup(self.ID, secgroupId) +} + +func (self *SInstance) RevokeSecurityGroup() error { + nics, err := self.getNics() + if err != nil { + return err + } + for _, nic := range nics { + if err := nic.revokeSecurityGroup(); err != nil { + return err + } + } + return nil +} diff --git a/pkg/util/azure/region.go b/pkg/util/azure/region.go index 00dfefb556..756a46938f 100644 --- a/pkg/util/azure/region.go +++ b/pkg/util/azure/region.go @@ -8,6 +8,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/util/seclib2" + "yunion.io/x/pkg/util/secrules" ) type SVMSize struct { @@ -416,3 +417,14 @@ func (region *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { } return ieips, nil } + +func (region *SRegion) SyncSecurityGroup(secgroupId string, vpcId string, name string, desc string, rules []secrules.SecurityRule) (string, error) { + if len(secgroupId) == 0 { + secgroup, err := region.CreateSecurityGroup(name, "") + if err != nil { + return "", err + } + secgroupId = secgroup.ID + } + return region.updateClassicSecurityGroupRules(secgroupId, rules) +} diff --git a/pkg/util/azure/securitygroup.go b/pkg/util/azure/securitygroup.go index 2911130226..a4a7a63284 100644 --- a/pkg/util/azure/securitygroup.go +++ b/pkg/util/azure/securitygroup.go @@ -370,21 +370,6 @@ func (self *SSecurityGroup) Refresh() error { return jsonutils.Update(self, sec) } -func (region *SRegion) checkSecurityGroup(tagId, name string) (*SSecurityGroup, error) { - secgroups, err := region.GetSecurityGroups() - if err != nil { - return nil, err - } - for i := 0; i < len(secgroups); i++ { - for k, v := range secgroups[i].Tags { - if k == "id" && v == tagId || secgroups[i].Name == name { - return &secgroups[i], nil - } - } - } - return region.CreateSecurityGroup(name, tagId) -} - func convertRulePort(rule secrules.SecurityRule) []string { ports := []string{} if len(rule.Ports) > 0 { @@ -452,6 +437,7 @@ func (region *SRegion) updateSecurityGroupRules(secgroupId string, rules []secru if err != nil { return "", err } + sort.Sort(secrules.SecurityRuleSet(rules)) securityRules := []SecurityRules{} priority := int32(100) ruleStrs := []string{} @@ -486,64 +472,13 @@ func (region *SRegion) AttachSecurityToInterfaces(secgroupId string, nicIds []st } func (region *SRegion) AssiginSecurityGroup(instanceId, secgroupId string) error { - if instance, err := region.GetInstance(instanceId); err != nil { + instance, err := region.GetInstance(instanceId) + if err != nil { return err - } else { - nicIds := []string{} - for _, nic := range instance.Properties.NetworkProfile.NetworkInterfaces { - nicIds = append(nicIds, nic.ID) - } - return region.AttachSecurityToInterfaces(secgroupId, nicIds) } -} - -func (self *SRegion) syncSecgroupRules(secgroupId string, rules []secrules.SecurityRule) (string, error) { - secgroup, err := self.GetSecurityGroupDetails(secgroupId) - if err != nil { - return "", err + nicIds := []string{} + for _, nic := range instance.Properties.NetworkProfile.NetworkInterfaces { + nicIds = append(nicIds, nic.ID) } - sort.Sort(secrules.SecurityRuleSet(rules)) - sort.Sort(SecurityRulesSet(*secgroup.Properties.SecurityRules)) - - newRules := []secrules.SecurityRule{} - - i, j := 0, 0 - for i < len(rules) || j < len(*secgroup.Properties.SecurityRules) { - if i < len(rules) && j < len(*secgroup.Properties.SecurityRules) { - (*secgroup.Properties.SecurityRules)[j].Properties.Priority = 1 - srcRule := (*secgroup.Properties.SecurityRules)[j].Properties.String() - destRule := rules[i].String() - cmp := strings.Compare(srcRule, destRule) - if cmp == 0 { - // keep secRule - newRules = append(newRules, rules[i]) - i++ - j++ - } else if cmp > 0 { - // remove srcRule - j++ - } else { - // add destRule - newRules = append(newRules, rules[i]) - i++ - } - } else if i >= len(rules) { - // del other rules - j++ - } else if j >= len(*secgroup.Properties.SecurityRules) { - // add rule - newRules = append(newRules, rules[i]) - i++ - } - } - return self.updateSecurityGroupRules(secgroup.ID, newRules) - -} - -func (self *SRegion) syncSecurityGroup(tagId, name string, rules []secrules.SecurityRule) (string, error) { - secgroup, err := self.checkSecurityGroup(tagId, name) - if err != nil { - return "", err - } - return self.syncSecgroupRules(secgroup.ID, rules) + return region.AttachSecurityToInterfaces(secgroupId, nicIds) } diff --git a/pkg/util/azure/vpc.go b/pkg/util/azure/vpc.go index b75d14bbde..ff506c61e0 100644 --- a/pkg/util/azure/vpc.go +++ b/pkg/util/azure/vpc.go @@ -5,7 +5,6 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" - "yunion.io/x/pkg/util/secrules" ) type AddressSpace struct { @@ -103,14 +102,6 @@ func (self *SVpc) fetchSecurityGroups() error { } } -func (self *SVpc) SyncSecurityGroup(tag string, name string, rules []secrules.SecurityRule) (string, error) { - secgrp, err := self.region.checkSecurityGroup(tag, name) - if err != nil { - return "", err - } - return self.region.syncSecgroupRules(secgrp.ID, rules) -} - func (self *SVpc) getWire() *SWire { if self.iwires == nil { self.fetchWires() diff --git a/pkg/util/esxi/virtualmachine.go b/pkg/util/esxi/virtualmachine.go index 680a28c654..f2858520af 100644 --- a/pkg/util/esxi/virtualmachine.go +++ b/pkg/util/esxi/virtualmachine.go @@ -9,7 +9,6 @@ import ( "github.com/vmware/govmomi/vim25/types" "yunion.io/x/jsonutils" - "yunion.io/x/pkg/util/secrules" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" @@ -39,10 +38,6 @@ func (self *SVirtualMachine) GetGlobalId() string { return self.getUuid() } -func (self *SVirtualMachine) SyncSecurityGroup(secgroupId, name string, rules []secrules.SecurityRule) error { - return nil -} - func (self *SVirtualMachine) GetStatus() string { vm := object.NewVirtualMachine(self.manager.client.Client, self.getVirtualMachine().Self) state, err := vm.PowerState(self.manager.context) @@ -244,4 +239,12 @@ func (self *SVirtualMachine) GetBillingType() string { func (self *SVirtualMachine) GetExpiredAt() time.Time { return time.Time{} -} \ No newline at end of file +} + +func (self *SVirtualMachine) AssignSecurityGroup(secgroupId string) error { + return cloudprovider.ErrNotImplemented +} + +func (self *SVirtualMachine) RevokeSecurityGroup() error { + return cloudprovider.ErrNotImplemented +}