diff --git a/pkg/cloudcommon/db/db_dispatcher.go b/pkg/cloudcommon/db/db_dispatcher.go index 8b4179f50d..89d6cd54dd 100644 --- a/pkg/cloudcommon/db/db_dispatcher.go +++ b/pkg/cloudcommon/db/db_dispatcher.go @@ -21,6 +21,7 @@ import ( "yunion.io/x/onecloud/pkg/mcclient/auth" "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/util/httputils" + "yunion.io/x/onecloud/pkg/util/logclient" ) type DBModelDispatcher struct { @@ -740,6 +741,7 @@ func (dispatcher *DBModelDispatcher) Create(ctx context.Context, query jsonutils return nil, httperrors.NewGeneralError(err) } OpsLog.LogEvent(model, ACT_CREATE, model.GetShortDesc(), userCred) + logclient.AddActionLog(ctx, userCred, logclient.ACT_CREATE, "", model, "") dispatcher.modelManager.OnCreateComplete(ctx, []IModel{model}, userCred, query, data) return getItemDetails(dispatcher.modelManager, model, ctx, userCred, query) } @@ -958,11 +960,13 @@ func updateItem(manager IModelManager, item IModel, ctx context.Context, userCre if err != nil { log.Errorf("validate update condition error: %s", err) + logclient.AddActionLog(ctx, userCred, logclient.ACT_UPDATE, "", item, err.Error()) return nil, httperrors.NewGeneralError(err) } dataDict, ok := data.(*jsonutils.JSONDict) if !ok { + logclient.AddActionLog(ctx, userCred, logclient.ACT_UPDATE, "", item, "Invalid data JSONObject") return nil, httperrors.NewInternalServerError("Invalid data JSONObject") } @@ -970,13 +974,16 @@ func updateItem(manager IModelManager, item IModel, ctx context.Context, userCre if len(name) > 0 { err = alterNameValidator(item, name) if err != nil { + logclient.AddActionLog(ctx, userCred, logclient.ACT_UPDATE, "", item, err.Error()) return nil, err } } dataDict, err = item.ValidateUpdateData(ctx, userCred, query, dataDict) if err != nil { - log.Errorf("validate update data error: %s", err) + errMsg := fmt.Sprintf("validate update data error: %s", err) + log.Errorf(errMsg) + logclient.AddActionLog(ctx, userCred, logclient.ACT_UPDATE, "", item, errMsg) return nil, httperrors.NewGeneralError(err) } item.PreUpdate(ctx, userCred, query, dataDict) @@ -985,7 +992,9 @@ func updateItem(manager IModelManager, item IModel, ctx context.Context, userCre filterData := dataDict.CopyIncludes(updateFields(manager, userCred)...) err = filterData.Unmarshal(item) if err != nil { - log.Errorf("unmarshal fail: %s", err) + errMsg := fmt.Sprintf("unmarshal fail: %s", err) + logclient.AddActionLog(ctx, userCred, logclient.ACT_UPDATE, "", item, errMsg) + log.Errorf(errMsg) return httperrors.NewGeneralError(err) } return nil @@ -999,8 +1008,10 @@ func updateItem(manager IModelManager, item IModel, ctx context.Context, userCre diffStr := sqlchemy.UpdateDiffString(diff) if len(diffStr) > 0 { OpsLog.LogEvent(item, ACT_UPDATE, diffStr, userCred) + logclient.AddActionLog(ctx, userCred, logclient.ACT_UPDATE, "", item, diffStr) } } + logclient.AddActionLog(ctx, userCred, logclient.ACT_UPDATE, dataDict.String(), item, "") return getItemDetails(manager, item, ctx, userCred, query) } @@ -1027,10 +1038,13 @@ func DeleteModel(ctx context.Context, userCred mcclient.TokenCredential, item IM return item.MarkDelete() }) if err != nil { - log.Errorf("save update error %s", err) + msg := fmt.Sprintf("save update error %s", err) + log.Errorf(msg) + logclient.AddActionLog(ctx, userCred, logclient.ACT_DELETE, "", item, msg) return httperrors.NewGeneralError(err) } OpsLog.LogEvent(item, ACT_DELETE, item.GetShortDesc(), userCred) + logclient.AddActionLog(ctx, userCred, logclient.ACT_DELETE, "", item, "") return nil } diff --git a/pkg/compute/tasks/guest_rebuild_root_task.go b/pkg/compute/tasks/guest_rebuild_root_task.go index 03345b85ac..165b8ff213 100644 --- a/pkg/compute/tasks/guest_rebuild_root_task.go +++ b/pkg/compute/tasks/guest_rebuild_root_task.go @@ -11,6 +11,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudcommon/notifyclient" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/util/logclient" ) func init() { @@ -48,6 +49,7 @@ func (self *GuestRebuildRootTask) StartRebuildRootDisk(ctx context.Context, gues }) if err != nil { self.SetStageFailed(ctx, err.Error()) + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_REBUILD, "", guest, err.Error()) return } else { db.OpsLog.LogEvent(gds.Root, db.ACT_UPDATE_STATUS, @@ -64,16 +66,19 @@ func (self *GuestRebuildRootTask) OnRebuildRootDiskComplete(ctx context.Context, imginfo, err := models.CachedimageManager.GetImageById(ctx, self.UserCred, imgId, false) if err != nil { self.SetStageFailed(ctx, err.Error()) + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_REBUILD, "", guest, err.Error()) return } osprof, err := osprofile.GetOSProfileFromImageProperties(imginfo.Properties, guest.Hypervisor) if err != nil { self.SetStageFailed(ctx, err.Error()) + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_REBUILD, "", guest, err.Error()) return } err = guest.SetMetadata(ctx, "__os_profile__", osprof, self.UserCred) if err != nil { self.SetStageFailed(ctx, err.Error()) + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_REBUILD, "", guest, err.Error()) return } if guest.OsType != osprof.OSType { @@ -83,11 +88,11 @@ func (self *GuestRebuildRootTask) OnRebuildRootDiskComplete(ctx context.Context, }) if err != nil { self.SetStageFailed(ctx, err.Error()) + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_REBUILD, "", guest, err.Error()) return } } db.OpsLog.LogEvent(guest, db.ACT_REBUILD_ROOT, "", self.UserCred) - // TODO: logclient guest.NotifyServerEvent(notifyclient.SERVER_REBUILD_ROOT, notifyclient.PRIORITY_IMPORTANT, true) self.SetStage("OnSyncStatusComplete", nil) guest.StartSyncstatus(ctx, self.UserCred, self.GetTaskId()) @@ -96,7 +101,7 @@ func (self *GuestRebuildRootTask) OnRebuildRootDiskComplete(ctx context.Context, func (self *GuestRebuildRootTask) OnRebuildRootDiskCompleteFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { db.OpsLog.LogEvent(guest, db.ACT_REBUILD_ROOT_FAIL, data.String(), self.UserCred) guest.SetStatus(self.UserCred, models.VM_REBUILD_ROOT_FAIL, "") - // TODO: logclient + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_REBUILD, "", guest, data.String()) } func (self *GuestRebuildRootTask) OnSyncStatusComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { @@ -106,6 +111,7 @@ func (self *GuestRebuildRootTask) OnSyncStatusComplete(ctx context.Context, gues } else { self.SetStageComplete(ctx, nil) } + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_REBUILD, "", guest, "") } func (self *GuestRebuildRootTask) OnGuestStartComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { @@ -137,6 +143,7 @@ func (self *KVMGuestRebuildRootTask) OnRebuildRootDiskComplete(ctx context.Conte func (self *KVMGuestRebuildRootTask) OnRebuildRootDiskCompleteFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { self.SetStageFailed(ctx, data.String()) + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_REBUILD, "", guest, data.String()) } func (self *KVMGuestRebuildRootTask) OnGuestDeployComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { diff --git a/pkg/compute/tasks/guest_start_task.go b/pkg/compute/tasks/guest_start_task.go index 7bbb2ca2dc..3965a51d05 100644 --- a/pkg/compute/tasks/guest_start_task.go +++ b/pkg/compute/tasks/guest_start_task.go @@ -4,10 +4,10 @@ import ( "context" "yunion.io/x/jsonutils" - "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/util/logclient" ) type GuestStartTask struct { @@ -59,6 +59,7 @@ func (self *GuestStartTask) OnStartComplete(ctx context.Context, obj db.IStandal db.OpsLog.LogEvent(guest, db.ACT_START, guest.GetShortDesc(), self.UserCred) self.SetStage("on_guest_syncstatus_after_start", nil) guest.StartSyncstatus(ctx, self.UserCred, self.GetTaskId()) + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_START, "", guest, "") // self.taskComplete(ctx, guest) } @@ -75,6 +76,7 @@ func (self *GuestStartTask) OnStartCompleteFailed(ctx context.Context, obj db.IS func (self *GuestStartTask) onStartGuestFailed(ctx context.Context, guest *models.SGuest, err error) { self.SetStageFailed(ctx, err.Error()) self.OnStartCompleteFailed(ctx, guest, jsonutils.NewString(err.Error())) + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_START, "", guest, err.Error()) } func (self *GuestStartTask) taskComplete(ctx context.Context, guest *models.SGuest) { diff --git a/pkg/compute/tasks/guest_stop_task.go b/pkg/compute/tasks/guest_stop_task.go index 2ed0f4aa6c..aa0119d549 100644 --- a/pkg/compute/tasks/guest_stop_task.go +++ b/pkg/compute/tasks/guest_stop_task.go @@ -6,10 +6,10 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" - "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/util/logclient" ) type GuestStopTask struct { @@ -58,10 +58,12 @@ func (self *GuestStopTask) OnGuestStopTaskComplete(ctx context.Context, obj db.I if guest.Status == models.VM_READY && guest.DisableDelete.IsFalse() && guest.ShutdownBehavior == models.SHUTDOWN_TERMINATE { guest.StartAutoDeleteGuestTask(ctx, self.UserCred, "") } + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_STOP, "", guest, "") } func (self *GuestStopTask) OnStopGuestFail(ctx context.Context, guest *models.SGuest, err error) { guest.SetStatus(self.UserCred, models.VM_STOP_FAILED, err.Error()) db.OpsLog.LogEvent(guest, db.ACT_STOP_FAIL, err.Error(), self.UserCred) self.SetStageFailed(ctx, err.Error()) + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_STOP, "", guest, err.Error()) } diff --git a/pkg/compute/tasks/guest_syncstatus_task.go b/pkg/compute/tasks/guest_syncstatus_task.go index 478f4afe6d..7b161e9f27 100644 --- a/pkg/compute/tasks/guest_syncstatus_task.go +++ b/pkg/compute/tasks/guest_syncstatus_task.go @@ -2,6 +2,7 @@ package tasks import ( "context" + "fmt" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -9,6 +10,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/util/logclient" ) type GuestSyncstatusTask struct { @@ -53,9 +55,14 @@ func (self *GuestSyncstatusTask) OnGetStatusSucc(ctx context.Context, guest *mod statusData.Add(jsonutils.NewString(statusStr), "status") guest.PerformStatus(ctx, self.UserCred, nil, statusData) self.SetStageComplete(ctx, nil) + fmt.Println(" \n*\n*\n*\n*\n*\n*\n*\n*\n*\n*\n*\\n*n* * * * * * * * * * * * * ") + fmt.Println("* * * * * * * * * * * * * server obj:", guest) + fmt.Println(" \n*\n*\n*\n*\n*\n*\n*\n*\n*\n*\n*\\n*n* * * * * * * * * * * * * ") + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_SYNC_STATUS, "", guest, "") } func (self *GuestSyncstatusTask) OnGetStatusFail(ctx context.Context, guest *models.SGuest, err error) { guest.SetStatus(self.UserCred, models.VM_UNKNOWN, err.Error()) self.SetStageComplete(ctx, nil) + logclient.AddActionLog(ctx, self.UserCred, logclient.ACT_VM_SYNC_STATUS, "", guest, err.Error()) } diff --git a/pkg/util/logclient/logclient.go b/pkg/util/logclient/logclient.go index 3f5ea151c2..b7b52ec23f 100644 --- a/pkg/util/logclient/logclient.go +++ b/pkg/util/logclient/logclient.go @@ -1,64 +1,100 @@ package logclient import ( - "fmt" - "net/http" "context" - "yunion.io/x/onecloud/pkg/mcclient/modules" + "fmt" + "log" + "net/http" + "yunion.io/x/jsonutils" - "yunion.io/x/onecloud/pkg/mcclient/auth" + "yunion.io/x/onecloud/pkg/compute/options" "yunion.io/x/onecloud/pkg/mcclient" - "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/mcclient/auth" + "yunion.io/x/onecloud/pkg/util/httputils" ) -func fetchRegion(req *http.Request) string { - r, e := req.Cookie("region") - if e != nil { - return "" +const ( + ACT_VM_RESET_PSWD = "重置密码" + ACT_VM_REBUILD = "重装系统" + ACT_VM_START = "开机" + ACT_VM_STOP = "关机" + ACT_VM_PURGE = "清除" + ACT_VM_CHANGE_FLAVOR = "调整配置" + ACT_VM_SYNC_CONF = "同步配置" + ACT_GUEST_ATTACH_ISOLATED_DEVICE = "挂载透传设备" + ACT_GUEST_DETACH_ISOLATED_DEVICE = "卸载透传设备" + ACT_VM_SYNC_STATUS = "同步状态" + ACT_CREATE = "创建" + ACT_DELETE = "删除" + ACT_UPDATE = "更新" + ACT_RESERVE_IP = "预留IP" + ACT_RELEASE_IP = "释放IP" + ACT_CANCEL_DELETE = "恢复" + ACT_UNCACHED_IMAGE = "清除缓存" + ACT_ENABLE = "启用" + ACT_DISABLE = "禁用" + ACT_ONLINE = "上线" + ACT_OFFLINE = "下线" + ACT_PUBLIC = "设为共享" + ACT_PRIVATE = "设为私有" + ACT_MERGE = "合并" + ACT_SPLIT = "分割" + ACT_ALLOCATE = "分配" + ACT_BM_MAINTENANCE = "进入离线状态" + ACT_BM_UNMAINTENANCE = "退出离线状态" + ACT_BM_CONVERT_HYPER = "转换为宿主机" + ACT_BM_UNCONVERT_HYPER = "转换为受管物理机" + ACT_ADDTAG = "添加标签" + ACT_RMTAG = "删除标签" + ACT_RESIZE = "扩容" + ACT_VM_ATTACH_DISK = "挂载磁盘" + ACT_VM_DETACH_DISK = "卸载磁盘" +) + +type IObject interface { + GetId() string + GetName() string + Keyword() string +} + +func AddActionLog(ctx context.Context, userCred mcclient.TokenCredential, action, notes string, obj IObject, e string) { + + token := userCred + logentry := jsonutils.NewDict() + logentry.Add(jsonutils.NewString(obj.GetName()), "obj_name") + logentry.Add(jsonutils.NewString(obj.Keyword()), "obj_type") + logentry.Add(jsonutils.NewString(obj.GetId()), "obj_id") + logentry.Add(jsonutils.NewString(action), "action") + logentry.Add(jsonutils.NewString(token.GetUserId()), "user_id") + logentry.Add(jsonutils.NewString(token.GetUserName()), "user") + logentry.Add(jsonutils.NewString(token.GetTenantId()), "tenant_id") + logentry.Add(jsonutils.NewString(token.GetTenantName()), "tenant") + // todo: 正式版去掉下面这行。 + notes = "[region2]" + notes + + if len(e) > 0 { + // 失败日志 + logentry.Add(jsonutils.JSONFalse, "success") + notes = fmt.Sprintf("%s%s", notes, e) + logentry.Add(jsonutils.NewString(notes), "notes") + } else { + // 成功日志 + logentry.Add(jsonutils.JSONTrue, "success") + logentry.Add(jsonutils.NewString(notes), "notes") } - return r.Value -} -func AddActionLog(ctx context.Context, userCred mcclient.TokenCredential, action, notes string, e error) { - // 记录企业信息变更操作日志 - -// token := auth.FetchUserCredential(ctx) - log.Errorf("\n.\n.\n.\n.\n.") - log.Errorf("[AddActionLog]ctx: %s", ctx) -// log.Errorf("[AddActionLog] token: %s", token) - log.Errorf("[AddActionLog] token.userid: %s", userCred.GetUserId()) - log.Errorf("\n.\n.\n.\n.\n.") - // userid := userCred.GetUserId() - // username := userCred.GetUserName() - // tenantid := userCred.GetTenantId() - token := userCred - // s := auth.GetAdminSession(fetchRegion(req), "") - s := auth.GetSession(userCred, "", "") - log.Errorf("session id: Fzu3qiEYUS9P %s", s) - - log := jsonutils.NewDict() - log.Add(jsonutils.NewString("infos"), "obj_type") - log.Add(jsonutils.NewString("-"), "obj_id") - log.Add(jsonutils.NewString("-"), "obj_name") - log.Add(jsonutils.NewString("更新"), "action") - log.Add(jsonutils.NewString(token.GetUserId()), "user_id") - log.Add(jsonutils.NewString(token.GetUserName()), "user") - log.Add(jsonutils.NewString(token.GetTenantId()), "tenant_id") - log.Add(jsonutils.NewString(token.GetTenantName()), "tenant") - log.Add(jsonutils.NewString(notes), "notes") - - if e != nil { - // 失败日志 - log.Add(jsonutils.JSONFalse, "success") - } else { - // 成功日志 - log.Add(jsonutils.JSONTrue, "success") - } - - _, e = modules.Actions.Create(s, log) - if e != nil { - fmt.Printf("create action log failed %s", e) - } else { - fmt.Println("create action log sucess") - } + uri, err := auth.GetServiceURL("log", options.Options.Region, "", "") + if err != nil { + log.Println("log service not ready", err) + return + } + + uri = fmt.Sprintf("%s/actions", uri) + header := http.Header{} + header.Add("X-Auth-Token", userCred.GetTokenString()) + _, _, err = httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", uri, header, logentry, false) + if err != nil { + log.Println("post log error", err) + return + } }