diff --git a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/servers/PolicyServerManagementService.scala b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/servers/PolicyServerManagementService.scala index 33aad269bee..e4390f3582e 100644 --- a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/servers/PolicyServerManagementService.scala +++ b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/servers/PolicyServerManagementService.scala @@ -526,8 +526,8 @@ object PolicyServerConfigurationObjects { val objectType = ObjectCriterion("node", Seq(Criterion("policyServerId", StringComparator, None),Criterion("agentName", AgentComparator, None))) NodeGroup( NodeGroupId(s"hasPolicyServer-${nodeId.value}") - , s"All nodes managed by ${nodeId.value} policy server" - , s"All nodes known by Rudder directly connected to the ${nodeId.value} server. This group exists only as internal purpose and should not be used to configure Nodes." + , s"All nodes managed by '${nodeId.value}' policy server" + , s"All nodes known by Rudder directly connected to the '${nodeId.value}' server. This group exists only as internal purpose and should not be used to configure Nodes." , Nil , Some( Query( diff --git a/webapp/sources/rudder/rudder-web/src/main/scala/bootstrap/liftweb/checks/migration/CheckMigrateSystemTechniques7_0.scala b/webapp/sources/rudder/rudder-web/src/main/scala/bootstrap/liftweb/checks/migration/CheckMigrateSystemTechniques7_0.scala new file mode 100644 index 00000000000..c5d5ef05e76 --- /dev/null +++ b/webapp/sources/rudder/rudder-web/src/main/scala/bootstrap/liftweb/checks/migration/CheckMigrateSystemTechniques7_0.scala @@ -0,0 +1,207 @@ +/* +************************************************************************************* +* Copyright 2021 Normation SAS +************************************************************************************* +* +* This file is part of Rudder. +* +* Rudder is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* In accordance with the terms of section 7 (7. Additional Terms.) of +* the GNU General Public License version 3, the copyright holders add +* the following Additional permissions: +* Notwithstanding to the terms of section 5 (5. Conveying Modified Source +* Versions) and 6 (6. Conveying Non-Source Forms.) of the GNU General +* Public License version 3, when you create a Related Module, this +* Related Module is not considered as a part of the work and may be +* distributed under the license agreement of your choice. +* A "Related Module" means a set of sources files including their +* documentation that, without modification of the Source Code, enables +* supplementary functions or services in addition to those offered by +* the Software. +* +* Rudder is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Rudder. If not, see . + +* +************************************************************************************* +*/ + +package bootstrap.liftweb.checks.migration + +import com.normation.rudder.domain.logger.MigrationLogger +import com.normation.rudder.domain.policies.DirectiveUid + +import bootstrap.liftweb.BootstrapChecks + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.Future +import scala.util.Success + +import zio._ +import zio.syntax._ +import com.normation.errors._ +import com.normation.inventory.domain.NodeId +import com.normation.rudder.repository.RoDirectiveRepository +import com.normation.rudder.domain.Constants +import com.normation.ldap.sdk.LDAPConnectionProvider +import com.normation.ldap.sdk.RwLDAPConnection +import com.normation.rudder.domain.RudderDit +import com.normation.rudder.domain.logger.ApplicationLogger +import com.normation.rudder.services.nodes.NodeInfoService +import com.normation.rudder.services.servers.AllowedNetwork +import com.normation.rudder.services.servers.PolicyServer +import com.normation.rudder.services.servers.PolicyServerManagementService +import com.normation.rudder.services.servers.PolicyServers + +import com.unboundid.ldap.sdk.DN + +import zio.syntax._ +import com.normation.errors._ + + +/* + * This migration check looks if we need to migrate a 6.x Rudder to a 7.x set of + * techniques/directives/group/rules. + * See https://issues.rudder.io/issues/19650 for details of migration + */ + +class CheckMigratedSystemTechniques( + policyServerService : PolicyServerManagementService + , roDirectiveRepository: RoDirectiveRepository + , ldap : LDAPConnectionProvider[RwLDAPConnection] + , dit : RudderDit + ) extends BootstrapChecks { + + val allowedNetworks6_x_7_0 = new MigrateAllowedNetworks6_x_7_0(policyServerService, roDirectiveRepository) + + def DN(child: String, parentDN: DN) = new DN(child+","+parentDN.toString) + + val systemTechniquesCatDN = DN(s"activeTechniqueId=common,techniqueCategoryId=Rudder Internal", dit.ACTIVE_TECHNIQUES_LIB.dn) + + val activeTechniquesToRemove() + + override def description: String = "Migrate system configuration object and allowed networks to Rudder 7.0 format" + + override def checks() : Unit = { + ??? + } + + + /* + * migration is needed if there still exists an active technique named "inventory" since it's removal is the last + * step of the process. + */ + def checkMigrationNeeded(): IOResult[Boolean] = { + for { + con <- ldap + res <- con.exists(dit.ACTIVE_TECHNIQUES_LIB.) + } + } + + def removeServerRoles(): IOResult[Unit] = { + ??? + } + +} + + + + +/* + * This class includes a copy of 6.x "policyServerService" which knew how to get allowed networks from + * corresponding directives. + * It is a bit tweaked to work alone and with 7.0 data. + */ +class MigrateAllowedNetworks6_x_7_0( + policyServerService : PolicyServerManagementService + , roDirectiveRepository: RoDirectiveRepository +) { + + +///// from rudder 6.2 - policyServerSerice ///// + def buildCommonDirectiveId(policyServerId: NodeId) = DirectiveUid("common-" + policyServerId.value) + + /** + * The list of authorized network is not directly stored in an + * entry. We have to look for the DistributePolicy directive for + * that server and the rudderPolicyVariables: ALLOWEDNETWORK + */ + def getAuthorizedNetworks(policyServerId:NodeId) : IOResult[Seq[String]] = { + for { + directive <- roDirectiveRepository.getDirective(buildCommonDirectiveId(policyServerId)) + } yield { + val allowedNetworks = directive.toList.flatMap(_.parameters.getOrElse("ALLOWEDNETWORK", List())) + allowedNetworks.toList + } + } +///// end from rudder 6.2 - policyServerSerice ///// + + + /* + * Create allowedNetworks with new format for root and possible additionnal relay server given + * in parameter + */ + def createNewAllowedNetworkd(relayServers: List[NodeId]): IOResult[Unit] = { + def getOldAllowedNetFor(nodeId: NodeId) = { + getAuthorizedNetworks(nodeId).map(ips => + PolicyServer(nodeId, ips.map(ip => AllowedNetwork(ip, ip)).toList) + ) + } + + for { + root <- getOldAllowedNetFor(Constants.ROOT_POLICY_SERVER_ID) + relays <- ZIO.foreach(relayServers)(getOldAllowedNetFor) + all = PolicyServers(root, relays) + _ <- policyServerService.savePolicyServers(all) + } yield () + } + + +} + +class MigrateTechniques6_x_7_0( + ldap: LDAPConnectionProvider[RwLDAPConnection] + , dit : RudderDit +) { +///// from rudder 6.2 - policyServerSerice ///// + + /** + * Delete things related to a relay: + * - group: nodeGroupId=hasPolicyServer-${uuid},groupCategoryId=SystemGroups,groupCategoryId=GroupRoot,ou=Rudder,cn=rudder-configuration + * - rule target: ruleTarget=policyServer:${RELAY_UUID},groupCategoryId=SystemGroups,groupCategoryId=GroupRoot,ou=Rudder,cn=rudder-configuration + * - directive: directiveId=${RELAY_UUID}-distributePolicy,activeTechniqueId=distributePolicy,techniqueCategoryId=Rudder Internal,techniqueCategoryId=Active Techniques,ou=Rudder,cn=rudder-configuration + * - directive: directiveId=common-${RELAY_UUID},activeTechniqueId=common,techniqueCategoryId=Rudder Internal,techniqueCategoryId=Active Techniques,ou=Rudder,cn=rudder-configuratio + * - rule: ruleId=${RELAY_UUID}-DP,ou=Rules,ou=Rudder,cn=rudder-configuration + * - rule: ruleId=hasPolicyServer-${RELAY_UUID},ou=Rules,ou=Rudder,cn=rudder-configuration + */ + def deleteRelaySystemObjectsPure(policyServerId: NodeId): IOResult[Unit] = { + if(policyServerId == Constants.ROOT_POLICY_SERVER_ID) { + Inconsistency("Root server configuration elements can't be deleted").fail + } else { // we don't have specific validation to do: if the node is not a policy server, nothing will be done + def DN(child: String, parentDN: DN) = new DN(child+","+parentDN.toString) + val id = policyServerId.value + + for { + con <- ldap + _ <- con.delete(DN(s"nodeGroupId=hasPolicyServer-${id}", dit.GROUP.SYSTEM.dn)) + _ <- con.delete(DN(s"ruleTarget=policyServer:${id}", dit.GROUP.SYSTEM.dn)) + _ <- con.delete(DN(s"directiveId=${id}-distributePolicy,activeTechniqueId=distributePolicy,techniqueCategoryId=Rudder Internal", dit.ACTIVE_TECHNIQUES_LIB.dn)) + _ <- con.delete(DN(s"directiveId=common-${id},activeTechniqueId=common,techniqueCategoryId=Rudder Internal", dit.ACTIVE_TECHNIQUES_LIB.dn)) + _ <- con.delete(DN(s"ruleId=${id}-DP", dit.RULES.dn)) + _ <- con.delete(DN(s"ruleId=hasPolicyServer-${id}", dit.RULES.dn)) + _ = ApplicationLogger.info(s"System configuration object (rules, directives, groups) related to relay '${id}' were successfully deleted.") + } yield () + } + } +///// end from rudder 6.2 - policyServerSerice ///// + +}