aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2018-04-06 15:57:42 +1200
committerTom Ryder <tom@sanctum.geek.nz>2018-04-06 15:57:42 +1200
commitc34e00a9ef50d2d37c4cda6d666f8d4a25fc44c9 (patch)
tree6104830820a526e4e8658503fc3678cf8bd30927
downloadnagios-check-speedtest-servers-c34e00a9ef50d2d37c4cda6d666f8d4a25fc44c9.tar.gz
nagios-check-speedtest-servers-c34e00a9ef50d2d37c4cda6d666f8d4a25fc44c9.zip
First commitv0.01
-rw-r--r--LICENSE21
-rw-r--r--README.markdown24
-rwxr-xr-xcheck_speedtest_servers134
3 files changed, 179 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..b3215fc
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 Tom Ryder
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.markdown b/README.markdown
new file mode 100644
index 0000000..b9744da
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,24 @@
+check\_speedtest\_servers
+=========================
+
+Check that an Oookla Speedtest server with a specified URL and/or host is
+present on the public list of servers.
+
+ $ check_speedtest_servers --host example.com:8080
+ $ check_speedtest_servers --url http://example.com/upload.php
+ $ check_speedtest_servers --host example.com:8080 http://example.com/upload.php
+
+Thanks
+------
+
+This was written on company time with my employer [Inspire Net][1], who has
+generously allowed me to open source it.
+
+License
+-------
+
+Copyright (c) [Tom Ryder][2]. Distributed under [MIT License][3].
+
+[1]: https://www.inspire.net.nz/
+[2]: https://sanctum.geek.nz/
+[3]: https://opensource.org/licenses/MIT
diff --git a/check_speedtest_servers b/check_speedtest_servers
new file mode 100755
index 0000000..6b0aa10
--- /dev/null
+++ b/check_speedtest_servers
@@ -0,0 +1,134 @@
+#!/usr/bin/perl
+
+#
+# Check an Ookla Speedtest server with a specified URL and/or host is present
+# on the list of servers.
+#
+# Author: Tom Ryder <tom@sanctum.geek.nz>
+# Copyright: 2018 Tom Ryder
+#
+package Monitoring::Plugin::Speedtest::Servers;
+
+# Force me to write this properly
+use strict;
+use warnings;
+use utf8;
+
+# Require at least this Perl version
+# Should work even on very old Perls
+use 5.006;
+
+# Import required modules
+use English '-no_match_vars';
+use LWP::UserAgent ();
+use Monitoring::Plugin qw(%ERRORS);
+use XML::LibXML;
+
+# Decree package version
+our $VERSION = '0.01';
+
+# Add description and license package variables
+our $DESCRIPTION = <<'EOF';
+This plugin retrieves the list of speedtest servers from speedtest.net and
+checks for the presence of at least one server with the given host and/or URL.
+EOF
+our $LICENSE = <<'EOF';
+This plugin is distributed under an MIT license. See LICENSE, or visit
+<https://opensource.org/licenses/MIT>. Thanks to Inspire Net Ltd for allowing
+this open-source fork.
+EOF
+
+# Define custom options
+our @OPTS = (
+ {
+ spec => 'host|h=s',
+ label => 'HOSTNAME:PORT',
+ help => 'Hostname:port pair to find in list, usually *:8080',
+ },
+ {
+ spec => 'url|u=s',
+ label => 'URL',
+ help => 'URL to find in list, usually ends in /upload.php',
+ },
+);
+
+# URL from which the server list should be retrieved
+our $SERVERS_LIST_URL = 'https://www.speedtest.net/speedtest-servers.php';
+
+# Build Monitoring::Plugin object
+my $mp = Monitoring::Plugin->new(
+ usage => 'Usage: %s --host|-H HOSTNAME:PORT --url|-u URL',
+ version => $VERSION,
+ blurb => $DESCRIPTION,
+ license => $LICENSE,
+) or die "Failed plugin construct\n";
+
+# Anything that dies in here will raise ->plugin_die()
+eval {
+
+ # Define and parse custom options
+ for my $opt (@OPTS) {
+ $mp->add_arg( %{$opt} );
+ }
+ $mp->getopts();
+
+ # At least one of --host and --url must be specified
+ length $mp->opts->host
+ or length $mp->opts->url
+ or die "One or both --host or --url must be specified\n";
+
+ # Build a user agent that accepts only XML
+ my $ua = LWP::UserAgent->new();
+ $ua->default_header( Accept => 'application/xml;text/xml' );
+
+ # Attempt to retrieve the server list
+ my $response = $ua->get($SERVERS_LIST_URL);
+ $response->is_success
+ or die "$response->status_line\n";
+
+ # Parse the server list as an XML document
+ my $lxml = XML::LibXML->new();
+ my $doc = $lxml->load_xml( string => $response->decoded_content )
+ or die "Failed to parse response XML\n";
+
+ # Build an XPath query object
+ my $xpc = XML::LibXML::XPathContext->new($doc)
+ or die "Failed to build XPath query object on response XML\n";
+
+ # Build a query depending on which options we were provided
+ ## no critic (RequireInterpolationOfMetachars)
+ my $query = '/settings/servers/server';
+ if ( $mp->opts->url ) {
+ $query .= sprintf q{[@url='%s']}, $mp->opts->url;
+ }
+ if ( $mp->opts->host ) {
+ $query .= sprintf q{[@host='%s']}, $mp->opts->host;
+ }
+
+ # Check that we have at least one matching server
+ my @servers = $xpc->findnodes($query);
+ my $code = $mp->check_threshold(
+ check => scalar @servers,
+ critical => '1:',
+ );
+ my $message = sprintf '%u matching servers', scalar @servers;
+ $mp->add_message( $code, $message );
+
+ # Add OK-level messages showing the conditions we applied
+ # If we find an actual problem, "OK" will get replaced by ->check_messages()
+ if ( $mp->opts->host ) {
+ $mp->add_message( $ERRORS{OK}, sprintf 'host=%s', $mp->opts->host );
+ }
+ if ( $mp->opts->url ) {
+ $mp->add_message( $ERRORS{OK}, sprintf 'url=%s', $mp->opts->url );
+ }
+
+ # Exit with determined code and messages
+ $mp->plugin_exit(
+ $mp->check_messages(
+ join => q{, },
+ join_all => q{, },
+ ),
+ );
+
+} or $mp->plugin_die($EVAL_ERROR);