New server subcommand on test API

Tests if a host/port combination is reachable via server_reachable.
This commit is contained in:
Gina Häußge 2017-10-18 17:11:22 +02:00
parent 01b3b8a0e0
commit 9c3d7bbbc3
4 changed files with 177 additions and 5 deletions

View file

@ -68,6 +68,21 @@ Test paths or URLs
when the test could be performed. The status code of the response does NOT reflect the
test result!
.. _sec-api-util-test-server:
server
Tests whether a provided server identified by host and port can be reached. Protocol can optionally be specified
as well. Supported parameters are:
* ``host``: The host to test. IP or host name. Mandatory.
* ``port``: The port to test. Integer. Mandatory.
* ``protocol``: The protocol to test with. ``tcp`` or ``udp``. Optional, defaults to ``tcp``.
* ``timeout``: A timeout for the test, in seconds. If no successful connection to the server could be established
within this time frame, the check will be considered a failure. Optional, defaults to 3.05 seconds.
The ``server`` command returns :http:statuscode:`200` with a :ref:`Server test result <sec-api-util-datamodel-servertestresult>`
when the test could be performed. The status code of the response does NOT reflect the test result!
Requires admin rights.
**Example 1**
@ -226,6 +241,35 @@ Test paths or URLs
}
}
**Example 6**
Test whether a server is reachable on a given port via TCP.
.. sourcecode:: http
POST /api/util/test HTTP/1.1
Host: example.com
X-Api-Key: abcdef...
Content-Type: application/json
{
"command": "server",
"host": "8.8.8.8",
"port": 53
}
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"host": "8.8.8.8",
"port": 53,
"protocol": "tcp",
"result": true
}
:json command: The command to execute, currently either ``path`` or ``url``
:json path: ``path`` command only: the path to test
:json check_type: ``path`` command only: the type of path to test for, either ``file`` or ``dir``
@ -233,8 +277,11 @@ Test paths or URLs
:json url: ``url`` command only: the URL to test
:json status: ``url`` command only: one or more expected status codes
:json method: ``url`` command only: the HTTP method to use for the check
:json timeout: ``url`` command only: the timeout for the HTTP request
:json timeout: ``url`` and ``server`` commands only: the timeout for the test request
:json response: ``url`` command only: whether to include response data and if so in what form
:json host: ``server`` command only: the server to test
:json port: ``server`` command only: the port to test
:json protocol: ``server`` command only: the protocol to test
:statuscode 200: No error occurred
.. _sec-api-util-datamodel:
@ -244,6 +291,9 @@ Data model
.. _sec-api-util-datamodel-pathtestresult:
Path test result
----------------
.. list-table::
:widths: 15 5 10 30
:header-rows: 1
@ -275,6 +325,9 @@ Data model
.. _sec-api-util-datamodel-urltestresult:
URL test result
---------------
.. list-table::
:widths: 15 5 10 30
:header-rows: 1
@ -306,3 +359,33 @@ Data model
- object
- A dictionary with all headers of the checked URL's response. Only present if ``response`` in the
request was set.
.. _sec-api-util-datamodel-servertestresult:
Server test result
------------------
.. list-table::
:widths: 15 5 10 30
:header-rows: 1
* - Name
- Multiplicity
- Type
- Description
* - ``host``
- 1
- string
- The host that was tested.
* - ``port``
- 1
- int
- The port that was tested
* - ``protocol``
- 1
- string
- The protocol that was tested, ``tcp`` or ``udp``
* - ``result``
- 1
- bool
- ``true`` if the check passed.

View file

@ -126,8 +126,16 @@
.done(function(response) {
if (response.result) {
// check passed
var content = response.response.content;
var mimeType = "image/jpeg";
var headers = response.response.headers;
if (headers && headers["content-type"]) {
mimeType = headers["content-type"].split(";")[0];
}
var image = $("#someimage");
image.
image.src = "data:" + mimeType + ";base64," + content;
} else {
// check failed
}
@ -153,6 +161,48 @@
:param object opts: Additional options for the request
:returns Promise: A `jQuery Promise <http://api.jquery.com/Types/#Promise>`_ for the request's response
.. js:function:: OctoPrintClient.util.testServer(host, port, additional, opts)
Test if a server is reachable. More options supported by the :ref:`server test command <sec-api-util-test-server>`
can be provided via the ``additional`` object.
**Example 1**
Test if ``8.8.8.8`` is reachable on port 53 within the default timeout.
.. code-block:: javascript
OctoPrint.util.testServer("8.8.8.8", 53)
.done(function(response) {
if (response.result) {
// check passed
} else {
// check failed
}
});
**Example 2**
Test if ``127.0.0.1`` is reachable on port 1234 and UDP.
.. code-block:: javascript
OctoPrint.util.testUrl("127.0.0.1", 1234, {"protocol": "udp"})
.done(function(response) {
if (response.result) {
// check passed
} else {
// check failed
}
});
:param string url: Host to test
:param int port: Port to test
:param object additional: Additional parameters for the test command
:param object opts: Additional options for the request
:returns Promise: A `jQuery Promise <http://api.jquery.com/Types/#Promise>`_ for the request's response
.. seealso::
:ref:`Util API <sec-api-util>`

View file

@ -243,7 +243,8 @@ def _logout(user):
def utilTestPath():
valid_commands = dict(
path=["path"],
url=["url"]
url=["url"],
server=["host", "port"]
)
command, data, response = get_json_command_from_request(request, valid_commands)
@ -336,7 +337,7 @@ def utilTestPath():
try:
timeout = float(data["timeout"])
except:
return make_response("{!r} is not a valid value for timeout (must be int or float)".format(data["timeout"]))
return make_response("{!r} is not a valid value for timeout (must be int or float)".format(data["timeout"]), 400)
if "status" in data:
request_status = data["status"]
@ -383,5 +384,33 @@ def utilTestPath():
headers=dict(response.headers),
content=content
)
return jsonify(**result)
elif command == "server":
host = data["host"]
try:
port = int(data["port"])
except:
return make_response("{!r} is not a valid value for port (must be int)".format(data["port"]), 400)
timeout = 3.05
if "timeout" in data:
try:
timeout = float(data["timeout"])
except:
return make_response("{!r} is not a valid value for timeout (must be int or float)".format(data["timeout"]), 400)
protocol = data.get("protocol", "tcp")
if protocol not in ("tcp", "udp"):
return make_response("{!r} is not a valid value for protocol, must be tcp or udp".format(protocol), 400)
from octoprint.util import server_reachable
reachable = server_reachable(host, port, timeout=timeout, proto=protocol)
result = dict(host=host,
port=port,
protocol=protocol,
result=reachable)
return jsonify(**result)

View file

@ -45,6 +45,16 @@
return this.test("url", data, opts);
};
OctoPrintUtilClient.prototype.testServer = function(host, port, additional, opts) {
additional = additional || {};
var data = $.extend({}, additional);
data.host = host;
data.port = port;
return this.test("server", data, opts);
};
OctoPrintClient.registerComponent("util", OctoPrintUtilClient);
return OctoPrintUtilClient;
});