-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
package com.normation.plugins.scaleoutrelay | ||
|
||
import bootstrap.liftweb.RudderConfig | ||
import com.normation.box.IOToBox | ||
import com.normation.cfclerk.domain.TechniqueVersion | ||
import com.normation.eventlog.{EventActor, ModificationId} | ||
import com.normation.inventory.domain.NodeId | ||
import com.normation.rudder.domain.nodes.NodeGroup | ||
import com.normation.rudder.domain.nodes.NodeGroupCategoryId | ||
import com.normation.rudder.domain.nodes.NodeGroupId | ||
import com.normation.rudder.domain.policies._ | ||
import com.normation.rudder.domain.queries._ | ||
import com.normation.rudder.rule.category.RuleCategoryId | ||
import net.liftweb.common.Failure | ||
import net.liftweb.common.Full | ||
|
||
object ScaleOutRelayService { | ||
private val nodeInfosService = RudderConfig.nodeInfoService | ||
private val woLDAPNodeGroupRepository = RudderConfig.woNodeGroupRepository | ||
private val woLDAPNodeRepository = RudderConfig.woNodeRepository | ||
private val woDirectiveRepository = RudderConfig.woDirectiveRepository | ||
private val woRuleRepository = RudderConfig.woRuleRepository | ||
private val uuidGen = RudderConfig.stringUuidGenerator | ||
private val policyServerManagementService = RudderConfig.policyServerManagementService | ||
private val removeNodeService = RudderConfig.removeNodeService | ||
|
||
def saveAllObjects(uuid: NodeId, actor: EventActor, reason:Option[String]) = { | ||
for { | ||
updatedNode <- createNodeToPolicyServerType(uuid) | ||
commonDirective <- createCommonDirective(uuid) | ||
|
||
directDistribPolicy = createDirectiveDistributePolicy(uuid) | ||
ruleTarget = createPolicyServer(uuid) | ||
nodeGroup = createNodeGroup(uuid) | ||
ruleDistribPolicy = createRuleDistributePolicy(uuid) | ||
ruleSetup = createRuleSetup(uuid) | ||
modId = ModificationId(uuidGen.newUuid) | ||
categoryId = NodeGroupCategoryId("SystemGroups") | ||
activeTechniqueId = ActiveTechniqueId("distributePolicy") | ||
activeTechniqueIdCommon = ActiveTechniqueId("common") | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
removedNode <- removeNodeService.removeNode(uuid, modId, actor) | ||
|
||
g <- woLDAPNodeRepository.createNode(updatedNode, modId, actor, reason).toBox | ||
This comment has been minimized.
Sorry, something went wrong.
fanf
|
||
a <- woLDAPNodeGroupRepository.createPolicyServerTarget(ruleTarget, modId, actor, reason).toBox | ||
b <- woLDAPNodeGroupRepository.create(nodeGroup, categoryId, modId, actor, reason).toBox | ||
This comment has been minimized.
Sorry, something went wrong.
fanf
|
||
c <- woDirectiveRepository.saveSystemDirective(activeTechniqueId,directDistribPolicy, modId, actor, reason).toBox | ||
d <- woDirectiveRepository.saveSystemDirective(activeTechniqueIdCommon,commonDirective, modId, actor, reason).toBox | ||
e <- woRuleRepository.create(ruleSetup, modId, actor, reason).toBox | ||
f <- woRuleRepository.create(ruleDistribPolicy, modId, actor, reason).toBox | ||
|
||
} yield { | ||
uuid | ||
} | ||
} | ||
|
||
def createNodeToPolicyServerType(uuid: NodeId) = { | ||
This comment has been minimized.
Sorry, something went wrong.
fanf
|
||
for { | ||
nodeInfos <- nodeInfosService.getNodeInfo(uuid) | ||
node <- nodeInfos match { | ||
case Some(nodeinf) => Full(nodeinf.node) | ||
case _ => Failure(s"Update node to Policy Server failed, cannot find ${uuid.value}") | ||
} | ||
} yield { | ||
node.copy(id = uuid, name = uuid.value, isSystem = true, isPolicyServer = true) | ||
} | ||
} | ||
|
||
def createPolicyServer(uuid: NodeId) = { | ||
PolicyServerTarget(uuid) | ||
} | ||
|
||
def createNodeGroup(uuid: NodeId) = { | ||
val objectType = ObjectCriterion("node", Seq(Criterion("policyServerId", StringComparator, None),Criterion("agentName", AgentComparator, None))) | ||
val attribute = Criterion("agentName", StringComparator) | ||
val comparator = Equals | ||
val value = "cfengine" | ||
|
||
val attribute2 = Criterion("policyServerId", StringComparator) | ||
val comparator2 = Equals | ||
val value2 = uuid.value | ||
NodeGroup( | ||
NodeGroupId(s"hasPolicyServer-${uuid.value}") | ||
, s"All classic Nodes managed by ${uuid.value} policy server" | ||
, s"All classic Nodes known by Rudder directly connected to the ${uuid.value} server. This group exists only as internal purpose and should not be used to configure Nodes." | ||
, Some( | ||
Query( | ||
NodeAndPolicyServerReturnType | ||
, And | ||
, List(CriterionLine(objectType, attribute, comparator, value) | ||
, CriterionLine(objectType, attribute2, comparator2, value2)) | ||
) | ||
) | ||
, true | ||
, Set() | ||
, true | ||
, true | ||
) | ||
} | ||
|
||
def createDirectiveDistributePolicy(uuid: NodeId) = { | ||
Directive( | ||
DirectiveId(s"${uuid.value}-distributePolicy") | ||
, TechniqueVersion("1.0") | ||
, Map() | ||
, s"${uuid.value}-Distribute Policy" | ||
, "Distribute policy - Technical" | ||
, None | ||
, "" | ||
, 0 | ||
, true | ||
, true | ||
, Tags(Set.empty) | ||
) | ||
} | ||
|
||
def createCommonDirective(uuid: NodeId) = { | ||
for { | ||
nodeInfos <- nodeInfosService.getNodeInfo(uuid) | ||
This comment has been minimized.
Sorry, something went wrong.
fanf
|
||
hostname <- nodeInfos match { | ||
case Some(n) => Full(n.hostname) | ||
case _ => Failure(s"Cannot retrieve hostname of ${uuid.value}") | ||
This comment has been minimized.
Sorry, something went wrong.
fanf
|
||
} | ||
policyserverId <- nodeInfos match { | ||
case Some(n) => Full(n.policyServerId) | ||
case _ => Failure(s"Cannot retrieve Policy Server ID of ${uuid.value}") | ||
} | ||
authorizedNetworks <- policyServerManagementService.getAuthorizedNetworks(uuid) | ||
} yield { | ||
val parameters = | ||
Map ( | ||
"OWNER" -> Seq("${rudder.node.admin}") | ||
, "UUID" -> Seq("${rudder.node.id}") | ||
, "POLICYSERVER" -> Seq(hostname) | ||
, "POLICYSERVER_ID" -> Seq(policyserverId.value) | ||
, "POLICYSERVER_ADMIN" -> Seq("root") | ||
, "ALLOWEDNETWORK" -> authorizedNetworks | ||
) | ||
Directive( | ||
DirectiveId(s"common-${uuid.value}") | ||
, TechniqueVersion("1.0") | ||
, parameters | ||
, s"Common-${uuid.value}" | ||
, "Common - Technical" | ||
, None | ||
, "" | ||
, 0 | ||
, true | ||
, true | ||
, Tags(Set.empty) | ||
) | ||
} | ||
} | ||
|
||
def createRuleDistributePolicy(uuid: NodeId) = { | ||
Rule( | ||
RuleId(s"${uuid.value}-DP") | ||
, s"${uuid.value}-distributePolicy" | ||
, RuleCategoryId("rootRuleCategory") | ||
, Set(PolicyServerTarget(uuid)) | ||
, Set(DirectiveId(s"${uuid.value}-distributePolicy")) | ||
, "Distribute Policy - Technical" | ||
, "This rule allows to distribute policies to nodes" | ||
, true | ||
, true | ||
) | ||
} | ||
|
||
def createRuleSetup(uuid: NodeId) = { | ||
Rule( | ||
RuleId(s"hasPolicyServer-${uuid.value}") | ||
, s"Rudder system policy: basic setup (common)-${uuid.value}" | ||
, RuleCategoryId("rootRuleCategory") | ||
, Set(GroupTarget(NodeGroupId(s"hasPolicyServer-${uuid.value}"))) | ||
, Set(DirectiveId(s"common-${uuid.value}")) | ||
, "Common - Technical" | ||
, "This is the basic system rule which all nodes must have." | ||
, true | ||
, true | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package com.normation.plugins.scaleoutrelay.api | ||
|
||
|
||
import com.normation.eventlog.EventActor | ||
import com.normation.inventory.domain.NodeId | ||
import com.normation.plugins.scaleoutrelay.ScaleOutRelayService | ||
import com.normation.rudder.api.HttpAction.POST | ||
import com.normation.rudder.repository.json.DataExtractor.CompleteJson | ||
import com.normation.rudder.rest.EndpointSchema.syntax._ | ||
import com.normation.rudder.rest.RestUtils.toJsonError | ||
import com.normation.rudder.rest.RestUtils.toJsonResponse | ||
import com.normation.rudder.rest._ | ||
import com.normation.rudder.rest.lift.DefaultParams | ||
import com.normation.rudder.rest.lift.LiftApiModule | ||
import com.normation.rudder.rest.lift.LiftApiModuleProvider | ||
import net.liftweb.common.Box | ||
import net.liftweb.common.Full | ||
import net.liftweb.http.LiftResponse | ||
import net.liftweb.http.Req | ||
import net.liftweb.json.JsonAST.JValue | ||
import net.liftweb.json.JsonDSL._ | ||
import net.liftweb.json.NoTypeHints | ||
import sourcecode.Line | ||
|
||
|
||
|
||
sealed trait ScaleOutRelayApi extends EndpointSchema with GeneralApi with SortIndex | ||
object ScaleOutRelayApi extends ApiModuleProvider[ScaleOutRelayApi] { | ||
|
||
final case object PromoteNodeToRelay extends ScaleOutRelayApi with OneParam with StartsAtVersion10 { | ||
val z = implicitly[Line].value | ||
val description = "Promote a node to relay" | ||
val (action, path) = POST / "scaleoutrelay" / "promote" / "{nodeId}" | ||
} | ||
|
||
override def endpoints: List[ScaleOutRelayApi] = ca.mrvisser.sealerate.values[ScaleOutRelayApi].toList.sortBy( _.z ) | ||
} | ||
|
||
class ScaleOutRelayApiImpl( | ||
restExtractorService: RestExtractorService | ||
) extends LiftApiModuleProvider[ScaleOutRelayApi] { | ||
|
||
api => | ||
|
||
implicit val formats = net.liftweb.json.Serialization.formats((NoTypeHints)) | ||
override def schemas = ScaleOutRelayApi | ||
|
||
override def getLiftEndpoints(): List[LiftApiModule] = { | ||
ScaleOutRelayApi.endpoints.map { | ||
case ScaleOutRelayApi.PromoteNodeToRelay => PromoteNodeToRelay | ||
}.toList | ||
} | ||
|
||
def extractNodeUUID(json: JValue): Box[String] = { | ||
This comment has been minimized.
Sorry, something went wrong.
fanf
|
||
for { | ||
nodeUUID <- CompleteJson.extractJsonString(json, "UUID") | ||
} yield { | ||
nodeUUID | ||
} | ||
} | ||
|
||
def response(function: Box[JValue], req: Req, errorMessage: String, id: Option[String], dataName: String)(implicit action: String): LiftResponse = { | ||
RestUtils.response(restExtractorService, dataName, id)(function, req, errorMessage) | ||
} | ||
|
||
object PromoteNodeToRelay extends LiftApiModule { | ||
val schema = ScaleOutRelayApi.PromoteNodeToRelay | ||
val restExtractor = api.restExtractorService | ||
|
||
def process(version: ApiVersion, path: ApiPath, nodeId: String, req: Req, params: DefaultParams, authz: AuthzToken): LiftResponse = { | ||
val response: JValue = "toto" -> "Ok" | ||
val uuid = ScaleOutRelayService.saveAllObjects(NodeId(nodeId), EventActor("rudder"), Some(s"Promote node ${nodeId} to relay")) | ||
println(uuid) | ||
uuid match { | ||
case Full(id) => toJsonResponse(None,id.value)("promoteToRelay",true) | ||
case _ => toJsonError(None, s"Error when trying to promote mode $nodeId")("promoteToRelay",true) | ||
} | ||
} | ||
} | ||
} |
It feels like these three strings should be defined as constants somewhere (in the object, most likely)