Skip to content

Commit

Permalink
Fixes #24779: Groups compliance summary need API pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
clarktsiory committed Apr 26, 2024
1 parent 59c83fe commit e51a4c0
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

package com.normation.rudder.apidata

import cats.syntax.traverse.*
import com.normation.GitVersion
import com.normation.GitVersion.ParseRev
import com.normation.GitVersion.Revision
Expand All @@ -59,6 +60,7 @@ import com.normation.rudder.domain.properties.PropertyProvider
import com.normation.rudder.domain.queries.NodeReturnType
import com.normation.rudder.domain.queries.Query
import com.normation.rudder.domain.queries.QueryReturnType
import com.normation.rudder.domain.reports.CompliancePrecision
import com.normation.rudder.rule.category.RuleCategory
import com.normation.rudder.rule.category.RuleCategoryId
import com.normation.rudder.services.queries.CmdbQueryParser
Expand Down Expand Up @@ -622,4 +624,14 @@ class ZioJsonExtractor(queryParser: CmdbQueryParser with JsonQueryLexer) {
}
}

def extractCompliancePrecisionFromParams(params: Map[String, List[String]]): PureResult[Option[CompliancePrecision]] = {
for {
precision <-
params.parseString("precision", s => s.toIntOption.toRight(s"percent precison must be an integer, was: '${s}'"))
res <- precision.traverse(CompliancePrecision.fromPrecision(_).toPureResult)
} yield {
res
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +244,6 @@ trait RoNodeGroupRepository {
// TODO: add QC
def getAll(): IOResult[Seq[NodeGroup]]

/**
* Get all node groups by ids
*/
def getAllByIds(ids: Seq[NodeGroupId]): IOResult[Seq[NodeGroup]]

/**
* Get all the node group id and the set of ndoes within
* Goal is to be more efficient
Expand Down Expand Up @@ -277,6 +272,14 @@ trait RoNodeGroupRepository {
qc: QueryContext
): IOResult[SortedMap[List[NodeGroupCategoryId], CategoryAndNodeGroup]]

/**
* Get all node groups grouped by their direct parent category.
* Group ids can be filtered, by default return all groups with an empty filter.
*/
def getGroupsByCategoryByIds(ids: Seq[NodeGroupId] = Seq.empty, includeSystem: Boolean = false)(implicit
qc: QueryContext
): IOResult[Map[NodeGroupCategory, Seq[NodeGroup]]]

/**
* Retrieve all groups that have at least one of the given
* node ID in there member list.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,52 @@ class RoLDAPNodeGroupRepository(
}
}

def getGroupsByCategoryByIds(ids: Seq[NodeGroupId], includeSystem: Boolean = false)(implicit
qc: QueryContext
): IOResult[Map[NodeGroupCategory, Seq[NodeGroup]]] = {
groupLibMutex.readLock {
for {
con <- ldap
entries <- if (ids.isEmpty) con.searchSub(rudderDit.GROUP.dn, IS(OC_RUDDER_NODE_GROUP))
else con.searchSub(rudderDit.GROUP.dn, OR(ids.map(id => EQ(A_NODE_GROUP_UUID, id.serialize))*))
groups <- ZIO.foreach(entries)(groupEntry => {
for {
g <- mapper
.entry2NodeGroup(groupEntry)
.toIO
.chainError(s"Error when mapping server group entry into a Group instance. Entry: ${groupEntry}")
allNodes <- nodeFactRepo.getAll()
nodeIds = g.serverList.intersect(allNodes.keySet.toSet)
y = g.copy(serverList = nodeIds)
} yield (groupEntry, y)
})
cats <-
ZIO.foreach(groups) {
case (groupEntry, g) => {
for {
parentCategoryEntry <-
con
.get(groupEntry.dn.getParent)
.notOptional(s"Parent category of entry with ID '${g.id.serialize}' was not found")
parentCategory <-
mapper
.entry2NodeGroupCategory(parentCategoryEntry)
.toIO
.chainError(
"Error when transforming LDAP entry %s into an active technique category".format(parentCategoryEntry)
)
} yield {
parentCategory
}
}
}
result = cats.zip(groups).groupBy(_._1).map { case (cat, pairs) => (cat, pairs.map(_._2._2)) }
} yield {
result
}
}
}

def getNodeGroupOpt(id: NodeGroupId)(implicit qc: QueryContext): IOResult[Option[(NodeGroup, NodeGroupCategoryId)]] = {
groupLibMutex.readLock(for {
con <- ldap
Expand Down Expand Up @@ -446,23 +492,6 @@ class RoLDAPNodeGroupRepository(
}
}

def getAllByIds(ids: Seq[NodeGroupId]): IOResult[Seq[NodeGroup]] = {
for {
con <- ldap
// for each directive entry, map it. if one fails, all fails
entries <-
groupLibMutex.readLock(con.searchSub(rudderDit.GROUP.dn, OR(ids.map(id => EQ(A_NODE_GROUP_UUID, id.serialize))*)))
groups <- ZIO.foreach(entries)(groupEntry => {
mapper
.entry2NodeGroup(groupEntry)
.toIO
.chainError(s"Error when transforming LDAP entry into a Group instance. Entry: ${groupEntry}")
})
} yield {
groups
}
}

def getAllNodeIds(): IOResult[Map[NodeGroupId, Set[NodeId]]] = {
for {
con <- ldap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2356,8 +2356,17 @@ class MockNodeGroups(nodesRepo: MockNodes) {
} yield cat
}
override def getAll(): IOResult[Seq[NodeGroup]] = categories.get.map(_.allGroups.values.map(_.nodeGroup).toSeq)
override def getAllByIds(ids: Seq[NodeGroupId]): IOResult[Seq[NodeGroup]] = {
categories.get.map(_.allGroups.values.map(_.nodeGroup).filter(g => ids.contains(g.id)).toSeq)
override def getGroupsByCategoryByIds(ids: Seq[NodeGroupId], includeSystem: Boolean = false)(implicit
qc: QueryContext
): IOResult[Map[NodeGroupCategory, Seq[NodeGroup]]] = {
categories.get.map { root =>
val groups = root.allGroups.values.map(_.nodeGroup).filter(g => ids.contains(g.id)).toSeq
val categories = groups.map(g => root.categoryByGroupId(g.id)).distinct
categories.map { c =>
val cat = root.allCategories(c).toNodeGroupCategory
(cat, groups.filter(g => root.categoryByGroupId(g.id) == c))
}.toMap
}
}

override def getAllNodeIds(): IOResult[Map[NodeGroupId, Set[NodeId]]] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ final case class ByDirectiveByNodeRuleCompliance(
components: Seq[ByRuleByNodeByDirectiveByComponentCompliance]
)

final case class ByNodeGroupFullCompliance(
id: String,
name: String,
category: String,
targeted: ByNodeGroupCompliance,
global: ByNodeGroupCompliance
)
final case class ByNodeGroupCompliance(
id: String,
name: String,
Expand Down
Loading

0 comments on commit e51a4c0

Please sign in to comment.