diff --git a/pkg/cloudcommon/consts/opslog.go b/pkg/cloudcommon/consts/opslog.go new file mode 100644 index 0000000000..e19769d72a --- /dev/null +++ b/pkg/cloudcommon/consts/opslog.go @@ -0,0 +1,13 @@ +package consts + +var ( + globalOpsLogEnabled = true +) + +func DisableOpsLog() { + globalOpsLogEnabled = false +} + +func OpsLogEnabled() bool { + return globalOpsLogEnabled +} diff --git a/pkg/cloudcommon/db/opslog.go b/pkg/cloudcommon/db/opslog.go index 3b0fe4b8e4..cbc395cf41 100644 --- a/pkg/cloudcommon/db/opslog.go +++ b/pkg/cloudcommon/db/opslog.go @@ -9,10 +9,12 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" - "yunion.io/x/onecloud/pkg/mcclient" - "yunion.io/x/onecloud/pkg/util/logclient" "yunion.io/x/pkg/util/stringutils" "yunion.io/x/sqlchemy" + + "yunion.io/x/onecloud/pkg/cloudcommon/consts" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" ) const ( @@ -172,22 +174,23 @@ type SOpsLogManager struct { type SOpsLog struct { SModelBase - Id int64 `primary:"true" auto_increment:"true" list:"user"` // = Column(BigInteger, primary_key=True) - ObjType string `width:"40" charset:"ascii" nullable:"false" list:"user"` // = Column(VARCHAR(40, charset='ascii'), nullable=False) - ObjId string `width:"128" charset:"ascii" nullable:"false" list:"user"` // = Column(VARCHAR(ID_LENGTH, charset='ascii'), nullable=False) - ObjName string `width:"128" charset:"utf8" nullable:"false" list:"user"` //= Column(VARCHAR(128, charset='utf8'), nullable=False) - Action string `width:"32" charset:"ascii" nullable:"false" list:"user"` //= Column(VARCHAR(32, charset='ascii'), nullable=False) - Notes string `width:"2048" charset:"utf8" list:"user"` // = Column(VARCHAR(2048, charset='utf8')) - ProjectId string `name:"tenant_id" width:"128" charset:"ascii" list:"user"` // = Column(VARCHAR(ID_LENGTH, charset='ascii')) - Project string `name:"tenant" width:"128" charset:"utf8" list:"user"` // tenant = Column(VARCHAR(128, charset='utf8')) - UserId string `width:"128" charset:"ascii" list:"user"` // = Column(VARCHAR(ID_LENGTH, charset='ascii')) - User string `width:"128" charset:"utf8" list:"user"` // = Column(VARCHAR(128, charset='utf8')) - DomainId string `width:"128" charset:"ascii" list:"user"` - Domain string `width:"128" charset:"utf8" list:"user"` - Roles string `width:"64" charset:"ascii" list:"user"` // = Column(VARCHAR(64, charset='ascii')) - // billing_type = Column(VARCHAR(64, charset='ascii'), nullable=True) - OpsTime time.Time `nullable:"false" list:"user"` // = Column(DateTime, nullable=False) - OwnerProjectId string `name:"owner_tenant_id" width:"128" charset:"ascii" list:"user"` // = Column(VARCHAR(ID_LENGTH, charset='ascii')) + Id int64 `primary:"true" auto_increment:"true" list:"user"` // = Column(BigInteger, primary_key=True) + ObjType string `width:"40" charset:"ascii" nullable:"false" list:"user" create:"required"` // = Column(VARCHAR(40, charset='ascii'), nullable=False) + ObjId string `width:"128" charset:"ascii" nullable:"false" list:"user" create:"required"` // = Column(VARCHAR(ID_LENGTH, charset='ascii'), nullable=False) + ObjName string `width:"128" charset:"utf8" nullable:"false" list:"user" create:"required"` //= Column(VARCHAR(128, charset='utf8'), nullable=False) + Action string `width:"32" charset:"utf8" nullable:"false" list:"user" create:"required"` //= Column(VARCHAR(32, charset='ascii'), nullable=False) + Notes string `width:"2048" charset:"utf8" list:"user" create:"required"` // = Column(VARCHAR(2048, charset='utf8')) + ProjectId string `name:"tenant_id" width:"128" charset:"ascii" list:"user" create:"required"` // = Column(VARCHAR(ID_LENGTH, charset='ascii')) + Project string `name:"tenant" width:"128" charset:"utf8" list:"user" create:"required"` // tenant = Column(VARCHAR(128, charset='utf8')) + UserId string `width:"128" charset:"ascii" list:"user" create:"required"` // = Column(VARCHAR(ID_LENGTH, charset='ascii')) + User string `width:"128" charset:"utf8" list:"user" create:"required"` // = Column(VARCHAR(128, charset='utf8')) + DomainId string `width:"128" charset:"ascii" list:"user" create:"optional"` + Domain string `width:"128" charset:"utf8" list:"user" create:"optional"` + Roles string `width:"64" charset:"ascii" list:"user" create:"optional"` // = Column(VARCHAR(64, charset='ascii')) + + // BillingType string `width:"64" charset:"ascii" default:"postpaid" list:"user" create:"user"` // billing_type = Column(VARCHAR(64, charset='ascii'), nullable=True) + OpsTime time.Time `nullable:"false" list:"user"` // = Column(DateTime, nullable=False) + OwnerProjectId string `name:"owner_tenant_id" width:"128" charset:"ascii" list:"user" create:"optional"` // = Column(VARCHAR(ID_LENGTH, charset='ascii')) // owner_user_id = Column(VARCHAR(ID_LENGTH, charset='ascii')) } @@ -221,6 +224,9 @@ func (opslog *SOpsLog) GetModelManager() IModelManager { */ func (manager *SOpsLogManager) LogEvent(model IModel, action string, notes interface{}, userCred mcclient.TokenCredential) { + if !consts.OpsLogEnabled() { + return + } if len(model.GetId()) == 0 || len(model.GetName()) == 0 { return } @@ -238,10 +244,11 @@ func (manager *SOpsLogManager) LogEvent(model IModel, action string, notes inter opslog.Domain = userCred.GetDomainName() opslog.Roles = strings.Join(userCred.GetRoles(), ",") opslog.OpsTime = time.Now().UTC() - virtualModel, ok := model.(IVirtualModel) - if ok && virtualModel != nil { + + if virtualModel, ok := model.(IVirtualModel); ok && virtualModel != nil { opslog.OwnerProjectId = virtualModel.GetOwnerProjectId() } + err := manager.TableSpec().Insert(&opslog) if err != nil { log.Errorf("fail to insert opslog: %s", err) @@ -334,9 +341,8 @@ func (manager *SOpsLogManager) ListItemFilter(ctx context.Context, q *sqlchemy.S func (manager *SOpsLogManager) SyncOwner(m IModel, former *STenant, userCred mcclient.TokenCredential) { notes := jsonutils.NewDict() notes.Add(jsonutils.NewString(former.GetId()), "former_project_id") - notes.Add(jsonutils.NewString(former.GetName()), "form_project") + notes.Add(jsonutils.NewString(former.GetName()), "former_project") manager.LogEvent(m, ACT_CHANGE_OWNER, notes, userCred) - logclient.AddActionLog(m, logclient.ACT_CHANGE_OWNER, nil, userCred, true) } func (manager *SOpsLogManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool { @@ -360,7 +366,7 @@ func (self *SOpsLog) AllowDeleteItem(ctx context.Context, userCred mcclient.Toke } func (self *SOpsLog) ValidateDeleteCondition(ctx context.Context) error { - return fmt.Errorf("forbidden") + return httperrors.NewForbiddenError("not allow to delete log") } func (self *SOpsLogManager) FilterById(q *sqlchemy.SQuery, idStr string) *sqlchemy.SQuery { diff --git a/pkg/cloudcommon/db/virtualresource.go b/pkg/cloudcommon/db/virtualresource.go index c058152781..0ec403e7fc 100644 --- a/pkg/cloudcommon/db/virtualresource.go +++ b/pkg/cloudcommon/db/virtualresource.go @@ -14,6 +14,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/util/logclient" ) type SVirtualResourceBaseManager struct { @@ -232,6 +233,7 @@ func (model *SVirtualResourceBase) PerformChangeOwner(ctx context.Context, userC return nil, err } OpsLog.SyncOwner(model, former, userCred) + logclient.AddActionLog(model, logclient.ACT_CHANGE_OWNER, nil, userCred, true) return nil, nil } diff --git a/pkg/logger/models/actionlog.go b/pkg/logger/models/actionlog.go index 82e23570ce..993c52b17a 100644 --- a/pkg/logger/models/actionlog.go +++ b/pkg/logger/models/actionlog.go @@ -1,8 +1,13 @@ package models import ( - "yunion.io/x/onecloud/pkg/cloudcommon/db" + "context" "time" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/mcclient" ) type SActionlogManager struct { @@ -12,9 +17,9 @@ type SActionlogManager struct { type SActionlog struct { db.SOpsLog - StartTime time.Time `nullable:"false" list:"user"` // = Column(DateTime, nullable=False) - Success bool `default:"true" list:"user"` // = Column(Boolean, default=True) - Action string `width:"32" charset:"utf8" nullable:"false" list:"user"` //= Column(VARCHAR(32, charset='utf8'), nullable=False) + // StartTime time.Time `nullable:"false" list:"user"` // = Column(DateTime, nullable=False) + Success bool `default:"true" list:"user" create:"required"` // = Column(Boolean, default=True) + // Action string `width:"32" charset:"utf8" nullable:"false" list:"user"` //= Column(VARCHAR(32, charset='utf8'), nullable=False) } var ActonLog *SActionlogManager @@ -22,3 +27,8 @@ var ActonLog *SActionlogManager func init() { ActonLog = &SActionlogManager{db.SOpsLogManager{db.NewModelBaseManager(SActionlog{}, "action_tbl", "action", "actions")}} } + +func (action *SActionlog) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + action.OpsTime = time.Now().UTC() + return nil +} diff --git a/pkg/logger/service/handlers.go b/pkg/logger/service/handlers.go index 68a1d46dcc..854864f19f 100644 --- a/pkg/logger/service/handlers.go +++ b/pkg/logger/service/handlers.go @@ -1,9 +1,9 @@ package service import ( - "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/appsrv" "yunion.io/x/onecloud/pkg/appsrv/dispatcher" + "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/logger/models" ) diff --git a/pkg/logger/service/service.go b/pkg/logger/service/service.go index a6b6fdcbf7..ec2ddccdae 100644 --- a/pkg/logger/service/service.go +++ b/pkg/logger/service/service.go @@ -7,9 +7,10 @@ import ( "yunion.io/x/log" - "yunion.io/x/onecloud/pkg/logger/options" "yunion.io/x/onecloud/pkg/cloudcommon" + "yunion.io/x/onecloud/pkg/cloudcommon/consts" "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/logger/options" ) const ( @@ -17,6 +18,9 @@ const ( ) func StartService() { + + consts.DisableOpsLog() + opts := &options.Options commonOpts := &opts.CommonOptions dbOpts := &opts.DBOptions @@ -37,4 +41,4 @@ func StartService() { } cloudcommon.ServeForever(app, commonOpts) -} \ No newline at end of file +} diff --git a/pkg/util/logclient/logclient.go b/pkg/util/logclient/logclient.go index c130b8b8e1..6cf19144ba 100644 --- a/pkg/util/logclient/logclient.go +++ b/pkg/util/logclient/logclient.go @@ -2,12 +2,14 @@ package logclient import ( "context" + "strings" "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/util/stringutils" "yunion.io/x/onecloud/pkg/appsrv" + "yunion.io/x/onecloud/pkg/cloudcommon/consts" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/auth" "yunion.io/x/onecloud/pkg/mcclient/modules" @@ -85,6 +87,11 @@ type IObject interface { Keyword() string } +type IVirtualObject interface { + IObject + GetOwnerProjectId() string +} + type IModule interface { Create(session *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) } @@ -100,6 +107,9 @@ func PostWebsocketNotify(model IObject, action string, iNotes interface{}, userC } func addLog(model IObject, action string, iNotes interface{}, userCred mcclient.TokenCredential, success bool, api IModule) { + if !consts.OpsLogEnabled() { + return + } token := userCred notes := stringutils.Interface2String(iNotes) @@ -122,6 +132,7 @@ func addLog(model IObject, action string, iNotes interface{}, userCred mcclient. } logentry := jsonutils.NewDict() + logentry.Add(jsonutils.NewString(objName), "obj_name") logentry.Add(jsonutils.NewString(model.Keyword()), "obj_type") logentry.Add(jsonutils.NewString(objId), "obj_id") @@ -130,6 +141,16 @@ func addLog(model IObject, action string, iNotes interface{}, userCred mcclient. logentry.Add(jsonutils.NewString(token.GetUserName()), "user") logentry.Add(jsonutils.NewString(token.GetTenantId()), "tenant_id") logentry.Add(jsonutils.NewString(token.GetTenantName()), "tenant") + logentry.Add(jsonutils.NewString(token.GetDomainId()), "domain_id") + logentry.Add(jsonutils.NewString(token.GetDomainName()), "domain") + logentry.Add(jsonutils.NewString(strings.Join(token.GetRoles(), ",")), "roles") + + if virtualModel, ok := model.(IVirtualObject); ok { + ownerProjId := virtualModel.GetOwnerProjectId() + if len(ownerProjId) > 0 { + logentry.Add(jsonutils.NewString(ownerProjId), "owner_tenant_id") + } + } if !success { // 失败日志