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 #20437: Error when writing techniques via the technique editor #4059

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 @@ -113,38 +113,63 @@ final case class MethodNotFound(message : String, exception : Option[Throwable])
* with the given input file and config file
*/
trait RuddercOptionsForTarget[T <: RuddercTarget] {
def options(inputFilePath: String, configFilePath: String): List[String]
def options(techniquePath: String)(implicit ruddercConfig: RuddercConfig): List[String]
def targetName: String
}

object RuddercOptionsForTarget {
// the compile line is common to both target, only the file extension type for agent changes
def buildOptions(extension: String, techniquePath: String)(implicit ruddercConfig: RuddercConfig) = {
"compile" :: "--json-logs" :: "--format" :: extension ::
"--input" :: s"""${ruddercConfig.outputPath}/${techniquePath}/technique.rd""" ::
s"--config-file=${ruddercConfig.configFilePath}" :: Nil
}

implicit val cfengineRuddercOption = new RuddercOptionsForTarget[RuddercTarget.CFEngine.type] {
override def options(inputFilePath: String, configFilePath: String): List[String] = {
"compile" :: "-j" :: "-f" :: "cf" :: "-i" :: inputFilePath :: s"--config-file=${configFilePath}" :: Nil
override def options(techniquePath: String)(implicit ruddercConfig: RuddercConfig): List[String] = {
buildOptions("cf", techniquePath)
}
override def targetName: String = "CFEngine"
}

implicit val dscRuddercOption = new RuddercOptionsForTarget[RuddercTarget.DSC.type] {
override def options(inputFilePath: String, configFilePath: String): List[String] = {
"compile" :: "-j" :: "-f" :: "dsc" :: "-i" :: inputFilePath :: s"--config-file=${configFilePath}" :: Nil
override def options(techniquePath: String)(implicit ruddercConfig: RuddercConfig): List[String] = {
buildOptions("dsc", techniquePath)
}
override def targetName: String = "DSC"
}
}

class RudderCRunner (
object RuddercOptionForSave {
def options(techniquePath: String)(implicit ruddercConfig: RuddercConfig): List[String] = {
"save" :: "--json-logs" ::
"--input" :: s"""${ruddercConfig.outputPath}/${techniquePath}/technique.json""" ::
s"--config-file=${ruddercConfig.configFilePath}" :: Nil
}
}

final case class RuddercConfig(
configFilePath : String
, rudderCPath : String
, outputPath : String
)

class RudderCRunner(
configFilePath : String
, rudderCPath : String
, outputPath : String
) {

implicit val config = RuddercConfig(configFilePath, rudderCPath, outputPath)
import RuddercOptionsForTarget._

def compileForTarget[T <: RuddercTarget](techniquePath: String, configFilePath: String)(implicit ruddercOptionsForTarget: RuddercOptionsForTarget[T]) = {
/*
* `techniquePath` is the relative path of the technique.
*/
def compileForTarget[T <: RuddercTarget](techniquePath: String)(implicit ruddercOptionsForTarget: RuddercOptionsForTarget[T]) = {
for {
time_1 <- currentTimeMillis
r <- RunNuCommand.run(Cmd(rudderCPath, ruddercOptionsForTarget.options(s"""${outputPath}/${techniquePath}/technique.json""", configFilePath), Map.empty))
r <- RunNuCommand.run(Cmd(rudderCPath, ruddercOptionsForTarget.options(techniquePath), Map.empty))
res <- r.await
_ <- ZIO.when(res.code != 0) {
Inconsistency(
Expand All @@ -158,8 +183,12 @@ class RudderCRunner (

def writeOne[T <: RuddercTarget](target: T, ruddercTargets: Set[RuddercTarget], technique: EditorTechnique, methods: Map[BundleName, GenericMethod], fallback: AgentSpecificTechniqueWriter, outputPath: String, configFilePath: String) = {
if(ruddercTargets.contains(target)) {
TechniqueWriterLoggerPure.debug(s"Using rudderc for target '${target.name}' for technique '${technique.path}'") *>
compileForTarget[RuddercTarget.CFEngine.type](s"""${outputPath}/${technique.path}/technique.json""", configFilePath)
TechniqueWriterLoggerPure.debug(s"Using rudderc for target '${target.name}' for technique '${technique.path}'") *> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need test integration from end to end to catch these things

target match {
case RuddercTarget.DSC => compileForTarget[RuddercTarget.DSC.type](technique.path)
case RuddercTarget.CFEngine => compileForTarget[RuddercTarget.CFEngine.type](technique.path)
}
}
} else {
TechniqueWriterLoggerPure.debug(s"Using fallback technique generation in place of rudderc for technique '${technique.path}' because target '${target.name}' not enabled in settings") *>
fallback.writeAgentFiles(technique, methods)
Expand All @@ -170,7 +199,7 @@ class RudderCRunner (

for {
time_0 <- currentTimeMillis
r <- RunNuCommand.run(Cmd(rudderCPath, "save" :: "-j" :: "-i" :: s"""${outputPath}/${technique.path}/technique.json""" :: s"--config-file=${configFilePath}" :: Nil, Map.empty))
r <- RunNuCommand.run(Cmd(rudderCPath, RuddercOptionForSave.options(technique.path), Map.empty))
res <- r.await
_ <- ZIO.when(res.code != 0) {
Inconsistency(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ import com.normation.rudder.ncf.TechniqueReader
import com.normation.rudder.ncf.TechniqueSerializer
import com.normation.rudder.ncf.TechniqueWriter
import com.normation.rudder.services.policies.RuleApplicationStatusServiceImpl
import com.normation.rudder.services.queries.PendingNodesLDAPQueryChecker

/*
* This file provides all the necessary plumbing to allow test REST API.
Expand Down