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 #12439: Allow to search on machine type in search nodes request (backport 4.1) #1906

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -90,8 +90,10 @@ sealed trait KeyValueComparator extends BaseComparator
case object HasKey extends KeyValueComparator { override val id = "hasKey" }

trait ComparatorList {


def comparators : Seq[CriterionComparator]
def comparatorForString(s:String) : Option[CriterionComparator] = {
def comparatorForString(s: String) : Option[CriterionComparator] = {
val lower = s.toLowerCase
for(comp <- comparators) {
if(lower == comp.id.toLowerCase) return Some(comp)
Expand All @@ -108,9 +110,9 @@ object OrderedComparators extends ComparatorList {
override def comparators : Seq[CriterionComparator] = BaseComparators.comparators ++ Seq(Lesser, LesserEq, Greater, GreaterEq)
}

sealed trait CriterionType extends ComparatorList {
sealed trait CriterionType extends ComparatorList {
/*
* validate the value and return a normalized one
* validate the value and returns a normalized one
* for the field.
* DO NOT FORGET TO USE attrs ! (especially 'id')
*/
Expand Down Expand Up @@ -169,7 +171,7 @@ trait TStringComparator extends CriterionType {
comparator match {
case Regex | NotRegex =>
try {
val _ = java.util.regex.Pattern.compile(v) //yes, "_" is not used, side effect are fabulous
val _ = java.util.regex.Pattern.compile(v) //yes, "_" is not used, side effects are fabulous! KEEP IT
Full(v)
} catch {
case ex: java.util.regex.PatternSyntaxException => Failure(s"The regular expression '${v}' is not valid. Expected regex syntax is the java one, documented here: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html", Full(ex), Empty)
Expand Down Expand Up @@ -315,6 +317,39 @@ case object MemoryComparator extends CriterionType {
}
}


case object MachineComparator extends CriterionType {

val machineTypes = "Virtual machine" :: "Physical machine" :: Nil

override def comparators = Seq(Equals, NotEquals)
override protected def validateSubCase(v: String, comparator:CriterionComparator) = {
if (null == v || v.length == 0) Failure("Empty string not allowed") else Full(v)
}

override def toLDAP(value: String) = Full(value)

override def buildFilter(attributeName: String, comparator: CriterionComparator, value: String): Filter = {
val v = value match {
// the machine can't belong to another type
case "Virtual machine" => OC_VM
case "Physical machine" => OC_PM
}
comparator match {
case Equals => IS(v)
case _ => NOT(IS(v))
}
}

override def toForm(value: String, func: String => Any, attrs: (String, String)*) : Elem =
SHtml.select(
(machineTypes map (e => (e,e))).toSeq
, { if(machineTypes.contains(value)) Full(value) else Empty}
, func
, attrs:_*
)
}

case object OstypeComparator extends CriterionType {
val osTypes = List("AIX", "BSD", "Linux", "Solaris", "Windows")
override def comparators = Seq(Equals, NotEquals)
Expand All @@ -341,10 +376,10 @@ case object OstypeComparator extends CriterionType {

override def toForm(value: String, func: String => Any, attrs: (String, String)*) : Elem =
SHtml.select(
(osTypes map (e => (e,e))).toSeq,
{ if(osTypes.contains(value)) Full(value) else Empty},
func,
attrs:_*
(osTypes map (e => (e,e))).toSeq
, { if(osTypes.contains(value)) Full(value) else Empty}
, func
, attrs:_*
)
}

Expand Down
Expand Up @@ -49,7 +49,7 @@ import com.normation.rudder.domain.NodeDit
import com.normation.rudder.domain.RudderLDAPConstants.A_NODE_PROPERTY

/*
* Here we define all data needed logic by the to create the search
* Here we define all data needed logic by the webapp to create the search
* form.
*
* The search form is organized in 4 levels :
Expand All @@ -73,7 +73,7 @@ case object QueryNodeDn extends DnType
case object QuerySoftwareDn extends DnType

/*
* Mapping datas for LDAP query processor
* Mapping data for LDAP query processor
*
* Here, we store what are the LDAP URL for each type,
* how join are made between them, etc.
Expand All @@ -100,8 +100,8 @@ final case class LDAPObjectTypeFilter(value: Filter)

class DitQueryData(dit:InventoryDit, nodeDit: NodeDit) {
private val peObjectCriterion = ObjectCriterion(OC_PE, Seq(
// Criterion(A_MACHINE_UUID, StringComparator),
// Criterion(A_MACHINE_DN, StringComparator), //we don't want to search on that
//Criterion(A_MACHINE_UUID, StringComparator),
//Criterion(A_MACHINE_DN, StringComparator), //we don't want to search on that
Criterion(A_DESCRIPTION, StringComparator),
Criterion(A_MODEL, StringComparator),
Criterion(A_SERIAL_NUMBER, StringComparator),
Expand All @@ -128,6 +128,7 @@ class DitQueryData(dit:InventoryDit, nodeDit: NodeDit) {

protected val criteriaSet = Set(
ObjectCriterion(OC_MACHINE, Seq(
Criterion("machineType", MachineComparator),
Criterion(A_MACHINE_UUID, StringComparator),
Criterion(A_NAME, StringComparator),
Criterion(A_DESCRIPTION, StringComparator),
Expand Down
Expand Up @@ -63,7 +63,7 @@ import com.normation.inventory.ldap.core.InventoryMapper
* - the quantity of data on the wires.
*
* The general tactic is to have a local cache (a map of nodeid -> nodeinfo),
* and before any access, we are checking of an update is necessary with
* and before any access, we are checking if an update is necessary with
* a very quick oracle.
* The oracle only look for at least one entry modified since the last oracle
* check, and if one is found, says the cache is dirty.
Expand Down
Expand Up @@ -120,7 +120,7 @@ object DefaultRequestLimits extends RequestLimits(0,0,0,0)
* for accepted nodes (it also checks that the node is registered
* in the ou=Nodes branch)
*/
class AccepetedNodesLDAPQueryProcessor(
class AcceptedNodesLDAPQueryProcessor(
nodeDit : NodeDit
, inventoryDit : InventoryDit
, processor : InternalLDAPQueryProcessor
Expand Down Expand Up @@ -184,6 +184,7 @@ class AccepetedNodesLDAPQueryProcessor(
}

override def process(query:Query) : Box[Seq[NodeInfo]] = {

//only keep the one of the form Full(...)
queryAndChekNodeId(query, NodeInfoService.nodeInfoAttributes, None).map { seq => seq.flatMap {
case QueryResult(nodeEntry, inventoryEntry,machine) =>
Expand Down Expand Up @@ -331,7 +332,7 @@ class InternalLDAPQueryProcessor(

//transform all the DNs we get to filters for the targeted object type
//here, we are objectType dependent: we use a mapping that is saying
// "for that objectType, that dnType is transformed into a filter like that"
//"for that objectType, that dnType is transformed into a filter like that"
val filterSeqSet : Seq[Set[Filter]] =
(dnMapSets map { case (dnType, dnMapSet) =>
dnMapSet map { dn => nodeJoinFilters(dnType)(dn) }
Expand Down
Expand Up @@ -105,7 +105,7 @@ class TestQueryProcessor extends Loggable {

val nodeInfoService = new NaiveNodeInfoServiceCachedImpl(ldap, nodeDit, DIT, removedDIT, pendingDIT, ldapMapper, inventoryMapper)

val queryProcessor = new AccepetedNodesLDAPQueryProcessor(
val queryProcessor = new AcceptedNodesLDAPQueryProcessor(
nodeDit,
DIT,
internalLDAPQueryProcessor,
Expand Down
Expand Up @@ -111,6 +111,7 @@ os.name.FreeBSD=FreeBSD
os.name.UnknownBSD=Other BSD

# Attributes
ldap.attr.machineType=Machine Type
ldap.attr.OS=Operating System Type
ldap.attr.osName=Operating System Name
ldap.attr.osFullName=Operating System Detailed Name
Expand Down
Expand Up @@ -1104,7 +1104,7 @@ object RudderConfig extends Loggable {
poolSize = 2)

//query processor for accepted nodes
private[this] lazy val queryProcessor = new AccepetedNodesLDAPQueryProcessor(
private[this] lazy val queryProcessor = new AcceptedNodesLDAPQueryProcessor(
nodeDitImpl,
acceptedNodesDitImpl,
new InternalLDAPQueryProcessor(roLdap, acceptedNodesDitImpl, ditQueryDataImpl, ldapEntityMapper),
Expand Down
Expand Up @@ -491,7 +491,7 @@ object SearchNodeComponent {
val otOptions : List[(String,String)] = {
val opts = Buffer[(String,String)]()
def add(s:String, pre:String="") = opts += ((s,pre + S.?("ldap.object."+s)))

add(OC_NODE)
add(OC_NET_IF, " ├─ ")
add(OC_FS, " ├─ ")
Expand Down