Project

General

Profile

Actions

User story #8563

closed

Make the quicksearch bar in menu able to also search rule, group, directive, etc

Added by François ARMAND almost 8 years ago. Updated over 7 years ago.

Status:
Released
Priority:
N/A
Category:
Web - UI & UX
Target version:
UX impact:
Suggestion strength:
User visibility:
Effort required:
Name check:
Fix check:
Regression:

Description

The current "quick search" bar is very limited, and only allows to search for nodes, by hostname. But of course we also want to search for all the directives using a given parameters, or touching a given path, or all the rules embeding a directive, etc - and of course, when an interesting item is found, we want to jump to its corresponding definition.

Contrary to usual rules, we proposed to build such quicksearch in Rudder 3.1 BUT behind a feature switch guard (disabled by default). The idea is that that feature is a major UX help but it does not touch any sensitive part of servers configuration, and is read-only on everything (contrary to the search used for group, for example) - it's just a new way to query information.

On the feature itself, we would like to keep it simple, what means, among other things, not be able to "and" or "or" things. In fact, the proposed quicksearch would be better view as big filter on Nodes, Groups, Directives, Parameters and Rules, we the whole query phrase is exactly looked for in the objects and only the one matching it are kept. That would also helps keep the response time low, and in such feature, it is much more important to be able to quickly iterate between queries to get what we are looking for than to be able to build the exact query matching the exact subset of elements we need.

For the same reason, only a subset of objects properties will be look for (typically, given the current state of Rudder, allowing to search on node by software would notably complexify the query engine and lower performance).

Queries can be refined by providing a subset of objects or attributes to look into. Attribute names used in REST API responses would be used for that.

For example, to only look for nodes with hostname containing "mysubdomain" you could write:

mysubdomain object:node attribute:hostname

And if you want to only get the rules and groups with "security policy" in their name or description, you could write:

security policy object:group object:rule attribute:displayName attribute:description attribute:longDescription attribute:shortDescription

Or more succintly:

security policy object:group,rule attribute:displayName,description,longDescription,shortDescription

All the object/attributes filters name case insensitive, and we will also configure aliases, so that you could write the previous request (yes, I tend to make object in their plural form):

security policy object:groups,rules attribute:name,description

Screenshot of the prototype is attached.

Some question:

- what are the correct names for filters? "object" feels okayish. Could be "type". "attribute" is quite long. "key" is short, but not very self-descriptive. Or perhaps just have a "filter" or "only" keyword, and the engine find by itself if it's an object or an attribute ?
- I'm pretty sure we want to limit the number of results by type, be have a chance to see the rules even if 5000 nodes matches. In the example, I limited to 3 for the example, but 50 or 100 seems better. What do you think ?
- as explained, I selected some attribute base on technical constraints (the list is below). Are you ok with the list ?
- what is the correct way to let an user discover what is searchable, and how? I'm thinking to two may ideas:

1/ have a query form UI displayed when the focus is on the input field, withe a tree clickable for each object, letting the user check what he wants for each (defaults: everything checked, clicking on an object select/unselect all its attributes). Of course, one would be able to also just write the filter by hand once he learned their name.

2/ just have a documentation openable near the field, with all attributes and their names and aliases.

In all case, it would be better to have completion on object/attribute names.

So, any feedback would be very welcomed!


Files


Subtasks 24 (0 open24 closed)

