diff --git a/docs/README.md b/docs/README.md index 3658cf6d6..f2dfc52e8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -392,7 +392,35 @@ Each issue has its own dropdown-menu, which typically contains: But note that there might be more possible solutions, some of which may actually be more preferred. * A navigation-command to go to a page for more details. -## Custom command documentation +## Command documentation + +### Internal documentation +When at least a part of a command is entered, the documentation will have a menu item to run a salt command that collects the internal documentation. +When the target field is still empty, all minions are asked to produce the documentation. +Otherwise the given target is used. When using identical minions, there is not much difference, but with minions on different operating systems, this helps to get the best matching documentation. +Although multiple minions may return the documentation, only the first answer is actually presented. +When some minions are offline, it may be useful to specify a target that does not include the offline minions, e.g. by specifying a single minion that is known to be online. + +### External documentation +When the function "Online reference for ..." is used, a set of URLs is produced. The URLs point to the SaltStack documentation on the `docs.saltproject.io` website. +When more parts of the command are already typed in, then more specific URLs become available. +This function does not execute a command to any minion. +When the command-box is opened for the first time, a list of command-providers is retrieved from all minions to determine which providers (categories) are available. +An alternative target can be specified in the configurationfile for retrieving the list. + +To skip retrieving this information, use value `SKIP`. +``` +test_providers_target: "SKIP" +``` + +To specify an alternative target to retrieve this information, use any other value. +This may be single minion-id, or any other minion pattern. +The target-type is automatically decided, just like in the "Target" field. +``` +test_providers_target: "minion7" +``` + +### Custom command documentation A custom HTML help text can be shown from the "Manual Run" overlay. To use it, diff --git a/saltgui/static/scripts/Api.js b/saltgui/static/scripts/Api.js index af447572b..be17b4fee 100644 --- a/saltgui/static/scripts/Api.js +++ b/saltgui/static/scripts/Api.js @@ -3,6 +3,7 @@ import {Character} from "./Character.js"; import {CommandBox} from "./CommandBox.js"; import {Router} from "./Router.js"; +import {TargetType} from "./TargetType.js"; import {Utils} from "./Utils.js"; export class HTTPError extends Error { @@ -180,11 +181,12 @@ export class API { return this.apiRequest("POST", "/", params); } - getLocalTestProviders () { + getLocalTestProviders (pTgt) { const params = { "client": "local", "fun": "test.providers", - "tgt": "*" + "tgt": pTgt, + "tgt_type": TargetType.getTargetTypeFromTarget(pTgt) }; return this.apiRequest("POST", "/", params); } diff --git a/saltgui/static/scripts/CommandBox.js b/saltgui/static/scripts/CommandBox.js index bc0112328..44228690a 100644 --- a/saltgui/static/scripts/CommandBox.js +++ b/saltgui/static/scripts/CommandBox.js @@ -485,12 +485,17 @@ export class CommandBox { return; } - const localTestProviders = pApi.getLocalTestProviders(); + const target = Utils.getStorageItem("session", "test_providers_target", "*"); + if (target === "SKIP") { + Documentation.PROVIDERS = {"SKIPPED": []}; + return; + } + const localTestProviders = pApi.getLocalTestProviders(target); localTestProviders.then((pData) => { Documentation._handleLocalTestProviders(pData); }, () => { - // VOID + Documentation.PROVIDERS = {"ERROR": []}; }); } diff --git a/saltgui/static/scripts/Documentation.js b/saltgui/static/scripts/Documentation.js index c0abe5901..04d622376 100644 --- a/saltgui/static/scripts/Documentation.js +++ b/saltgui/static/scripts/Documentation.js @@ -291,6 +291,12 @@ export class Documentation { if (Object.keys(Documentation.PROVIDERS).length === 0) { html += "

The documentation index has not been retrieved yet. We'll just assume this is a regular command.

"; concreteModules = [cmd[1]]; + } else if ("SKIPPED" in Documentation.PROVIDERS) { + html += "

The documentation index is skipped on this system. We'll just assume this is a regular command.

"; + concreteModules = [cmd[1]]; + } else if ("ERROR" in Documentation.PROVIDERS) { + html += "

The documentation index could not be retrieved. We'll just assume this is a regular command.

"; + concreteModules = [cmd[1]]; } switch (concreteModules.length) { diff --git a/saltgui/static/scripts/TargetType.js b/saltgui/static/scripts/TargetType.js index f57ae8f4f..54020bfea 100644 --- a/saltgui/static/scripts/TargetType.js +++ b/saltgui/static/scripts/TargetType.js @@ -87,30 +87,37 @@ export class TargetType { } } - static autoSelectTargetType (pTarget) { - - if (!TargetType.menuTargetType._system) { - // user has selected the value, do not touch it - return; - } - + static getTargetTypeFromTarget (pTarget) { if (Array.isArray(pTarget)) { - TargetType.menuTargetType._value = "list"; - } else if (pTarget.includes("@") || pTarget.includes(" ") || + return "list"; + } + if (pTarget.includes("@") || pTarget.includes(" ") || pTarget.includes("(") || pTarget.includes(")")) { // "@" is a strong indicator for compound target // but "space", "(" and ")" are also typical for compound target - TargetType.menuTargetType._value = "compound"; - } else if (pTarget.includes(",")) { + return "compound"; + } + if (pTarget.includes(",")) { // "," is a strong indicator for list target (when it is also not compound) - TargetType.menuTargetType._value = "list"; - } else if (pTarget.startsWith("#")) { + return "list"; + } + if (pTarget.startsWith("#")) { // "#" at the start of a line is a strong indicator for nodegroup target // this is not a SALTSTACK standard, but our own invention - TargetType.menuTargetType._value = "nodegroup"; - } else { - TargetType.menuTargetType._value = "glob"; + return "nodegroup"; } + return "glob"; + } + + static autoSelectTargetType (pTarget) { + + if (!TargetType.menuTargetType._system) { + // user has selected the value, do not touch it + return; + } + + const targetType = TargetType.getTargetTypeFromTarget (pTarget); + TargetType.menuTargetType._value = targetType; // show the new title TargetType._updateTargetTypeText(); diff --git a/saltgui/static/scripts/panels/Login.js b/saltgui/static/scripts/panels/Login.js index f88f1cd6b..8a5b207a9 100644 --- a/saltgui/static/scripts/panels/Login.js +++ b/saltgui/static/scripts/panels/Login.js @@ -484,6 +484,12 @@ export class LoginPanel extends Panel { const clusterInfo = "This is node " + id + " from cluster " + clusterId + " " + JSON.stringify(clusterPeers).replace(/"/g, ""); Utils.setStorageItem("session", "cluster_info", clusterInfo); } + + let testProvidersTarget = wheelConfigValuesData.test_providers_target; + if (!testProvidersTarget) { + testProvidersTarget = "*"; + } + Utils.setStorageItem("session", "test_providers_target", testProvidersTarget); } _onLoginFailure (error) {