mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
fix: secgroup cache reference
This commit is contained in:
@@ -15,48 +15,16 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type SecGroupCacheListOptions struct {
|
||||
options.BaseListOptions
|
||||
Secgroup string `help:"Secgroup ID or Name"`
|
||||
}
|
||||
|
||||
R(&SecGroupCacheListOptions{}, "secgroup-cache-list", "List security group caches", func(s *mcclient.ClientSession, args *SecGroupCacheListOptions) error {
|
||||
params, err := options.ListStructToParams(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.SecGroupCaches.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(result, modules.SecGroupCaches.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
type SecGroupCacheIdOptions struct {
|
||||
ID string `help:"ID or Name or secgroup cache"`
|
||||
}
|
||||
R(&SecGroupCacheIdOptions{}, "secgroup-cache-show", "Show security group cache", func(s *mcclient.ClientSession, args *SecGroupCacheIdOptions) error {
|
||||
result, err := modules.SecGroupCaches.Get(s, args.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&SecGroupCacheIdOptions{}, "secgroup-cache-delete", "Delete security group cache", func(s *mcclient.ClientSession, args *SecGroupCacheIdOptions) error {
|
||||
result, err := modules.SecGroupCaches.Delete(s, args.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
cmd := shell.NewResourceCmd(&modules.SecGroupCaches).WithKeyword("secgroup-cache")
|
||||
cmd.List(&compute.SecGroupCacheListOptions{})
|
||||
cmd.Show(&compute.SecGroupCacheIdOptions{})
|
||||
cmd.Delete(&compute.SecGroupCacheIdOptions{})
|
||||
cmd.Perform("syncstatus", &compute.SecGroupCacheIdOptions{})
|
||||
cmd.Get("references", &compute.SecGroupCacheIdOptions{})
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package compute
|
||||
|
||||
const (
|
||||
SECGROUP_CACHE_STATUS_READY = "ready"
|
||||
SECGROUP_CACHE_STATUS_UNKNOWN = "unknown"
|
||||
SECGROUP_CACHE_STATUS_DELETING = "deleting"
|
||||
SECGROUP_CACHE_STATUS_CACHING = "caching"
|
||||
SECGROUP_CACHE_STATUS_DELETE_FAILED = "delete_failed"
|
||||
|
||||
@@ -415,6 +415,7 @@ type ICloudSecurityGroup interface {
|
||||
GetVpcId() string
|
||||
|
||||
SyncRules(common, inAdds, outAdds, inDels, outDels []SecurityRule) error
|
||||
GetReferences() ([]SecurityGroupReference, error)
|
||||
Delete() error
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,10 @@ import (
|
||||
"yunion.io/x/pkg/utils"
|
||||
)
|
||||
|
||||
type SecurityGroupReference struct {
|
||||
Id string
|
||||
}
|
||||
|
||||
type SecDriver interface {
|
||||
GetDefaultSecurityGroupInRule() SecurityRule
|
||||
GetDefaultSecurityGroupOutRule() SecurityRule
|
||||
|
||||
@@ -1693,11 +1693,6 @@ func (cache *SSecurityGroupCache) purge(ctx context.Context, userCred mcclient.T
|
||||
lockman.LockObject(ctx, cache)
|
||||
defer lockman.ReleaseObject(ctx, cache)
|
||||
|
||||
err := cache.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cache.RealDelete(ctx, userCred)
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,9 @@ type SSecurityGroupCache struct {
|
||||
SManagedResourceBase
|
||||
SSecurityGroupResourceBase
|
||||
|
||||
// 被其他安全组引用的次数
|
||||
ReferenceCount int `nullable:"false" list:"user" json:"reference_count"`
|
||||
|
||||
// 安全组Id
|
||||
// SecgroupId string `width:"128" charset:"ascii" list:"user" create:"required"`
|
||||
|
||||
@@ -388,14 +391,26 @@ func (self *SSecurityGroupCache) GetSecgroup() (*SSecurityGroup, error) {
|
||||
return model.(*SSecurityGroup), nil
|
||||
}
|
||||
|
||||
func (self *SSecurityGroupCache) syncWithCloudSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudSecurityGroup) ([]SSecurityGroupRule, error) {
|
||||
func (self *SSecurityGroupCache) SyncBaseInfo(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudSecurityGroup) error {
|
||||
_, err := db.Update(self, func() error {
|
||||
self.Status = api.SECGROUP_CACHE_STATUS_READY
|
||||
self.Name = ext.GetName()
|
||||
self.Description = ext.GetDescription()
|
||||
self.ExternalProjectId = ext.GetProjectId()
|
||||
references, err := ext.GetReferences()
|
||||
if err == nil {
|
||||
self.ReferenceCount = len(references)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "db.Update")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SSecurityGroupCache) syncWithCloudSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudSecurityGroup) ([]SSecurityGroupRule, error) {
|
||||
err := self.SyncBaseInfo(ctx, userCred, ext)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "db.Update")
|
||||
}
|
||||
@@ -519,6 +534,8 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.C
|
||||
cache.Name = added[i].GetName()
|
||||
cache.Description = added[i].GetDescription()
|
||||
cache.ExternalId = added[i].GetGlobalId()
|
||||
references, _ := added[i].GetReferences()
|
||||
cache.ReferenceCount = len(references)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -543,6 +560,40 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.C
|
||||
return localSecgroups, remoteSecgroups, syncResult
|
||||
}
|
||||
|
||||
func (self *SSecurityGroupCache) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return db.IsProjectAllowPerform(userCred, self, "syncstatus")
|
||||
}
|
||||
|
||||
// 同步安全组缓存状态
|
||||
func (self *SSecurityGroupCache) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.DiskSyncstatusInput) (jsonutils.JSONObject, error) {
|
||||
return nil, self.StartSyncstatusTask(ctx, userCred, "")
|
||||
}
|
||||
|
||||
func (self *SSecurityGroupCache) AllowGetDetailsReferences(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return db.IsAdminAllowGetSpec(userCred, self, "references")
|
||||
}
|
||||
|
||||
// 获取引用信息
|
||||
func (self *SSecurityGroupCache) GetDetailsReferences(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) ([]cloudprovider.SecurityGroupReference, error) {
|
||||
iSecgroup, err := self.GetISecurityGroup()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetISecurityGroup")
|
||||
}
|
||||
return iSecgroup.GetReferences()
|
||||
}
|
||||
|
||||
func (self *SSecurityGroupCache) StartSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
return StartResourceSyncStatusTask(ctx, userCred, self, "SecurityGroupCacheSyncstatusTask", "")
|
||||
}
|
||||
|
||||
func (self *SSecurityGroupCache) ValidateDeleteCondition(ctx context.Context) error {
|
||||
if self.ReferenceCount > 0 && self.Status == api.SECGROUP_CACHE_STATUS_READY {
|
||||
return httperrors.NewNotEmptyError("security group has been reference in %d security group", self.ReferenceCount)
|
||||
}
|
||||
|
||||
return self.SStatusStandaloneResourceBase.ValidateDeleteCondition(ctx)
|
||||
}
|
||||
|
||||
func (self *SSecurityGroupCache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
log.Infof("do nothing for delete secgroup cache")
|
||||
return nil
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type SecurityGroupCacheSyncstatusTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(SecurityGroupCacheSyncstatusTask{})
|
||||
}
|
||||
|
||||
func (self *SecurityGroupCacheSyncstatusTask) taskFailed(ctx context.Context, cache *models.SSecurityGroupCache, err error) {
|
||||
cache.SetStatus(self.UserCred, api.SECGROUP_CACHE_STATUS_UNKNOWN, err.Error())
|
||||
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
|
||||
}
|
||||
|
||||
func (self *SecurityGroupCacheSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
cache := obj.(*models.SSecurityGroupCache)
|
||||
|
||||
iSecgroup, err := cache.GetISecurityGroup()
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, cache, errors.Wrapf(err, "GetISecurityGroup"))
|
||||
return
|
||||
}
|
||||
|
||||
cache.SyncBaseInfo(ctx, self.GetUserCred(), iSecgroup)
|
||||
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
)
|
||||
|
||||
type SecGroupCacheListOptions struct {
|
||||
options.BaseListOptions
|
||||
Secgroup string `help:"Secgroup ID or Name"`
|
||||
}
|
||||
|
||||
func (opts *SecGroupCacheListOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return options.ListStructToParams(opts)
|
||||
}
|
||||
|
||||
type SecGroupCacheIdOptions struct {
|
||||
ID string `help:"ID or Name or secgroup cache"`
|
||||
}
|
||||
|
||||
func (opts *SecGroupCacheIdOptions) GetId() string {
|
||||
return opts.ID
|
||||
}
|
||||
|
||||
func (opts *SecGroupCacheIdOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -150,6 +150,52 @@ func (self *SSecurityGroup) Refresh() error {
|
||||
return jsonutils.Update(self, group)
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetReferences() ([]cloudprovider.SecurityGroupReference, error) {
|
||||
references, err := self.vpc.region.DescribeSecurityGroupReferences(self.SecurityGroupId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "DescribeSecurityGroupReferences")
|
||||
}
|
||||
ret := []cloudprovider.SecurityGroupReference{}
|
||||
for _, reference := range references {
|
||||
if reference.SecurityGroupId == self.SecurityGroupId {
|
||||
for _, sec := range reference.ReferencingSecurityGroups.ReferencingSecurityGroup {
|
||||
ret = append(ret, cloudprovider.SecurityGroupReference{
|
||||
Id: sec.SecurityGroupId,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
type ReferencingSecurityGroup struct {
|
||||
AliUid string
|
||||
SecurityGroupId string
|
||||
}
|
||||
|
||||
type ReferencingSecurityGroups struct {
|
||||
ReferencingSecurityGroup []ReferencingSecurityGroup
|
||||
}
|
||||
|
||||
type SecurityGroupReferences struct {
|
||||
SecurityGroupId string
|
||||
ReferencingSecurityGroups ReferencingSecurityGroups
|
||||
}
|
||||
|
||||
func (self *SRegion) DescribeSecurityGroupReferences(id string) ([]SecurityGroupReferences, error) {
|
||||
params := map[string]string{
|
||||
"RegionId": self.RegionId,
|
||||
"SecurityGroupId.1": id,
|
||||
}
|
||||
resp, err := self.ecsRequest("DescribeSecurityGroupReferences", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "DescribeSecurityGroupReferences")
|
||||
}
|
||||
ret := []SecurityGroupReferences{}
|
||||
err = resp.Unmarshal(&ret, "SecurityGroupReferences", "SecurityGroupReference")
|
||||
return ret, errors.Wrapf(err, "resp.Unmarshal")
|
||||
}
|
||||
|
||||
func (self *SRegion) GetSecurityGroups(vpcId, name string, securityGroupIds []string, offset int, limit int) ([]SSecurityGroup, int, error) {
|
||||
if limit > 50 || limit <= 0 {
|
||||
limit = 50
|
||||
|
||||
@@ -38,10 +38,10 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
type SecurityGroupShowOptions struct {
|
||||
type SecurityGroupIdOptions struct {
|
||||
ID string `help:"ID or name of security group"`
|
||||
}
|
||||
shellutils.R(&SecurityGroupShowOptions{}, "security-group-show", "Show details of a security group", func(cli *aliyun.SRegion, args *SecurityGroupShowOptions) error {
|
||||
shellutils.R(&SecurityGroupIdOptions{}, "security-group-show", "Show details of a security group", func(cli *aliyun.SRegion, args *SecurityGroupIdOptions) error {
|
||||
secgrp, err := cli.GetSecurityGroupDetails(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -50,6 +50,15 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&SecurityGroupIdOptions{}, "security-group-references", "Show references of a security group", func(cli *aliyun.SRegion, args *SecurityGroupIdOptions) error {
|
||||
references, err := cli.DescribeSecurityGroupReferences(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(references, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
type SecurityGroupCreateOptions struct {
|
||||
NAME string `help:"SecurityGroup name"`
|
||||
VpcId string `help:"VPC ID"`
|
||||
|
||||
@@ -136,6 +136,46 @@ func (self *SecurityGroupPolicy) String() string {
|
||||
return strings.Join(result, ";")
|
||||
}
|
||||
|
||||
type ReferredSecurityGroup struct {
|
||||
SecurityGroupId string
|
||||
ReferredSecurityGroupIds []string
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetReferences() ([]cloudprovider.SecurityGroupReference, error) {
|
||||
references, err := self.region.DescribeSecurityGroupReferences(self.SecurityGroupId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "DescribeSecurityGroupReferences")
|
||||
}
|
||||
ret := []cloudprovider.SecurityGroupReference{}
|
||||
for _, refer := range references {
|
||||
if refer.SecurityGroupId == self.SecurityGroupId {
|
||||
for _, id := range refer.ReferredSecurityGroupIds {
|
||||
ret = append(ret, cloudprovider.SecurityGroupReference{
|
||||
Id: id,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) DescribeSecurityGroupReferences(id string) ([]ReferredSecurityGroup, error) {
|
||||
params := map[string]string{
|
||||
"Region": self.Region,
|
||||
"SecurityGroupIds.0": id,
|
||||
}
|
||||
resp, err := self.vpcRequest("DescribeSecurityGroupReferences", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "DescribeSecurityGroupReferences")
|
||||
}
|
||||
ret := []ReferredSecurityGroup{}
|
||||
err = resp.Unmarshal(&ret, "ReferredSecurityGroupSet")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "resp.Unmarshal")
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SecurityGroupPolicy) toRules() []cloudprovider.SecurityRule {
|
||||
result := []cloudprovider.SecurityRule{}
|
||||
rule := cloudprovider.SecurityRule{
|
||||
|
||||
@@ -55,6 +55,15 @@ func init() {
|
||||
return cloudprovider.ErrNotFound
|
||||
})
|
||||
|
||||
shellutils.R(&SecurityGroupOptions{}, "security-group-references", "Show references of a security group", func(cli *qcloud.SRegion, args *SecurityGroupOptions) error {
|
||||
references, err := cli.DescribeSecurityGroupReferences(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(references, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&SecurityGroupOptions{}, "security-group-delete", "Delete SecurityGroup", func(cli *qcloud.SRegion, args *SecurityGroupOptions) error {
|
||||
return cli.DeleteSecurityGroup(args.ID)
|
||||
})
|
||||
|
||||
@@ -14,6 +14,12 @@
|
||||
|
||||
package multicloud
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
|
||||
type SSecurityGroup struct {
|
||||
SVirtualResourceBase
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetReferences() ([]cloudprovider.SecurityGroupReference, error) {
|
||||
return []cloudprovider.SecurityGroupReference{}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user