User story #8669: Remove old node search and feature switch in Rudder 3.3ReleasedVincent MEMBRÉ2016-10-05Actions
User story #9231: Remove migration script for (node properties, quicksearch) feature switch ReleasedBenoît PECCATTE2016-10-05Actions
Bug #10077: (old) Autocomplete jar is still presentReleasedVincent MEMBRÉActions
User story #9093: Document the new quick search barReleasedJonathan CLARKE2016-09-20Actions
User story #9102: Make the new Quicksearch UI beautifulReleasedVincent MEMBRÉ2016-09-22Actions
User story #9111: Adapt quicksearch for 4.0ReleasedFrançois ARMAND2016-09-22Actions
Bug #9117: Quicksearch test broken and attribute inconsistenciesReleasedVincent MEMBRÉ2016-09-25Actions
Bug #9121: Quicksearch is not looking for multiline inputsReleasedVincent MEMBRÉ2016-09-26Actions
Bug #9127: Quicksearch bar is broken in 3.2RejectedVincent MEMBRÉ2016-09-27Actions
Bug #9129: Bad title style for quicksearch activation in admin tabReleasedVincent MEMBRÉ2016-09-27Actions
Bug #9134: The link to the quicksearch doc is wrong in 3.1ReleasedVincent MEMBRÉ2016-09-27Actions
Bug #9136: The link to the quicksearch doc is wrong in 3.2ReleasedVincent MEMBRÉ2016-09-27Actions
Bug #9150: Repair quicksearch in 3.2ReleasedFrançois ARMAND2016-09-27Actions
Bug #9168: Empty page "Rudder -API settings"ReleasedFrançois ARMAND2016-09-28Actions
Bug #9170: Broken style on header bar in 3.2ReleasedVincent MEMBRÉ2016-09-28Actions
Bug #9183: quicksearch returns system rules/directives/groupsReleasedVincent MEMBRÉ2016-09-29Actions
Bug #9186: We must not use proprietary font "segoeui.ttf"ReleasedVincent MEMBRÉ2016-09-29Actions
Bug #9195: Quicksearch does not work on "is enable", directive name, and a lot of othersReleasedVincent MEMBRÉ2016-09-30Actions
Bug #9197: Quicksearch does not redirect to a rule when you are on the rule page. ReleasedVincent MEMBRÉ2016-09-30Actions
Bug #9210: The quicksearch "in" keyword is "enabled" and not "isenabled"ReleasedFrançois ARMAND2016-10-04Actions
Bug #9212: Quisearch does not show any nodesReleasedFrançois ARMAND2016-10-04Actions
Bug #9219: Searching on os type does not workReleasedNicolas CHARLES2016-10-04Actions
Bug #9221: When searching for a node "in:xxx", we see node id in place of node nameReleasedNicolas CHARLES2016-10-04Actions
Bug #9224: Quicksearch with in:parameter_[name,value] leads to error 500 on serverReleasedNicolas CHARLES2016-10-04Actions

Related issues 1 (0 open1 closed)

Has duplicate Rudder - User story #4294: Proposal: search function for rules and directivesRejected2013-12-30Actions
Actions #2

Updated by François ARMAND almost 8 years ago

The list of attributes on which we currently look

  //common
  final case object Name             extends QSAttribute { override val name = "displayName" }
  final case object Description      extends QSAttribute { override val name = "description" }
  final case object ShortDescription extends QSAttribute { override val name = "shortDescription" }
  final case object LongDescription  extends QSAttribute { override val name = "longDescription" }
  final case object IsEnabled        extends QSAttribute { override val name = "isEnabled" }

  //Nodes
  final case object NodeId          extends QSAttribute { override val name = "id" }
  final case object Fqdn            extends QSAttribute { override val name = "hostname" }
  final case object OsType          extends QSAttribute { override val name = "os.type" }
  final case object OsName          extends QSAttribute { override val name = "os.name" }
  final case object OsVersion       extends QSAttribute { override val name = "os.version" }
  final case object OsFullName      extends QSAttribute { override val name = "os.fullName" }
  final case object OsKernelVersion extends QSAttribute { override val name = "os.kernelVersion" }
  final case object OsServicePack   extends QSAttribute { override val name = "os.servicePack" }
  final case object Arch            extends QSAttribute { override val name = "architectureDescription" }
  final case object Ram             extends QSAttribute { override val name = "ram" }
  final case object IpAddresses     extends QSAttribute { override val name = "ipAddresses" }
  final case object PolicyServerId  extends QSAttribute { override val name = "policyServerId" }
  final case object Properties      extends QSAttribute { override val name = "properties" }
  final case object RudderRoles     extends QSAttribute { override val name = "rudderRoles" }

  //Groups
  final case object GroupId   extends QSAttribute { override val name = "id" }
  final case object IsDynamic extends QSAttribute { override val name = "isDynamic" }

  //Directives
  final case object DirectiveId       extends QSAttribute { override val name = "id" }
  final case object DirectiveVarName  extends QSAttribute { override val name = "var.name" }
  final case object DirectiveVarValue extends QSAttribute { override val name = "var.value" }
  final case object TechniqueName     extends QSAttribute { override val name = "techniqueName" }
  final case object TechniqueVersion  extends QSAttribute { override val name = "techniqueVersion" }

  //Parameters
  final case object ParameterName  extends QSAttribute { override val name = "id" }
  final case object ParameterValue extends QSAttribute { override val name = "value" }

  //Rules
  final case object RuleId       extends QSAttribute { override val name = "id" }
  final case object DirectiveIds extends QSAttribute { override val name = "directives" }
  final case object Targets      extends QSAttribute { override val name = "targets" }

