Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
ElaadF authored and clarktsiory committed Apr 4, 2024
1 parent a0787ba commit a6da78b
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 8 deletions.
Expand Up @@ -38,12 +38,15 @@
package com.normation.rudder.rest.data

import com.normation.inventory.domain.NodeId
import com.normation.rudder.domain.policies.Directive
import com.normation.rudder.domain.policies.DirectiveId
import com.normation.rudder.domain.policies.PolicyMode
import com.normation.rudder.domain.policies.Rule
import com.normation.rudder.domain.policies.RuleId
import com.normation.rudder.domain.reports._
import com.normation.rudder.domain.reports.ComplianceLevel
import com.normation.rudder.reports.ComplianceModeName
import com.normation.rudder.repository.FullActiveTechnique
import java.lang
import net.liftweb.json._
import net.liftweb.json.JsonAST
Expand Down Expand Up @@ -123,10 +126,11 @@ final case class ByDirectiveByNodeRuleCompliance(
)

final case class ByRuleDirectiveCompliance(
id: DirectiveId,
name: String,
compliance: ComplianceLevel,
components: Seq[ByRuleComponentCompliance]
id: DirectiveId,
name: String,
compliance: ComplianceLevel,
skippedDetails: Option[SkippedDetails],
components: Seq[ByRuleComponentCompliance]
)

sealed trait ByRuleComponentCompliance {
Expand Down Expand Up @@ -194,6 +198,44 @@ final case class ByRuleByNodeByDirectiveByValueCompliance(
values: Seq[ComponentValueStatusReport]
) extends ByRuleByNodeByDirectiveByComponentCompliance

final case class SkippedDetails(
overridingRuleId: RuleId,
overridingRuleName: String
)
final case class DirectiveComplianceOverride(
overridenRuleId: RuleId,
directiveId: DirectiveId,
directiveName: String,
overridingRuleId: RuleId
) {
def toComplianceByRule(rules: Map[RuleId, Rule]): ByRuleDirectiveCompliance = {
ByRuleDirectiveCompliance(
directiveId,
directiveName,
ComplianceLevel(), // TODO: no reports ?
Some(SkippedDetails(overridingRuleId, rules.get(overridingRuleId).map(_.name).getOrElse("unknown rule"))),
Seq.empty
)
}
}

object ComplianceOverrides {
def getOverridenDirective(
overrides: List[OverridenPolicy],
directives: Map[DirectiveId, (FullActiveTechnique, Directive)]
): List[DirectiveComplianceOverride] = {
val overridesData = for {
over <- overrides
(_, overridenDir) <- directives.get(over.policy.directiveId)
(_, overridingDir) <- directives.get(over.overridenBy.directiveId)
} yield {
DirectiveComplianceOverride(over.policy.ruleId, over.policy.directiveId, overridenDir.name, over.overridenBy.ruleId)

}
overridesData.toList
}
}

object GroupComponentCompliance {
// This function do the recursive treatment of components, we will have each time a pair of Sequence of tuple (NodeId , component compliance structure)
def recurseComponent(
Expand Down Expand Up @@ -644,6 +686,9 @@ object JsonCompliance {
~ ("name" -> directive.name)
~ ("compliance" -> directive.compliance.complianceWithoutPending(precision))
~ ("complianceDetails" -> percents(directive.compliance, precision))
~ ("skippedDetails" -> directive.skippedDetails.map(s =>
("overridingRuleId" -> s.overridingRuleId.serialize) ~ ("overridingRuleName" -> s.overridingRuleName)
))
~ ("components" -> components(directive.components, level, precision))
)
})
Expand Down
Expand Up @@ -66,6 +66,7 @@ import com.normation.rudder.rest.RestUtils._
import com.normation.rudder.rest.data._
import com.normation.rudder.services.nodes.NodeInfoService
import com.normation.rudder.services.reports.ReportingService
import com.normation.rudder.services.reports.ReportingServiceUtils
import com.normation.zio.currentTimeMillis
import net.liftweb.common._
import net.liftweb.http.LiftResponse
Expand Down Expand Up @@ -565,6 +566,28 @@ class ComplianceAPIService(
val t7 = System.currentTimeMillis()
TimingDebugLoggerPure.logEffect.trace(s"getByRulesCompliance - group reports by rules in ${t7 - t6} ms")

val overridesByRules = ruleObjects.keys.flatMap { ruleId =>
ComplianceOverrides
.getOverridenDirective(
ReportingServiceUtils.buildRuleStatusReport(ruleId, reportsByNode).overrides,
directives
)
.map(d => (d.overridenRuleId, d))
}.toMap

val overridesRules = overridesByRules.toSeq.map {
case (ruleId, overrideDirective) =>
val rule = ruleObjects.get(ruleId)
val nodeIds = rule.map(r => RoNodeGroupRepository.getNodeIds(allGroups, r.targets, nodeInfos)).getOrElse(Set.empty)
ByRuleRuleCompliance(
ruleId,
ruleObjects.get(ruleId).map(_.name).getOrElse("Unknown rule"),
ComplianceLevel(noAnswer = nodeIds.size),
compliance.mode,
Seq(overrideDirective.toComplianceByRule(ruleObjects)) // TODO: rule objects will not contain the overriding rules...
)
}

// for each rule for each node, we want to have a
// directiveId -> reporttype map
val nonEmptyRules = reportsByRule.toSeq.map {
Expand All @@ -588,9 +611,10 @@ class ComplianceAPIService(
directives.get(directiveId).map(_._2.name).getOrElse("Unknown directive"),
ComplianceLevel.sum(
nodeDirectives.map(_._2.compliance)
), // here we want the compliance by components of the directive.
// if level is high enough, get all components and group by their name
{
),
None, {
// here we want the compliance by components of the directive.
// if level is high enough, get all components and group by their name
val byComponents: Map[String, immutable.Iterable[(NodeId, ComponentStatusReport)]] = if (computedLevel < 3) {
Map()
} else {
Expand Down Expand Up @@ -638,7 +662,7 @@ class ComplianceAPIService(
)

// return the full list
val result = nonEmptyRules ++ initializedCompliances
val result = nonEmptyRules ++ overridesRules ++ initializedCompliances

val t10 = System.currentTimeMillis()
TimingDebugLoggerPure.logEffect.trace(s"getByRulesCompliance - Compute result in ${t10 - t9} ms")
Expand Down

0 comments on commit a6da78b

Please sign in to comment.