Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Elaad committed Sep 27, 2019
1 parent d30aef2 commit 06386b1
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 84 deletions.
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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) =>
Expand Down
Expand Up @@ -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
Expand All @@ -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 = <div class="error">Error when trying to get last event logs. Error message was: {fail.messageChain}</div>
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 = <div class="error">Error when trying to get last event logs. Error message was: {fail.messageChain}</div>
// 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
Expand Down
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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)
Expand Down
Expand Up @@ -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
Expand All @@ -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._

/**
Expand Down Expand Up @@ -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)
Expand Down
Expand Up @@ -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'))
Expand All @@ -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 ="<p><i class='fa fa-exclamation-triangle warnicon' aria-hidden='true'></i><b>Are you sure you want to restore configuration policy" + action + "this</b></p><span><button class='btn btn-default' onClick=cancelRollback(" + id + ")>Cancel</button></span><span><button class='btn btn-default' onClick=confirmRollback(" + id + ")>Confirm</button></span>";
$(confirmDiv).html(confirmHtml);
}

function computeCompliancePercent (complianceArray) {
return computeComplianceOK(complianceArray).percent;
}
Expand Down
Expand Up @@ -44,5 +44,32 @@
</div>
</div>
</div>

<script id="rollbackBlock" type="text/html">
<div class='rollbackDisplay'>
<fieldset class='rollbackFieldSet'>
<legend>Rollback</legend>
<div id='rollbackID'>
<span class='alignRollback'>Restore configuration policy to</span>
<ul style='display: inline-block;padding-left:5px; text-align:left;'>
<input class='radio' type='radio' id='after' name='action' value='after' checked/>
<label for='after'>After</label>
<input class='radio' type='radio' id='before' name='action' value='before'/>
<label for='before'>Before</label>
</ul>
<span class='alignRollback'>this change</span>
<span>
<button id='restoreBtn'>Restore</button>
</span>
</div>
<span id='confirmID'></span>
</fieldset>
</div>
</script>

</lift:surround>





0 comments on commit 06386b1

Please sign in to comment.