Skip to content

Commit

Permalink
Fixes #18846: Agent run schedule problem
Browse files Browse the repository at this point in the history
  • Loading branch information
fanf committed Feb 3, 2021
1 parent f7ad56b commit 9d3e61b
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,9 @@ object ExpectedReportsSerialisation {
, json \ "splayHour"
, json \ "splaytime"
) match {
case (JInt(i), JInt(sm), JInt(sph), JInt(spt)) =>
case (JInt(i), JInt(minute), JInt(hour), JInt(splay)) =>
try {
Some(AgentRunInterval(overrides, i.toValidInt, sm.toValidInt, spt.toValidInt, spt.toValidInt))
Some(AgentRunInterval(overrides, i.toValidInt, minute.toValidInt, hour.toValidInt, splay.toValidInt))
} catch {
case ex: NumberFormatException => None
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class AgentRunIntervalServiceImpl (
splaytime <- readGlobalSplaytime()
} yield {
AgentRunInterval(
None, interval, startHour, startMinute, splaytime
None, interval, startMinute, startHour, splaytime
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,10 +430,6 @@ trait PromiseGenerationService {
def getAllInventories(): Box[Map[NodeId, NodeInventory]]
def getGlobalComplianceMode(): Box[GlobalComplianceMode]
def getGlobalAgentRun() : Box[AgentRunInterval]
def getAgentRunInterval : () => Box[Int]
def getAgentRunSplaytime : () => Box[Int]
def getAgentRunStartHour : () => Box[Int]
def getAgentRunStartMinute : () => Box[Int]
def getScriptEngineEnabled : () => Box[FeatureSwitch]
def getGlobalPolicyMode : () => Box[GlobalPolicyMode]
def getComputeDynGroups : () => Box[Boolean]
Expand Down Expand Up @@ -666,10 +662,6 @@ class PromiseGenerationServiceImpl (
, override val complianceCache : CachedFindRuleNodeStatusReports
, override val promisesFileWriterService: PolicyWriterService
, override val writeNodeCertificatesPem: WriteNodeCertificatesPem
, override val getAgentRunInterval : () => Box[Int]
, override val getAgentRunSplaytime : () => Box[Int]
, override val getAgentRunStartHour : () => Box[Int]
, override val getAgentRunStartMinute : () => Box[Int]
, override val getScriptEngineEnabled : () => Box[FeatureSwitch]
, override val getGlobalPolicyMode : () => Box[GlobalPolicyMode]
, override val getComputeDynGroups : () => Box[Boolean]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import com.normation.cfclerk.domain.SystemVariableSpec
import com.normation.cfclerk.domain.Variable
import com.normation.cfclerk.services.MissingSystemVariable
import com.normation.cfclerk.services.SystemVariableSpecService
import com.normation.errors.Inconsistency
import com.normation.errors.PureResult
import com.normation.inventory.domain.AgentInfo
import com.normation.inventory.domain.AgentType
import com.normation.inventory.domain.AgentVersion
Expand All @@ -60,7 +62,6 @@ import com.normation.rudder.services.servers.PolicyServerManagementService
import com.normation.rudder.services.servers.RelaySynchronizationMethod
import com.normation.zio._
import net.liftweb.common.Box
import net.liftweb.common.Empty
import net.liftweb.common.EmptyBox
import net.liftweb.common.Failure
import net.liftweb.common.Full
Expand Down Expand Up @@ -197,40 +198,31 @@ class SystemVariableServiceImpl(

val storeAllCentralizedLogsInFile = getProp("STORE_ALL_CENTRALIZED_LOGS_IN_FILE", getStoreAllCentralizedLogsInFile)

for {
schedule <- ComputeSchedule.computeSchedule(globalAgentRun.startHour, globalAgentRun.startMinute, globalAgentRun.interval) ?~! "Could not compute the run schedule"
} yield {
val varAgentRunInterval = systemVariableSpecService.get("AGENT_RUN_INTERVAL").toVariable(Seq(globalAgentRun.interval.toString))
val varAgentRunSplayTime = systemVariableSpecService.get("AGENT_RUN_SPLAYTIME").toVariable(Seq(globalAgentRun.splaytime.toString))
val varAgentRunSchedule = systemVariableSpecService.get("AGENT_RUN_SCHEDULE").toVariable(Seq(schedule))
logger.trace("Global system variables done")
val vars =
varToolsFolder ::
varSharedFilesFolder ::
varCommunityPort ::
varWebdavUser ::
varWebdavPassword ::
syslogPortConfig ::
configurationRepositoryFolder ::
denyBadClocks ::
skipIdentify ::
relaySyncMethod ::
relaySyncPromises ::
relaySyncSharedFiles ::
varAgentRunInterval ::
varAgentRunSchedule ::
varAgentRunSplayTime ::
modifiedFilesTtl ::
cfengineOutputsTtl ::
storeAllCentralizedLogsInFile ::
varSendMetrics ::
syslogProtocolDisabled ::
reportProtocol ::
rudderVerifyCertificates ::
varServerVersion ::
Nil
vars.map(v => (v.spec.name,v)).toMap
}
logger.trace("Global system variables done")
val vars =
varToolsFolder ::
varSharedFilesFolder ::
varCommunityPort ::
varWebdavUser ::
varWebdavPassword ::
syslogPortConfig ::
configurationRepositoryFolder ::
denyBadClocks ::
skipIdentify ::
relaySyncMethod ::
relaySyncPromises ::
relaySyncSharedFiles ::
modifiedFilesTtl ::
cfengineOutputsTtl ::
storeAllCentralizedLogsInFile ::
varSendMetrics ::
syslogProtocolDisabled ::
reportProtocol ::
rudderVerifyCertificates ::
varServerVersion ::
Nil

Full(vars.map(v => (v.spec.name,v)).toMap)
}

// allNodeInfos has to contain ALL the node info (those of every node within Rudder)
Expand Down Expand Up @@ -297,10 +289,10 @@ class SystemVariableServiceImpl(

val varAllowedNetworks = systemVariableSpecService.get("AUTHORIZED_NETWORKS").toVariable(authorizedNetworks)

val agentRunParams =
val agentRunParams = {
if (nodeInfo.isPolicyServer) {
val policyServerSchedule = """ "Min00", "Min05", "Min10", "Min15", "Min20", "Min25", "Min30", "Min35", "Min40", "Min45", "Min50", "Min55" """
Full((AgentRunInterval(Some(false), 5, 0, 0, 0), policyServerSchedule))
Right((AgentRunInterval(Some(false), 5, 0, 0, 0), policyServerSchedule))
} else {
val runInterval = nodeInfo.nodeReportingConfiguration.agentRunInterval match {
case Some(nodeRunInterval) if nodeRunInterval.overrides.getOrElse(false) =>
Expand All @@ -313,11 +305,12 @@ class SystemVariableServiceImpl(
runInterval.startHour
, runInterval.startMinute
, runInterval.interval
) ?~! s"Could not compute the run schedule for node ${nodeInfo.id.value}"
} yield {
( runInterval, schedule )
).chainError(s"Could not compute the run schedule for node ${nodeInfo.id.value}")
} yield {
( runInterval, schedule )
}
}
}

val heartBeatFrequency = {
if (nodeInfo.isPolicyServer) {
Expand All @@ -339,7 +332,7 @@ class SystemVariableServiceImpl(
}
}

val AgentRunVariables = ( agentRunParams.map {
val agentRunVariables = ( agentRunParams.map {
case (runInterval,schedule) =>

// The heartbeat should be strictly shorter than the run execution, otherwise they may be skipped
Expand Down Expand Up @@ -627,16 +620,14 @@ class SystemVariableServiceImpl(

val variables = globalSystemVariables ++ baseVariables ++ policyServerVars

(AgentRunVariables, varNodeReportingProtocol) match {
case (Full(runValues), Full(reporting)) =>
(agentRunVariables, varNodeReportingProtocol) match {
case (Right(runValues), Full(reporting)) =>
Full(variables ++ runValues + reporting)
case (Empty, Full(reporting)) =>
Full(variables + reporting)
case (f1, f2:Failure) =>
// prefer message on reporting mode
f2
case (fail, _) =>
fail
fail.toBox
}
}

Expand Down Expand Up @@ -684,28 +675,28 @@ object ComputeSchedule {
startHour : Int
, startMinute : Int
, executionInterval: Int
): Box[String] = {
): PureResult[String] = {

val minutesFreq = executionInterval % 60
val hoursFreq: Int = executionInterval / 60

(minutesFreq, hoursFreq) match {
case (m, h) if m > 0 && h > 0 => Failure(s"Agent execution interval can only be defined as minutes (less than 60) or complete hours, (${h} hours ${m} minutes is not supported)")
case (m, h) if m > 0 && h > 0 => Left(Inconsistency(s"Agent execution interval can only be defined as minutes (less than 60) or complete hours, (${h} hours ${m} minutes is not supported)"))
case (m, h) if h == 0 =>
// two cases, hour is 0, then only minutes

// let's modulate startMinutes by minutes
val actualStartMinute = startMinute % minutesFreq
val mins = Range(actualStartMinute, 60, minutesFreq) // range doesn't return the end range
//val mins = for ( min <- 0 to 59; if ((min%minutesFreq) == actualStartMinute) ) yield { min }
Full(mins.map("\"Min" + "%02d".format(_) + "\"").mkString(", "))
Right(mins.map("\"Min" + "%02d".format(_) + "\"").mkString(", "))

case _ =>
// hour is not 0, then we don't have minutes
val actualStartHour = startHour % hoursFreq
val hours = Range(actualStartHour, 24, hoursFreq)
val minutesFormat = "Min" + "%02d".format(startMinute)
Full(hours.map("\"Hr" + "%02d".format(_) + "." + minutesFormat + "\"").mkString(", "))
Right(hours.map("\"Hr" + "%02d".format(_) + "." + minutesFormat + "\"").mkString(", "))
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

package com.normation.rudder.services.policies

import com.normation.errors.Inconsistency
import org.junit.runner.RunWith
import net.liftweb.common.Full
import org.specs2.mutable.Specification
Expand All @@ -51,41 +52,41 @@ import org.specs2.runner.JUnitRunner
@RunWith(classOf[JUnitRunner])
class TestComputeSchedule extends Specification {

"A squedule with 5 minutes interval" should {
"A schedule with 5 minutes interval" should {
"be the default one when starting at 0:00" in {
ComputeSchedule.computeSchedule(0,0,5) must beEqualTo (
Full(""""Min00", "Min05", "Min10", "Min15", "Min20", "Min25", "Min30", "Min35", "Min40", "Min45", "Min50", "Min55"""")
Right(""""Min00", "Min05", "Min10", "Min15", "Min20", "Min25", "Min30", "Min35", "Min40", "Min45", "Min50", "Min55"""")
)
}

"be the default one when starting at 4:00" in {
ComputeSchedule.computeSchedule(4,0,5) must beEqualTo (
Full(""""Min00", "Min05", "Min10", "Min15", "Min20", "Min25", "Min30", "Min35", "Min40", "Min45", "Min50", "Min55"""")
Right(""""Min00", "Min05", "Min10", "Min15", "Min20", "Min25", "Min30", "Min35", "Min40", "Min45", "Min50", "Min55"""")
)
}

"be the default one of by 2 minutes when starting at 4:02" in {
ComputeSchedule.computeSchedule(4,2,5) must beEqualTo (
Full(""""Min02", "Min07", "Min12", "Min17", "Min22", "Min27", "Min32", "Min37", "Min42", "Min47", "Min52", "Min57"""")
Right(""""Min02", "Min07", "Min12", "Min17", "Min22", "Min27", "Min32", "Min37", "Min42", "Min47", "Min52", "Min57"""")
)
}
}

"A squedule with non trivial interval" should {
"fail if a mix of hours and minutes" in {
ComputeSchedule.computeSchedule(0,0, 63) must beEqualTo (
Failure("Agent execution interval can only be defined as minutes (less than 60) or complete hours, (1 hours 3 minutes is not supported)")
Left(Inconsistency("Agent execution interval can only be defined as minutes (less than 60) or complete hours, (1 hours 3 minutes is not supported)"))
)
}

"be every hours if defined with an interval of 1 hour" in {
ComputeSchedule.computeSchedule(0,0,60) must beEqualTo (
Full(""""Hr00.Min00", "Hr01.Min00", "Hr02.Min00", "Hr03.Min00", "Hr04.Min00", "Hr05.Min00", "Hr06.Min00", "Hr07.Min00", "Hr08.Min00", "Hr09.Min00", "Hr10.Min00", "Hr11.Min00", "Hr12.Min00", "Hr13.Min00", "Hr14.Min00", "Hr15.Min00", "Hr16.Min00", "Hr17.Min00", "Hr18.Min00", "Hr19.Min00", "Hr20.Min00", "Hr21.Min00", "Hr22.Min00", "Hr23.Min00"""")
Right(""""Hr00.Min00", "Hr01.Min00", "Hr02.Min00", "Hr03.Min00", "Hr04.Min00", "Hr05.Min00", "Hr06.Min00", "Hr07.Min00", "Hr08.Min00", "Hr09.Min00", "Hr10.Min00", "Hr11.Min00", "Hr12.Min00", "Hr13.Min00", "Hr14.Min00", "Hr15.Min00", "Hr16.Min00", "Hr17.Min00", "Hr18.Min00", "Hr19.Min00", "Hr20.Min00", "Hr21.Min00", "Hr22.Min00", "Hr23.Min00"""")
)
}
"be every two hours if defined with an interval of 2 hours, and off by some minutes" in {
ComputeSchedule.computeSchedule(3,12,120) must beEqualTo (
Full(""""Hr01.Min12", "Hr03.Min12", "Hr05.Min12", "Hr07.Min12", "Hr09.Min12", "Hr11.Min12", "Hr13.Min12", "Hr15.Min12", "Hr17.Min12", "Hr19.Min12", "Hr21.Min12", "Hr23.Min12"""")
Right(""""Hr01.Min12", "Hr03.Min12", "Hr05.Min12", "Hr07.Min12", "Hr09.Min12", "Hr11.Min12", "Hr13.Min12", "Hr15.Min12", "Hr17.Min12", "Hr19.Min12", "Hr21.Min12", "Hr23.Min12"""")
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ import org.eclipse.jgit.lib.PersonIdent
import org.joda.time.DateTime
import org.specs2.matcher.MatchResult
import zio._
import zio.duration.durationInt
import zio.syntax._

import scala.concurrent.duration.FiniteDuration
Expand Down Expand Up @@ -272,10 +271,6 @@ object RestTestSetUp {
override def getAllInventories(): Box[Map[NodeId, NodeInventory]] = ???
override def getGlobalComplianceMode(): Box[GlobalComplianceMode] = ???
override def getGlobalAgentRun(): Box[AgentRunInterval] = ???
override def getAgentRunInterval: () => Box[Int] = ???
override def getAgentRunSplaytime: () => Box[Int] = ???
override def getAgentRunStartHour: () => Box[Int] = ???
override def getAgentRunStartMinute: () => Box[Int] = ???
override def getScriptEngineEnabled: () => Box[FeatureSwitch] = ???
override def getGlobalPolicyMode: () => Box[GlobalPolicyMode] = ???
override def getComputeDynGroups: () => Box[Boolean] = ???
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1823,10 +1823,6 @@ object RudderConfig extends Loggable {
, reportingServiceImpl
, rudderCf3PromisesFileWriterService
, new WriteNodeCertificatesPemImpl(Some(RUDDER_RELAY_RELOAD))
, () => configService.agent_run_interval().toBox
, () => configService.agent_run_splaytime().toBox
, () => configService.agent_run_start_hour().toBox
, () => configService.agent_run_start_minute().toBox
, () => configService.rudder_featureSwitch_directiveScriptEngine().toBox
, () => configService.rudder_global_policy_mode().toBox
, () => configService.rudder_generation_compute_dyngroups().toBox
Expand Down

0 comments on commit 9d3e61b

Please sign in to comment.