Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #7375: Add an option in the web interface to completely disable reporting #955

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -42,7 +42,7 @@ import com.normation.cfclerk.domain.IntegerVType
import com.normation.cfclerk.domain.BooleanVType
import com.normation.cfclerk.domain.BasicStringVType
import com.normation.cfclerk.domain.RegexConstraint

import com.normation.rudder.reports.ComplianceModeName

class SystemVariableSpecServiceImpl extends SystemVariableSpecService {

Expand Down Expand Up @@ -164,8 +164,14 @@ class SystemVariableSpecServiceImpl extends SystemVariableSpecService {
, constraint = Constraint(
typeName = BasicStringVType(
regex = Some(RegexConstraint(
pattern = "(full-compliance|changes-only)"
, errorMsg = s"Forbiden value, only 'full-compliane' and 'changes-only' are authorized"
pattern = {
val allModes = ComplianceModeName.allModes.map(_.name).mkString("(", "|", ")")
allModes
}
, errorMsg = {
val allModes = ComplianceModeName.allModes.map(_.name).mkString("'", "' or '", "'")
s"Forbiden value, only ${allModes} are authorized"
}
))
)
, default=Some("full-compliance")
Expand Down
Expand Up @@ -49,7 +49,6 @@ import com.google.common.cache.CacheBuilder
import java.util.concurrent.TimeUnit
import com.google.common.cache.CacheLoader


/**
* Log information about compliance.
* This log is intended to be used in debug & trace level.
Expand All @@ -59,7 +58,6 @@ import com.google.common.cache.CacheLoader
object ComplianceDebugLogger extends Logger {
override protected def _logger = LoggerFactory.getLogger("explain_compliance")


//we have one logger defined by node.
//they automatically expires after some time.

Expand Down Expand Up @@ -121,9 +119,9 @@ object ComplianceDebugLogger extends Logger {
implicit class AgentRunConfigurationToLog(info: (NodeId, ComplianceMode, ResolvedAgentRunInterval)) {

private[this] def log(c: ComplianceMode, r: ResolvedAgentRunInterval): String = {
val h = c match {
case FullCompliance => ""
case ChangesOnly(_) => s", hearbeat every ${r.heartbeatPeriod} run(s)"
val h = c.mode match {
case ChangesOnly => s", hearbeat every ${r.heartbeatPeriod} run(s)"
case _ => ""
}
s"run interval: ${r.interval.toStandardMinutes.getMinutes} min${h}"
}
Expand All @@ -135,7 +133,4 @@ object ComplianceDebugLogger extends Logger {
}
}


}


Expand Up @@ -44,47 +44,71 @@ import net.liftweb.json._
* - error_only: only report for repaired and error reports.
*/

sealed trait ComplianceMode {
def name: String
sealed trait ComplianceModeName {
val name : String
}

final case object FullCompliance extends ComplianceMode {
case object FullCompliance extends ComplianceModeName {
val name = "full-compliance"
}
final case class ChangesOnly (
heartbeatPeriod : Int
)extends ComplianceMode {
val name = ChangesOnly.name
}

object ChangesOnly {
case object ChangesOnly extends ComplianceModeName {
val name = "changes-only"
}

case object ReportDisabled extends ComplianceModeName {
val name = "reports-disabled"
}

object ComplianceModeName {
val allModes : List[ComplianceModeName] = FullCompliance :: ChangesOnly :: ReportDisabled :: Nil

def parse (value : String) : Box[ComplianceModeName] = {
allModes.find { _.name == value } match {
case None =>
Failure(s"Unable to parse the compliance mode name '${value}'. was expecting ${allModes.map(_.name).mkString("'", "' or '", "'")}.")
case Some(mode) =>
Full(mode)
}
}
}

sealed trait ComplianceMode {
def mode: ComplianceModeName
def heartbeatPeriod : Int
val name = mode.name
}

case class GlobalComplianceMode (
mode : ComplianceModeName
, heartbeatPeriod : Int
) extends ComplianceMode

case class NodeComplianceMode (
mode : ComplianceModeName
, heartbeatPeriod : Int
, overrideGlobal : Boolean
) extends ComplianceMode

trait ComplianceModeService {
def getComplianceMode : Box[ComplianceMode]
def getGlobalComplianceMode : Box[GlobalComplianceMode]
}

class ComplianceModeServiceImpl (
readComplianceMode : () => Box[String]
, readHeartbeatFreq : () => Box[Int]
) extends ComplianceModeService {

def getComplianceMode : Box[ComplianceMode] = {
readComplianceMode() match {
case Full(FullCompliance.name) => Full(FullCompliance)
case Full(ChangesOnly.name) =>
readHeartbeatFreq() match {
case Full(freq) => Full(ChangesOnly(freq))
case eb : EmptyBox =>
val fail = eb ?~! "Could not get heartbeat period"
fail
}
case Full(value) =>
Failure(s"Unable to parse the compliance mode name. was expecting '${FullCompliance.name}' or '${ChangesOnly.name}' and got '${value}'")
case eb : EmptyBox =>
val fail = eb ?~! "Could not get compliance mode name"
fail
}
def getGlobalComplianceMode : Box[GlobalComplianceMode] = {
for {
modeName <- readComplianceMode()
mode <- ComplianceModeName.parse(modeName)
heartbeat <- readHeartbeatFreq()
} yield {
GlobalComplianceMode(
mode
, heartbeat
)
}
}
}
Expand Up @@ -94,8 +94,14 @@ trait AgentRunIntervalService {

}

class AgentRunIntervalServiceImpl(
nodeInfoService: NodeInfoService, readGlobalInterval: () => Box[Int], readGlobalStartHour: () => Box[Int], readGlobalStartMinute: () => Box[Int], readGlobalSplaytime: () => Box[Int], readGlobalHeartbeat: () => Box[Int]) extends AgentRunIntervalService {
class AgentRunIntervalServiceImpl (
nodeInfoService: NodeInfoService
, readGlobalInterval: () => Box[Int]
, readGlobalStartHour: () => Box[Int]
, readGlobalStartMinute: () => Box[Int]
, readGlobalSplaytime: () => Box[Int]
, readGlobalHeartbeat: () => Box[Int]
) extends AgentRunIntervalService {

override def getGlobalAgentRun(): Box[AgentRunInterval] = {
for {
Expand Down Expand Up @@ -151,4 +157,3 @@ object SyslogTCP extends SyslogProtocol {
object SyslogUDP extends SyslogProtocol {
val value = "UDP"
}

Expand Up @@ -78,7 +78,7 @@ import com.normation.rudder.services.policies.write.Cf3PromisesFileWriterService
import com.normation.rudder.services.policies.write.Cf3PromisesFileWriterService
import com.normation.rudder.services.policies.write.Cf3PolicyDraft
import com.normation.rudder.services.policies.write.Cf3PolicyDraftId

import com.normation.rudder.reports.GlobalComplianceMode

/**
* The main service which deploy modified rules and
Expand Down Expand Up @@ -124,7 +124,6 @@ trait PromiseGenerationService extends Loggable {
timeFetchAll = (System.currentTimeMillis - initialTime)
_ = logger.debug(s"All relevant information fetched in ${timeFetchAll}ms, start names historization.")


nodeContextsTime = System.currentTimeMillis
nodeContexts <- getNodeContexts(activeNodeIds, allNodeInfos, allInventories, globalParameters, globalAgentRun, globalComplianceMode) ?~! "Could not get node interpolation context"
timeNodeContexts = (System.currentTimeMillis - nodeContextsTime)
Expand All @@ -140,7 +139,6 @@ trait PromiseGenerationService extends Loggable {
_ = logger.debug(s"Historization of names done in ${timeHistorize}ms, start to build rule values.")
///// end ignoring


ruleValTime = System.currentTimeMillis
//only keep actually applied rules in a format where parameter analysis on directive is done.
ruleVals <- buildRuleVals(activeRuleIds, allRules, directiveLib, groupLib, allNodeInfos) ?~! "Cannot build Rule vals"
Expand All @@ -152,7 +150,6 @@ trait PromiseGenerationService extends Loggable {
timeBuildConfig = (System.currentTimeMillis - buildConfigTime)
_ = logger.debug(s"Node's target configuration built in ${timeBuildConfig}, start to update rule values.")


sanitizeTime = System.currentTimeMillis
_ <- forgetOtherNodeConfigurationState(config.map(_.nodeInfo.id).toSet) ?~! "Cannot clean the configuration cache"
sanitizedNodeConfig <- sanitize(config) ?~! "Cannot set target configuration node"
Expand Down Expand Up @@ -202,8 +199,6 @@ trait PromiseGenerationService extends Loggable {
result
}



/**
* Snapshot all information needed:
* - node infos
Expand Down Expand Up @@ -240,7 +235,6 @@ trait PromiseGenerationService extends Loggable {
*/
def findDependantRules() : Box[Seq[Rule]]


/**
* Rule vals are just rules with a analysis of parameter
* on directive done, so that we will be able to bind them
Expand All @@ -257,8 +251,6 @@ trait PromiseGenerationService extends Loggable {
, globalComplianceMode : ComplianceMode
): Box[Map[NodeId, InterpolationContext]]



/**
* From a list of ruleVal, find the list of all impacted nodes
* with the actual Cf3PolicyDraftBean they will have.
Expand All @@ -283,7 +275,6 @@ trait PromiseGenerationService extends Loggable {
*/
def forgetOtherNodeConfigurationState(keep: Set[NodeId]) : Box[Set[NodeId]]


/**
* Get the actual cached values for NodeConfiguration
*/
Expand Down Expand Up @@ -311,7 +302,6 @@ trait PromiseGenerationService extends Loggable {
*/
def writeNodeConfigurations(rootNodeId: NodeId, allNodeConfig: Map[NodeId, NodeConfiguration], versions: Map[NodeId, NodeConfigId], cache: Map[NodeId, NodeConfigurationCache]) : Box[Set[NodeConfiguration]]


/**
* Set the expected reports for the rule
* Caution : we can't handle deletion with this
Expand Down Expand Up @@ -348,7 +338,6 @@ trait PromiseGenerationService extends Loggable {
, globalStartMinute: Int
) : Box[Unit]


protected def computeNodeConfigIdFromCache(config: NodeConfigurationCache): NodeConfigId = {
NodeConfigId(config.hashCode.toString)
}
Expand Down Expand Up @@ -426,7 +415,7 @@ trait PromiseGeneration_performeIO extends PromiseGenerationService {
override def getGroupLibrary(): Box[FullNodeGroupCategory] = roNodeGroupRepository.getFullGroupLibrary()
override def getAllGlobalParameters: Box[Seq[GlobalParameter]] = parameterService.getAllGlobalParameters()
override def getAllInventories(): Box[Map[NodeId, NodeInventory]] = roInventoryRepository.getAllNodeInventories(AcceptedInventory)
override def getGlobalComplianceMode(): Box[ComplianceMode] = complianceModeService.getComplianceMode
override def getGlobalComplianceMode(): Box[GlobalComplianceMode] = complianceModeService.getGlobalComplianceMode
override def getGlobalAgentRun(): Box[AgentRunInterval] = agentRunService.getGlobalAgentRun()
override def getAppliedRuleIds(rules:Seq[Rule], groupLib: FullNodeGroupCategory, directiveLib: FullActiveTechniqueCategory, allNodeInfos: Map[NodeId, NodeInfo]): Set[RuleId] = {
rules.filter(r => ruleApplicationStatusService.isApplied(r, groupLib, directiveLib, allNodeInfos) match {
Expand All @@ -436,8 +425,6 @@ trait PromiseGeneration_performeIO extends PromiseGenerationService {

}



/**
* Build interpolation contexts.
*
Expand Down Expand Up @@ -479,7 +466,6 @@ trait PromiseGeneration_performeIO extends PromiseGenerationService {
}.map( _.toMap)
}


for {
globalSystemVariables <- systemVarService.getGlobalSystemVariables()
parameters <- buildParams(globalParameters) ?~! "Can not parsed global parameter (looking for interpolated variables)"
Expand Down Expand Up @@ -535,7 +521,6 @@ trait PromiseGeneration_buildRuleVals extends PromiseGenerationService {
trait PromiseGeneration_buildNodeConfigurations extends PromiseGenerationService with Loggable {
def roNodeGroupRepository: RoNodeGroupRepository


/**
* This is the draft of the policy, not yet a cfengine policy, but a level of abstraction between both
*/
Expand All @@ -551,9 +536,6 @@ trait PromiseGeneration_buildNodeConfigurations extends PromiseGenerationService
, directiveOrder : BundleOrder
) extends HashcodeCaching




/**
* From a list of ruleVal, find the list of all impacted nodes
* with the actual Cf3PolicyDraft they will have.
Expand All @@ -568,15 +550,12 @@ trait PromiseGeneration_buildNodeConfigurations extends PromiseGenerationService
, allNodeInfos : Map[NodeId, NodeInfo]
) : Box[Seq[NodeConfiguration]] = {


//step 1: from RuleVals to expanded rules vals
//1.1: group by nodes (because parameter expansion is node sensitive
//1.3: build node config, binding ${rudder.parameters} parameters


//1.1: group by nodes


val seqOfMapOfPolicyDraftByNodeId = ruleVals.map { ruleVal =>

val wantedNodeIds = groupLib.getNodeIds(ruleVal.targets, allNodeInfos)
Expand Down Expand Up @@ -675,7 +654,6 @@ trait PromiseGeneration_buildNodeConfigurations extends PromiseGenerationService

}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

trait PromiseGeneration_updateAndWriteRule extends PromiseGenerationService {
Expand Down Expand Up @@ -711,7 +689,6 @@ trait PromiseGeneration_updateAndWriteRule extends PromiseGenerationService {

def getNodeConfigurationCache(): Box[Map[NodeId, NodeConfigurationCache]] = nodeConfigurationService.getNodeConfigurationCache()


/**
* Detect changes in rules and update their serial
* Returns two seq : the updated rules, and the deleted rules
Expand Down Expand Up @@ -803,7 +780,6 @@ trait PromiseGeneration_updateAndWriteRule extends PromiseGenerationService {

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


trait PromiseGeneration_setExpectedReports extends PromiseGenerationService {
def reportingService : ExpectedReportsUpdate
def complianceCache : CachedFindRuleNodeStatusReports
Expand Down Expand Up @@ -883,7 +859,6 @@ trait PromiseGeneration_setExpectedReports extends PromiseGenerationService {
}
).toMap


//we also want to build the list of overriden directive based on unique techniques.
val overriden = configs.flatMap { nodeConfig =>
nodeConfig.policyDrafts.flatMap( x => x.overrides.map { case (ruleId, directiveId) =>
Expand All @@ -899,7 +874,6 @@ trait PromiseGeneration_setExpectedReports extends PromiseGenerationService {
}
}


trait PromiseGeneration_historization extends PromiseGenerationService {
def historizationService : HistorizationService

Expand All @@ -924,7 +898,4 @@ trait PromiseGeneration_historization extends PromiseGenerationService {
}
}



}