Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
fanf committed Jun 15, 2022
1 parent 17f750a commit 293d595
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ package com.normation.rudder.rest.lift
import com.normation.cfclerk.domain.Technique
import com.normation.cfclerk.domain.TechniqueId
import com.normation.rudder.api.ApiVersion
import com.normation.rudder.apidata.JsonResponseObjects.JRDirective
import com.normation.rudder.apidata.JsonResponseObjects.JRRule
import com.normation.rudder.apidata.implicits._
import com.normation.rudder.configuration.ConfigurationRepository
Expand Down Expand Up @@ -155,7 +156,7 @@ class ArchiveApi(
ruleIds <- parseRuleIds(req)
directiveIds <- parseDirectiveIds(req)
techniquesIds <- parseTechniqueIds(req)
zippables <- archiveBuilderService.buildArchive(rootDirName, techniquesIds, ruleIds)
zippables <- archiveBuilderService.buildArchive(rootDirName, techniquesIds, directiveIds, ruleIds)
} yield {
zippables
}
Expand Down Expand Up @@ -313,7 +314,7 @@ class ZipArchiveBuilderService(
* Any missing object will lead to an error.
* For each element, an human readable name derived from the object name is used when possible.
*/
def buildArchive(rootDirName: String, techniqueIds: Seq[TechniqueId], ruleIds: Seq[RuleId]): IOResult[Chunk[Zippable]] = {
def buildArchive(rootDirName: String, techniqueIds: Seq[TechniqueId], directiveIds: Seq[DirectiveId], ruleIds: Seq[RuleId]): IOResult[Chunk[Zippable]] = {
// normalize to no slash at end
val root = rootDirName.strip().replaceAll("""/$""", "")

Expand All @@ -334,22 +335,30 @@ class ZipArchiveBuilderService(
name <- findName(rule.name, ".json", usedNames, RULES_DIR)
} yield Zippable(rulesDir + "/" + name, Some(getJsonZippableContent(json)))
}
// directives need access to technique, but we don't want to look up several time the same one
techniques <- RefM.make(Map.empty[TechniqueId, Technique])

// techniques are a bit complicated: we can have some that will go in the archive, and other
// that we need to retrieve because a directive needs it. So we keep a local cache of retrieved
// techniques.
directivesDir = root + "/" + DIRECTIVES_DIR
_ <- usedNames.update( _ + ((DIRECTIVES_DIR, Set.empty[String])))
directivesDirZip = Zippable(directivesDir, None)
directivesZip <- ZIO.foreach(directiveIds) { directiveId =>
for {
ad <- configRepo.getDirective(directiveId).notOptional(s"Rule with id ${directiveId.serialize} was not found in Rudder")
tech <- getTechnique(TechniqueId(ad.activeTechnique.techniqueName, ad.directive.techniqueVersion), techniques)
json = JRDirective.fromDirective(tech, ad.directive, None).toJsonPretty
name <- findName(ad.directive.name, ".json", usedNames, DIRECTIVES_DIR)
} yield Zippable(directivesDir + "/" + name, Some(getJsonZippableContent(json)))
}
// Techniques don't need name normalization, their name is already normalized
techniques <- RefM.make(Map.empty[TechniqueId, Technique])
techniquesDir = root + "/" + TECHNIQUES_DIR
techniquesDirZip = Zippable(techniquesDir, None)
techniquesZip <- ZIO.foreach(techniqueIds) { techniqueId =>
for {
technique <- getTechnique(techniqueId, techniques)
techZips <- getTechniqueZippable(techniquesDir, techniqueId)
} yield techZips
}
} yield {
Chunk(rootZip, rulesDirZip) ++ rulesZip ++ techniquesZip.flatten
Chunk(rootZip, rulesDirZip) ++ rulesZip ++ techniquesZip.flatten ++ directivesZip
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import com.normation.rudder.domain.appconfig.FeatureSwitch
import com.normation.rudder.domain.policies.RuleId
import com.normation.rudder.domain.policies.RuleUid
import com.normation.rudder.git.ZipUtils
import com.normation.utils.DateFormaterService

import better.files.File
import net.liftweb.common.Full
Expand All @@ -52,6 +53,7 @@ import net.liftweb.http.InMemoryResponse
import net.liftweb.http.OutputStreamResponse
import org.apache.commons.io.FileUtils
import org.eclipse.jgit.revwalk.RevWalk
import org.joda.time.DateTime
import org.junit.runner.RunWith
import org.specs2.mutable.Specification
import org.specs2.runner.JUnitRunner
Expand All @@ -69,7 +71,7 @@ class ArchiveApiTests extends Specification with AfterAll with Loggable {
val restTestSetUp = RestTestSetUp.newEnv
val restTest = new RestTest(restTestSetUp.liftRules)

val testDir = File("/tmp/test-rudder-response-content")
val testDir = File(s"/tmp/test-rudder-response-content-${DateFormaterService.serialize(DateTime.now())}")
testDir.createDirectoryIfNotExists(true)

override def afterAll(): Unit = {
Expand Down Expand Up @@ -147,6 +149,30 @@ class ArchiveApiTests extends Specification with AfterAll with Loggable {
}
}

"correctly build an archive of one directive" >> {

// rule with ID rule1 defined in com/normation/rudder/MockServices.scala has name:
// 10. Global configuration for all nodes
// so: 10__Global_configuration_for_all_nodes
val fileName = "10__Clock_Configuration.json"

val archiveName = "archive-directive"
restTestSetUp.archiveAPIModule.rootDirName.set(archiveName).runNow

restTest.testGETResponse("/api/archive/export?directives=directive1") {
case Full(OutputStreamResponse(out, _, _, _, 200)) =>
val zipFile = testDir/s"${archiveName}.zip"
val zipOut = new FileOutputStream(zipFile.toJava)
out(zipOut)
zipOut.close()
// unzip
ZipUtils.unzip(new ZipFile(zipFile.toJava), zipFile.parent.toJava).runNow

(testDir/s"${archiveName}/directives").children.toList.map(_.name) must containTheSameElementsAs(List(fileName))
case err => ko(s"I got an error in test: ${err}")
}
}


"correctly build an archive of one technique" >> {
val archiveName = "archive-technique"
Expand Down Expand Up @@ -174,7 +200,6 @@ class ArchiveApiTests extends Specification with AfterAll with Loggable {

val initRev = {
val head = restTestSetUp.mockGitRepo.gitRepo.db.exactRef("refs/heads/master")
import org.eclipse.jgit.revwalk.RevCommit
val walk = new RevWalk(restTestSetUp.mockGitRepo.gitRepo.db)
val commit = walk.parseCommit(head.getObjectId)
walk.dispose()
Expand Down Expand Up @@ -233,8 +258,7 @@ class ArchiveApiTests extends Specification with AfterAll with Loggable {
// unzip
ZipUtils.unzip(new ZipFile(zipFile.toJava), zipFile.parent.toJava).runNow

val r = (testDir / s"${archiveName}/rules/${ruleFileName}").contentAsString.fromJson[JQRule].getOrElse(throw new IllegalArgumentException(s"error in rule deserialization"))

//val r = (testDir / s"${archiveName}/rules/${ruleFileName}").contentAsString.fromJson[JQRule].getOrElse(throw new IllegalArgumentException(s"error in rule deserialization"))
//(r.shortDescription.getOrElse("") must beMatching("global config for all nodes")) and
((testDir/s"${archiveName}/techniques/${techniqueId}").children.toList.map(_.name) must containTheSameElementsAs(baseFiles))

Expand Down

0 comments on commit 293d595

Please sign in to comment.