From 06386b19289230e01dce69a24e6e40185a201a5d Mon Sep 17 00:00:00 2001 From: Elaad Date: Thu, 26 Sep 2019 15:21:38 +0200 Subject: [PATCH] Work in progress --- .../rudder/rest/internal/EventLogAPI.scala | 9 +- ...e.scala => EventLogDetailsDisplayer.scala} | 147 +++++++++--------- .../bootstrap/liftweb/RudderConfig.scala | 14 +- .../web/services/EventListDisplayer.scala | 9 +- .../javascript/rudder/rudder-datatable.js | 55 ++++++- .../webapp/secure/utilities/eventLogs.html | 27 ++++ 6 files changed, 177 insertions(+), 84 deletions(-) rename webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/{EventLogDetailsService.scala => EventLogDetailsDisplayer.scala} (94%) diff --git a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/internal/EventLogAPI.scala b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/internal/EventLogAPI.scala index 3a8695792a8..b4ff0a99ae1 100644 --- a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/internal/EventLogAPI.scala +++ b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/internal/EventLogAPI.scala @@ -52,7 +52,7 @@ import net.liftweb.json.JsonDSL._ class EventLogAPI ( repos: EventLogRepository , restExtractor : RestExtractorService - , eventLogDetail : EventListDisplayer + , eventLogDetail : EventLogDetailsDisplayer ) extends RestHelper with Loggable { def serialize(event: EventLog): JValue = { @@ -97,15 +97,15 @@ class EventLogAPI ( val draw = req.params.get("draw") match { case Some(value :: Nil) => Full(value.toInt) - case None => Failure("Missing 'draw' field from datatable's request") + case _ => Failure("Missing 'draw' field from datatable's request") } val start = req.params.get("start") match { case Some(value :: Nil) => Full(value) - case None => Failure("Missing 'start' field from datatable's request") + case _ => Failure("Missing 'start' field from datatable's request") } val length = req.params.get("length") match { case Some(value :: Nil) => Full(value) - case None => Failure("Missing 'length' field from datatable's request") + case _ => Failure("Missing 'length' field from datatable's request") } val response = (draw, start, length) match { @@ -138,6 +138,7 @@ class EventLogAPI ( } JsonResponse(response, Nil, Nil, 200) + // add a changerequest field to send the url if necessary case Get(id :: "details" :: Nil, _) => repos.getEventLogByCriteria(Some(s"id = $id")).toBox match { case Full(e) => diff --git a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/EventLogDetailsService.scala b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/EventLogDetailsDisplayer.scala similarity index 94% rename from webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/EventLogDetailsService.scala rename to webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/EventLogDetailsDisplayer.scala index c50e64d8e6b..4360d770d09 100644 --- a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/EventLogDetailsService.scala +++ b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/EventLogDetailsDisplayer.scala @@ -75,7 +75,7 @@ import scala.xml._ * Used to display the event list, in the pending modification (AsyncDeployment), * or in the administration EventLogsViewer */ -class EventListDisplayer( +class EventLogDetailsDisplayer( logDetailsService : EventLogDetailsService , repos : EventLogRepository , nodeGroupRepository : RoNodeGroupRepository @@ -91,81 +91,76 @@ class EventListDisplayer( private[this] val gridName = "eventLogsGrid" - def display(refreshEvents:() => Box[Seq[EventLog]]) : NodeSeq = { - val limit: Int = 500 - //common part between last events and interval - def displayEvents(events: Box[Seq[EventLog]]) :JsCmd = { - events match { - case Full(events) => - val lines = { - val el = events.map(EventLogLine(_)).toList.sortWith(_.event.creationDate.getMillis > _.event.creationDate.getMillis) - if(el.size > limit) JsTableData(el.take(limit)) else JsTableData(el) - } - JsRaw(s"refreshTable('${gridName}',${lines.json.toJsCmd})") - case eb : EmptyBox => - val fail = eb ?~! "Could not get latest event logs" - logger.error(fail.messageChain) - val xml =
Error when trying to get last event logs. Error message was: {fail.messageChain}
- SetHtml("eventLogsError",xml) - } - } - - def getLastEvents : JsCmd = { - displayEvents(refreshEvents()) - } - - def getEventsInterval(jsonInterval: String): JsCmd = { - import java.sql.Timestamp - val format = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss") - - displayEvents(for { - parsed <- tryo(parse(jsonInterval)) ?~! s"Error when trying to parse '${jsonInterval}' as a JSON datastructure with fields 'start' and 'end'" - startStr <- parsed \ "start" match { - case JString(startStr) if startStr.nonEmpty => - val date = tryo(DateTime.parse(startStr, format)) ?~! s"Error when trying to parse start date '${startStr}" - date match { - case Full(d) => Full(Some(new Timestamp(d.getMillis))) - case eb: EmptyBox => - eb ?~! s"Invalid start date" - } - case _ => Full(None) - } - endStr <- parsed \ "end" match { - case JString(endStr) if endStr.nonEmpty => - val date = tryo(DateTime.parse(endStr, format)) ?~! s"Error when trying to parse end date '${endStr}" - date match { - case Full(d) => Full(Some(new Timestamp(d.getMillis))) - case eb: EmptyBox => - eb ?~! s"Invalid end date" - } - case _ => Full(None) - } - whereStatement = (startStr, endStr) match { - case (None, None) => None - case (Some(start), None) => Some(s" creationdate > '$start'") - case (None, Some(end)) => Some(s" creationdate < '$end'") - case (Some(start), Some(end)) => - val orderedDate = if(start.after(end)) (end, start) else (start, end) - Some(s" creationdate > '${orderedDate._1}' and creationdate < '${orderedDate._2}'") - } - logs <- repos.getEventLogByCriteria(whereStatement, None, Some("id DESC")).toBox - } yield { - logs - }) - } - - val refresh = AnonFunc(SHtml.ajaxInvoke( () => getLastEvents)) - - Script(OnLoad(JsRaw(s""" - var pickEventLogsInInterval = ${AnonFunc(SHtml.ajaxCall(JsRaw( - """'{"start":"'+$(".pickStartInput").val()+'", "end":"'+$(".pickEndInput").val()+'"}'""" - ), getEventsInterval)._2).toJsCmd} - var refreshEventLogs = ${refresh.toJsCmd}; - createEventLogTable('${gridName}',[], '${S.contextPath}', refreshEventLogs, pickEventLogsInInterval) - refreshEventLogs(); - """))) - - } +// def display(refreshEvents:() => Box[Seq[EventLog]]) : NodeSeq = { +// //common part between last events and interval +// def displayEvents(events: Box[Seq[EventLog]]) :JsCmd = { +// events match { +// case Full(events) => +// val lines = events.map(EventLogLine(_)).toList.sortWith(_.event.creationDate.getMillis > _.event.creationDate.getMillis) +// case eb : EmptyBox => +// val fail = eb ?~! "Could not get latest event logs" +// logger.error(fail.messageChain) +// val xml =
Error when trying to get last event logs. Error message was: {fail.messageChain}
+// SetHtml("eventLogsError",xml) +// } +// } +// +// def getLastEvents : JsCmd = { +// displayEvents(refreshEvents()) +// } +// +// def getEventsInterval(jsonInterval: String): JsCmd = { +// import java.sql.Timestamp +// val format = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss") +// +// displayEvents(for { +// parsed <- tryo(parse(jsonInterval)) ?~! s"Error when trying to parse '${jsonInterval}' as a JSON datastructure with fields 'start' and 'end'" +// startStr <- parsed \ "start" match { +// case JString(startStr) if startStr.nonEmpty => +// val date = tryo(DateTime.parse(startStr, format)) ?~! s"Error when trying to parse start date '${startStr}" +// date match { +// case Full(d) => Full(Some(new Timestamp(d.getMillis))) +// case eb: EmptyBox => +// eb ?~! s"Invalid start date" +// } +// case _ => Full(None) +// } +// endStr <- parsed \ "end" match { +// case JString(endStr) if endStr.nonEmpty => +// val date = tryo(DateTime.parse(endStr, format)) ?~! s"Error when trying to parse end date '${endStr}" +// date match { +// case Full(d) => Full(Some(new Timestamp(d.getMillis))) +// case eb: EmptyBox => +// eb ?~! s"Invalid end date" +// } +// case _ => Full(None) +// } +// whereStatement = (startStr, endStr) match { +// case (None, None) => None +// case (Some(start), None) => Some(s" creationdate > '$start'") +// case (None, Some(end)) => Some(s" creationdate < '$end'") +// case (Some(start), Some(end)) => +// val orderedDate = if(start.after(end)) (end, start) else (start, end) +// Some(s" creationdate > '${orderedDate._1}' and creationdate < '${orderedDate._2}'") +// } +// logs <- repos.getEventLogByCriteria(whereStatement, None, Some("id DESC")).toBox +// } yield { +// logs +// }) +// } +// +// val refresh = AnonFunc(SHtml.ajaxInvoke( () => getLastEvents)) +// +// Script(OnLoad(JsRaw(s""" +// var pickEventLogsInInterval = ${AnonFunc(SHtml.ajaxCall(JsRaw( +// """'{"start":"'+$(".pickStartInput").val()+'", "end":"'+$(".pickEndInput").val()+'"}'""" +// ), getEventsInterval)._2).toJsCmd} +// var refreshEventLogs = ${refresh.toJsCmd}; +// createEventLogTable('${gridName}',[], '${S.contextPath}', refreshEventLogs, pickEventLogsInInterval) +// refreshEventLogs(); +// """))) + +// } /* * Javascript object containing all data to create a line in event logs table diff --git a/webapp/sources/rudder/rudder-web/src/main/scala/bootstrap/liftweb/RudderConfig.scala b/webapp/sources/rudder/rudder-web/src/main/scala/bootstrap/liftweb/RudderConfig.scala index 376bad8fbba..d3fb293e132 100644 --- a/webapp/sources/rudder/rudder-web/src/main/scala/bootstrap/liftweb/RudderConfig.scala +++ b/webapp/sources/rudder/rudder-web/src/main/scala/bootstrap/liftweb/RudderConfig.scala @@ -1002,7 +1002,7 @@ object RudderConfig extends Loggable { // Internal APIs val sharedFileApi = new SharedFilesAPI(restExtractorService,RUDDER_DIR_SHARED_FILES_FOLDER) - val eventLogApi= new EventLogAPI(eventLogRepository, restExtractorService, eventListDisplayerImpl) + val eventLogApi= new EventLogAPI(eventLogRepository, restExtractorService, eventLogDetailsDisplayerImpl) lazy val asyncWorkflowInfo = new AsyncWorkflowInfo lazy val configService: ReadConfigService with UpdateConfigService = { @@ -1351,6 +1351,18 @@ object RudderConfig extends Loggable { , personIdentServiceImpl , linkUtil ) + + private[this] lazy val eventLogDetailsDisplayerImpl = new EventLogDetailsDisplayer( + eventLogDetailsServiceImpl + , logRepository + , roLdapNodeGroupRepository + , roLdapDirectiveRepository + , nodeInfoServiceImpl + , roLDAPRuleCategoryRepository + , modificationService + , personIdentServiceImpl + , linkUtil + ) private[this] lazy val fileManagerImpl = new FileManager(UPLOAD_ROOT_DIRECTORY) private[this] lazy val databaseManagerImpl = new DatabaseManagerImpl(reportsRepositoryImpl, updateExpectedRepo) private[this] lazy val softwareInventoryDAO: ReadOnlySoftwareDAO = new ReadOnlySoftwareDAOImpl(inventoryDitService, roLdap, inventoryMapper) diff --git a/webapp/sources/rudder/rudder-web/src/main/scala/com/normation/rudder/web/services/EventListDisplayer.scala b/webapp/sources/rudder/rudder-web/src/main/scala/com/normation/rudder/web/services/EventListDisplayer.scala index 30c8338c9fe..ed66bd34e0a 100644 --- a/webapp/sources/rudder/rudder-web/src/main/scala/com/normation/rudder/web/services/EventListDisplayer.scala +++ b/webapp/sources/rudder/rudder-web/src/main/scala/com/normation/rudder/web/services/EventListDisplayer.scala @@ -38,6 +38,11 @@ package com.normation.rudder.web.services import com.normation.box._ import com.normation.eventlog.EventLog +import com.normation.inventory.domain.NodeId +import com.normation.rudder.domain.eventlog.{AcceptNodeEventLog, ActivateRedButton, AddChangeRequest, AddDirective, AddGlobalParameter, AddNodeGroup, AddRule, ApplicationStarted, AutomaticStartDeployement, BadCredentialsEventLog, ClearCacheEventLog, CreateAPIAccountEventLog, DeleteAPIAccountEventLog, DeleteChangeRequest, DeleteDirective, DeleteGlobalParameter, DeleteNodeEventLog, DeleteNodeGroup, DeleteRule, DeleteTechnique, ExportFullArchive, ExportGroupsArchive, ExportParametersArchive, ExportRulesArchive, ExportTechniqueLibraryArchive, FailedDeployment, ImportFullArchive, ImportGroupsArchive, ImportParametersArchive, ImportRulesArchive, ImportTechniqueLibraryArchive, LoginEventLog, LogoutEventLog, ManualStartDeployement, ModifyAPIAccountEventLog, ModifyChangeRequest, ModifyDirective, ModifyGlobalParameter, ModifyGlobalProperty, ModifyNode, ModifyNodeGroup, ModifyRule, ModifyTechnique, RefuseNodeEventLog, ReleaseRedButton, ReloadTechniqueLibrary, Rollback, SuccessfulDeployment, UpdatePolicyServer, WorkflowStepChanged} +import com.normation.rudder.domain.nodes.NodeGroupId +import com.normation.rudder.domain.policies.{DirectiveId, RuleId} +import com.normation.rudder.domain.workflows.{ChangeRequestId, WorkflowStepChange} import com.normation.rudder.repository._ import com.normation.rudder.rule.category.RoRuleCategoryRepository import com.normation.rudder.services.eventlog.EventLogDetailsService @@ -56,6 +61,7 @@ import net.liftweb.util.Helpers._ import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat +import scala.util._ import scala.xml._ /** @@ -84,9 +90,8 @@ class EventListDisplayer( case Full(events) => val lines = { val el = events.map(EventLogLine(_)).toList.sortWith(_.event.creationDate.getMillis > _.event.creationDate.getMillis) - if(el.size > limit) JsTableData(el.take(limit)) else JsTableData(el) + JsTableData(el) } - JsRaw(s"refreshTable('${gridName}',${lines.json.toJsCmd})") case eb : EmptyBox => val fail = eb ?~! "Could not get latest event logs" logger.error(fail.messageChain) diff --git a/webapp/sources/rudder/rudder-web/src/main/webapp/javascript/rudder/rudder-datatable.js b/webapp/sources/rudder/rudder-web/src/main/webapp/javascript/rudder/rudder-datatable.js index 2ef37123ede..046cbb390e8 100644 --- a/webapp/sources/rudder/rudder-web/src/main/webapp/javascript/rudder/rudder-datatable.js +++ b/webapp/sources/rudder/rudder-web/src/main/webapp/javascript/rudder/rudder-datatable.js @@ -1391,11 +1391,17 @@ function createEventLogTable(gridId, data, contextPath, refresh, pickEventLogsIn var detailsTd = $("."+detailsId); detailsTd.attr("id",detailsId); // Set data in the open row with the details function from data -// fnData.details(detailsId); $.getJSON(contextPath + '/secure/api/eventlog/' + fnData.id + "/details", function(data) { var html = $.parseHTML( data["data"]["content"] ); + // add the link of changerequest here + //var CRurl = $.parseHTML( data["data"]["CRurl"] ); + // add CRurl at the beggining of 'html' $("td#"+detailsId).append( html ); }); + + var rollbackBlock = setupRollbackBlock(fnData.id); + $("td#"+detailsId).append(rollbackBlock); + $('#restoreBtn'+fnData.id).click(showConfirmationDialog(fnData.id)); // Set final css var color = 'color1'; if(tableRow.hasClass('color2')) @@ -1416,6 +1422,53 @@ function createEventLogTable(gridId, data, contextPath, refresh, pickEventLogsIn createTable(gridId,data, columns, params, contextPath, refresh, "event_logs", false, pickEventLogsInInterval); } +// why 'rollbackBlock' don't change ?? +function setupRollbackBlock(id) { + var rollbackID = 'rollback' + id; + var confirmID = 'confirm' + id; + var btnID = 'restoreBtn' + id; + var rollbackBlock = $('#rollbackBlock').clone().html(); + // if i log the following line, rollbackID have been replaced + // but the returned rollbackblock have not changed + console.log($(rollbackBlock).find('#rollbackID').attr('id',rollbackID)) + $(rollbackBlock).find('#rollbackID').attr('id',rollbackID); + $(rollbackBlock).find('#confirmID').attr('id',confirmID); + $(rollbackBlock).find('#restoreBtn').attr('id',btnID); + return rollbackBlock; +} + +function getRadioChecked(radios) { + for (var i = 0, length = radios.length; i < length; i++) { + if (radios[i].checked) { + return radios[i].value; + } + } +} + +function confirmRollback(id) { + $('#confirm'+id).stop(true, true).slideDown(1000); + var radios = document.getElementsByName('action'); + var action = getRadioChecked(radios); + $.getJSON(contextPath + '/secure/api/eventlog/' + fnData.id + "/details/rollback?mode=confirm&action="+action, function(data) { + console.log(data["data"]["content"]); + }); +} + +function cancelRollback(id) { + $('#confirm'+id).innerHTML = ""; + $('#rollback'+id).show(); +} + +function showConfirmationDialog(id) { +console.log("showconfirmationdialog") + $('#rollback'+id).hide(); + var confirmDiv = $('confirm'+id); + var radios = $('action'); + var action = getRadioChecked(radios); + var confirmHtml ="

Are you sure you want to restore configuration policy" + action + "this

"; + $(confirmDiv).html(confirmHtml); +} + function computeCompliancePercent (complianceArray) { return computeComplianceOK(complianceArray).percent; } diff --git a/webapp/sources/rudder/rudder-web/src/main/webapp/secure/utilities/eventLogs.html b/webapp/sources/rudder/rudder-web/src/main/webapp/secure/utilities/eventLogs.html index 9e5a9b20486..8cc3a2f38ba 100644 --- a/webapp/sources/rudder/rudder-web/src/main/webapp/secure/utilities/eventLogs.html +++ b/webapp/sources/rudder/rudder-web/src/main/webapp/secure/utilities/eventLogs.html @@ -44,5 +44,32 @@ + + + + + + +