With their aliases:

    val attributeNames = QSAttribute.all.map { a => a match {
      case Name              => (a, Set(Name.name, "name") )
      case Description       => (a, descriptions)
      case ShortDescription  => (a, descriptions)
      case LongDescription   => (a, descriptions)
      case IsEnabled         => (a, Set(IsEnabled.name, "enabled") )
      case NodeId            => (a, Set(NodeId.name, "nodeid") )
      case Fqdn              => (a, Set(Fqdn.name, "hostname") )
      case OsType            => (a, Set(OsType.name, "ostype", "os"))
      case OsName            => (a, Set(OsName.name, "osname", "os") ) //not also full name because osFullname contains osName, not the reverse
      case OsVersion         => (a, Set(OsVersion.name, "osversion", "os") )
      case OsFullName        => (a, Set(OsFullName.name, "osfullname", OsName.name, "osname", "os") )
      case OsKernelVersion   => (a, Set(OsKernelVersion.name, "oskernelversion", "oskernel", "kernel", "version", "os") )
      case OsServicePack     => (a, Set(OsServicePack.name, "osservicepack", "ossp", "sp", "servicepack", "os") )
      case Arch              => (a, Set(Arch.name, "architecture", "arch") )
      case Ram               => (a, Set(Ram.name, "memory") )
      case IpAddresses       => (a, Set(IpAddresses.name, "ip", "ips", "networkips") )
      case PolicyServerId    => (a, Set(PolicyServerId.name, "policyserver") )
      case Properties        => (a, Set(Properties.name, "node.props", "nodeprops", "node.properties", "nodeproperties") )
      case RudderRoles       => (a, Set(RudderRoles.name, "serverrole", "serverroles", "role", "roles") )
      case GroupId           => (a, Set(GroupId.name, "groupid") )
      case IsDynamic         => (a, Set(IsDynamic.name, "isdynamic") )
      case DirectiveId       => (a, Set(DirectiveId.name, "directiveid") )
      case DirectiveVarName  => (a, Set(DirectiveVarName.name, "directivevar", "parameter", "parameters", "variable", "variables") )
      case DirectiveVarValue => (a, Set(DirectiveVarValue.name,"directivevalue", "parameter", "parameters", "variable", "variables") )
      case TechniqueName     => (a, Set(TechniqueName.name, "technique", "techniqueid") )
      case TechniqueVersion  => (a, Set(TechniqueVersion.name, "technique", "techniqueid", "version") )
      case ParameterName     => (a, Set(ParameterName.name, "parametername", "paramname", "name", "parameter", "param") )
      case ParameterValue    => (a, Set(ParameterValue.name, "parametervalue", "paramvalue", "value", "parameter", "param") )
      case RuleId            => (a, Set(RuleId.name, "ruleid") )
      case DirectiveIds      => (a, Set(DirectiveIds.name, "directiveids", "id", "ids") )
      case Targets           => (a, Set(Targets.name, "target", "group", "groups") )
    } } 

<pre>
Actions #3

Updated by François ARMAND almost 8 years ago

  • Status changed from In progress to Pending technical review
  • Assignee changed from François ARMAND to Vincent MEMBRÉ
  • Pull Request set to https://github.com/Normation/rudder/pull/1119
Actions #4

Updated by Nicolas CHARLES almost 8 years ago

i'd really like to keep this simple. Object is clearly not an intuitive name for a "normal" user.
we could mimic the google search system : https://www.google.com/advanced_search

so, rather than object, we could use "in" :

security policy in:directives

oracle in:nodes

security policy in:directivesdescription

with node being node or nodes; directive being directive or directive (so always accept singular and plural); and for a specific attribute we could concatenate it (with nothing, with _, with -,etc)

what do you think ?

Actions #5

Updated by Janos Mattyasovszky almost 8 years ago

Nicolas CHARLES wrote:

we could mimic the google search system : https://www.google.com/advanced_search
what do you think ?

it sounds very promising!

Actions #6

Updated by Janos Mattyasovszky almost 8 years ago

François ARMAND wrote:

The list of attributes on which we currently look

 case Fqdn              => (a, Set(Fqdn.name, "hostname") ) 

Could you also add fqdn for FQDN ? :)

