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 #4480: When restoring archive (full or groups) dynamic groups are created empty #2204

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class UpdateDynamicGroups(
}
}

private[this] def displayNodechange (nodes : Seq[NodeId]) : String = {
private[this] def displayNodechange (nodes : Set[NodeId]) : String = {
if (nodes.nonEmpty) {
nodes.map(_.value).mkString("[ ",", "," ]")
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ import com.normation.eventlog.EventLog
import com.normation.rudder.rule.category.RoRuleCategoryRepository
import com.normation.rudder.rule.category.GitRuleCategoryArchiver
import java.io.File

import com.normation.rudder.rule.category.ImportRuleCategoryLibrary
import com.normation.rudder.repository.EventLogRepository
import com.normation.rudder.batch.UpdateDynamicGroups
import com.normation.rudder.services.queries.DynGroupUpdaterService

class ItemArchiveManagerImpl(
roRuleRepository : RoRuleRepository
Expand Down Expand Up @@ -89,7 +90,7 @@ class ItemArchiveManagerImpl(
, eventLogger : EventLogRepository
, asyncDeploymentAgent : AsyncDeploymentAgent
, gitModificationRepo : GitModificationRepository
, updateDynamicGroups : UpdateDynamicGroups
, updateDynamicGroups : DynGroupUpdaterService
) extends
ItemArchiveManager with
Loggable with
Expand Down Expand Up @@ -273,8 +274,7 @@ class ItemArchiveManagerImpl(
eventLogged <- eventLogger.saveEventLog(modId,new ImportFullArchive(actor,archiveId, reason))
commit <- restoreCommitAtHead(commiter,"User %s requested full archive restoration to commit %s".format(actor.name,archiveId.value),archiveId,FullArchive,modId)
} yield {
// For now trigger both, at least we will end in correct state ... We should add a way to force a deployment in group updater, even if do not need by itself ...
updateDynamicGroups.startManualUpdate

asyncDeploymentAgent ! AutomaticStartDeployment(modId, actor)
archiveId
}
Expand Down Expand Up @@ -355,8 +355,9 @@ class ItemArchiveManagerImpl(
for {
parsed <- parseGroupLibrary.getArchive(archiveId)
imported <- importGroupLibrary.swapGroupLibrary(parsed, includeSystem)
dynGroup <- updateDynamicGroups.updateAll(modId,actor,reason)
} yield {
if(deploy) { updateDynamicGroups.startManualUpdate }
if(deploy) { asyncDeploymentAgent ! AutomaticStartDeployment(modId, actor) }
archiveId
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
package com.normation.rudder.services.queries

import com.normation.inventory.domain.NodeId
import com.normation.rudder.domain.nodes.NodeGroupId
import com.normation.rudder.domain.nodes.{NodeGroup, NodeGroupId}
import net.liftweb.common._
import com.normation.rudder.repository.WoNodeGroupRepository
import com.normation.rudder.repository.RoNodeGroupRepository
Expand All @@ -54,11 +54,18 @@ import com.normation.eventlog.ModificationId
* state pre-update.
*/
case class DynGroupDiff(
members:Seq[NodeId],
removed:Seq[NodeId],
added:Seq[NodeId]
members:Set[NodeId],
removed:Set[NodeId],
added:Set[NodeId]
) extends HashcodeCaching

object DynGroupDiff {
def apply(newGroup : NodeGroup, oldGroup : NodeGroup): DynGroupDiff = {
val plus = newGroup.serverList -- oldGroup.serverList
val minus = newGroup.serverList -- newGroup.serverList
DynGroupDiff(newGroup.serverList, minus, plus)
}
}

trait DynGroupUpdaterService {
/**
Expand All @@ -71,6 +78,10 @@ trait DynGroupUpdaterService {
* @return
*/
def update(dynGroupId:NodeGroupId, modId: ModificationId, actor:EventActor, reason:Option[String]) : Box[DynGroupDiff]

def updateAll(modId: ModificationId, actor:EventActor, reason:Option[String]) : Box[Seq[DynGroupDiff]]

def computeDynGroup (group : NodeGroup): Box[NodeGroup]
}


Expand All @@ -80,25 +91,44 @@ class DynGroupUpdaterServiceImpl(
queryProcessor : QueryProcessor
) extends DynGroupUpdaterService with Loggable {

override def computeDynGroup (group : NodeGroup): Box[NodeGroup] = {
for {
_ <- if(group.isDynamic) Full("OK") else Failure("Can not update a not dynamic group")
query <- Box(group.query) ?~! s"No query defined for group '${group.name}' (${group.id.value})"
newMembers <- queryProcessor.process(query) ?~! s"Error when processing request for updating dynamic group '${group.name}' (${group.id.value})"
//save
newMemberIdsSet = newMembers.map(_.id).toSet
} yield {
group.copy(serverList = newMemberIdsSet)
}
}

override def updateAll(modId: ModificationId, actor:EventActor, reason:Option[String]) : Box[Seq[DynGroupDiff]] = {
for {
allGroups <- roNodeGroupRepository.getAll()
dynGroups = allGroups.filter(_.isDynamic)
result <- com.normation.utils.Control.sequence(dynGroups) {
group =>
for {
newGroup <- computeDynGroup(group)
savedGroup <- woNodeGroupRepository.updateDynGroupNodes(newGroup, modId, actor, reason) ?~! s"Error when saving update for dynamic group '${group.name}' (${group.id.value})"
} yield {
DynGroupDiff(newGroup, group)
}
}
} yield {
result
}
}

override def update(dynGroupId:NodeGroupId, modId: ModificationId, actor:EventActor, reason:Option[String]) : Box[DynGroupDiff] = {

for {
(group,_) <- roNodeGroupRepository.getNodeGroup(dynGroupId)
isDynamic <- if(group.isDynamic) Full("OK") else Failure("Can not update a not dynamic group")
query <- group.query
newMembers <- queryProcessor.process(query) ?~! s"Error when processing request for updating dynamic group with id ${dynGroupId.value}"
//save
newMemberIdsSet = newMembers.map( _.id).toSet
savedGroup <- {
val newGroup = group.copy(serverList = newMemberIdsSet)
woNodeGroupRepository.updateDynGroupNodes(newGroup, modId, actor, reason)
} ?~! s"Error when saving update for dynamic group '${group.name}' (${group.id.value})"
(group,_) <- roNodeGroupRepository.getNodeGroup(dynGroupId)
newGroup <- computeDynGroup(group)
savedGroup <- woNodeGroupRepository.updateDynGroupNodes(newGroup, modId, actor, reason) ?~! s"Error when saving update for dynamic group '${group.name}' (${group.id.value})"
} yield {
val plus = newMemberIdsSet -- group.serverList
val minus = group.serverList -- newMemberIdsSet
DynGroupDiff(newMemberIdsSet.toSeq, minus.toSeq, plus.toSeq)
DynGroupDiff(newGroup, group)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ object RudderConfig extends Loggable {
val eventListDisplayer: EventListDisplayer = eventListDisplayerImpl
val asyncDeploymentAgent: AsyncDeploymentAgent = asyncDeploymentAgentImpl
val policyServerManagementService: PolicyServerManagementService = psMngtService
val updateDynamicGroupsService : DynGroupUpdaterService = dynGroupUpdaterService
val updateDynamicGroups: UpdateDynamicGroups = dyngroupUpdaterBatch
val checkInventoryUpdate = new CheckInventoryUpdate(nodeInfoServiceImpl, asyncDeploymentAgent, stringUuidGenerator, 15.seconds)
val databaseManager: DatabaseManager = databaseManagerImpl
Expand Down Expand Up @@ -1363,7 +1364,7 @@ object RudderConfig extends Loggable {
, logRepository
, asyncDeploymentAgentImpl
, gitModificationRepository
, dyngroupUpdaterBatch
, updateDynamicGroupsService
)

private[this] lazy val globalComplianceModeService : ComplianceModeService =
Expand Down Expand Up @@ -1629,12 +1630,14 @@ object RudderConfig extends Loggable {
private[this] lazy val categoryHierarchyDisplayerImpl: CategoryHierarchyDisplayer = new CategoryHierarchyDisplayer()
private[this] lazy val dyngroupUpdaterBatch: UpdateDynamicGroups = new UpdateDynamicGroups(
dynGroupServiceImpl
, new DynGroupUpdaterServiceImpl(roLdapNodeGroupRepository, woLdapNodeGroupRepository, queryProcessor)
, dynGroupUpdaterService
, asyncDeploymentAgentImpl
, uuidGen
, RUDDER_BATCH_DYNGROUP_UPDATEINTERVAL
)

private[this] lazy val dynGroupUpdaterService = new DynGroupUpdaterServiceImpl(roLdapNodeGroupRepository, woLdapNodeGroupRepository, queryProcessor)

private[this] lazy val dbCleaner: AutomaticReportsCleaning = {
val cleanFrequency = AutomaticReportsCleaning.buildFrequency(
RUDDER_BATCH_REPORTSCLEANER_FREQUENCY
Expand Down