Project

General

Profile

« Previous | Next » 

Revision 773dddb8

Added by François ARMAND almost 7 years ago

Fixes #10485: Inventory endpoint accepts inventory even if ldap or postgresql connectivity failed

View differences:

inventory-provisioning-web/src/main/scala/com/normation/inventory/provisioning/endpoint/FusionReportEndpoint.scala
import org.springframework.util.CollectionUtils.MultiValueMapAdapter
import org.springframework.http.HttpHeaders
import scala.util.control.NonFatal
import com.normation.ldap.sdk.LDAPConnectionProvider
import com.normation.ldap.sdk.RwLDAPConnection
import com.normation.inventory.ldap.core.InventoryDit
object FusionReportEndpoint{
val printer = PeriodFormat.getDefault
......
, queueSize: Int
, repo : FullInventoryRepository[Seq[LDIFChangeRecord]]
, digestService : InventoryDigestServiceV1
, ldap : LDAPConnectionProvider[RwLDAPConnection]
, nodeInventoryDit: InventoryDit
) extends Loggable {
//start the report processor actor
......
)
}
def save(report: InventoryReport) = {
(ReportProcessor !? report) match {
case OkToSave =>
//release connection
new ResponseEntity("Inventory correctly received and sent to inventory processor.\n", HttpStatus.ACCEPTED)
case TooManyInQueue =>
new ResponseEntity("Too many inventories waiting to be saved.\n", HttpStatus.SERVICE_UNAVAILABLE)
/*
* Before actually trying to save, check that LDAP is up to at least
* avoid the case where we are telling the use "everything is fine"
* but just fail after.
*/
def save(reportName: String, report: InventoryReport): ResponseEntity[String] = {
checkLdapAlive match {
case Full(ok) =>
(ReportProcessor !? report) match {
case OkToSave =>
//release connection
new ResponseEntity("Inventory correctly received and sent to inventory processor.\n", HttpStatus.ACCEPTED)
case TooManyInQueue =>
new ResponseEntity("Too many inventories waiting to be saved.\n", HttpStatus.SERVICE_UNAVAILABLE)
}
case eb: EmptyBox =>
val e = (eb ?~! s"There is an error with the LDAP backend preventing acceptation of inventory '${reportName}'")
logger.error(e.messageChain)
new ResponseEntity(e.messageChain, HttpStatus.INTERNAL_SERVER_ERROR)
}
}
/*
* A method that check LDAP health status.
* It must be quick and simple.
*/
def checkLdapAlive: Box[String] = {
for {
con <- ldap
res <- con.get(nodeInventoryDit.NODES.dn, "1.1")
} yield {
"ok"
}
}
......
// For now we set the status to certified since we want pending inventories to have their inventory signed
// When we will have a 'pending' status for keys we should set that value instead of certified
val certifiedReport = report.copy(node = report.node.copyWithMain(main => main.copy(keyStatus = CertifiedKey)))
save(certifiedReport)
save(inventory, certifiedReport)
} else {
// Signature is not valid, reject inventory
val msg = s"Rejecting Inventory '${inventory}' for Node '${report.node.main.id.value}' because signature is not valid, you can update the inventory key by running the following command '/opt/rudder/bin/rudder-keys change-key ${report.node.main.id.value} <your new public key>'"
......
digestService.getKey(report) match {
// Status is undefined => We accept unsigned inventory
case Full((_,UndefinedKey)) => {
save(report)
save(inventory, report)
}
// We are in certified state, refuse inventory with no signature
case Full((_,CertifiedKey)) =>
inventory-provisioning-web/src/main/scala/com/normation/inventory/provisioning/endpoint/config/AppConfig.scala
, WAITING_QUEUE_SIZE
, fullInventoryRepository
, new InventoryDigestServiceV1(fullInventoryRepository)
, rwLdapConnectionProvider
, pendingNodesDit
)
}
}

Also available in: Unified diff