Actions #7

Updated by Maxime Longuet almost 8 years ago

For me, on a single input text box you write only keyword. And search engine automatically says find on node or directive or rule. Please not include langage tag on this search. Simple is better. If i want complex search engine i'm going to a form with more input.

Regards

Actions #8

Updated by Janos Mattyasovszky almost 8 years ago

Maybe if it could be enabled/disabled as a feature? Not sure currently there is such a thing as user profile settings, where one could enable/disable this on a per-user basis, but a global checkbox would also be nice if not everyone want so use such a feature...

Actions #9

Updated by François ARMAND almost 8 years ago

Nicolas CHARLES wrote:

i'd really like to keep this simple. Object is clearly not an intuitive name for a "normal" user.
we could mimic the google search system : https://www.google.com/advanced_search

so, rather than object, we could use "in" :
[...]
with node being node or nodes; directive being directive or directive (so always accept singular and plural); and for a specific attribute we could concatenate it (with nothing, with _, with -,etc)

what do you think ?

I like the "in" for object, but not that much the concatenation idea. Because if I want to look in all description (because I need to change a business word to another, for ex. I need to remove a client name), it will be cumbersome. But having a mighy "in", sufficiently smart to know what is an object and what is an attibute by itself allows:

security policy in:directives

oracle in:nodes

security policy in:directives,description

security policy in:descriptions

Janos Mattyasovszky wrote:

François ARMAND wrote:

The list of attributes on which we currently look

[...]

Could you also add fqdn for FQDN ? :)

Ah, that was the intent :) Good catch :)

Janos Mattyasovszky wrote:

Maybe if it could be enabled/disabled as a feature? Not sure currently there is such a thing as user profile settings, where one could enable/disable this on a per-user basis, but a global checkbox would also be nice if not everyone want so use such a feature...

We don't have user profile, but the new search bar is behind a feature switch, i.e a configuration checkbox in administration -> settings screen, saying something like "do you want to enable the new search?". Default is to keep the current bar for existing version, and use the new bar by default for next major Rudder version.

Maxime Longuet wrote:

For me, on a single input text box you write only keyword. And search engine automatically says find on node or directive or rule. Please not include langage tag on this search. Simple is better. If i want complex search engine i'm going to a form with more input.

It is the actual behavior. If you just write a keywords, it's search everywhere. The tags are here to help filter results. A typical use case is when you want to search on directive parameter something quite common elsewhere, like "root" which happens to be the Rudder server id (and it is everywhere: in groups, system directive names and values, rules, as policy server id of a lot of nodes, etc etc). So to limit the noise, you can specify that you only want to look at some place.

Actions #10

Updated by François ARMAND almost 8 years ago

  • Subject changed from Make the search bar in menu able to also search rule, group, directive, etc to Make the quicksearch bar in menu able to also search rule, group, directive, etc
Actions #11

Updated by François ARMAND almost 8 years ago

  • Has duplicate User story #4294: Proposal: search function for rules and directives added
Actions #12

Updated by François ARMAND almost 8 years ago

PR updated to add "fqdn" alias to "hostname" and change the filter mode into "in:directives,name,descriptions" mode.

Actions #13

Updated by Vincent MEMBRÉ over 7 years ago

  • Target version changed from 3.1.12 to 3.1.13
Actions #16

Updated by Vincent MEMBRÉ over 7 years ago

  • Target version changed from 3.1.13 to 3.1.14
Actions #17

Updated by Vincent MEMBRÉ over 7 years ago

  • Assignee changed from Vincent MEMBRÉ to François ARMAND
Actions #18

Updated by Vincent MEMBRÉ over 7 years ago

  • Pull Request deleted (https://github.com/Normation/rudder/pull/1119)
Actions #19

Updated by Vincent MEMBRÉ over 7 years ago

  • Pull Request set to https://github.com/Normation/rudder/pull/1188
Actions #20

Updated by Matthieu CERDA over 7 years ago

Actions #21

Updated by François ARMAND over 7 years ago

  • Status changed from Pending technical review to Pending release
  • % Done changed from 0 to 100
Actions #22

Updated by Vincent MEMBRÉ over 7 years ago

Actions #23

Updated by Vincent MEMBRÉ over 7 years ago

  • Status changed from Pending release to Released

This bug has been fixed in Rudder 3.1.15/14 and 3.2.8/7 which were released today.

Actions

Also available in: Atom PDF