User story #8563
closedMake the quicksearch bar in menu able to also search rule, group, directive, etc
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
Updated by François ARMAND over 8 years ago
- File rudder_quicksearch_ex2_2016-06-17_16-35-07.jpg rudder_quicksearch_ex2_2016-06-17_16-35-07.jpg added
- File rudder_quicksearch_ex1_2016-06-17_16-35-07.jpg rudder_quicksearch_ex1_2016-06-17_16-35-07.jpg added
- Description updated (diff)
Add screenshots
Updated by François ARMAND over 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>
Updated by François ARMAND over 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
Updated by Nicolas CHARLES over 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 ?
Updated by Janos Mattyasovszky over 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!
Updated by Janos Mattyasovszky over 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 ? :)
Updated by Maxime Longuet over 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
Updated by Janos Mattyasovszky over 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...
Updated by François ARMAND over 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_searchso, 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.
Updated by François ARMAND over 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
Updated by François ARMAND over 8 years ago
- Has duplicate User story #4294: Proposal: search function for rules and directives added
Updated by François ARMAND over 8 years ago
PR updated to add "fqdn" alias to "hostname" and change the filter mode into "in:directives,name,descriptions" mode.
Updated by Vincent MEMBRÉ over 8 years ago
- Target version changed from 3.1.12 to 3.1.13
Updated by Vincent MEMBRÉ over 8 years ago
Work in progess here: https://github.com/VinceMacBuche/rudder/commit/46580ed1ad1ad14d215db22f4c806c7253cf4ba5
Updated by Vincent MEMBRÉ over 8 years ago
Work in progess here: https://github.com/VinceMacBuche/rudder/commit/ef2d32676edb8e018a848f03973149b77a1869b8
Updated by Vincent MEMBRÉ over 8 years ago
- Target version changed from 3.1.13 to 3.1.14
Updated by Vincent MEMBRÉ over 8 years ago
- Assignee changed from Vincent MEMBRÉ to François ARMAND
Updated by Vincent MEMBRÉ over 8 years ago
- Pull Request deleted (
https://github.com/Normation/rudder/pull/1119)
Updated by Vincent MEMBRÉ over 8 years ago
- Pull Request set to https://github.com/Normation/rudder/pull/1188
Updated by Matthieu CERDA over 8 years ago
- Related to User story #9093: Document the new quick search bar added
Updated by François ARMAND about 8 years ago
- Status changed from Pending technical review to Pending release
- % Done changed from 0 to 100
Applied in changeset rudder|f7cb5f616e111665ab6b7f0a9af29123ed6bb6d3.
Updated by Vincent MEMBRÉ about 8 years ago
- Related to deleted (User story #9093: Document the new quick search bar)
Updated by Vincent MEMBRÉ about 8 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.
- 3.1: Announce Changelog
- 3.2: Announce Changelog
- Download: https://www.rudder-project.org/site/get-rudder/downloads/