diff --git a/cmd/climc/shell/compute/loadbalanceracls.go b/cmd/climc/shell/compute/loadbalanceracls.go index 7d0a26360b..cd640f4a03 100644 --- a/cmd/climc/shell/compute/loadbalanceracls.go +++ b/cmd/climc/shell/compute/loadbalanceracls.go @@ -137,4 +137,21 @@ func init() { printLbAcl(lbacl) return nil }) + R(&options.LoadbalancerAclPublicOptions{}, "lbacl-public", "Public lbacl", func(s *mcclient.ClientSession, opts *options.LoadbalancerAclPublicOptions) error { + params := jsonutils.Marshal(opts) + lbacl, err := modules.LoadbalancerAcls.PerformAction(s, opts.ID, "public", params) + if err != nil { + return err + } + printLbAcl(lbacl) + return nil + }) + R(&options.LoadbalancerAclPrivateOptions{}, "lbacl-private", "Private lbacl", func(s *mcclient.ClientSession, opts *options.LoadbalancerAclPrivateOptions) error { + lbacl, err := modules.LoadbalancerAcls.PerformAction(s, opts.ID, "private", nil) + if err != nil { + return err + } + printLbAcl(lbacl) + return nil + }) } diff --git a/cmd/climc/shell/compute/loadbalancercertificates.go b/cmd/climc/shell/compute/loadbalancercertificates.go index 99139d4935..45971b0da6 100644 --- a/cmd/climc/shell/compute/loadbalancercertificates.go +++ b/cmd/climc/shell/compute/loadbalancercertificates.go @@ -15,6 +15,8 @@ package compute import ( + "yunion.io/x/jsonutils" + "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/mcclient/options" @@ -81,4 +83,21 @@ func init() { printObject(lbcert) return nil }) + R(&options.LoadbalancerCertificatePublicOptions{}, "lbcert-public", "Public lbcert", func(s *mcclient.ClientSession, opts *options.LoadbalancerCertificatePublicOptions) error { + params := jsonutils.Marshal(opts) + lbcert, err := modules.LoadbalancerCertificates.PerformAction(s, opts.ID, "public", params) + if err != nil { + return err + } + printObject(lbcert) + return nil + }) + R(&options.LoadbalancerCertificatePrivateOptions{}, "lbcert-private", "Private lbcert", func(s *mcclient.ClientSession, opts *options.LoadbalancerCertificatePrivateOptions) error { + lbcert, err := modules.LoadbalancerCertificates.PerformAction(s, opts.ID, "private", nil) + if err != nil { + return err + } + printObject(lbcert) + return nil + }) } diff --git a/pkg/apis/compute/cachedloadbalanceracl.go b/pkg/apis/compute/cachedloadbalanceracl.go index 89281402ef..121d68caf4 100644 --- a/pkg/apis/compute/cachedloadbalanceracl.go +++ b/pkg/apis/compute/cachedloadbalanceracl.go @@ -17,7 +17,7 @@ package compute import "yunion.io/x/onecloud/pkg/apis" type CachedLoadbalancerAclDetails struct { - apis.SharableVirtualResourceDetails + apis.VirtualResourceDetails CloudregionResourceInfo ManagedResourceInfo @@ -25,7 +25,7 @@ type CachedLoadbalancerAclDetails struct { } type CachedLoadbalancerAclListInput struct { - apis.SharableVirtualResourceListInput + apis.VirtualResourceListInput RegionalFilterListInput ManagedResourceListInput LoadbalancerAclFilterListInput diff --git a/pkg/apis/compute/loadbalancer.go b/pkg/apis/compute/loadbalancer.go index b5dfb1f419..e9db107a4b 100644 --- a/pkg/apis/compute/loadbalancer.go +++ b/pkg/apis/compute/loadbalancer.go @@ -104,7 +104,7 @@ type LoadbalancerAgentListInput struct { } type LoadbalancerCertificateListInput struct { - apis.VirtualResourceListInput + apis.SharableVirtualResourceListInput apis.ExternalizedResourceBaseListInput UsableResourceListInput diff --git a/pkg/apis/compute/loadbalanceracl.go b/pkg/apis/compute/loadbalanceracl.go index c17d2aa5da..26d03e5c41 100644 --- a/pkg/apis/compute/loadbalanceracl.go +++ b/pkg/apis/compute/loadbalanceracl.go @@ -22,6 +22,8 @@ type LoadbalancerAclDetails struct { CloudregionResourceInfo SLoadbalancerAcl + + LbListenerCount int `json:"lb_listener_count"` } type LoadbalancerAclResourceInfo struct { diff --git a/pkg/apis/compute/loadbalancercertificate.go b/pkg/apis/compute/loadbalancercertificate.go index 3de78303b4..692a020eed 100644 --- a/pkg/apis/compute/loadbalancercertificate.go +++ b/pkg/apis/compute/loadbalancercertificate.go @@ -17,8 +17,10 @@ package compute import "yunion.io/x/onecloud/pkg/apis" type LoadbalancerCertificateDetails struct { - apis.VirtualResourceDetails + apis.SharableVirtualResourceDetails SLoadbalancerCertificate + + LbListenerCount int `json:"lb_listener_count"` } type LoadbalancerCertificateResourceInfo struct { diff --git a/pkg/compute/models/loadbalanceracls.go b/pkg/compute/models/loadbalanceracls.go index e47b04c6d9..5abc685bee 100644 --- a/pkg/compute/models/loadbalanceracls.go +++ b/pkg/compute/models/loadbalanceracls.go @@ -35,6 +35,7 @@ import ( 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/cloudcommon/policy" "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/httperrors" @@ -166,10 +167,10 @@ func loadbalancerAclsValidateAclEntries(data *jsonutils.JSONDict, update bool) ( return data, nil } -func (man *SLoadbalancerAclManager) FetchByFingerPrint(fingerprint string) (*SLoadbalancerAcl, error) { +func (man *SLoadbalancerAclManager) FetchByFingerPrint(projectId string, fingerprint string) (*SLoadbalancerAcl, error) { ret := &SLoadbalancerAcl{} q := man.Query().IsFalse("pending_deleted") - q = q.Equals("fingerprint", fingerprint).Asc("created_at").Limit(1) + q = q.Equals("tenant_id", projectId).Equals("fingerprint", fingerprint).Asc("created_at").Limit(1) err := q.First(ret) if err != nil { return nil, err @@ -178,9 +179,9 @@ func (man *SLoadbalancerAclManager) FetchByFingerPrint(fingerprint string) (*SLo return ret, nil } -func (man *SLoadbalancerAclManager) CountByFingerPrint(fingerprint string) int { +func (man *SLoadbalancerAclManager) CountByFingerPrint(projectId string, fingerprint string) int { q := man.Query().IsFalse("pending_deleted") - return q.Equals("fingerprint", fingerprint).Asc("created_at").Count() + return q.Equals("tenant_id", projectId).Equals("fingerprint", fingerprint).Asc("created_at").Count() } func (man *SLoadbalancerAclManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { @@ -299,6 +300,23 @@ func (manager *SLoadbalancerAclManager) FetchCustomizeColumns( } } + for i := range objs { + q := LoadbalancerListenerManager.Query().Equals("acl_id", objs[i].(*SLoadbalancerAcl).GetId()) + ownerId, queryScope, err := db.FetchCheckQueryOwnerScope(ctx, userCred, query, LoadbalancerListenerManager, policy.PolicyActionList, true) + if err != nil { + log.Errorf("FetchCheckQueryOwnerScope error: %v", err) + return rows + } + + q = LoadbalancerListenerManager.FilterByOwner(q, ownerId, queryScope) + count, err := q.CountWithError() + if err != nil { + log.Errorf("db.CountWithError error: %v", err) + } + + rows[i].LbListenerCount = count + } + return rows } @@ -365,7 +383,6 @@ func (lbacl *SLoadbalancerAcl) PerformPatch(ctx context.Context, userCred mcclie func (lbacl *SLoadbalancerAcl) ValidateDeleteCondition(ctx context.Context) error { men := []db.IModelManager{ LoadbalancerListenerManager, - CachedLoadbalancerAclManager, } lbaclId := lbacl.Id @@ -397,6 +414,18 @@ func (lbacl *SLoadbalancerAcl) PerformPurge(ctx context.Context, userCred mcclie func (lbacl *SLoadbalancerAcl) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { if !lbacl.PendingDeleted { + caches, err := lbacl.GetCachedAcls() + if err != nil { + return errors.Wrap(err, "GetCachedAcls") + } + + for i := range caches { + err := caches[i].MarkPendingDelete(userCred) + if err != nil { + return errors.Wrap(err, "MarkPendingDelete") + } + } + return lbacl.DoPendingDelete(ctx, userCred) } diff --git a/pkg/compute/models/loadbalancercachedacls.go b/pkg/compute/models/loadbalancercachedacls.go index 47de1c847a..ec9b9fbdd6 100644 --- a/pkg/compute/models/loadbalancercachedacls.go +++ b/pkg/compute/models/loadbalancercachedacls.go @@ -33,13 +33,14 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/util/rbacutils" "yunion.io/x/onecloud/pkg/util/stringutils2" ) // +onecloud:swagger-gen-ignore type SCachedLoadbalancerAclManager struct { SLoadbalancerLogSkipper - db.SSharableVirtualResourceBaseManager + db.SVirtualResourceBaseManager SManagedResourceBaseManager SCloudregionResourceBaseManager SLoadbalancerAclResourceBaseManager @@ -49,7 +50,7 @@ var CachedLoadbalancerAclManager *SCachedLoadbalancerAclManager func init() { CachedLoadbalancerAclManager = &SCachedLoadbalancerAclManager{ - SSharableVirtualResourceBaseManager: db.NewSharableVirtualResourceBaseManager( + SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager( SCachedLoadbalancerAcl{}, "cachedloadbalanceracls_tbl", "cachedloadbalanceracl", @@ -61,7 +62,7 @@ func init() { } type SCachedLoadbalancerAcl struct { - db.SSharableVirtualResourceBase + db.SVirtualResourceBase db.SExternalizedResourceBase SManagedResourceBase SCloudregionResourceBase @@ -79,21 +80,21 @@ func (lbacl *SCachedLoadbalancerAcl) ValidateUpdateData(ctx context.Context, use if err != nil { return nil, err } - input := apis.SharableVirtualResourceBaseUpdateInput{} + input := apis.VirtualResourceBaseUpdateInput{} err = data.Unmarshal(&input) if err != nil { return nil, errors.Wrap(err, "Unmarshal") } - input, err = lbacl.SSharableVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, input) + input, err = lbacl.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, input) if err != nil { - return nil, errors.Wrap(err, "SSharableVirtualResourceBase.ValidateUpdateData") + return nil, errors.Wrap(err, "SVirtualResourceBase.ValidateUpdateData") } data.Update(jsonutils.Marshal(input)) return data, nil } func (lbacl *SCachedLoadbalancerAcl) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) { - lbacl.SSharableVirtualResourceBase.PostUpdate(ctx, userCred, query, data) + lbacl.SVirtualResourceBase.PostUpdate(ctx, userCred, query, data) lbacl.SetStatus(userCred, api.LB_SYNC_CONF, "") lbacl.StartLoadBalancerAclSyncTask(ctx, userCred, "") } @@ -166,7 +167,7 @@ func (man *SCachedLoadbalancerAclManager) ValidateCreateData(ctx context.Context } func (lbacl *SCachedLoadbalancerAcl) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) { - lbacl.SSharableVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) + lbacl.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) lbacl.SetStatus(userCred, api.LB_CREATING, "") if err := lbacl.StartLoadBalancerAclCreateTask(ctx, userCred, ""); err != nil { @@ -236,15 +237,15 @@ func (man *SCachedLoadbalancerAclManager) FetchCustomizeColumns( ) []api.CachedLoadbalancerAclDetails { rows := make([]api.CachedLoadbalancerAclDetails, len(objs)) - virtRows := man.SSharableVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList) + virtRows := man.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList) manRows := man.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList) regionRows := man.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList) for i := range rows { rows[i] = api.CachedLoadbalancerAclDetails{ - SharableVirtualResourceDetails: virtRows[i], - ManagedResourceInfo: manRows[i], - CloudregionResourceInfo: regionRows[i], + VirtualResourceDetails: virtRows[i], + ManagedResourceInfo: manRows[i], + CloudregionResourceInfo: regionRows[i], } } @@ -262,6 +263,7 @@ func (lbacl *SCachedLoadbalancerAcl) ValidateDeleteCondition(ctx context.Context lbaclId := lbacl.Id n, err := t.Query(). Filter(sqlchemy.OR(sqlchemy.IsNull(pdF), sqlchemy.IsFalse(pdF))). + Equals("domain_id", lbacl.DomainId). Equals("acl_id", lbaclId). CountWithError() if err != nil { @@ -510,24 +512,24 @@ func (man *SCachedLoadbalancerAclManager) newFromCloudLoadbalancerAcl(ctx contex } f := aclEntites.Fingerprint() - if LoadbalancerAclManager.CountByFingerPrint(f) == 0 { - localAcl := SLoadbalancerAcl{} + if LoadbalancerAclManager.CountByFingerPrint(provider.ProjectId, f) == 0 { + localAcl := &SLoadbalancerAcl{} localAcl.Name = acl.Name localAcl.Description = acl.Description localAcl.AclEntries = &aclEntites localAcl.Fingerprint = f - // usercread - localAcl.DomainId = userCred.GetProjectDomainId() - localAcl.ProjectId = userCred.GetProjectId() - localAcl.ProjectSrc = string(apis.OWNER_SOURCE_CLOUD) + localAcl.IsPublic = true + localAcl.PublicScope = string(rbacutils.ScopeDomain) err := LoadbalancerAclManager.TableSpec().Insert(ctx, &localAcl) if err != nil { return nil, errors.Wrap(err, "cachedLoadbalancerAclManager.new.InsertAcl") } + + SyncCloudProject(userCred, localAcl, provider.GetOwnerId(), extAcl, provider.GetId()) } { - localAcl, err := LoadbalancerAclManager.FetchByFingerPrint(f) + localAcl, err := LoadbalancerAclManager.FetchByFingerPrint(provider.ProjectId, f) if err != nil { return nil, errors.Wrap(err, "cachedLoadbalancerAclManager.new.FetchByFingerPrint") } @@ -561,9 +563,9 @@ func (manager *SCachedLoadbalancerAclManager) ListItemFilter( ) (*sqlchemy.SQuery, error) { var err error - q, err = manager.SSharableVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query.SharableVirtualResourceListInput) + q, err = manager.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VirtualResourceListInput) if err != nil { - return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.ListItemFilter") + return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemFilter") } q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput) if err != nil { @@ -590,9 +592,9 @@ func (manager *SCachedLoadbalancerAclManager) OrderByExtraFields( ) (*sqlchemy.SQuery, error) { var err error - q, err = manager.SSharableVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.SharableVirtualResourceListInput) + q, err = manager.SVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VirtualResourceListInput) if err != nil { - return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.OrderByExtraFields") + return nil, errors.Wrap(err, "SVirtualResourceBaseManager.OrderByExtraFields") } q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput) if err != nil { @@ -613,7 +615,7 @@ func (manager *SCachedLoadbalancerAclManager) OrderByExtraFields( func (manager *SCachedLoadbalancerAclManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) { var err error - q, err = manager.SSharableVirtualResourceBaseManager.QueryDistinctExtraField(q, field) + q, err = manager.SVirtualResourceBaseManager.QueryDistinctExtraField(q, field) if err == nil { return q, nil } @@ -640,9 +642,9 @@ func (manager *SCachedLoadbalancerAclManager) ListItemExportKeys(ctx context.Con ) (*sqlchemy.SQuery, error) { var err error - q, err = manager.SSharableVirtualResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys) + q, err = manager.SVirtualResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys) if err != nil { - return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.ListItemExportKeys") + return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemExportKeys") } if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) { q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys) diff --git a/pkg/compute/models/loadbalancercachedcertificates.go b/pkg/compute/models/loadbalancercachedcertificates.go index 83dd6835d8..72a7d184a3 100644 --- a/pkg/compute/models/loadbalancercachedcertificates.go +++ b/pkg/compute/models/loadbalancercachedcertificates.go @@ -100,6 +100,7 @@ func (self *SCachedLoadbalancerCertificate) ValidateDeleteCondition(ctx context. t := man.TableSpec().Instance() pdF := t.Field("pending_deleted") n, err := t.Query(). + Equals("domain_id", self.DomainId). Equals("certificate_id", lbcertId). Filter(sqlchemy.OR(sqlchemy.IsNull(pdF), sqlchemy.IsFalse(pdF))). CountWithError() @@ -114,6 +115,10 @@ func (self *SCachedLoadbalancerCertificate) ValidateDeleteCondition(ctx context. return nil } +func (self *SCachedLoadbalancerCertificate) ValidatePurgeCondition(ctx context.Context) error { + return nil +} + func (self *SCachedLoadbalancerCertificate) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { return nil } @@ -312,12 +317,14 @@ func (man *SCachedLoadbalancerCertificateManager) newFromCloudLoadbalancerCertif lbcert.CloudregionId = region.Id c := SLoadbalancerCertificate{} - q1 := LoadbalancerCertificateManager.Query().IsFalse("pending_deleted").Equals("fingerprint", extCertificate.GetFingerprint()) + q1 := LoadbalancerCertificateManager.Query().IsFalse("pending_deleted") + q1 = q1.Equals("fingerprint", extCertificate.GetFingerprint()) + q1 = q1.Equals("tenant_id", provider.ProjectId) err = q1.First(&c) if err != nil { switch err { case sql.ErrNoRows: - localcert, err := LoadbalancerCertificateManager.CreateCertificate(ctx, userCred, lbcert.Name, extCertificate) + localcert, err := LoadbalancerCertificateManager.CreateCertificate(ctx, userCred, provider, lbcert.Name, extCertificate) if err != nil { return nil, fmt.Errorf("newFromCloudLoadbalancerCertificate CreateCertificate %s", err) } diff --git a/pkg/compute/models/loadbalancercertificates.go b/pkg/compute/models/loadbalancercertificates.go index 7e54419221..c46a25f2c4 100644 --- a/pkg/compute/models/loadbalancercertificates.go +++ b/pkg/compute/models/loadbalancercertificates.go @@ -31,16 +31,18 @@ import ( "yunion.io/x/onecloud/pkg/apis" api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/policy" "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/util/rbacutils" "yunion.io/x/onecloud/pkg/util/stringutils2" ) type SLoadbalancerCertificateManager struct { SLoadbalancerLogSkipper - db.SVirtualResourceBaseManager + db.SSharableVirtualResourceBaseManager db.SExternalizedResourceBaseManager } @@ -48,7 +50,7 @@ var LoadbalancerCertificateManager *SLoadbalancerCertificateManager func init() { LoadbalancerCertificateManager = &SLoadbalancerCertificateManager{ - SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager( + SSharableVirtualResourceBaseManager: db.NewSharableVirtualResourceBaseManager( SLoadbalancerCertificate{}, "loadbalancercertificates_tbl", "loadbalancercertificate", @@ -63,7 +65,7 @@ func init() { // - notify users of cert expiration // - ca info: self-signed, public ca type SLoadbalancerCertificate struct { - db.SVirtualResourceBase + db.SSharableVirtualResourceBase db.SExternalizedResourceBase // SManagedResourceBase @@ -100,12 +102,12 @@ func (lbcert *SLoadbalancerCertificate) ValidateUpdateData(ctx context.Context, updateData.Set("description", jsonutils.NewString(desc)) } - input := apis.VirtualResourceBaseUpdateInput{} + input := apis.SharableVirtualResourceBaseUpdateInput{} err := updateData.Unmarshal(&input) if err != nil { return nil, errors.Wrap(err, "Unmarshal") } - input, err = lbcert.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, input) + input, err = lbcert.SSharableVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, input) if err != nil { return nil, errors.Wrap(err, "SVirtualResourceBase.ValidateUpdateData") } @@ -115,7 +117,7 @@ func (lbcert *SLoadbalancerCertificate) ValidateUpdateData(ctx context.Context, } func (lbcert *SLoadbalancerCertificate) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) { - lbcert.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) + lbcert.SSharableVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data) lbcert.SetStatus(userCred, api.LB_STATUS_ENABLED, "") } @@ -138,14 +140,31 @@ func (manager *SLoadbalancerCertificateManager) FetchCustomizeColumns( ) []api.LoadbalancerCertificateDetails { rows := make([]api.LoadbalancerCertificateDetails, len(objs)) - virtRows := manager.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList) + virtRows := manager.SSharableVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList) for i := range rows { rows[i] = api.LoadbalancerCertificateDetails{ - VirtualResourceDetails: virtRows[i], + SharableVirtualResourceDetails: virtRows[i], } } + for i := range objs { + q := LoadbalancerListenerManager.Query().Equals("certificate_id", objs[i].(*SLoadbalancerCertificate).GetId()) + ownerId, queryScope, err := db.FetchCheckQueryOwnerScope(ctx, userCred, query, LoadbalancerListenerManager, policy.PolicyActionList, true) + if err != nil { + log.Errorf("FetchCheckQueryOwnerScope error: %v", err) + return rows + } + + q = LoadbalancerListenerManager.FilterByOwner(q, ownerId, queryScope) + count, err := q.CountWithError() + if err != nil { + log.Errorf("db.CountWithError error: %v", err) + } + + rows[i].LbListenerCount = count + } + return rows } @@ -220,9 +239,9 @@ func (man *SLoadbalancerCertificateManager) ListItemFilter( userCred mcclient.TokenCredential, query api.LoadbalancerCertificateListInput, ) (*sqlchemy.SQuery, error) { - q, err := man.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VirtualResourceListInput) + q, err := man.SSharableVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query.SharableVirtualResourceListInput) if err != nil { - return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemFilter") + return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.ListItemFilter") } q, err = man.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput) if err != nil { @@ -279,9 +298,9 @@ func (man *SLoadbalancerCertificateManager) OrderByExtraFields( ) (*sqlchemy.SQuery, error) { var err error - q, err = man.SVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VirtualResourceListInput) + q, err = man.SSharableVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.SharableVirtualResourceListInput) if err != nil { - return nil, errors.Wrap(err, "SVirtualResourceBaseManager.OrderByExtraFields") + return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.OrderByExtraFields") } return q, nil @@ -290,7 +309,7 @@ func (man *SLoadbalancerCertificateManager) OrderByExtraFields( func (man *SLoadbalancerCertificateManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) { var err error - q, err = man.SVirtualResourceBaseManager.QueryDistinctExtraField(q, field) + q, err = man.SSharableVirtualResourceBaseManager.QueryDistinctExtraField(q, field) if err == nil { return q, nil } @@ -305,12 +324,12 @@ func (man *SLoadbalancerCertificateManager) ValidateCreateData(ctx context.Conte } data = v.UpdateCertKeyInfo(ctx, data) - input := apis.VirtualResourceCreateInput{} + input := apis.SharableVirtualResourceCreateInput{} err := data.Unmarshal(&input) if err != nil { return nil, httperrors.NewInternalServerError("unmarshal VirtualResourceCreateInput fail %s", err) } - input, err = man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input) + input, err = man.SSharableVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input) if err != nil { return nil, err } @@ -383,7 +402,7 @@ func (man *SLoadbalancerCertificateManager) InitializeData() error { return nil } -func (man *SLoadbalancerCertificateManager) CreateCertificate(ctx context.Context, userCred mcclient.TokenCredential, name string, extCert cloudprovider.ICloudLoadbalancerCertificate) (*SLoadbalancerCertificate, error) { +func (man *SLoadbalancerCertificateManager) CreateCertificate(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, name string, extCert cloudprovider.ICloudLoadbalancerCertificate) (*SLoadbalancerCertificate, error) { fingerprint := extCert.GetFingerprint() if len(fingerprint) == 0 { return nil, fmt.Errorf("CreateCertificate fingerprint can not be empty") @@ -402,25 +421,25 @@ func (man *SLoadbalancerCertificateManager) CreateCertificate(ctx context.Contex if count == 0 { cert := &SLoadbalancerCertificate{} + cert.SetModelManager(man, cert) err := data.Unmarshal(cert) if err != nil { return nil, err } - // usercred - cert.DomainId = userCred.GetProjectDomainId() - cert.ProjectId = userCred.GetProjectId() - cert.ProjectSrc = string(apis.OWNER_SOURCE_CLOUD) - // other information's cert.CommonName = extCert.GetCommonName() cert.SubjectAlternativeNames = extCert.GetSubjectAlternativeNames() cert.NotAfter = extCert.GetExpireTime() + cert.PublicScope = string(rbacutils.ScopeDomain) + cert.IsPublic = true err = man.TableSpec().Insert(ctx, cert) if err != nil { return nil, err } + + SyncCloudProject(userCred, cert, provider.GetOwnerId(), extCert, provider.GetId()) } ret := &SLoadbalancerCertificate{} diff --git a/pkg/compute/models/purge.go b/pkg/compute/models/purge.go index 34c3689bd0..0d54e8f565 100644 --- a/pkg/compute/models/purge.go +++ b/pkg/compute/models/purge.go @@ -176,7 +176,7 @@ func (lbcert *SCachedLoadbalancerCertificate) purge(ctx context.Context, userCre lockman.LockObject(ctx, lbcert) defer lockman.ReleaseObject(ctx, lbcert) - err := lbcert.ValidateDeleteCondition(ctx) + err := lbcert.ValidatePurgeCondition(ctx) if err != nil { return err } diff --git a/pkg/compute/regiondrivers/managedvirtual.go b/pkg/compute/regiondrivers/managedvirtual.go index d57118b4de..9719944222 100644 --- a/pkg/compute/regiondrivers/managedvirtual.go +++ b/pkg/compute/regiondrivers/managedvirtual.go @@ -129,20 +129,49 @@ func (self *SManagedVirtualizationRegionDriver) ValidateUpdateLoadbalancerListen return data, nil } +func validateUniqueById(ctx context.Context, userCred mcclient.TokenCredential, man db.IResourceModelManager, id string) error { + q := man.Query().Equals("id", id) + q = man.FilterByOwner(q, userCred, man.NamespaceScope()) + count, err := q.CountWithError() + if err != nil { + if err == sql.ErrNoRows { + return httperrors.NewResourceNotFoundError("failed to find %s %s", man.Keyword(), id) + } + return httperrors.NewGeneralError(err) + } + + if count > 1 { + return httperrors.NewDuplicateResourceError(id) + } + + return nil +} + func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict, lb *models.SLoadbalancer, backendGroup db.IModel) (*jsonutils.JSONDict, error) { if aclStatus, _ := data.GetString("acl_status"); aclStatus == api.LB_BOOL_ON { aclId, _ := data.GetString("acl_id") if len(aclId) == 0 { return nil, httperrors.NewMissingParameterError("acl") } - _, err := models.LoadbalancerAclManager.FetchById(aclId) + + err := validateUniqueById(ctx, userCred, models.LoadbalancerAclManager, aclId) if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError("failed to find acl %s", aclId) - } - return nil, httperrors.NewGeneralError(err) + return nil, err } } + + if lt, _ := data.GetString("listener_type"); lt == api.LB_LISTENER_TYPE_HTTPS { + certId, _ := data.GetString("certificate_id") + if len(certId) == 0 { + return nil, httperrors.NewMissingParameterError("certificate_id") + } + + err := validateUniqueById(ctx, userCred, models.LoadbalancerCertificateManager, certId) + if err != nil { + return nil, err + } + } + return data, nil } @@ -153,6 +182,21 @@ func (self *SManagedVirtualizationRegionDriver) ValidateUpdateLoadbalancerListen if listenerPort, _ := data.Int("listener_port"); listenerPort != 0 && listenerPort != int64(lblis.ListenerPort) { return nil, httperrors.NewInputParameterError("cannot change loadbalancer listener listener_port") } + + aclId, _ := data.GetString("acl_id") + if len(aclId) > 0 && lblis.AclId != aclId { + err := validateUniqueById(ctx, userCred, models.LoadbalancerAclManager, aclId) + if err != nil { + return nil, err + } + } + + if certId, _ := data.GetString("certificate_id"); len(certId) > 0 { + err := validateUniqueById(ctx, userCred, models.LoadbalancerCertificateManager, certId) + if err != nil { + return nil, err + } + } return data, nil } diff --git a/pkg/mcclient/modules/mod_loadbalanceracls.go b/pkg/mcclient/modules/mod_loadbalanceracls.go index a0ada2aa0a..bed1529074 100644 --- a/pkg/mcclient/modules/mod_loadbalanceracls.go +++ b/pkg/mcclient/modules/mod_loadbalanceracls.go @@ -32,6 +32,8 @@ func init() { []string{ "id", "name", + "project", + "is_public", "acl_entries", }, []string{"tenant"}, diff --git a/pkg/mcclient/options/loadbalanceracls.go b/pkg/mcclient/options/loadbalanceracls.go index c7aeb88d44..a8d028802e 100644 --- a/pkg/mcclient/options/loadbalanceracls.go +++ b/pkg/mcclient/options/loadbalanceracls.go @@ -19,8 +19,36 @@ import ( "strings" "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/apis" ) +type SharableProjectizedResourceBaseCreateInput struct { + apis.ProjectizedResourceCreateInput + apis.SharableResourceBaseCreateInput +} + +func (opts *SharableProjectizedResourceBaseCreateInput) Params() (*jsonutils.JSONDict, error) { + params, err := optionsStructToParams(opts.SharableResourceBaseCreateInput) + if err != nil { + return nil, err + } + + projectInput, err := optionsStructToParams(opts.ProjectizedResourceCreateInput.ProjectizedResourceInput) + if err != nil { + return nil, err + } + + domainInput, err := optionsStructToParams(opts.ProjectizedResourceCreateInput.DomainizedResourceInput) + if err != nil { + return nil, err + } + + params.Update(projectInput) + params.Update(domainInput) + return params, nil +} + type AclEntry struct { Cidr string Comment string @@ -70,6 +98,8 @@ func (entries AclEntries) String() string { } type LoadbalancerAclCreateOptions struct { + SharableProjectizedResourceBaseCreateInput + NAME string AclEntry []string `help:"acl entry with cidr and comment separated by #, e.g. 10.9.0.0/16#no comment" json:"-"` Manager string `json:"manager_id"` @@ -103,11 +133,29 @@ type LoadbalancerAclActionPatchOptions struct { Del []string `help:"acl entry with cidr and comment separated by #, e.g. 10.9.0.0/16#no comment" json:"-"` } +type LoadbalancerAclPublicOptions struct { + ID string `json:"-"` + Scope string `help:"sharing scope" choices:"system|domain|project"` + SharedProjects []string `help:"Share to projects"` + SharedDomains []string `help:"Share to domains"` +} + +type LoadbalancerAclPrivateOptions struct { + ID string `json:"-"` +} + func (opts *LoadbalancerAclCreateOptions) Params() (*jsonutils.JSONDict, error) { params, err := optionsStructToParams(opts) if err != nil { return nil, err } + + sp, err := opts.SharableProjectizedResourceBaseCreateInput.Params() + if err != nil { + return nil, err + } + + params.Update(sp) aclEntries := NewAclEntries(opts.AclEntry) aclEntriesJson := jsonutils.Marshal(aclEntries) params.Set("acl_entries", aclEntriesJson) @@ -119,6 +167,7 @@ func (opts *LoadbalancerAclUpdateOptions) Params() (*jsonutils.JSONDict, error) if err != nil { return nil, err } + // - when it's nil, we leave it alone without updating // - when it's non-nil, we update it as a whole if opts.AclEntry != nil { diff --git a/pkg/mcclient/options/loadbalancercertificates.go b/pkg/mcclient/options/loadbalancercertificates.go index 6e620fcce3..ff747b1ff7 100644 --- a/pkg/mcclient/options/loadbalancercertificates.go +++ b/pkg/mcclient/options/loadbalancercertificates.go @@ -48,6 +48,8 @@ func loadbalancerCertificateLoadFiles(cert, pkey string, allowEmpty bool) (*json } type LoadbalancerCertificateCreateOptions struct { + SharableProjectizedResourceBaseCreateInput + NAME string Cert string `required:"true" json:"-" help:"path to certificate file"` @@ -59,6 +61,14 @@ func (opts *LoadbalancerCertificateCreateOptions) Params() (*jsonutils.JSONDict, if err != nil { return nil, err } + + sp, err := opts.SharableProjectizedResourceBaseCreateInput.Params() + if err != nil { + return nil, err + } + + params.Update(sp) + paramsCertKey, err := loadbalancerCertificateLoadFiles(opts.Cert, opts.Pkey, false) if err != nil { return nil, err @@ -98,5 +108,17 @@ func (opts *LoadbalancerCertificateUpdateOptions) Params() (*jsonutils.JSONDict, if err != nil { return nil, err } + return paramsCertKey, nil } + +type LoadbalancerCertificatePublicOptions struct { + ID string `json:"-"` + Scope string `help:"sharing scope" choices:"system|domain|project"` + SharedProjects []string `help:"Share to projects"` + SharedDomains []string `help:"Share to domains"` +} + +type LoadbalancerCertificatePrivateOptions struct { + ID string `json:"-"` +}